aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/testing/sysfs-bus-pci-devices-cciss28
-rw-r--r--Documentation/ABI/testing/sysfs-class-uwb_rc-wusbhc (renamed from Documentation/ABI/testing/sysfs-class-usb_host)4
-rw-r--r--Documentation/SubmittingPatches2
-rw-r--r--Documentation/arm/tcm.txt10
-rw-r--r--Documentation/cgroups/cgroups.txt11
-rw-r--r--Documentation/connector/cn_test.c2
-rw-r--r--Documentation/connector/connector.txt8
-rw-r--r--Documentation/debugging-via-ohci1394.txt8
-rw-r--r--Documentation/feature-removal-schedule.txt30
-rw-r--r--Documentation/filesystems/ext3.txt16
-rw-r--r--Documentation/filesystems/ext4.txt13
-rw-r--r--Documentation/filesystems/proc.txt1
-rw-r--r--Documentation/filesystems/vfat.txt2
-rw-r--r--Documentation/hwmon/ltc42157
-rw-r--r--Documentation/hwmon/ltc42457
-rw-r--r--Documentation/i2c/instantiating-devices2
-rw-r--r--Documentation/infiniband/user_mad.txt4
-rw-r--r--Documentation/infiniband/user_verbs.txt2
-rw-r--r--Documentation/isdn/INTERFACE.CAPI83
-rw-r--r--Documentation/kernel-parameters.txt1
-rw-r--r--Documentation/misc-devices/eeprom (renamed from Documentation/i2c/chips/eeprom)0
-rw-r--r--Documentation/misc-devices/max6875 (renamed from Documentation/i2c/chips/max6875)6
-rw-r--r--Documentation/networking/pktgen.txt8
-rw-r--r--Documentation/networking/timestamping/timestamping.c2
-rw-r--r--Documentation/scsi/hptiop.txt21
-rw-r--r--Documentation/sound/alsa/HD-Audio-Models.txt2
-rw-r--r--Documentation/vm/ksm.txt13
-rw-r--r--Documentation/vm/page-types.c304
-rw-r--r--Documentation/vm/pagemap.txt8
-rw-r--r--Documentation/w1/masters/ds24826
-rw-r--r--MAINTAINERS82
-rw-r--r--Makefile48
-rw-r--r--arch/arm/common/sa1111.c25
-rw-r--r--arch/arm/configs/h3600_defconfig1
-rw-r--r--arch/arm/configs/iop33x_defconfig554
-rw-r--r--arch/arm/configs/omap3_beagle_defconfig1
-rw-r--r--arch/arm/include/asm/bitops.h6
-rw-r--r--arch/arm/include/asm/glue.h26
-rw-r--r--arch/arm/include/asm/hardware/iop3xx.h1
-rw-r--r--arch/arm/include/asm/smp_plat.h16
-rw-r--r--arch/arm/include/asm/unistd.h1
-rw-r--r--arch/arm/kernel/entry-armv.S18
-rw-r--r--arch/arm/kernel/entry-common.S11
-rw-r--r--arch/arm/kernel/head-common.S4
-rw-r--r--arch/arm/kernel/smp.c13
-rw-r--r--arch/arm/kernel/smp_twd.c4
-rw-r--r--arch/arm/kernel/time.c1
-rw-r--r--arch/arm/kernel/traps.c81
-rw-r--r--arch/arm/mach-bcmring/core.c6
-rw-r--r--arch/arm/mach-bcmring/include/mach/system.h2
-rw-r--r--arch/arm/mach-davinci/board-dm365-evm.c1
-rw-r--r--arch/arm/mach-ep93xx/Kconfig44
-rw-r--r--arch/arm/mach-ep93xx/Makefile.boot9
-rw-r--r--arch/arm/mach-ep93xx/clock.c166
-rw-r--r--arch/arm/mach-ep93xx/core.c31
-rw-r--r--arch/arm/mach-ep93xx/edb93xx.c31
-rw-r--r--arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h42
-rw-r--r--arch/arm/mach-ep93xx/include/mach/gpio.h16
-rw-r--r--arch/arm/mach-ep93xx/include/mach/memory.h6
-rw-r--r--arch/arm/mach-ep93xx/include/mach/platform.h4
-rw-r--r--arch/arm/mach-ep93xx/micro9.c132
-rw-r--r--arch/arm/mach-integrator/pci_v3.c3
-rw-r--r--arch/arm/mach-iop32x/include/mach/iop32x.h2
-rw-r--r--arch/arm/mach-iop33x/include/mach/iop33x.h2
-rw-r--r--arch/arm/mach-ns9xxx/clock.c2
-rw-r--r--arch/arm/mach-omap2/board-rx51-peripherals.c80
-rw-r--r--arch/arm/mach-omap2/board-zoom2.c4
-rw-r--r--arch/arm/mach-omap2/clock24xx.c1
-rw-r--r--arch/arm/mach-omap2/clock34xx.c35
-rw-r--r--arch/arm/mach-omap2/clockdomain.c74
-rw-r--r--arch/arm/mach-omap2/pm-debug.c4
-rw-r--r--arch/arm/mach-omap2/pm34xx.c187
-rw-r--r--arch/arm/mach-omap2/powerdomain.c39
-rw-r--r--arch/arm/mach-pxa/cpufreq-pxa2xx.c2
-rw-r--r--arch/arm/mach-pxa/csb726.c2
-rw-r--r--arch/arm/mach-sa1100/Kconfig5
-rw-r--r--arch/arm/mach-sa1100/Makefile1
-rw-r--r--arch/arm/mach-sa1100/time.c2
-rw-r--r--arch/arm/mach-u300/gpio.c10
-rw-r--r--arch/arm/mach-u300/include/mach/gpio.h1
-rw-r--r--arch/arm/mm/Kconfig57
-rw-r--r--arch/arm/mm/Makefile4
-rw-r--r--arch/arm/mm/cache-v6.S20
-rw-r--r--arch/arm/mm/cache-v7.S19
-rw-r--r--arch/arm/mm/fault-armv.c9
-rw-r--r--arch/arm/mm/fault.c58
-rw-r--r--arch/arm/mm/highmem.c2
-rw-r--r--arch/arm/mm/init.c2
-rw-r--r--arch/arm/mm/mmap.c2
-rw-r--r--arch/arm/mm/mmu.c39
-rw-r--r--arch/arm/mm/pabort-legacy.S19
-rw-r--r--arch/arm/mm/pabort-v6.S19
-rw-r--r--arch/arm/mm/pabort-v7.S20
-rw-r--r--arch/arm/mm/proc-arm1020.S2
-rw-r--r--arch/arm/mm/proc-arm1020e.S2
-rw-r--r--arch/arm/mm/proc-arm1022.S2
-rw-r--r--arch/arm/mm/proc-arm1026.S2
-rw-r--r--arch/arm/mm/proc-arm6_7.S4
-rw-r--r--arch/arm/mm/proc-arm720.S2
-rw-r--r--arch/arm/mm/proc-arm740.S2
-rw-r--r--arch/arm/mm/proc-arm7tdmi.S2
-rw-r--r--arch/arm/mm/proc-arm920.S2
-rw-r--r--arch/arm/mm/proc-arm922.S2
-rw-r--r--arch/arm/mm/proc-arm925.S2
-rw-r--r--arch/arm/mm/proc-arm926.S2
-rw-r--r--arch/arm/mm/proc-arm940.S2
-rw-r--r--arch/arm/mm/proc-arm946.S2
-rw-r--r--arch/arm/mm/proc-arm9tdmi.S2
-rw-r--r--arch/arm/mm/proc-fa526.S2
-rw-r--r--arch/arm/mm/proc-feroceon.S2
-rw-r--r--arch/arm/mm/proc-mohawk.S2
-rw-r--r--arch/arm/mm/proc-sa110.S2
-rw-r--r--arch/arm/mm/proc-sa1100.S2
-rw-r--r--arch/arm/mm/proc-v6.S2
-rw-r--r--arch/arm/mm/proc-v7.S2
-rw-r--r--arch/arm/mm/proc-xsc3.S2
-rw-r--r--arch/arm/mm/proc-xscale.S2
-rw-r--r--arch/arm/plat-iop/pci.c3
-rw-r--r--arch/arm/plat-iop/time.c2
-rw-r--r--arch/arm/plat-omap/dma.c15
-rw-r--r--arch/arm/plat-omap/include/mach/cpu.h37
-rw-r--r--arch/arm/plat-omap/include/mach/powerdomain.h2
-rw-r--r--arch/arm/plat-omap/iovmm.c9
-rw-r--r--arch/arm/plat-omap/mcbsp.c2
-rw-r--r--arch/arm/plat-omap/sram.c3
-rw-r--r--arch/arm/plat-s3c24xx/adc.c1
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/mci.h3
-rw-r--r--arch/blackfin/ADI_BSD.txt41
-rw-r--r--arch/blackfin/Kconfig13
-rw-r--r--arch/blackfin/include/asm/atomic.h6
-rw-r--r--arch/blackfin/include/asm/bfin-global.h26
-rw-r--r--arch/blackfin/include/asm/bfin5xx_spi.h2
-rw-r--r--arch/blackfin/include/asm/bfin_rotary.h4
-rw-r--r--arch/blackfin/include/asm/bfin_simple_timer.h6
-rw-r--r--arch/blackfin/include/asm/bitops.h6
-rw-r--r--arch/blackfin/include/asm/blackfin.h5
-rw-r--r--arch/blackfin/include/asm/bug.h6
-rw-r--r--arch/blackfin/include/asm/byteorder.h5
-rw-r--r--arch/blackfin/include/asm/cache.h9
-rw-r--r--arch/blackfin/include/asm/cacheflush.h27
-rw-r--r--arch/blackfin/include/asm/cdef_LPBlackfin.h32
-rw-r--r--arch/blackfin/include/asm/checksum.h9
-rw-r--r--arch/blackfin/include/asm/clocks.h27
-rw-r--r--arch/blackfin/include/asm/context.S27
-rw-r--r--arch/blackfin/include/asm/cplb.h27
-rw-r--r--arch/blackfin/include/asm/cplbinit.h27
-rw-r--r--arch/blackfin/include/asm/cpu.h21
-rw-r--r--arch/blackfin/include/asm/def_LPBlackfin.h36
-rw-r--r--arch/blackfin/include/asm/dma-mapping.h6
-rw-r--r--arch/blackfin/include/asm/dpmc.h6
-rw-r--r--arch/blackfin/include/asm/early_printk.h22
-rw-r--r--arch/blackfin/include/asm/elf.h6
-rw-r--r--arch/blackfin/include/asm/entry.h6
-rw-r--r--arch/blackfin/include/asm/fcntl.h6
-rw-r--r--arch/blackfin/include/asm/fixed_code.h10
-rw-r--r--arch/blackfin/include/asm/flat.h5
-rw-r--r--arch/blackfin/include/asm/gpio.h27
-rw-r--r--arch/blackfin/include/asm/hardirq.h6
-rw-r--r--arch/blackfin/include/asm/io.h6
-rw-r--r--arch/blackfin/include/asm/irq.h19
-rw-r--r--arch/blackfin/include/asm/irq_handler.h6
-rw-r--r--arch/blackfin/include/asm/l1layout.h5
-rw-r--r--arch/blackfin/include/asm/linkage.h6
-rw-r--r--arch/blackfin/include/asm/mmu.h9
-rw-r--r--arch/blackfin/include/asm/mmu_context.h27
-rw-r--r--arch/blackfin/include/asm/module.h6
-rw-r--r--arch/blackfin/include/asm/mutex.h4
-rw-r--r--arch/blackfin/include/asm/nand.h12
-rw-r--r--arch/blackfin/include/asm/page.h6
-rw-r--r--arch/blackfin/include/asm/page_offset.h9
-rw-r--r--arch/blackfin/include/asm/pda.h21
-rw-r--r--arch/blackfin/include/asm/pgtable.h12
-rw-r--r--arch/blackfin/include/asm/poll.h7
-rw-r--r--arch/blackfin/include/asm/portmux.h5
-rw-r--r--arch/blackfin/include/asm/posix_types.h6
-rw-r--r--arch/blackfin/include/asm/processor.h6
-rw-r--r--arch/blackfin/include/asm/ptrace.h6
-rw-r--r--arch/blackfin/include/asm/sections.h6
-rw-r--r--arch/blackfin/include/asm/segment.h6
-rw-r--r--arch/blackfin/include/asm/sigcontext.h6
-rw-r--r--arch/blackfin/include/asm/siginfo.h6
-rw-r--r--arch/blackfin/include/asm/smp.h21
-rw-r--r--arch/blackfin/include/asm/spinlock.h6
-rw-r--r--arch/blackfin/include/asm/spinlock_types.h6
-rw-r--r--arch/blackfin/include/asm/stat.h6
-rw-r--r--arch/blackfin/include/asm/string.h6
-rw-r--r--arch/blackfin/include/asm/swab.h6
-rw-r--r--arch/blackfin/include/asm/system.h32
-rw-r--r--arch/blackfin/include/asm/thread_info.h24
-rw-r--r--arch/blackfin/include/asm/tlb.h6
-rw-r--r--arch/blackfin/include/asm/trace.h5
-rw-r--r--arch/blackfin/include/asm/traps.h13
-rw-r--r--arch/blackfin/include/asm/uaccess.h5
-rw-r--r--arch/blackfin/include/asm/unistd.h6
-rw-r--r--arch/blackfin/kernel/asm-offsets.c27
-rw-r--r--arch/blackfin/kernel/bfin_dma_5xx.c1
-rw-r--r--arch/blackfin/kernel/bfin_gpio.c27
-rw-r--r--arch/blackfin/kernel/cplb-mpu/cplbinit.c20
-rw-r--r--arch/blackfin/kernel/cplb-mpu/cplbmgr.c19
-rw-r--r--arch/blackfin/kernel/cplb-nompu/cplbinit.c19
-rw-r--r--arch/blackfin/kernel/cplb-nompu/cplbmgr.c16
-rw-r--r--arch/blackfin/kernel/cplbinfo.c26
-rw-r--r--arch/blackfin/kernel/dma-mapping.c27
-rw-r--r--arch/blackfin/kernel/early_printk.c23
-rw-r--r--arch/blackfin/kernel/entry.S27
-rw-r--r--arch/blackfin/kernel/fixed_code.S5
-rw-r--r--arch/blackfin/kernel/flat.c18
-rw-r--r--arch/blackfin/kernel/init_task.c27
-rw-r--r--arch/blackfin/kernel/irqchip.c27
-rw-r--r--arch/blackfin/kernel/module.c27
-rw-r--r--arch/blackfin/kernel/process.c27
-rw-r--r--arch/blackfin/kernel/ptrace.c28
-rw-r--r--arch/blackfin/kernel/setup.c6
-rw-r--r--arch/blackfin/kernel/shadow_console.c2
-rw-r--r--arch/blackfin/kernel/signal.c27
-rw-r--r--arch/blackfin/kernel/sys_bfin.c41
-rw-r--r--arch/blackfin/kernel/time-ts.c10
-rw-r--r--arch/blackfin/kernel/time.c64
-rw-r--r--arch/blackfin/kernel/traps.c27
-rw-r--r--arch/blackfin/kernel/vmlinux.lds.S27
-rw-r--r--arch/blackfin/lib/ashldi3.c27
-rw-r--r--arch/blackfin/lib/ashrdi3.c27
-rw-r--r--arch/blackfin/lib/checksum.c30
-rw-r--r--arch/blackfin/lib/divsi3.S28
-rw-r--r--arch/blackfin/lib/gcclib.h27
-rw-r--r--arch/blackfin/lib/lshrdi3.c27
-rw-r--r--arch/blackfin/lib/memchr.S27
-rw-r--r--arch/blackfin/lib/memcmp.S27
-rw-r--r--arch/blackfin/lib/memcpy.S37
-rw-r--r--arch/blackfin/lib/memmove.S27
-rw-r--r--arch/blackfin/lib/memset.S27
-rw-r--r--arch/blackfin/lib/modsi3.S36
-rw-r--r--arch/blackfin/lib/muldi3.S6
-rw-r--r--arch/blackfin/lib/outs.S29
-rw-r--r--arch/blackfin/lib/smulsi3_highpart.S6
-rw-r--r--arch/blackfin/lib/udivsi3.S27
-rw-r--r--arch/blackfin/lib/umodsi3.S27
-rw-r--r--arch/blackfin/lib/umulsi3_highpart.S6
-rw-r--r--arch/blackfin/mach-bf518/boards/ezbrd.c45
-rw-r--r--arch/blackfin/mach-bf518/dma.c28
-rw-r--r--arch/blackfin/mach-bf518/include/mach/bf518.h27
-rw-r--r--arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h29
-rw-r--r--arch/blackfin/mach-bf518/include/mach/blackfin.h29
-rw-r--r--arch/blackfin/mach-bf518/include/mach/cdefBF512.h29
-rw-r--r--arch/blackfin/mach-bf518/include/mach/cdefBF514.h29
-rw-r--r--arch/blackfin/mach-bf518/include/mach/cdefBF516.h29
-rw-r--r--arch/blackfin/mach-bf518/include/mach/cdefBF518.h70
-rw-r--r--arch/blackfin/mach-bf518/include/mach/cdefBF51x_base.h28
-rw-r--r--arch/blackfin/mach-bf518/include/mach/defBF512.h28
-rw-r--r--arch/blackfin/mach-bf518/include/mach/defBF514.h28
-rw-r--r--arch/blackfin/mach-bf518/include/mach/defBF516.h28
-rw-r--r--arch/blackfin/mach-bf518/include/mach/defBF518.h56
-rw-r--r--arch/blackfin/mach-bf518/include/mach/defBF51x_base.h28
-rw-r--r--arch/blackfin/mach-bf518/include/mach/gpio.h3
-rw-r--r--arch/blackfin/mach-bf518/include/mach/irq.h29
-rw-r--r--arch/blackfin/mach-bf518/include/mach/portmux.h6
-rw-r--r--arch/blackfin/mach-bf518/ints-priority.c27
-rw-r--r--arch/blackfin/mach-bf527/boards/cm_bf527.c61
-rw-r--r--arch/blackfin/mach-bf527/boards/ezbrd.c45
-rw-r--r--arch/blackfin/mach-bf527/boards/ezkit.c60
-rw-r--r--arch/blackfin/mach-bf527/dma.c28
-rw-r--r--arch/blackfin/mach-bf527/include/mach/bf527.h27
-rw-r--r--arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h29
-rw-r--r--arch/blackfin/mach-bf527/include/mach/blackfin.h29
-rw-r--r--arch/blackfin/mach-bf527/include/mach/cdefBF522.h29
-rw-r--r--arch/blackfin/mach-bf527/include/mach/cdefBF525.h29
-rw-r--r--arch/blackfin/mach-bf527/include/mach/cdefBF527.h29
-rw-r--r--arch/blackfin/mach-bf527/include/mach/cdefBF52x_base.h28
-rw-r--r--arch/blackfin/mach-bf527/include/mach/defBF522.h28
-rw-r--r--arch/blackfin/mach-bf527/include/mach/defBF525.h28
-rw-r--r--arch/blackfin/mach-bf527/include/mach/defBF527.h28
-rw-r--r--arch/blackfin/mach-bf527/include/mach/defBF52x_base.h28
-rw-r--r--arch/blackfin/mach-bf527/include/mach/gpio.h3
-rw-r--r--arch/blackfin/mach-bf527/include/mach/irq.h29
-rw-r--r--arch/blackfin/mach-bf527/include/mach/portmux.h6
-rw-r--r--arch/blackfin/mach-bf527/ints-priority.c27
-rw-r--r--arch/blackfin/mach-bf533/boards/H8606.c33
-rw-r--r--arch/blackfin/mach-bf533/boards/blackstamp.c29
-rw-r--r--arch/blackfin/mach-bf533/boards/cm_bf533.c45
-rw-r--r--arch/blackfin/mach-bf533/boards/ezkit.c132
-rw-r--r--arch/blackfin/mach-bf533/boards/ip0x.c37
-rw-r--r--arch/blackfin/mach-bf533/boards/stamp.c60
-rw-r--r--arch/blackfin/mach-bf533/dma.c28
-rw-r--r--arch/blackfin/mach-bf533/include/mach/bf533.h27
-rw-r--r--arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h29
-rw-r--r--arch/blackfin/mach-bf533/include/mach/blackfin.h28
-rw-r--r--arch/blackfin/mach-bf533/include/mach/cdefBF532.h28
-rw-r--r--arch/blackfin/mach-bf533/include/mach/defBF532.h44
-rw-r--r--arch/blackfin/mach-bf533/include/mach/gpio.h3
-rw-r--r--arch/blackfin/mach-bf533/include/mach/irq.h28
-rw-r--r--arch/blackfin/mach-bf533/include/mach/portmux.h6
-rw-r--r--arch/blackfin/mach-bf533/ints-priority.c27
-rw-r--r--arch/blackfin/mach-bf537/boards/cm_bf537e.c46
-rw-r--r--arch/blackfin/mach-bf537/boards/cm_bf537u.c46
-rw-r--r--arch/blackfin/mach-bf537/boards/minotaur.c6
-rw-r--r--arch/blackfin/mach-bf537/boards/pnav10.c31
-rw-r--r--arch/blackfin/mach-bf537/boards/stamp.c60
-rw-r--r--arch/blackfin/mach-bf537/boards/tcm_bf537.c46
-rw-r--r--arch/blackfin/mach-bf537/dma.c28
-rw-r--r--arch/blackfin/mach-bf537/include/mach/bf537.h27
-rw-r--r--arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h29
-rw-r--r--arch/blackfin/mach-bf537/include/mach/blackfin.h29
-rw-r--r--arch/blackfin/mach-bf537/include/mach/cdefBF534.h29
-rw-r--r--arch/blackfin/mach-bf537/include/mach/cdefBF537.h29
-rw-r--r--arch/blackfin/mach-bf537/include/mach/defBF534.h28
-rw-r--r--arch/blackfin/mach-bf537/include/mach/defBF537.h29
-rw-r--r--arch/blackfin/mach-bf537/include/mach/gpio.h3
-rw-r--r--arch/blackfin/mach-bf537/include/mach/irq.h29
-rw-r--r--arch/blackfin/mach-bf537/include/mach/portmux.h6
-rw-r--r--arch/blackfin/mach-bf537/ints-priority.c27
-rw-r--r--arch/blackfin/mach-bf538/boards/ezkit.c46
-rw-r--r--arch/blackfin/mach-bf538/dma.c28
-rw-r--r--arch/blackfin/mach-bf538/include/mach/bf538.h27
-rw-r--r--arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h29
-rw-r--r--arch/blackfin/mach-bf538/include/mach/blackfin.h29
-rw-r--r--arch/blackfin/mach-bf538/include/mach/cdefBF538.h28
-rw-r--r--arch/blackfin/mach-bf538/include/mach/defBF539.h44
-rw-r--r--arch/blackfin/mach-bf538/include/mach/gpio.h3
-rw-r--r--arch/blackfin/mach-bf538/include/mach/irq.h29
-rw-r--r--arch/blackfin/mach-bf538/include/mach/portmux.h6
-rw-r--r--arch/blackfin/mach-bf538/ints-priority.c27
-rw-r--r--arch/blackfin/mach-bf548/boards/cm_bf548.c48
-rw-r--r--arch/blackfin/mach-bf548/boards/ezkit.c49
-rw-r--r--arch/blackfin/mach-bf548/dma.c27
-rw-r--r--arch/blackfin/mach-bf548/include/mach/bf548.h27
-rw-r--r--arch/blackfin/mach-bf548/include/mach/bf54x-lq043.h6
-rw-r--r--arch/blackfin/mach-bf548/include/mach/bf54x_keys.h6
-rw-r--r--arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h29
-rw-r--r--arch/blackfin/mach-bf548/include/mach/blackfin.h29
-rw-r--r--arch/blackfin/mach-bf548/include/mach/cdefBF542.h28
-rw-r--r--arch/blackfin/mach-bf548/include/mach/cdefBF544.h28
-rw-r--r--arch/blackfin/mach-bf548/include/mach/cdefBF547.h28
-rw-r--r--arch/blackfin/mach-bf548/include/mach/cdefBF548.h28
-rw-r--r--arch/blackfin/mach-bf548/include/mach/cdefBF549.h28
-rw-r--r--arch/blackfin/mach-bf548/include/mach/cdefBF54x_base.h28
-rw-r--r--arch/blackfin/mach-bf548/include/mach/defBF542.h28
-rw-r--r--arch/blackfin/mach-bf548/include/mach/defBF544.h28
-rw-r--r--arch/blackfin/mach-bf548/include/mach/defBF547.h28
-rw-r--r--arch/blackfin/mach-bf548/include/mach/defBF548.h28
-rw-r--r--arch/blackfin/mach-bf548/include/mach/defBF549.h28
-rw-r--r--arch/blackfin/mach-bf548/include/mach/defBF54x_base.h28
-rw-r--r--arch/blackfin/mach-bf548/include/mach/gpio.h30
-rw-r--r--arch/blackfin/mach-bf548/include/mach/irq.h29
-rw-r--r--arch/blackfin/mach-bf548/include/mach/portmux.h6
-rw-r--r--arch/blackfin/mach-bf548/ints-priority.c27
-rw-r--r--arch/blackfin/mach-bf561/atomic.S21
-rw-r--r--arch/blackfin/mach-bf561/boards/cm_bf561.c45
-rw-r--r--arch/blackfin/mach-bf561/boards/ezkit.c44
-rw-r--r--arch/blackfin/mach-bf561/boards/tepla.c14
-rw-r--r--arch/blackfin/mach-bf561/coreb.c2
-rw-r--r--arch/blackfin/mach-bf561/dma.c28
-rw-r--r--arch/blackfin/mach-bf561/include/mach/bf561.h27
-rw-r--r--arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h29
-rw-r--r--arch/blackfin/mach-bf561/include/mach/blackfin.h28
-rw-r--r--arch/blackfin/mach-bf561/include/mach/cdefBF561.h28
-rw-r--r--arch/blackfin/mach-bf561/include/mach/defBF561.h29
-rw-r--r--arch/blackfin/mach-bf561/include/mach/gpio.h3
-rw-r--r--arch/blackfin/mach-bf561/include/mach/irq.h29
-rw-r--r--arch/blackfin/mach-bf561/include/mach/portmux.h6
-rw-r--r--arch/blackfin/mach-bf561/include/mach/smp.h6
-rw-r--r--arch/blackfin/mach-bf561/ints-priority.c27
-rw-r--r--arch/blackfin/mach-bf561/secondary.S24
-rw-r--r--arch/blackfin/mach-bf561/smp.c21
-rw-r--r--arch/blackfin/mach-common/arch_checks.c27
-rw-r--r--arch/blackfin/mach-common/cache-c.c2
-rw-r--r--arch/blackfin/mach-common/cache.S2
-rw-r--r--arch/blackfin/mach-common/cpufreq.c27
-rw-r--r--arch/blackfin/mach-common/entry.S31
-rw-r--r--arch/blackfin/mach-common/head.S2
-rw-r--r--arch/blackfin/mach-common/interrupt.S30
-rw-r--r--arch/blackfin/mach-common/ints-priority.c35
-rw-r--r--arch/blackfin/mach-common/irqpanic.c27
-rw-r--r--arch/blackfin/mach-common/pm.c34
-rw-r--r--arch/blackfin/mach-common/smp.c22
-rw-r--r--arch/blackfin/mm/blackfin_sram.h27
-rw-r--r--arch/blackfin/mm/init.c27
-rw-r--r--arch/blackfin/mm/isram-driver.c14
-rw-r--r--arch/blackfin/mm/sram-alloc.c27
-rw-r--r--arch/cris/arch-v10/drivers/sync_serial.c2
-rw-r--r--arch/cris/arch-v32/drivers/mach-fs/gpio.c2
-rw-r--r--arch/m32r/include/asm/io.h7
-rw-r--r--arch/m32r/kernel/m32r_ksyms.c6
-rw-r--r--arch/m32r/kernel/smp.c1
-rw-r--r--arch/m32r/kernel/time.c9
-rw-r--r--arch/m32r/kernel/traps.c4
-rw-r--r--arch/m32r/lib/delay.c4
-rw-r--r--arch/m32r/mm/discontig.c5
-rw-r--r--arch/m32r/mm/mmu.S12
-rw-r--r--arch/m68k/include/asm/hardirq_mm.h12
-rw-r--r--arch/m68knommu/kernel/asm-offsets.c28
-rw-r--r--arch/m68knommu/kernel/entry.S6
-rw-r--r--arch/m68knommu/mm/init.c2
-rw-r--r--arch/m68knommu/platform/5206e/config.c1
-rw-r--r--arch/m68knommu/platform/68328/entry.S32
-rw-r--r--arch/m68knommu/platform/68360/entry.S16
-rw-r--r--arch/m68knommu/platform/coldfire/entry.S20
-rw-r--r--arch/microblaze/kernel/entry.S2
-rw-r--r--arch/microblaze/kernel/hw_exception_handler.S2
-rw-r--r--arch/microblaze/kernel/process.c2
-rw-r--r--arch/mips/alchemy/common/dbdma.c8
-rw-r--r--arch/mips/basler/excite/excite_iodev.c2
-rw-r--r--arch/mips/bcm63xx/Makefile2
-rw-r--r--arch/mips/bcm63xx/boards/board_bcm963xx.c8
-rw-r--r--arch/mips/bcm63xx/dev-pcmcia.c144
-rw-r--r--arch/mips/bcm63xx/dev-uart.c41
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_pcmcia.h13
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_uart.h6
-rw-r--r--arch/mips/include/asm/smp.h15
-rw-r--r--arch/mips/include/asm/unaligned.h4
-rw-r--r--arch/mips/kernel/kspd.c33
-rw-r--r--arch/mips/kernel/rtlx.c15
-rw-r--r--arch/mips/kernel/smp.c14
-rw-r--r--arch/mips/kernel/smtc.c5
-rw-r--r--arch/mips/kernel/vpe.c77
-rw-r--r--arch/mips/mm/sc-mips.c5
-rw-r--r--arch/mips/oprofile/op_model_loongson2.c14
-rw-r--r--arch/mips/pci/ops-pmcmsp.c5
-rw-r--r--arch/mips/sgi-ip27/ip27-smp.c2
-rw-r--r--arch/mips/sibyte/bcm1480/irq.c4
-rw-r--r--arch/mips/sibyte/common/sb_tbprof.c33
-rw-r--r--arch/mips/sibyte/swarm/setup.c2
-rw-r--r--arch/mn10300/include/asm/uaccess.h73
-rw-r--r--arch/mn10300/unit-asb2303/include/unit/clock.h6
-rw-r--r--arch/mn10300/unit-asb2305/include/unit/clock.h6
-rw-r--r--arch/parisc/Kconfig1
-rw-r--r--arch/parisc/include/asm/fixmap.h4
-rw-r--r--arch/parisc/include/asm/hardirq.h20
-rw-r--r--arch/parisc/include/asm/ptrace.h5
-rw-r--r--arch/parisc/include/asm/syscall.h40
-rw-r--r--arch/parisc/include/asm/thread_info.h14
-rw-r--r--arch/parisc/kernel/asm-offsets.c4
-rw-r--r--arch/parisc/kernel/entry.S21
-rw-r--r--arch/parisc/kernel/irq.c5
-rw-r--r--arch/parisc/kernel/module.c2
-rw-r--r--arch/parisc/kernel/ptrace.c42
-rw-r--r--arch/parisc/kernel/signal.c5
-rw-r--r--arch/parisc/kernel/syscall.S22
-rw-r--r--arch/parisc/kernel/vmlinux.lds.S10
-rw-r--r--arch/parisc/mm/init.c11
-rw-r--r--arch/powerpc/include/asm/firmware.h10
-rw-r--r--arch/powerpc/kernel/cputable.c2
-rw-r--r--arch/powerpc/kernel/entry_64.S3
-rw-r--r--arch/powerpc/kernel/kgdb.c6
-rw-r--r--arch/powerpc/kernel/pci-common.c2
-rw-r--r--arch/powerpc/kernel/process.c10
-rw-r--r--arch/powerpc/kernel/vmlinux.lds.S1
-rw-r--r--arch/powerpc/kvm/timing.c2
-rw-r--r--arch/powerpc/mm/slb_low.S10
-rw-r--r--arch/powerpc/platforms/cell/axon_msi.c2
-rw-r--r--arch/powerpc/platforms/cell/spufs/file.c2
-rw-r--r--arch/powerpc/platforms/powermac/low_i2c.c7
-rw-r--r--arch/powerpc/platforms/pseries/dtl.c2
-rw-r--r--arch/powerpc/platforms/pseries/firmware.c3
-rw-r--r--arch/s390/hypfs/hypfs_diag.c2
-rw-r--r--arch/s390/include/asm/delay.h7
-rw-r--r--arch/s390/include/asm/elf.h12
-rw-r--r--arch/s390/include/asm/ptrace.h4
-rw-r--r--arch/s390/include/asm/ucontext.h15
-rw-r--r--arch/s390/kernel/compat_signal.c35
-rw-r--r--arch/s390/kernel/compat_wrapper.S2
-rw-r--r--arch/s390/kernel/ftrace.c3
-rw-r--r--arch/s390/kernel/module.c3
-rw-r--r--arch/s390/kernel/processor.c6
-rw-r--r--arch/s390/kernel/ptrace.c70
-rw-r--r--arch/s390/kernel/setup.c15
-rw-r--r--arch/s390/kernel/swsusp_asm64.S26
-rw-r--r--arch/s390/kernel/vdso.c16
-rw-r--r--arch/s390/kernel/vmlinux.lds.S1
-rw-r--r--arch/s390/kvm/kvm-s390.h2
-rw-r--r--arch/s390/lib/delay.c27
-rw-r--r--arch/s390/lib/uaccess_mvcos.c12
-rw-r--r--arch/s390/lib/uaccess_std.c14
-rw-r--r--arch/s390/mm/pgtable.c10
-rw-r--r--arch/sh/boards/board-magicpanelr2.c2
-rw-r--r--arch/sh/boards/mach-dreamcast/setup.c2
-rw-r--r--arch/sh/boards/mach-ecovec24/setup.c63
-rw-r--r--arch/sh/kernel/cpu/sh3/entry.S2
-rw-r--r--arch/sh/kernel/entry-common.S2
-rw-r--r--arch/sh/kernel/ftrace.c37
-rw-r--r--arch/sh/kernel/io_generic.c3
-rw-r--r--arch/sh/kernel/machvec.c3
-rw-r--r--arch/sh/kernel/setup.c2
-rw-r--r--arch/sh/kernel/sh_ksyms_32.c1
-rw-r--r--arch/sh/kernel/signal_32.c9
-rw-r--r--arch/sh/kernel/smp.c2
-rw-r--r--arch/sh/kernel/traps_32.c11
-rw-r--r--arch/sh/mm/cache-sh4.c2
-rw-r--r--arch/sh/mm/cache-sh7705.c4
-rw-r--r--arch/sh/mm/cache.c2
-rw-r--r--arch/sh/mm/ioremap_32.c2
-rw-r--r--arch/sh/mm/pmb.c37
-rw-r--r--arch/sparc/Kconfig2
-rw-r--r--arch/sparc/include/asm/hardirq_32.h12
-rw-r--r--arch/sparc/include/asm/irq_32.h4
-rw-r--r--arch/sparc/include/asm/pgtable_64.h4
-rw-r--r--arch/sparc/kernel/ktlb.S8
-rw-r--r--arch/sparc/kernel/ldc.c4
-rw-r--r--arch/sparc/kernel/perf_event.c579
-rw-r--r--arch/sparc/mm/init_64.c2
-rw-r--r--arch/sparc/oprofile/init.c1
-rw-r--r--arch/um/drivers/line.c1
-rw-r--r--arch/um/drivers/port_kern.c1
-rw-r--r--arch/um/kernel/irq.c1
-rw-r--r--arch/x86/Kconfig15
-rw-r--r--arch/x86/Kconfig.cpu3
-rw-r--r--arch/x86/ia32/ia32entry.S36
-rw-r--r--arch/x86/include/asm/checksum_32.h3
-rw-r--r--arch/x86/include/asm/cmpxchg_32.h30
-rw-r--r--arch/x86/include/asm/kvm_host.h1
-rw-r--r--arch/x86/include/asm/mce.h2
-rw-r--r--arch/x86/include/asm/paravirt.h28
-rw-r--r--arch/x86/include/asm/paravirt_types.h10
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce.c58
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce_intel.c1
-rw-r--r--arch/x86/kernel/cpu/mtrr/if.c17
-rw-r--r--arch/x86/kernel/e820.c4
-rw-r--r--arch/x86/kernel/early_printk.c5
-rw-r--r--arch/x86/kernel/i386_ksyms_32.c10
-rw-r--r--arch/x86/kernel/irq.c4
-rw-r--r--arch/x86/kernel/pci-dma.c4
-rw-r--r--arch/x86/kernel/pci-gart_64.c1
-rw-r--r--arch/x86/kernel/reboot.c1
-rw-r--r--arch/x86/kernel/time.c3
-rw-r--r--arch/x86/kernel/trampoline.c12
-rw-r--r--arch/x86/kernel/trampoline_64.S4
-rw-r--r--arch/x86/kernel/vmi_32.c2
-rw-r--r--arch/x86/kvm/lapic.c2
-rw-r--r--arch/x86/kvm/mmu.c84
-rw-r--r--arch/x86/kvm/paging_tmpl.h18
-rw-r--r--arch/x86/kvm/svm.c25
-rw-r--r--arch/x86/kvm/vmx.c2
-rw-r--r--arch/x86/kvm/x86.c2
-rw-r--r--arch/x86/lib/Makefile4
-rw-r--r--arch/x86/lib/cmpxchg8b_emu.S57
-rw-r--r--arch/x86/xen/debugfs.c2
-rw-r--r--arch/xtensa/kernel/time.c1
-rw-r--r--block/blk-barrier.c45
-rw-r--r--block/blk-core.c9
-rw-r--r--block/blk-settings.c34
-rw-r--r--block/blk-sysfs.c11
-rw-r--r--block/blk-tag.c2
-rw-r--r--block/cfq-iosched.c242
-rw-r--r--block/compat_ioctl.c13
-rw-r--r--block/elevator.c4
-rw-r--r--block/ioctl.c17
-rw-r--r--crypto/aead.c1
-rw-r--r--drivers/acpi/Kconfig12
-rw-r--r--drivers/acpi/Makefile2
-rw-r--r--drivers/acpi/ac.c1
-rw-r--r--drivers/acpi/acpi_pad.c514
-rw-r--r--drivers/acpi/button.c3
-rw-r--r--drivers/acpi/dock.c16
-rw-r--r--drivers/acpi/ec.c56
-rw-r--r--drivers/acpi/pci_root.c11
-rw-r--r--drivers/acpi/proc.c2
-rw-r--r--drivers/acpi/processor_core.c7
-rw-r--r--drivers/acpi/scan.c7
-rw-r--r--drivers/acpi/video.c9
-rw-r--r--drivers/acpi/video_detect.c2
-rw-r--r--drivers/ata/ahci.c198
-rw-r--r--drivers/ata/libata-acpi.c40
-rw-r--r--drivers/ata/libata-core.c3
-rw-r--r--drivers/ata/libata-eh.c50
-rw-r--r--drivers/ata/libata.h2
-rw-r--r--drivers/ata/pata_ali.c2
-rw-r--r--drivers/ata/pata_atp867x.c101
-rw-r--r--drivers/atm/ambassador.c8
-rw-r--r--drivers/atm/eni.c2
-rw-r--r--drivers/atm/firestream.c2
-rw-r--r--drivers/atm/fore200e.c2
-rw-r--r--drivers/atm/horizon.c2
-rw-r--r--drivers/atm/iphase.c2
-rw-r--r--drivers/atm/zatm.c2
-rw-r--r--drivers/block/DAC960.c156
-rw-r--r--drivers/block/cciss.c834
-rw-r--r--drivers/block/cciss.h12
-rw-r--r--drivers/block/cpqarray.c63
-rw-r--r--drivers/char/agp/parisc-agp.c2
-rw-r--r--drivers/char/apm-emulation.c2
-rw-r--r--drivers/char/applicom.c1
-rw-r--r--drivers/char/bfin-otp.c2
-rw-r--r--drivers/char/cyclades.c2
-rw-r--r--drivers/char/dtlk.c1
-rw-r--r--drivers/char/epca.c1
-rw-r--r--drivers/char/generic_serial.c1
-rw-r--r--drivers/char/genrtc.c1
-rw-r--r--drivers/char/ipmi/ipmi_devintf.c1
-rw-r--r--drivers/char/ipmi/ipmi_msghandler.c1
-rw-r--r--drivers/char/istallion.c1
-rw-r--r--drivers/char/nozomi.c1
-rw-r--r--drivers/char/pty.c1
-rw-r--r--drivers/char/rio/riocmd.c1
-rw-r--r--drivers/char/rio/rioctrl.c1
-rw-r--r--drivers/char/rio/riotty.c1
-rw-r--r--drivers/char/rtc.c1
-rw-r--r--drivers/char/ser_a2232.c1
-rw-r--r--drivers/char/serial167.c7
-rw-r--r--drivers/char/sonypi.c1
-rw-r--r--drivers/char/stallion.c1
-rw-r--r--drivers/char/tlclk.c1
-rw-r--r--drivers/char/tpm/tpm.c3
-rw-r--r--drivers/char/tty_buffer.c31
-rw-r--r--drivers/char/tty_ldisc.c7
-rw-r--r--drivers/char/vt_ioctl.c8
-rw-r--r--drivers/char/xilinx_hwicap/xilinx_hwicap.c2
-rw-r--r--drivers/connector/cn_proc.c3
-rw-r--r--drivers/connector/cn_queue.c12
-rw-r--r--drivers/connector/connector.c22
-rw-r--r--drivers/edac/Kconfig14
-rw-r--r--drivers/edac/Makefile5
-rw-r--r--drivers/edac/amd64_edac.c104
-rw-r--r--drivers/edac/amd64_edac.h23
-rw-r--r--drivers/edac/amd64_edac_inj.c49
-rw-r--r--drivers/edac/edac_mce_amd.c32
-rw-r--r--drivers/firewire/core-cdev.c1
-rw-r--r--drivers/firewire/sbp2.c39
-rw-r--r--drivers/firmware/iscsi_ibft.c2
-rw-r--r--drivers/firmware/iscsi_ibft_find.c4
-rw-r--r--drivers/gpio/gpiolib.c2
-rw-r--r--drivers/gpu/drm/drm_crtc.c2
-rw-r--r--drivers/gpu/drm/drm_fb_helper.c138
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c1
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h2
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c10
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c10
-rw-r--r--drivers/gpu/drm/i915/i915_trace.h49
-rw-r--r--drivers/gpu/drm/i915/intel_display.c15
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h2
-rw-r--r--drivers/gpu/drm/i915/intel_fb.c10
-rw-r--r--drivers/gpu/drm/i915/intel_hdmi.c2
-rw-r--r--drivers/gpu/drm/i915/intel_tv.c3
-rw-r--r--drivers/gpu/drm/radeon/atombios_crtc.c1
-rw-r--r--drivers/gpu/drm/radeon/r100.c432
-rw-r--r--drivers/gpu/drm/radeon/r100d.h145
-rw-r--r--drivers/gpu/drm/radeon/r200.c3
-rw-r--r--drivers/gpu/drm/radeon/r300.c308
-rw-r--r--drivers/gpu/drm/radeon/r300d.h205
-rw-r--r--drivers/gpu/drm/radeon/r420.c6
-rw-r--r--drivers/gpu/drm/radeon/r420d.h24
-rw-r--r--drivers/gpu/drm/radeon/r520.c3
-rw-r--r--drivers/gpu/drm/radeon/r600.c314
-rw-r--r--drivers/gpu/drm/radeon/r600_blit.c10
-rw-r--r--drivers/gpu/drm/radeon/r600_blit_kms.c3
-rw-r--r--drivers/gpu/drm/radeon/r600_cs.c2
-rw-r--r--drivers/gpu/drm/radeon/r600d.h1
-rw-r--r--drivers/gpu/drm/radeon/radeon.h58
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.h253
-rw-r--r--drivers/gpu/drm/radeon/radeon_bios.c49
-rw-r--r--drivers/gpu/drm/radeon/radeon_clocks.c8
-rw-r--r--drivers/gpu/drm/radeon/radeon_device.c237
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c45
-rw-r--r--drivers/gpu/drm/radeon/radeon_encoders.c6
-rw-r--r--drivers/gpu/drm/radeon/radeon_fb.c18
-rw-r--r--drivers/gpu/drm/radeon/radeon_irq_kms.c6
-rw-r--r--drivers/gpu/drm/radeon/radeon_legacy_crtc.c1
-rw-r--r--drivers/gpu/drm/radeon/radeon_legacy_encoders.c9
-rw-r--r--drivers/gpu/drm/radeon/radeon_mode.h2
-rw-r--r--drivers/gpu/drm/radeon/radeon_object.c17
-rw-r--r--drivers/gpu/drm/radeon/rs100d.h40
-rw-r--r--drivers/gpu/drm/radeon/rs400.c275
-rw-r--r--drivers/gpu/drm/radeon/rs400d.h160
-rw-r--r--drivers/gpu/drm/radeon/rs600.c481
-rw-r--r--drivers/gpu/drm/radeon/rs600d.h470
-rw-r--r--drivers/gpu/drm/radeon/rs690.c355
-rw-r--r--drivers/gpu/drm/radeon/rs690d.h307
-rw-r--r--drivers/gpu/drm/radeon/rs690r.h99
-rw-r--r--drivers/gpu/drm/radeon/rv200d.h36
-rw-r--r--drivers/gpu/drm/radeon/rv250d.h123
-rw-r--r--drivers/gpu/drm/radeon/rv350d.h52
-rw-r--r--drivers/gpu/drm/radeon/rv515.c5
-rw-r--r--drivers/gpu/drm/radeon/rv770.c199
-rw-r--r--drivers/gpu/drm/ttm/ttm_global.c2
-rw-r--r--drivers/hid/hid-core.c2
-rw-r--r--drivers/hid/hid-twinhan.c4
-rw-r--r--drivers/hid/hidraw.c6
-rw-r--r--drivers/hwmon/Kconfig2
-rw-r--r--drivers/hwmon/asus_atk0110.c339
-rw-r--r--drivers/hwmon/fschmd.c2
-rw-r--r--drivers/hwmon/lis3lv02d_spi.c3
-rw-r--r--drivers/hwmon/ltc4215.c47
-rw-r--r--drivers/hwmon/ltc4245.c131
-rw-r--r--drivers/hwmon/sht15.c8
-rw-r--r--drivers/i2c/busses/i2c-amd756.c2
-rw-r--r--drivers/i2c/busses/i2c-amd8111.c4
-rw-r--r--drivers/i2c/busses/i2c-i801.c4
-rw-r--r--drivers/i2c/busses/i2c-isch.c2
-rw-r--r--drivers/i2c/busses/i2c-piix4.c4
-rw-r--r--drivers/i2c/busses/i2c-sis96x.c2
-rw-r--r--drivers/i2c/busses/i2c-viapro.c2
-rw-r--r--drivers/ide/ide-proc.c8
-rw-r--r--drivers/ide/sis5513.c10
-rw-r--r--drivers/ieee1394/raw1394.c1
-rw-r--r--drivers/ieee1394/video1394.c1
-rw-r--r--drivers/infiniband/core/addr.c2
-rw-r--r--drivers/infiniband/core/iwcm.c3
-rw-r--r--drivers/infiniband/core/ucm.c1
-rw-r--r--drivers/infiniband/core/ucma.c1
-rw-r--r--drivers/infiniband/core/user_mad.c1
-rw-r--r--drivers/infiniband/core/uverbs_main.c1
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_provider.c12
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_qp.c1
-rw-r--r--drivers/infiniband/hw/ipath/ipath_driver.c1
-rw-r--r--drivers/infiniband/hw/ipath/ipath_iba7220.c1
-rw-r--r--drivers/infiniband/hw/ipath/ipath_intr.c1
-rw-r--r--drivers/infiniband/hw/ipath/ipath_qp.c1
-rw-r--r--drivers/infiniband/hw/ipath/ipath_ruc.c1
-rw-r--r--drivers/infiniband/hw/ipath/ipath_ud.c1
-rw-r--r--drivers/infiniband/hw/ipath/ipath_user_pages.c1
-rw-r--r--drivers/infiniband/hw/ipath/ipath_user_sdma.c1
-rw-r--r--drivers/infiniband/hw/ipath/ipath_verbs_mcast.c1
-rw-r--r--drivers/infiniband/ulp/iser/iscsi_iser.c2
-rw-r--r--drivers/input/evdev.c1
-rw-r--r--drivers/input/input.c3
-rw-r--r--drivers/input/joydev.c1
-rw-r--r--drivers/input/joystick/xpad.c2
-rw-r--r--drivers/input/keyboard/hilkbd.c1
-rw-r--r--drivers/input/keyboard/sunkbd.c1
-rw-r--r--drivers/input/misc/rotary_encoder.c4
-rw-r--r--drivers/input/misc/sparcspkr.c4
-rw-r--r--drivers/input/misc/uinput.c1
-rw-r--r--drivers/input/misc/wistron_btns.c9
-rw-r--r--drivers/input/mousedev.c1
-rw-r--r--drivers/input/serio/Kconfig13
-rw-r--r--drivers/input/serio/i8042.c3
-rw-r--r--drivers/input/serio/libps2.c1
-rw-r--r--drivers/input/serio/serio_raw.c1
-rw-r--r--drivers/input/serio/serport.c1
-rw-r--r--drivers/input/touchscreen/ad7879.c4
-rw-r--r--drivers/isdn/capi/capi.c2
-rw-r--r--drivers/isdn/capi/capidrv.c27
-rw-r--r--drivers/isdn/capi/kcapi.c1
-rw-r--r--drivers/isdn/divert/divert_procfs.c1
-rw-r--r--drivers/isdn/gigaset/asyncdata.c28
-rw-r--r--drivers/isdn/gigaset/bas-gigaset.c87
-rw-r--r--drivers/isdn/gigaset/common.c134
-rw-r--r--drivers/isdn/gigaset/ev-layer.c30
-rw-r--r--drivers/isdn/gigaset/i4l.c23
-rw-r--r--drivers/isdn/gigaset/interface.c9
-rw-r--r--drivers/isdn/gigaset/isocdata.c30
-rw-r--r--drivers/isdn/hisax/arcofi.c1
-rw-r--r--drivers/isdn/hisax/hfc_2bds0.c1
-rw-r--r--drivers/isdn/hisax/hfc_pci.c1
-rw-r--r--drivers/isdn/hysdn/hysdn_procconf.c1
-rw-r--r--drivers/isdn/hysdn/hysdn_proclog.c1
-rw-r--r--drivers/isdn/mISDN/socket.c2
-rw-r--r--drivers/isdn/pcbit/drv.c1
-rw-r--r--drivers/isdn/pcbit/layer2.c1
-rw-r--r--drivers/isdn/sc/init.c1
-rw-r--r--drivers/leds/leds-pca9532.c3
-rw-r--r--drivers/lguest/interrupts_and_traps.c1
-rw-r--r--drivers/lguest/lguest_user.c2
-rw-r--r--drivers/macintosh/therm_adt746x.c4
-rw-r--r--drivers/macintosh/therm_pm72.c4
-rw-r--r--drivers/macintosh/via-pmu.c40
-rw-r--r--drivers/macintosh/windfarm_lm75_sensor.c4
-rw-r--r--drivers/macintosh/windfarm_max6690_sensor.c4
-rw-r--r--drivers/macintosh/windfarm_smu_sat.c4
-rw-r--r--drivers/md/dm-log-userspace-transfer.c6
-rw-r--r--drivers/media/dvb/dvb-core/dmxdev.c3
-rw-r--r--drivers/media/dvb/dvb-core/dvb_demux.c1
-rw-r--r--drivers/media/dvb/dvb-core/dvb_net.c1
-rw-r--r--drivers/media/dvb/firewire/firedtv-ci.c2
-rw-r--r--drivers/media/radio/radio-cadet.c1
-rw-r--r--drivers/media/video/cpia.c1
-rw-r--r--drivers/media/video/meye.c1
-rw-r--r--drivers/media/video/videobuf-core.c1
-rw-r--r--drivers/media/video/videobuf-dma-sg.c1
-rw-r--r--drivers/message/fusion/mptlan.c1
-rw-r--r--drivers/mfd/ab3100-core.c4
-rw-r--r--drivers/mfd/twl4030-core.c89
-rw-r--r--drivers/mfd/ucb1400_core.c1
-rw-r--r--drivers/mfd/ucb1x00-core.c1
-rw-r--r--drivers/misc/eeprom/max6875.c29
-rw-r--r--drivers/misc/hpilo.c1
-rw-r--r--drivers/misc/ibmasm/command.c1
-rw-r--r--drivers/misc/ibmasm/event.c1
-rw-r--r--drivers/misc/ibmasm/r_heartbeat.c1
-rw-r--r--drivers/misc/phantom.c3
-rw-r--r--drivers/misc/sgi-gru/grufile.c3
-rw-r--r--drivers/mmc/core/debugfs.c2
-rw-r--r--drivers/mmc/core/sdio_cis.c72
-rw-r--r--drivers/mmc/host/Kconfig41
-rw-r--r--drivers/mmc/host/mmci.c2
-rw-r--r--drivers/mmc/host/pxamci.c4
-rw-r--r--drivers/mmc/host/s3cmci.c608
-rw-r--r--drivers/mmc/host/s3cmci.h14
-rw-r--r--drivers/mtd/devices/m25p80.c1
-rw-r--r--drivers/mtd/devices/sst25l.c1
-rw-r--r--drivers/mtd/mtd_blkdevs.c19
-rw-r--r--drivers/net/3c59x.c77
-rw-r--r--drivers/net/Kconfig18
-rw-r--r--drivers/net/Makefile11
-rw-r--r--drivers/net/acenic.c3
-rw-r--r--drivers/net/au1000_eth.c4
-rw-r--r--drivers/net/bcm63xx_enet.c2
-rw-r--r--drivers/net/benet/be.h1
-rw-r--r--drivers/net/benet/be_cmds.c4
-rw-r--r--drivers/net/benet/be_cmds.h5
-rw-r--r--drivers/net/benet/be_ethtool.c2
-rw-r--r--drivers/net/benet/be_main.c29
-rw-r--r--drivers/net/bonding/bond_sysfs.c2
-rw-r--r--drivers/net/can/sja1000/sja1000_of_platform.c1
-rw-r--r--drivers/net/cnic.c3
-rw-r--r--drivers/net/cnic_if.h4
-rw-r--r--drivers/net/davinci_emac.c36
-rw-r--r--drivers/net/depca.c1
-rw-r--r--drivers/net/e100.c1
-rw-r--r--drivers/net/e1000e/82571.c4
-rw-r--r--drivers/net/e1000e/netdev.c13
-rw-r--r--drivers/net/eql.c1
-rw-r--r--drivers/net/ethoc.c83
-rw-r--r--drivers/net/ewrk3.c1
-rw-r--r--drivers/net/fec_mpc52xx.c6
-rw-r--r--drivers/net/fec_mpc52xx_phy.c1
-rw-r--r--drivers/net/forcedeth.c1
-rw-r--r--drivers/net/fs_enet/fs_enet-main.c1
-rw-r--r--drivers/net/fs_enet/mii-bitbang.c1
-rw-r--r--drivers/net/fs_enet/mii-fec.c1
-rw-r--r--drivers/net/fsl_pq_mdio.c1
-rw-r--r--drivers/net/gianfar.c4
-rw-r--r--drivers/net/hamachi.c1
-rw-r--r--drivers/net/hamradio/baycom_epp.c1
-rw-r--r--drivers/net/hamradio/baycom_ser_fdx.c1
-rw-r--r--drivers/net/hamradio/baycom_ser_hdx.c1
-rw-r--r--drivers/net/hamradio/hdlcdrv.c1
-rw-r--r--drivers/net/hamradio/mkiss.c4
-rw-r--r--drivers/net/hp100.c1
-rw-r--r--drivers/net/ibm_newemac/core.c9
-rw-r--r--drivers/net/ibm_newemac/emac.h1
-rw-r--r--drivers/net/igb/igb_ethtool.c1
-rw-r--r--drivers/net/igb/igb_main.c13
-rw-r--r--drivers/net/irda/sa1100_ir.c7
-rw-r--r--drivers/net/irda/toim3232-sir.c1
-rw-r--r--drivers/net/iseries_veth.c2
-rw-r--r--drivers/net/ixgbe/ixgbe_82598.c2
-rw-r--r--drivers/net/ixgbe/ixgbe_82599.c2
-rw-r--r--drivers/net/ixgbe/ixgbe_common.c232
-rw-r--r--drivers/net/ixgbe/ixgbe_ethtool.c4
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c56
-rw-r--r--drivers/net/ixgbe/ixgbe_type.h11
-rw-r--r--drivers/net/ixp2000/enp2611.c18
-rw-r--r--drivers/net/ixp2000/ixpdev.c11
-rw-r--r--drivers/net/ks8851_mll.c1697
-rw-r--r--drivers/net/meth.c2
-rw-r--r--drivers/net/mlx4/main.c1
-rw-r--r--drivers/net/netxen/netxen_nic_main.c5
-rw-r--r--drivers/net/ns83820.c1
-rw-r--r--drivers/net/pasemi_mac_ethtool.c3
-rw-r--r--drivers/net/pcmcia/3c574_cs.c13
-rw-r--r--drivers/net/pcmcia/pcnet_cs.c10
-rw-r--r--drivers/net/pcnet32.c1
-rw-r--r--drivers/net/phy/mdio-gpio.c1
-rw-r--r--drivers/net/pppol2tp.c2
-rw-r--r--drivers/net/qlge/qlge.h36
-rw-r--r--drivers/net/qlge/qlge_ethtool.c2
-rw-r--r--drivers/net/qlge/qlge_main.c139
-rw-r--r--drivers/net/qlge/qlge_mpi.c105
-rw-r--r--drivers/net/r8169.c987
-rw-r--r--drivers/net/sb1000.c1
-rw-r--r--drivers/net/sgiseeq.c2
-rw-r--r--drivers/net/sis900.c1
-rw-r--r--drivers/net/skfp/skfddi.c1
-rw-r--r--drivers/net/skge.c17
-rw-r--r--drivers/net/skge.h2
-rw-r--r--drivers/net/sky2.c7
-rw-r--r--drivers/net/sky2.h2
-rw-r--r--drivers/net/slip.c1
-rw-r--r--drivers/net/stmmac/Kconfig53
-rw-r--r--drivers/net/stmmac/Makefile4
-rw-r--r--drivers/net/stmmac/common.h330
-rw-r--r--drivers/net/stmmac/descs.h163
-rw-r--r--drivers/net/stmmac/gmac.c693
-rw-r--r--drivers/net/stmmac/gmac.h204
-rw-r--r--drivers/net/stmmac/mac100.c517
-rw-r--r--drivers/net/stmmac/mac100.h116
-rw-r--r--drivers/net/stmmac/stmmac.h98
-rw-r--r--drivers/net/stmmac/stmmac_ethtool.c395
-rw-r--r--drivers/net/stmmac/stmmac_main.c2204
-rw-r--r--drivers/net/stmmac/stmmac_mdio.c217
-rw-r--r--drivers/net/stmmac/stmmac_timer.c140
-rw-r--r--drivers/net/stmmac/stmmac_timer.h41
-rw-r--r--drivers/net/sungem.c1
-rw-r--r--drivers/net/tg3.c41
-rw-r--r--drivers/net/tg3.h2
-rw-r--r--drivers/net/tokenring/ibmtr.c1
-rw-r--r--drivers/net/typhoon.c1
-rw-r--r--drivers/net/usb/pegasus.c13
-rw-r--r--drivers/net/usb/pegasus.h6
-rw-r--r--drivers/net/usb/rndis_host.c1
-rw-r--r--drivers/net/virtio_net.c2
-rw-r--r--drivers/net/vmxnet3/Makefile35
-rw-r--r--drivers/net/vmxnet3/upt1_defs.h96
-rw-r--r--drivers/net/vmxnet3/vmxnet3_defs.h535
-rw-r--r--drivers/net/vmxnet3/vmxnet3_drv.c2565
-rw-r--r--drivers/net/vmxnet3/vmxnet3_ethtool.c566
-rw-r--r--drivers/net/vmxnet3/vmxnet3_int.h389
-rw-r--r--drivers/net/wan/c101.c1
-rw-r--r--drivers/net/wan/cosa.c1
-rw-r--r--drivers/net/wan/cycx_x25.c1
-rw-r--r--drivers/net/wan/dscc4.c1
-rw-r--r--drivers/net/wan/farsync.c1
-rw-r--r--drivers/net/wan/hdlc_cisco.c18
-rw-r--r--drivers/net/wan/n2.c1
-rw-r--r--drivers/net/wan/pci200syn.c1
-rw-r--r--drivers/net/wireless/Kconfig13
-rw-r--r--drivers/net/wireless/adm8211.h2
-rw-r--r--drivers/net/wireless/ath/ar9170/phy.c6
-rw-r--r--drivers/net/wireless/b43/b43.h168
-rw-r--r--drivers/net/wireless/b43/leds.c4
-rw-r--r--drivers/net/wireless/b43/leds.h4
-rw-r--r--drivers/net/wireless/b43/main.c7
-rw-r--r--drivers/net/wireless/b43/pio.c93
-rw-r--r--drivers/net/wireless/b43/xmit.c5
-rw-r--r--drivers/net/wireless/b43legacy/main.c1
-rw-r--r--drivers/net/wireless/b43legacy/phy.c1
-rw-r--r--drivers/net/wireless/hostap/hostap_info.c1
-rw-r--r--drivers/net/wireless/hostap/hostap_ioctl.c1
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2200.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-rs.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.c23
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.h20
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-hcmd.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c3
-rw-r--r--drivers/net/wireless/iwmc3200wifi/cfg80211.c1
-rw-r--r--drivers/net/wireless/iwmc3200wifi/commands.c1
-rw-r--r--drivers/net/wireless/iwmc3200wifi/main.c1
-rw-r--r--drivers/net/wireless/iwmc3200wifi/rx.c1
-rw-r--r--drivers/net/wireless/libertas/cmd.c1
-rw-r--r--drivers/net/wireless/libertas/cmdresp.c1
-rw-r--r--drivers/net/wireless/libertas/tx.c1
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c3
-rw-r--r--drivers/net/wireless/prism54/isl_ioctl.c1
-rw-r--r--drivers/net/wireless/prism54/islpci_dev.c1
-rw-r--r--drivers/net/wireless/prism54/islpci_mgt.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00debug.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c1
-rw-r--r--drivers/net/znet.c8
-rw-r--r--drivers/oprofile/event_buffer.c35
-rw-r--r--drivers/pci/dmar.c13
-rw-r--r--drivers/pci/hotplug/cpqphp.h1
-rw-r--r--drivers/pci/intel-iommu.c82
-rw-r--r--drivers/pci/pci.c27
-rw-r--r--drivers/pci/pcie/aer/aerdrv.c3
-rw-r--r--drivers/pci/pcie/portdrv_pci.c3
-rw-r--r--drivers/pci/quirks.c32
-rw-r--r--drivers/pci/setup-bus.c13
-rw-r--r--drivers/pci/setup-res.c37
-rw-r--r--drivers/pcmcia/Kconfig4
-rw-r--r--drivers/pcmcia/Makefile1
-rw-r--r--drivers/pcmcia/bcm63xx_pcmcia.c536
-rw-r--r--drivers/pcmcia/bcm63xx_pcmcia.h60
-rw-r--r--drivers/pcmcia/sa1100_assabet.c2
-rw-r--r--drivers/pcmcia/sa1100_neponset.c2
-rw-r--r--drivers/platform/x86/eeepc-laptop.c31
-rw-r--r--drivers/platform/x86/fujitsu-laptop.c2
-rw-r--r--drivers/platform/x86/sony-laptop.c127
-rw-r--r--drivers/rtc/interface.c1
-rw-r--r--drivers/rtc/rtc-dev.c1
-rw-r--r--drivers/s390/block/dasd.c18
-rw-r--r--drivers/s390/block/dasd_eckd.c13
-rw-r--r--drivers/s390/char/raw3270.c2
-rw-r--r--drivers/s390/char/sclp_async.c4
-rw-r--r--drivers/s390/char/sclp_vt220.c30
-rw-r--r--drivers/s390/char/tape_block.c3
-rw-r--r--drivers/s390/cio/blacklist.c13
-rw-r--r--drivers/s390/cio/chp.c2
-rw-r--r--drivers/s390/cio/device.c13
-rw-r--r--drivers/s390/cio/device.h1
-rw-r--r--drivers/s390/cio/device_fsm.c35
-rw-r--r--drivers/s390/cio/qdio_debug.c2
-rw-r--r--drivers/s390/cio/qdio_perf.c2
-rw-r--r--drivers/s390/crypto/zcrypt_pcixcc.c13
-rw-r--r--drivers/s390/scsi/zfcp_aux.c33
-rw-r--r--drivers/s390/scsi/zfcp_ccw.c40
-rw-r--r--drivers/s390/scsi/zfcp_cfdc.c17
-rw-r--r--drivers/s390/scsi/zfcp_ext.h2
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c22
-rw-r--r--drivers/scsi/Kconfig11
-rw-r--r--drivers/scsi/Makefile2
-rw-r--r--drivers/scsi/be2iscsi/Kconfig8
-rw-r--r--drivers/scsi/be2iscsi/Makefile8
-rw-r--r--drivers/scsi/be2iscsi/be.h183
-rw-r--r--drivers/scsi/be2iscsi/be_cmds.c523
-rw-r--r--drivers/scsi/be2iscsi/be_cmds.h877
-rw-r--r--drivers/scsi/be2iscsi/be_iscsi.c638
-rw-r--r--drivers/scsi/be2iscsi/be_iscsi.h75
-rw-r--r--drivers/scsi/be2iscsi/be_main.c3390
-rw-r--r--drivers/scsi/be2iscsi/be_main.h837
-rw-r--r--drivers/scsi/be2iscsi/be_mgmt.c321
-rw-r--r--drivers/scsi/be2iscsi/be_mgmt.h249
-rw-r--r--drivers/scsi/bfa/Makefile15
-rw-r--r--drivers/scsi/bfa/bfa_callback_priv.h57
-rw-r--r--drivers/scsi/bfa/bfa_cb_ioim_macros.h205
-rw-r--r--drivers/scsi/bfa/bfa_cee.c492
-rw-r--r--drivers/scsi/bfa/bfa_core.c402
-rw-r--r--drivers/scsi/bfa/bfa_csdebug.c58
-rw-r--r--drivers/scsi/bfa/bfa_fcpim.c175
-rw-r--r--drivers/scsi/bfa/bfa_fcpim_priv.h188
-rw-r--r--drivers/scsi/bfa/bfa_fcport.c1671
-rw-r--r--drivers/scsi/bfa/bfa_fcs.c182
-rw-r--r--drivers/scsi/bfa/bfa_fcs_lport.c940
-rw-r--r--drivers/scsi/bfa/bfa_fcs_port.c68
-rw-r--r--drivers/scsi/bfa/bfa_fcs_uf.c105
-rw-r--r--drivers/scsi/bfa/bfa_fcxp.c782
-rw-r--r--drivers/scsi/bfa/bfa_fcxp_priv.h138
-rw-r--r--drivers/scsi/bfa/bfa_fwimg_priv.h31
-rw-r--r--drivers/scsi/bfa/bfa_hw_cb.c142
-rw-r--r--drivers/scsi/bfa/bfa_hw_ct.c162
-rw-r--r--drivers/scsi/bfa/bfa_intr.c218
-rw-r--r--drivers/scsi/bfa/bfa_intr_priv.h115
-rw-r--r--drivers/scsi/bfa/bfa_ioc.c2382
-rw-r--r--drivers/scsi/bfa/bfa_ioc.h259
-rw-r--r--drivers/scsi/bfa/bfa_iocfc.c872
-rw-r--r--drivers/scsi/bfa/bfa_iocfc.h168
-rw-r--r--drivers/scsi/bfa/bfa_iocfc_q.c44
-rw-r--r--drivers/scsi/bfa/bfa_ioim.c1311
-rw-r--r--drivers/scsi/bfa/bfa_itnim.c1088
-rw-r--r--drivers/scsi/bfa/bfa_log.c346
-rw-r--r--drivers/scsi/bfa/bfa_log_module.c451
-rw-r--r--drivers/scsi/bfa/bfa_lps.c782
-rw-r--r--drivers/scsi/bfa/bfa_lps_priv.h38
-rw-r--r--drivers/scsi/bfa/bfa_module.c90
-rw-r--r--drivers/scsi/bfa/bfa_modules_priv.h43
-rw-r--r--drivers/scsi/bfa/bfa_os_inc.h222
-rw-r--r--drivers/scsi/bfa/bfa_port.c460
-rw-r--r--drivers/scsi/bfa/bfa_port_priv.h90
-rw-r--r--drivers/scsi/bfa/bfa_priv.h113
-rw-r--r--drivers/scsi/bfa/bfa_rport.c911
-rw-r--r--drivers/scsi/bfa/bfa_rport_priv.h45
-rw-r--r--drivers/scsi/bfa/bfa_sgpg.c231
-rw-r--r--drivers/scsi/bfa/bfa_sgpg_priv.h79
-rw-r--r--drivers/scsi/bfa/bfa_sm.c38
-rw-r--r--drivers/scsi/bfa/bfa_timer.c90
-rw-r--r--drivers/scsi/bfa/bfa_trcmod_priv.h66
-rw-r--r--drivers/scsi/bfa/bfa_tskim.c689
-rw-r--r--drivers/scsi/bfa/bfa_uf.c345
-rw-r--r--drivers/scsi/bfa/bfa_uf_priv.h47
-rw-r--r--drivers/scsi/bfa/bfad.c1182
-rw-r--r--drivers/scsi/bfa/bfad_attr.c649
-rw-r--r--drivers/scsi/bfa/bfad_attr.h65
-rw-r--r--drivers/scsi/bfa/bfad_drv.h295
-rw-r--r--drivers/scsi/bfa/bfad_fwimg.c95
-rw-r--r--drivers/scsi/bfa/bfad_im.c1230
-rw-r--r--drivers/scsi/bfa/bfad_im.h150
-rw-r--r--drivers/scsi/bfa/bfad_im_compat.h46
-rw-r--r--drivers/scsi/bfa/bfad_intr.c214
-rw-r--r--drivers/scsi/bfa/bfad_ipfc.h42
-rw-r--r--drivers/scsi/bfa/bfad_os.c50
-rw-r--r--drivers/scsi/bfa/bfad_tm.h59
-rw-r--r--drivers/scsi/bfa/bfad_trcmod.h52
-rw-r--r--drivers/scsi/bfa/fab.c62
-rw-r--r--drivers/scsi/bfa/fabric.c1278
-rw-r--r--drivers/scsi/bfa/fcbuild.c1449
-rw-r--r--drivers/scsi/bfa/fcbuild.h273
-rw-r--r--drivers/scsi/bfa/fcpim.c844
-rw-r--r--drivers/scsi/bfa/fcptm.c68
-rw-r--r--drivers/scsi/bfa/fcs.h30
-rw-r--r--drivers/scsi/bfa/fcs_auth.h37
-rw-r--r--drivers/scsi/bfa/fcs_fabric.h61
-rw-r--r--drivers/scsi/bfa/fcs_fcpim.h44
-rw-r--r--drivers/scsi/bfa/fcs_fcptm.h45
-rw-r--r--drivers/scsi/bfa/fcs_fcxp.h29
-rw-r--r--drivers/scsi/bfa/fcs_lport.h117
-rw-r--r--drivers/scsi/bfa/fcs_ms.h35
-rw-r--r--drivers/scsi/bfa/fcs_port.h32
-rw-r--r--drivers/scsi/bfa/fcs_rport.h61
-rw-r--r--drivers/scsi/bfa/fcs_trcmod.h56
-rw-r--r--drivers/scsi/bfa/fcs_uf.h32
-rw-r--r--drivers/scsi/bfa/fcs_vport.h39
-rw-r--r--drivers/scsi/bfa/fdmi.c1223
-rw-r--r--drivers/scsi/bfa/include/aen/bfa_aen.h92
-rw-r--r--drivers/scsi/bfa/include/aen/bfa_aen_adapter.h31
-rw-r--r--drivers/scsi/bfa/include/aen/bfa_aen_audit.h31
-rw-r--r--drivers/scsi/bfa/include/aen/bfa_aen_ethport.h35
-rw-r--r--drivers/scsi/bfa/include/aen/bfa_aen_ioc.h37
-rw-r--r--drivers/scsi/bfa/include/aen/bfa_aen_itnim.h33
-rw-r--r--drivers/scsi/bfa/include/aen/bfa_aen_lport.h51
-rw-r--r--drivers/scsi/bfa/include/aen/bfa_aen_port.h57
-rw-r--r--drivers/scsi/bfa/include/aen/bfa_aen_rport.h37
-rw-r--r--drivers/scsi/bfa/include/bfa.h177
-rw-r--r--drivers/scsi/bfa/include/bfa_fcpim.h159
-rw-r--r--drivers/scsi/bfa/include/bfa_fcptm.h47
-rw-r--r--drivers/scsi/bfa/include/bfa_svc.h324
-rw-r--r--drivers/scsi/bfa/include/bfa_timer.h53
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi.h174
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_boot.h34
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_cbreg.h305
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_cee.h119
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_ctreg.h611
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_fabric.h92
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_fcpim.h301
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_fcxp.h71
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_ioc.h202
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_iocfc.h177
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_lport.h89
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_lps.h96
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_port.h115
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_pport.h184
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_rport.h104
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_uf.h52
-rw-r--r--drivers/scsi/bfa/include/cna/bfa_cna_trcmod.h36
-rw-r--r--drivers/scsi/bfa/include/cna/cee/bfa_cee.h77
-rw-r--r--drivers/scsi/bfa/include/cna/port/bfa_port.h69
-rw-r--r--drivers/scsi/bfa/include/cna/pstats/ethport_defs.h36
-rw-r--r--drivers/scsi/bfa/include/cna/pstats/phyport_defs.h218
-rw-r--r--drivers/scsi/bfa/include/cs/bfa_checksum.h60
-rw-r--r--drivers/scsi/bfa/include/cs/bfa_debug.h44
-rw-r--r--drivers/scsi/bfa/include/cs/bfa_log.h184
-rw-r--r--drivers/scsi/bfa/include/cs/bfa_perf.h34
-rw-r--r--drivers/scsi/bfa/include/cs/bfa_plog.h162
-rw-r--r--drivers/scsi/bfa/include/cs/bfa_q.h81
-rw-r--r--drivers/scsi/bfa/include/cs/bfa_sm.h69
-rw-r--r--drivers/scsi/bfa/include/cs/bfa_trc.h176
-rw-r--r--drivers/scsi/bfa/include/cs/bfa_wc.h68
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_adapter.h82
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_aen.h73
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_audit.h38
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_auth.h112
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_boot.h71
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_cee.h159
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_driver.h40
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_ethport.h98
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_fcpim.h45
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_im_common.h32
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_im_team.h72
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_ioc.h152
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_iocfc.h310
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_ipfc.h70
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_itnim.h126
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_led.h35
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_lport.h68
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_mfg.h58
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_pci.h41
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_pm.h33
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_pom.h56
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_port.h245
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_pport.h383
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_qos.h99
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_rport.h199
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_status.h255
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_tin.h118
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_tsensor.h43
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_types.h30
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_version.h22
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_vf.h74
-rw-r--r--drivers/scsi/bfa/include/defs/bfa_defs_vport.h91
-rw-r--r--drivers/scsi/bfa/include/fcb/bfa_fcb.h33
-rw-r--r--drivers/scsi/bfa/include/fcb/bfa_fcb_fcpim.h76
-rw-r--r--drivers/scsi/bfa/include/fcb/bfa_fcb_port.h113
-rw-r--r--drivers/scsi/bfa/include/fcb/bfa_fcb_rport.h80
-rw-r--r--drivers/scsi/bfa/include/fcb/bfa_fcb_vf.h47
-rw-r--r--drivers/scsi/bfa/include/fcb/bfa_fcb_vport.h47
-rw-r--r--drivers/scsi/bfa/include/fcs/bfa_fcs.h73
-rw-r--r--drivers/scsi/bfa/include/fcs/bfa_fcs_auth.h82
-rw-r--r--drivers/scsi/bfa/include/fcs/bfa_fcs_fabric.h112
-rw-r--r--drivers/scsi/bfa/include/fcs/bfa_fcs_fcpim.h131
-rw-r--r--drivers/scsi/bfa/include/fcs/bfa_fcs_fdmi.h63
-rw-r--r--drivers/scsi/bfa/include/fcs/bfa_fcs_lport.h226
-rw-r--r--drivers/scsi/bfa/include/fcs/bfa_fcs_rport.h104
-rw-r--r--drivers/scsi/bfa/include/fcs/bfa_fcs_vport.h63
-rw-r--r--drivers/scsi/bfa/include/log/bfa_log_fcs.h28
-rw-r--r--drivers/scsi/bfa/include/log/bfa_log_hal.h30
-rw-r--r--drivers/scsi/bfa/include/log/bfa_log_linux.h44
-rw-r--r--drivers/scsi/bfa/include/log/bfa_log_wdrv.h36
-rw-r--r--drivers/scsi/bfa/include/protocol/ct.h492
-rw-r--r--drivers/scsi/bfa/include/protocol/fc.h1105
-rw-r--r--drivers/scsi/bfa/include/protocol/fc_sp.h224
-rw-r--r--drivers/scsi/bfa/include/protocol/fcp.h186
-rw-r--r--drivers/scsi/bfa/include/protocol/fdmi.h163
-rw-r--r--drivers/scsi/bfa/include/protocol/pcifw.h75
-rw-r--r--drivers/scsi/bfa/include/protocol/scsi.h1648
-rw-r--r--drivers/scsi/bfa/include/protocol/types.h42
-rw-r--r--drivers/scsi/bfa/loop.c422
-rw-r--r--drivers/scsi/bfa/lport_api.c291
-rw-r--r--drivers/scsi/bfa/lport_priv.h82
-rw-r--r--drivers/scsi/bfa/ms.c759
-rw-r--r--drivers/scsi/bfa/n2n.c105
-rw-r--r--drivers/scsi/bfa/ns.c1243
-rw-r--r--drivers/scsi/bfa/plog.c184
-rw-r--r--drivers/scsi/bfa/rport.c2618
-rw-r--r--drivers/scsi/bfa/rport_api.c180
-rw-r--r--drivers/scsi/bfa/rport_ftrs.c375
-rw-r--r--drivers/scsi/bfa/scn.c482
-rw-r--r--drivers/scsi/bfa/vfapi.c292
-rw-r--r--drivers/scsi/bfa/vport.c891
-rw-r--r--drivers/scsi/bnx2i/bnx2i.h2
-rw-r--r--drivers/scsi/bnx2i/bnx2i_hwi.c2
-rw-r--r--drivers/scsi/bnx2i/bnx2i_iscsi.c2
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_iscsi.c2
-rw-r--r--drivers/scsi/device_handler/scsi_dh_rdac.c2
-rw-r--r--drivers/scsi/hptiop.c37
-rw-r--r--drivers/scsi/hptiop.h3
-rw-r--r--drivers/scsi/iscsi_tcp.c2
-rw-r--r--drivers/scsi/libiscsi.c6
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c15
-rw-r--r--drivers/scsi/mpt2sas/Kconfig2
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2.h103
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h200
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_history.txt334
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_init.h18
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_ioc.h65
-rw-r--r--drivers/scsi/mpt2sas/mpi/mpi2_tool.h134
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.c446
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.h106
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_config.c22
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_ctl.c61
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_ctl.h2
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_debug.h2
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_scsih.c568
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_transport.c26
-rw-r--r--drivers/scsi/mvsas/mv_defs.h4
-rw-r--r--drivers/scsi/mvsas/mv_init.c4
-rw-r--r--drivers/scsi/pmcraid.c58
-rw-r--r--drivers/scsi/qla2xxx/qla_mid.c6
-rw-r--r--drivers/scsi/scsi.c11
-rw-r--r--drivers/scsi/scsi_debug.c139
-rw-r--r--drivers/scsi/scsi_error.c3
-rw-r--r--drivers/scsi/scsi_transport_fc.c2
-rw-r--r--drivers/scsi/sd.c140
-rw-r--r--drivers/scsi/sd.h9
-rw-r--r--drivers/scsi/sd_dif.c65
-rw-r--r--drivers/scsi/sg.c53
-rw-r--r--drivers/scsi/sr.c22
-rw-r--r--drivers/scsi/st.c3
-rw-r--r--drivers/serial/8250.c7
-rw-r--r--drivers/serial/Kconfig21
-rw-r--r--drivers/serial/Makefile1
-rw-r--r--drivers/serial/bcm63xx_uart.c890
-rw-r--r--drivers/serial/icom.c54
-rw-r--r--drivers/serial/sa1100.c2
-rw-r--r--drivers/serial/serial_core.c7
-rw-r--r--drivers/serial/serial_cs.c12
-rw-r--r--drivers/serial/serial_txx9.c39
-rw-r--r--drivers/sfi/sfi_core.c17
-rw-r--r--drivers/spi/Makefile2
-rw-r--r--drivers/spi/amba-pl022.c2
-rw-r--r--drivers/spi/spi_imx.c (renamed from drivers/spi/mxc_spi.c)383
-rw-r--r--drivers/spi/spidev.c2
-rw-r--r--drivers/staging/Kconfig4
-rw-r--r--drivers/staging/Makefile2
-rw-r--r--drivers/staging/agnx/Kconfig5
-rw-r--r--drivers/staging/agnx/Makefile8
-rw-r--r--drivers/staging/agnx/TODO22
-rw-r--r--drivers/staging/agnx/agnx.h156
-rw-r--r--drivers/staging/agnx/debug.h416
-rw-r--r--drivers/staging/agnx/pci.c635
-rw-r--r--drivers/staging/agnx/phy.c960
-rw-r--r--drivers/staging/agnx/phy.h409
-rw-r--r--drivers/staging/agnx/rf.c893
-rw-r--r--drivers/staging/agnx/sta.c218
-rw-r--r--drivers/staging/agnx/sta.h222
-rw-r--r--drivers/staging/agnx/table.c168
-rw-r--r--drivers/staging/agnx/table.h10
-rw-r--r--drivers/staging/agnx/xmit.c836
-rw-r--r--drivers/staging/agnx/xmit.h250
-rw-r--r--drivers/staging/b3dfg/b3dfg.c1
-rw-r--r--drivers/staging/comedi/Kconfig2
-rw-r--r--drivers/staging/comedi/comedi_fops.c2
-rw-r--r--drivers/staging/comedi/drivers/cb_das16_cs.c2
-rw-r--r--drivers/staging/comedi/drivers/cb_pcidio.c8
-rw-r--r--drivers/staging/comedi/drivers/jr3_pci.c18
-rw-r--r--drivers/staging/comedi/drivers/me_daq.c1
-rw-r--r--drivers/staging/comedi/drivers/ni_65xx.c12
-rw-r--r--drivers/staging/comedi/drivers/ni_daq_700.c2
-rw-r--r--drivers/staging/comedi/drivers/ni_daq_dio24.c2
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc_cs.c2
-rw-r--r--drivers/staging/comedi/drivers/ni_mio_common.c1
-rw-r--r--drivers/staging/comedi/drivers/ni_mio_cs.c2
-rw-r--r--drivers/staging/comedi/drivers/ni_pcidio.c1
-rw-r--r--drivers/staging/comedi/drivers/ni_pcimio.c22
-rw-r--r--drivers/staging/comedi/drivers/quatech_daqp_cs.c2
-rw-r--r--drivers/staging/comedi/drivers/s526.c109
-rw-r--r--drivers/staging/comedi/drivers/serial2002.c1
-rw-r--r--drivers/staging/cowloop/Kconfig16
-rw-r--r--drivers/staging/cowloop/Makefile1
-rw-r--r--drivers/staging/cowloop/TODO11
-rw-r--r--drivers/staging/cowloop/cowloop.c2842
-rw-r--r--drivers/staging/cowloop/cowloop.h66
-rw-r--r--drivers/staging/dst/dcore.c9
-rw-r--r--drivers/staging/et131x/et1310_address_map.h2
-rw-r--r--drivers/staging/et131x/et1310_rx.c20
-rw-r--r--drivers/staging/hv/osd.c1
-rw-r--r--drivers/staging/iio/Kconfig1
-rw-r--r--drivers/staging/iio/industrialio-core.c2
-rw-r--r--drivers/staging/iio/light/tsl2561.c4
-rw-r--r--drivers/staging/p9auth/p9auth.c14
-rw-r--r--drivers/staging/poch/poch.c1
-rw-r--r--drivers/staging/pohmelfs/config.c5
-rw-r--r--drivers/staging/rt2860/common/cmm_data_2860.c2
-rw-r--r--drivers/staging/rt2860/common/cmm_info.c1
-rw-r--r--drivers/staging/rt2860/rt_linux.c1
-rw-r--r--drivers/staging/rt3090/common/cmm_info.c1
-rw-r--r--drivers/staging/rt3090/rt_linux.c1
-rw-r--r--drivers/staging/rtl8192e/r8192E_core.c1
-rw-r--r--drivers/staging/sep/sep_driver.c1
-rw-r--r--drivers/staging/vme/bridges/vme_ca91cx42.c1
-rw-r--r--drivers/staging/vme/bridges/vme_tsi148.c1
-rw-r--r--drivers/staging/winbond/wbusb.c44
-rw-r--r--drivers/uio/uio.c1
-rw-r--r--drivers/usb/class/usbtmc.c4
-rw-r--r--drivers/usb/gadget/ether.c9
-rw-r--r--drivers/usb/gadget/imx_udc.c8
-rw-r--r--drivers/usb/gadget/inode.c1
-rw-r--r--drivers/usb/gadget/printer.c2
-rw-r--r--drivers/usb/gadget/r8a66597-udc.h105
-rw-r--r--drivers/usb/host/ehci-sched.c13
-rw-r--r--drivers/usb/host/isp1362-hcd.c18
-rw-r--r--drivers/usb/host/isp1362.h12
-rw-r--r--drivers/usb/host/pci-quirks.c2
-rw-r--r--drivers/usb/host/whci/asl.c23
-rw-r--r--drivers/usb/host/whci/debug.c6
-rw-r--r--drivers/usb/host/whci/pzl.c24
-rw-r--r--drivers/usb/host/xhci-hcd.c29
-rw-r--r--drivers/usb/misc/rio500.c3
-rw-r--r--drivers/usb/misc/usblcd.c3
-rw-r--r--drivers/usb/musb/Kconfig4
-rw-r--r--drivers/usb/musb/blackfin.c1
-rw-r--r--drivers/usb/musb/musb_core.h7
-rw-r--r--drivers/usb/musb/musb_regs.h9
-rw-r--r--drivers/usb/serial/aircable.c10
-rw-r--r--drivers/usb/serial/cp210x.c1
-rw-r--r--drivers/usb/serial/cypress_m8.c12
-rw-r--r--drivers/usb/serial/digi_acceleport.c8
-rw-r--r--drivers/usb/serial/empeg.c2
-rw-r--r--drivers/usb/serial/ftdi_sio.c422
-rw-r--r--drivers/usb/serial/garmin_gps.c12
-rw-r--r--drivers/usb/serial/generic.c2
-rw-r--r--drivers/usb/serial/ipaq.c9
-rw-r--r--drivers/usb/serial/keyspan_pda.c2
-rw-r--r--drivers/usb/serial/kl5kusb105.c2
-rw-r--r--drivers/usb/serial/mct_u232.c14
-rw-r--r--drivers/usb/serial/opticon.c13
-rw-r--r--drivers/usb/serial/option.c8
-rw-r--r--drivers/usb/serial/oti6858.c6
-rw-r--r--drivers/usb/serial/pl2303.c8
-rw-r--r--drivers/usb/serial/sierra.c2
-rw-r--r--drivers/usb/serial/symbolserial.c22
-rw-r--r--drivers/usb/serial/usb-serial.c10
-rw-r--r--drivers/usb/serial/visor.c28
-rw-r--r--drivers/usb/serial/whiteheat.c10
-rw-r--r--drivers/usb/storage/transport.c46
-rw-r--r--drivers/usb/storage/unusual_devs.h7
-rw-r--r--drivers/usb/wusbcore/security.c41
-rw-r--r--drivers/uwb/uwb-debug.c6
-rw-r--r--drivers/uwb/whc-rc.c1
-rw-r--r--drivers/video/da8xx-fb.c1
-rw-r--r--drivers/video/msm/mddi.c2
-rw-r--r--drivers/video/omap/blizzard.c10
-rw-r--r--drivers/video/omap/omapfb_main.c22
-rw-r--r--drivers/video/uvesafb.c5
-rw-r--r--drivers/w1/masters/ds2482.c35
-rw-r--r--drivers/w1/w1_netlink.c2
-rw-r--r--drivers/watchdog/riowd.c2
-rw-r--r--drivers/xen/xenfs/xenbus.c1
-rw-r--r--firmware/Makefile7
-rw-r--r--firmware/WHENCE5
-rw-r--r--firmware/cis/COMpad2.cis.ihex11
-rw-r--r--firmware/cis/COMpad4.cis.ihex9
-rw-r--r--firmware/cis/DP83903.cis.ihex14
-rw-r--r--firmware/cis/NE2K.cis.ihex8
-rw-r--r--firmware/cis/tamarack.cis.ihex10
-rw-r--r--fs/afs/cache.h12
-rw-r--r--fs/afs/internal.h2
-rw-r--r--fs/anon_inodes.c2
-rw-r--r--fs/bio.c49
-rw-r--r--fs/btrfs/acl.c6
-rw-r--r--fs/btrfs/async-thread.c81
-rw-r--r--fs/btrfs/async-thread.h10
-rw-r--r--fs/btrfs/btrfs_inode.h16
-rw-r--r--fs/btrfs/ctree.h38
-rw-r--r--fs/btrfs/disk-io.c60
-rw-r--r--fs/btrfs/extent-tree.c615
-rw-r--r--fs/btrfs/extent_io.c134
-rw-r--r--fs/btrfs/extent_io.h31
-rw-r--r--fs/btrfs/file.c79
-rw-r--r--fs/btrfs/inode.c357
-rw-r--r--fs/btrfs/ioctl.c69
-rw-r--r--fs/btrfs/ordered-data.c99
-rw-r--r--fs/btrfs/ordered-data.h4
-rw-r--r--fs/btrfs/relocation.c4
-rw-r--r--fs/btrfs/super.c9
-rw-r--r--fs/btrfs/transaction.c55
-rw-r--r--fs/btrfs/transaction.h5
-rw-r--r--fs/btrfs/tree-log.c56
-rw-r--r--fs/btrfs/tree-log.h3
-rw-r--r--fs/btrfs/volumes.c4
-rw-r--r--fs/btrfs/xattr.c2
-rw-r--r--fs/coda/psdev.c1
-rw-r--r--fs/ecryptfs/Kconfig3
-rw-r--r--fs/ecryptfs/main.c7
-rw-r--r--fs/ext3/super.c13
-rw-r--r--fs/ext4/Kconfig14
-rw-r--r--fs/ext4/ext4.h54
-rw-r--r--fs/ext4/ext4_extents.h7
-rw-r--r--fs/ext4/ext4_jbd2.h6
-rw-r--r--fs/ext4/extents.c444
-rw-r--r--fs/ext4/fsync.c5
-rw-r--r--fs/ext4/inode.c578
-rw-r--r--fs/ext4/mballoc.c305
-rw-r--r--fs/ext4/mballoc.h35
-rw-r--r--fs/ext4/migrate.c2
-rw-r--r--fs/ext4/move_extent.c20
-rw-r--r--fs/ext4/namei.c3
-rw-r--r--fs/ext4/super.c130
-rw-r--r--fs/fat/fat.h2
-rw-r--r--fs/fat/inode.c18
-rw-r--r--fs/fat/misc.c8
-rw-r--r--fs/fat/namei_vfat.c15
-rw-r--r--fs/file.c1
-rw-r--r--fs/jbd2/checkpoint.c7
-rw-r--r--fs/jbd2/commit.c59
-rw-r--r--fs/jbd2/journal.c198
-rw-r--r--fs/nfs/client.c2
-rw-r--r--fs/nfs/nfs4namespace.c12
-rw-r--r--fs/nfs/nfs4renewd.c6
-rw-r--r--fs/nfs/super.c36
-rw-r--r--fs/nfsd/nfsctl.c2
-rw-r--r--fs/nilfs2/btnode.c1
-rw-r--r--fs/nilfs2/dir.c2
-rw-r--r--fs/nilfs2/file.c2
-rw-r--r--fs/nilfs2/inode.c1
-rw-r--r--fs/nilfs2/mdt.c2
-rw-r--r--fs/nilfs2/nilfs.h4
-rw-r--r--fs/nls/nls_base.c8
-rw-r--r--fs/ocfs2/cluster/heartbeat.c2
-rw-r--r--fs/ocfs2/cluster/netdebug.c4
-rw-r--r--fs/ocfs2/dlm/dlmdebug.c8
-rw-r--r--fs/ocfs2/super.c2
-rw-r--r--fs/omfs/dir.c2
-rw-r--r--fs/omfs/file.c2
-rw-r--r--fs/omfs/omfs.h4
-rw-r--r--fs/proc/kcore.c1
-rw-r--r--fs/proc/page.c5
-rw-r--r--fs/romfs/storage.c4
-rw-r--r--fs/select.c1
-rw-r--r--fs/sysfs/dir.c3
-rw-r--r--fs/sysfs/file.c14
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.c38
-rw-r--r--fs/xfs/linux-2.6/xfs_file.c9
-rw-r--r--fs/xfs/linux-2.6/xfs_iops.c41
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.c2
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c59
-rw-r--r--fs/xfs/linux-2.6/xfs_sync.c36
-rw-r--r--fs/xfs/xfs_dfrag.c8
-rw-r--r--fs/xfs/xfs_dir2_leaf.c4
-rw-r--r--fs/xfs/xfs_inode.c4
-rw-r--r--fs/xfs/xfs_inode.h2
-rw-r--r--fs/xfs/xfs_inode_item.c18
-rw-r--r--fs/xfs/xfs_itable.c21
-rw-r--r--fs/xfs/xfs_vnodeops.c6
-rw-r--r--include/asm-generic/gpio.h1
-rw-r--r--include/asm-generic/hardirq.h2
-rw-r--r--include/drm/drm_crtc_helper.h3
-rw-r--r--include/drm/drm_fb_helper.h7
-rw-r--r--include/drm/drm_pciids.h4
-rw-r--r--include/linux/Kbuild1
-rw-r--r--include/linux/ata.h9
-rw-r--r--include/linux/atmdev.h2
-rw-r--r--include/linux/blkdev.h44
-rw-r--r--include/linux/blktrace_api.h2
-rw-r--r--include/linux/cgroup.h2
-rw-r--r--include/linux/connector.h11
-rw-r--r--include/linux/elf.h1
-rw-r--r--include/linux/fs.h6
-rw-r--r--include/linux/ftrace.h2
-rw-r--r--include/linux/futex.h4
-rw-r--r--include/linux/i2c/twl4030.h6
-rw-r--r--include/linux/init.h1
-rw-r--r--include/linux/interrupt.h2
-rw-r--r--include/linux/jbd2.h27
-rw-r--r--include/linux/kernel.h6
-rw-r--r--include/linux/libata.h12
-rw-r--r--include/linux/mmc/host.h1
-rw-r--r--include/linux/mroute.h4
-rw-r--r--include/linux/mroute6.h4
-rw-r--r--include/linux/net.h8
-rw-r--r--include/linux/netdevice.h2
-rw-r--r--include/linux/netfilter.h4
-rw-r--r--include/linux/pci_ids.h1
-rw-r--r--include/linux/perf_event.h5
-rw-r--r--include/linux/poll.h2
-rw-r--r--include/linux/rcupdate.h18
-rw-r--r--include/linux/rcutree.h13
-rw-r--r--include/linux/res_counter.h6
-rw-r--r--include/linux/serial_core.h3
-rw-r--r--include/linux/socket.h21
-rw-r--r--include/linux/usb/serial.h1
-rw-r--r--include/linux/workqueue.h1
-rw-r--r--include/net/compat.h4
-rw-r--r--include/net/inet_connection_sock.h6
-rw-r--r--include/net/ip.h4
-rw-r--r--include/net/ipv6.h4
-rw-r--r--include/net/mac80211.h2
-rw-r--r--include/net/sctp/structs.h4
-rw-r--r--include/net/sock.h22
-rw-r--r--include/net/tcp.h4
-rw-r--r--include/net/udp.h2
-rw-r--r--include/scsi/libiscsi.h3
-rw-r--r--include/scsi/scsi.h3
-rw-r--r--include/scsi/scsi_cmnd.h4
-rw-r--r--include/scsi/scsi_host.h15
-rw-r--r--include/trace/events/block.h33
-rw-r--r--include/trace/events/ext4.h178
-rw-r--r--include/trace/events/jbd2.h78
-rw-r--r--init/Kconfig18
-rw-r--r--init/main.c1
-rw-r--r--kernel/cgroup.c15
-rw-r--r--kernel/exit.c2
-rw-r--r--kernel/fork.c10
-rw-r--r--kernel/futex.c3
-rw-r--r--kernel/hrtimer.c2
-rw-r--r--kernel/irq/handle.c1
-rw-r--r--kernel/kprobes.c4
-rw-r--r--kernel/lockdep.c20
-rw-r--r--kernel/module.c7
-rw-r--r--kernel/mutex-debug.c1
-rw-r--r--kernel/panic.c3
-rw-r--r--kernel/perf_event.c282
-rw-r--r--kernel/rcupdate.c140
-rw-r--r--kernel/rcutorture.c4
-rw-r--r--kernel/rcutree.c330
-rw-r--r--kernel/rcutree.h86
-rw-r--r--kernel/rcutree_plugin.h103
-rw-r--r--kernel/rcutree_trace.c14
-rw-r--r--kernel/res_counter.c18
-rw-r--r--kernel/sched.c35
-rw-r--r--kernel/sched_clock.c4
-rw-r--r--kernel/time/tick-sched.c9
-rw-r--r--kernel/time/timekeeping.c1
-rw-r--r--kernel/time/timer_list.c2
-rw-r--r--kernel/time/timer_stats.c2
-rw-r--r--kernel/trace/blktrace.c39
-rw-r--r--kernel/trace/ftrace.c27
-rw-r--r--kernel/trace/kmemtrace.c2
-rw-r--r--kernel/trace/trace.c2
-rw-r--r--kernel/trace/trace_branch.c8
-rw-r--r--kernel/trace/trace_event_profile.c15
-rw-r--r--kernel/trace/trace_events_filter.c3
-rw-r--r--kernel/trace/trace_hw_branches.c8
-rw-r--r--kernel/trace/trace_output.c18
-rw-r--r--kernel/trace/trace_syscalls.c4
-rw-r--r--kernel/workqueue.c18
-rw-r--r--lib/Kconfig.debug7
-rw-r--r--lib/debugobjects.c1
-rw-r--r--lib/fault-inject.c1
-rw-r--r--lib/vsprintf.c2
-rw-r--r--mm/Kconfig4
-rw-r--r--mm/backing-dev.c2
-rw-r--r--mm/kmemleak.c5
-rw-r--r--mm/ksm.c10
-rw-r--r--mm/memcontrol.c127
-rw-r--r--mm/page-writeback.c3
-rw-r--r--mm/percpu.c5
-rw-r--r--mm/rmap.c4
-rw-r--r--mm/swapfile.c12
-rw-r--r--mm/vmalloc.c50
-rw-r--r--net/atm/common.c2
-rw-r--r--net/atm/common.h2
-rw-r--r--net/atm/pvc.c2
-rw-r--r--net/atm/svc.c2
-rw-r--r--net/ax25/af_ax25.c4
-rw-r--r--net/bluetooth/hci_sock.c2
-rw-r--r--net/bluetooth/l2cap.c4
-rw-r--r--net/bluetooth/rfcomm/sock.c4
-rw-r--r--net/bluetooth/sco.c2
-rw-r--r--net/can/raw.c2
-rw-r--r--net/compat.c12
-rw-r--r--net/core/dev.c6
-rw-r--r--net/core/net-sysfs.c4
-rw-r--r--net/core/pktgen.c10
-rw-r--r--net/core/sock.c27
-rw-r--r--net/dccp/dccp.h4
-rw-r--r--net/dccp/proto.c10
-rw-r--r--net/decnet/af_decnet.c6
-rw-r--r--net/ieee802154/dgram.c2
-rw-r--r--net/ieee802154/raw.c2
-rw-r--r--net/ipv4/af_inet.c1
-rw-r--r--net/ipv4/devinet.c16
-rw-r--r--net/ipv4/inet_connection_sock.c2
-rw-r--r--net/ipv4/ip_output.c1
-rw-r--r--net/ipv4/ip_sockglue.c6
-rw-r--r--net/ipv4/ipmr.c2
-rw-r--r--net/ipv4/raw.c6
-rw-r--r--net/ipv4/tcp.c10
-rw-r--r--net/ipv4/tcp_minisocks.c1
-rw-r--r--net/ipv4/tcp_output.c11
-rw-r--r--net/ipv4/udp.c80
-rw-r--r--net/ipv4/udp_impl.h4
-rw-r--r--net/ipv6/ip6mr.c2
-rw-r--r--net/ipv6/ipv6_sockglue.c6
-rw-r--r--net/ipv6/raw.c6
-rw-r--r--net/ipv6/sit.c2
-rw-r--r--net/ipv6/udp.c4
-rw-r--r--net/ipv6/udp_impl.h4
-rw-r--r--net/ipx/af_ipx.c2
-rw-r--r--net/irda/af_irda.c2
-rw-r--r--net/irda/ircomm/ircomm_tty_attach.c1
-rw-r--r--net/irda/irlan/irlan_common.c1
-rw-r--r--net/irda/irlan/irlan_eth.c1
-rw-r--r--net/irda/irnet/irnet_irda.c1
-rw-r--r--net/irda/irnet/irnet_ppp.c1
-rw-r--r--net/iucv/af_iucv.c2
-rw-r--r--net/llc/af_llc.c2
-rw-r--r--net/mac80211/ibss.c4
-rw-r--r--net/mac80211/rc80211_pid_debugfs.c1
-rw-r--r--net/mac80211/rx.c12
-rw-r--r--net/mac80211/sta_info.c2
-rw-r--r--net/mac80211/tx.c8
-rw-r--r--net/mac80211/util.c4
-rw-r--r--net/netfilter/nf_conntrack_core.c1
-rw-r--r--net/netfilter/nf_sockopt.c4
-rw-r--r--net/netlink/af_netlink.c2
-rw-r--r--net/netrom/af_netrom.c2
-rw-r--r--net/packet/af_packet.c2
-rw-r--r--net/phonet/pep.c2
-rw-r--r--net/phonet/socket.c1
-rw-r--r--net/rds/af_rds.c2
-rw-r--r--net/rfkill/core.c1
-rw-r--r--net/rose/af_rose.c2
-rw-r--r--net/rxrpc/af_rxrpc.c2
-rw-r--r--net/sched/act_pedit.c2
-rw-r--r--net/sched/cls_api.c2
-rw-r--r--net/sctp/socket.c62
-rw-r--r--net/socket.c2
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma_transport.c1
-rw-r--r--net/tipc/socket.c2
-rw-r--r--net/wireless/core.c1
-rw-r--r--net/wireless/nl80211.c3
-rw-r--r--net/x25/af_x25.c2
-rw-r--r--samples/tracepoints/tracepoint-sample.c2
-rw-r--r--scripts/Kbuild.include2
-rw-r--r--scripts/Makefile.lib2
-rwxr-xr-xscripts/checkkconfigsymbols.sh4
-rw-r--r--scripts/headers_install.pl2
-rwxr-xr-xscripts/mkcompile_h12
-rw-r--r--scripts/package/Makefile11
-rwxr-xr-xscripts/package/mkspec2
-rw-r--r--security/integrity/ima/ima_fs.c10
-rw-r--r--security/keys/keyctl.c2
-rw-r--r--sound/aoa/codecs/tas.c9
-rw-r--r--sound/arm/aaci.c1
-rw-r--r--sound/drivers/opl3/opl3_midi.c28
-rw-r--r--sound/mips/hal2.c2
-rw-r--r--sound/mips/sgio2audio.c2
-rw-r--r--sound/pci/bt87x.c2
-rw-r--r--sound/pci/ctxfi/ctatc.c4
-rw-r--r--sound/pci/echoaudio/echoaudio.c30
-rw-r--r--sound/pci/echoaudio/mia.c1
-rw-r--r--sound/pci/hda/hda_intel.c1
-rw-r--r--sound/pci/hda/patch_analog.c139
-rw-r--r--sound/pci/hda/patch_conexant.c12
-rw-r--r--sound/pci/hda/patch_nvhdmi.c31
-rw-r--r--sound/pci/hda/patch_realtek.c335
-rw-r--r--sound/pci/hda/patch_sigmatel.c49
-rw-r--r--sound/pci/ice1712/amp.c8
-rw-r--r--sound/pci/ice1712/ice1712.c2
-rw-r--r--sound/pci/ice1712/ice1724.c8
-rw-r--r--sound/pci/intel8x0.c12
-rw-r--r--sound/pci/via82xx.c27
-rw-r--r--sound/ppc/keywest.c14
-rw-r--r--sound/soc/blackfin/Kconfig98
-rw-r--r--sound/soc/blackfin/bf5xx-i2s.c8
-rw-r--r--sound/soc/blackfin/bf5xx-tdm.c8
-rw-r--r--sound/soc/codecs/wm8350.c4
-rw-r--r--sound/soc/codecs/wm8940.c2
-rw-r--r--sound/soc/davinci/davinci-i2s.c37
-rw-r--r--sound/soc/davinci/davinci-mcasp.c80
-rw-r--r--sound/soc/davinci/davinci-mcasp.h7
-rw-r--r--sound/soc/davinci/davinci-pcm.c13
-rw-r--r--sound/soc/davinci/davinci-pcm.h1
-rw-r--r--sound/soc/imx/mxc-ssi.c8
-rw-r--r--sound/soc/pxa/Kconfig2
-rw-r--r--sound/soc/soc-dapm.c5
-rw-r--r--sound/usb/usbmixer.c23
-rw-r--r--tools/perf/Documentation/perf-timechart.txt3
-rw-r--r--tools/perf/Makefile23
-rw-r--r--tools/perf/builtin-record.c6
-rw-r--r--tools/perf/builtin-sched.c4
-rw-r--r--tools/perf/builtin-stat.c8
-rw-r--r--tools/perf/builtin-timechart.c10
-rw-r--r--tools/perf/builtin-top.c1
-rw-r--r--tools/perf/builtin-trace.c6
-rw-r--r--tools/perf/design.txt3
-rw-r--r--tools/perf/util/parse-events.c5
-rw-r--r--tools/perf/util/svghelper.c14
-rw-r--r--tools/perf/util/symbol.c3
-rw-r--r--tools/perf/util/trace-event-parse.c17
-rw-r--r--virt/kvm/kvm_main.c16
1696 files changed, 91172 insertions, 22621 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-pci-devices-cciss b/Documentation/ABI/testing/sysfs-bus-pci-devices-cciss
index 0a92a7c93a62..4f29e5f1ebfa 100644
--- a/Documentation/ABI/testing/sysfs-bus-pci-devices-cciss
+++ b/Documentation/ABI/testing/sysfs-bus-pci-devices-cciss
@@ -31,3 +31,31 @@ Date: March 2009
31Kernel Version: 2.6.30 31Kernel Version: 2.6.30
32Contact: iss_storagedev@hp.com 32Contact: iss_storagedev@hp.com
33Description: A symbolic link to /sys/block/cciss!cXdY 33Description: A symbolic link to /sys/block/cciss!cXdY
34
35Where: /sys/bus/pci/devices/<dev>/ccissX/rescan
36Date: August 2009
37Kernel Version: 2.6.31
38Contact: iss_storagedev@hp.com
39Description: Kicks of a rescan of the controller to discover logical
40 drive topology changes.
41
42Where: /sys/bus/pci/devices/<dev>/ccissX/cXdY/lunid
43Date: August 2009
44Kernel Version: 2.6.31
45Contact: iss_storagedev@hp.com
46Description: Displays the 8-byte LUN ID used to address logical
47 drive Y of controller X.
48
49Where: /sys/bus/pci/devices/<dev>/ccissX/cXdY/raid_level
50Date: August 2009
51Kernel Version: 2.6.31
52Contact: iss_storagedev@hp.com
53Description: Displays the RAID level of logical drive Y of
54 controller X.
55
56Where: /sys/bus/pci/devices/<dev>/ccissX/cXdY/usage_count
57Date: August 2009
58Kernel Version: 2.6.31
59Contact: iss_storagedev@hp.com
60Description: Displays the usage count (number of opens) of logical drive Y
61 of controller X.
diff --git a/Documentation/ABI/testing/sysfs-class-usb_host b/Documentation/ABI/testing/sysfs-class-uwb_rc-wusbhc
index 46b66ad1f1b4..4e8106f7cfd9 100644
--- a/Documentation/ABI/testing/sysfs-class-usb_host
+++ b/Documentation/ABI/testing/sysfs-class-uwb_rc-wusbhc
@@ -1,4 +1,4 @@
1What: /sys/class/usb_host/usb_hostN/wusb_chid 1What: /sys/class/uwb_rc/uwbN/wusbhc/wusb_chid
2Date: July 2008 2Date: July 2008
3KernelVersion: 2.6.27 3KernelVersion: 2.6.27
4Contact: David Vrabel <david.vrabel@csr.com> 4Contact: David Vrabel <david.vrabel@csr.com>
@@ -9,7 +9,7 @@ Description:
9 9
10 Set an all zero CHID to stop the host controller. 10 Set an all zero CHID to stop the host controller.
11 11
12What: /sys/class/usb_host/usb_hostN/wusb_trust_timeout 12What: /sys/class/uwb_rc/uwbN/wusbhc/wusb_trust_timeout
13Date: July 2008 13Date: July 2008
14KernelVersion: 2.6.27 14KernelVersion: 2.6.27
15Contact: David Vrabel <david.vrabel@csr.com> 15Contact: David Vrabel <david.vrabel@csr.com>
diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches
index b7f9d3b4bbf6..72651f788f4e 100644
--- a/Documentation/SubmittingPatches
+++ b/Documentation/SubmittingPatches
@@ -232,7 +232,7 @@ your e-mail client so that it sends your patches untouched.
232When sending patches to Linus, always follow step #7. 232When sending patches to Linus, always follow step #7.
233 233
234Large changes are not appropriate for mailing lists, and some 234Large changes are not appropriate for mailing lists, and some
235maintainers. If your patch, uncompressed, exceeds 40 kB in size, 235maintainers. If your patch, uncompressed, exceeds 300 kB in size,
236it is preferred that you store your patch on an Internet-accessible 236it is preferred that you store your patch on an Internet-accessible
237server, and provide instead a URL (link) pointing to your patch. 237server, and provide instead a URL (link) pointing to your patch.
238 238
diff --git a/Documentation/arm/tcm.txt b/Documentation/arm/tcm.txt
index 074f4be6667f..77fd9376e6d7 100644
--- a/Documentation/arm/tcm.txt
+++ b/Documentation/arm/tcm.txt
@@ -29,11 +29,13 @@ TCM location and size. Notice that this is not a MMU table: you
29actually move the physical location of the TCM around. At the 29actually move the physical location of the TCM around. At the
30place you put it, it will mask any underlying RAM from the 30place you put it, it will mask any underlying RAM from the
31CPU so it is usually wise not to overlap any physical RAM with 31CPU so it is usually wise not to overlap any physical RAM with
32the TCM. The TCM memory exists totally outside the MMU and will 32the TCM.
33override any MMU mappings.
34 33
35Code executing inside the ITCM does not "see" any MMU mappings 34The TCM memory can then be remapped to another address again using
36and e.g. register accesses must be made to physical addresses. 35the MMU, but notice that the TCM if often used in situations where
36the MMU is turned off. To avoid confusion the current Linux
37implementation will map the TCM 1 to 1 from physical to virtual
38memory in the location specified by the machine.
37 39
38TCM is used for a few things: 40TCM is used for a few things:
39 41
diff --git a/Documentation/cgroups/cgroups.txt b/Documentation/cgroups/cgroups.txt
index 455d4e6d346d..0b33bfe7dde9 100644
--- a/Documentation/cgroups/cgroups.txt
+++ b/Documentation/cgroups/cgroups.txt
@@ -227,7 +227,14 @@ as the path relative to the root of the cgroup file system.
227Each cgroup is represented by a directory in the cgroup file system 227Each cgroup is represented by a directory in the cgroup file system
228containing the following files describing that cgroup: 228containing the following files describing that cgroup:
229 229
230 - tasks: list of tasks (by pid) attached to that cgroup 230 - tasks: list of tasks (by pid) attached to that cgroup. This list
231 is not guaranteed to be sorted. Writing a thread id into this file
232 moves the thread into this cgroup.
233 - cgroup.procs: list of tgids in the cgroup. This list is not
234 guaranteed to be sorted or free of duplicate tgids, and userspace
235 should sort/uniquify the list if this property is required.
236 Writing a tgid into this file moves all threads with that tgid into
237 this cgroup.
231 - notify_on_release flag: run the release agent on exit? 238 - notify_on_release flag: run the release agent on exit?
232 - release_agent: the path to use for release notifications (this file 239 - release_agent: the path to use for release notifications (this file
233 exists in the top cgroup only) 240 exists in the top cgroup only)
@@ -374,7 +381,7 @@ Now you want to do something with this cgroup.
374 381
375In this directory you can find several files: 382In this directory you can find several files:
376# ls 383# ls
377notify_on_release tasks 384cgroup.procs notify_on_release tasks
378(plus whatever files added by the attached subsystems) 385(plus whatever files added by the attached subsystems)
379 386
380Now attach your shell to this cgroup: 387Now attach your shell to this cgroup:
diff --git a/Documentation/connector/cn_test.c b/Documentation/connector/cn_test.c
index 1711adc33373..b07add3467f1 100644
--- a/Documentation/connector/cn_test.c
+++ b/Documentation/connector/cn_test.c
@@ -34,7 +34,7 @@ static char cn_test_name[] = "cn_test";
34static struct sock *nls; 34static struct sock *nls;
35static struct timer_list cn_test_timer; 35static struct timer_list cn_test_timer;
36 36
37static void cn_test_callback(struct cn_msg *msg) 37static void cn_test_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
38{ 38{
39 pr_info("%s: %lu: idx=%x, val=%x, seq=%u, ack=%u, len=%d: %s.\n", 39 pr_info("%s: %lu: idx=%x, val=%x, seq=%u, ack=%u, len=%d: %s.\n",
40 __func__, jiffies, msg->id.idx, msg->id.val, 40 __func__, jiffies, msg->id.idx, msg->id.val,
diff --git a/Documentation/connector/connector.txt b/Documentation/connector/connector.txt
index 81e6bf6ead57..78c9466a9aa8 100644
--- a/Documentation/connector/connector.txt
+++ b/Documentation/connector/connector.txt
@@ -23,7 +23,7 @@ handling, etc... The Connector driver allows any kernelspace agents to use
23netlink based networking for inter-process communication in a significantly 23netlink based networking for inter-process communication in a significantly
24easier way: 24easier way:
25 25
26int cn_add_callback(struct cb_id *id, char *name, void (*callback) (void *)); 26int cn_add_callback(struct cb_id *id, char *name, void (*callback) (struct cn_msg *, struct netlink_skb_parms *));
27void cn_netlink_send(struct cn_msg *msg, u32 __group, int gfp_mask); 27void cn_netlink_send(struct cn_msg *msg, u32 __group, int gfp_mask);
28 28
29struct cb_id 29struct cb_id
@@ -53,15 +53,15 @@ struct cn_msg
53Connector interfaces. 53Connector interfaces.
54/*****************************************/ 54/*****************************************/
55 55
56int cn_add_callback(struct cb_id *id, char *name, void (*callback) (void *)); 56int cn_add_callback(struct cb_id *id, char *name, void (*callback) (struct cn_msg *, struct netlink_skb_parms *));
57 57
58 Registers new callback with connector core. 58 Registers new callback with connector core.
59 59
60 struct cb_id *id - unique connector's user identifier. 60 struct cb_id *id - unique connector's user identifier.
61 It must be registered in connector.h for legal in-kernel users. 61 It must be registered in connector.h for legal in-kernel users.
62 char *name - connector's callback symbolic name. 62 char *name - connector's callback symbolic name.
63 void (*callback) (void *) - connector's callback. 63 void (*callback) (struct cn..) - connector's callback.
64 Argument must be dereferenced to struct cn_msg *. 64 cn_msg and the sender's credentials
65 65
66 66
67void cn_del_callback(struct cb_id *id); 67void cn_del_callback(struct cb_id *id);
diff --git a/Documentation/debugging-via-ohci1394.txt b/Documentation/debugging-via-ohci1394.txt
index 59a91e5c6909..611f5a5499b1 100644
--- a/Documentation/debugging-via-ohci1394.txt
+++ b/Documentation/debugging-via-ohci1394.txt
@@ -64,14 +64,14 @@ be used to view the printk buffer of a remote machine, even with live update.
64 64
65Bernhard Kaindl enhanced firescope to support accessing 64-bit machines 65Bernhard Kaindl enhanced firescope to support accessing 64-bit machines
66from 32-bit firescope and vice versa: 66from 32-bit firescope and vice versa:
67- ftp://ftp.suse.de/private/bk/firewire/tools/firescope-0.2.2.tar.bz2 67- http://halobates.de/firewire/firescope-0.2.2.tar.bz2
68 68
69and he implemented fast system dump (alpha version - read README.txt): 69and he implemented fast system dump (alpha version - read README.txt):
70- ftp://ftp.suse.de/private/bk/firewire/tools/firedump-0.1.tar.bz2 70- http://halobates.de/firewire/firedump-0.1.tar.bz2
71 71
72There is also a gdb proxy for firewire which allows to use gdb to access 72There is also a gdb proxy for firewire which allows to use gdb to access
73data which can be referenced from symbols found by gdb in vmlinux: 73data which can be referenced from symbols found by gdb in vmlinux:
74- ftp://ftp.suse.de/private/bk/firewire/tools/fireproxy-0.33.tar.bz2 74- http://halobates.de/firewire/fireproxy-0.33.tar.bz2
75 75
76The latest version of this gdb proxy (fireproxy-0.34) can communicate (not 76The latest version of this gdb proxy (fireproxy-0.34) can communicate (not
77yet stable) with kgdb over an memory-based communication module (kgdbom). 77yet stable) with kgdb over an memory-based communication module (kgdbom).
@@ -178,7 +178,7 @@ Step-by-step instructions for using firescope with early OHCI initialization:
178 178
179Notes 179Notes
180----- 180-----
181Documentation and specifications: ftp://ftp.suse.de/private/bk/firewire/docs 181Documentation and specifications: http://halobates.de/firewire/
182 182
183FireWire is a trademark of Apple Inc. - for more information please refer to: 183FireWire is a trademark of Apple Inc. - for more information please refer to:
184http://en.wikipedia.org/wiki/FireWire 184http://en.wikipedia.org/wiki/FireWire
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 89a47b5aff07..04e6c819b28a 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -451,3 +451,33 @@ Why: OSS sound_core grabs all legacy minors (0-255) of SOUND_MAJOR
451 will also allow making ALSA OSS emulation independent of 451 will also allow making ALSA OSS emulation independent of
452 sound_core. The dependency will be broken then too. 452 sound_core. The dependency will be broken then too.
453Who: Tejun Heo <tj@kernel.org> 453Who: Tejun Heo <tj@kernel.org>
454
455----------------------------
456
457What: Support for VMware's guest paravirtuliazation technique [VMI] will be
458 dropped.
459When: 2.6.37 or earlier.
460Why: With the recent innovations in CPU hardware acceleration technologies
461 from Intel and AMD, VMware ran a few experiments to compare these
462 techniques to guest paravirtualization technique on VMware's platform.
463 These hardware assisted virtualization techniques have outperformed the
464 performance benefits provided by VMI in most of the workloads. VMware
465 expects that these hardware features will be ubiquitous in a couple of
466 years, as a result, VMware has started a phased retirement of this
467 feature from the hypervisor. We will be removing this feature from the
468 Kernel too. Right now we are targeting 2.6.37 but can retire earlier if
469 technical reasons (read opportunity to remove major chunk of pvops)
470 arise.
471
472 Please note that VMI has always been an optimization and non-VMI kernels
473 still work fine on VMware's platform.
474 Latest versions of VMware's product which support VMI are,
475 Workstation 7.0 and VSphere 4.0 on ESX side, future maintainence
476 releases for these products will continue supporting VMI.
477
478 For more details about VMI retirement take a look at this,
479 http://blogs.vmware.com/guestosguide/2009/09/vmi-retirement.html
480
481Who: Alok N Kataria <akataria@vmware.com>
482
483----------------------------
diff --git a/Documentation/filesystems/ext3.txt b/Documentation/filesystems/ext3.txt
index 570f9bd9be2b..05d5cf1d743f 100644
--- a/Documentation/filesystems/ext3.txt
+++ b/Documentation/filesystems/ext3.txt
@@ -123,10 +123,18 @@ resuid=n The user ID which may use the reserved blocks.
123 123
124sb=n Use alternate superblock at this location. 124sb=n Use alternate superblock at this location.
125 125
126quota 126quota These options are ignored by the filesystem. They
127noquota 127noquota are used only by quota tools to recognize volumes
128grpquota 128grpquota where quota should be turned on. See documentation
129usrquota 129usrquota in the quota-tools package for more details
130 (http://sourceforge.net/projects/linuxquota).
131
132jqfmt=<quota type> These options tell filesystem details about quota
133usrjquota=<file> so that quota information can be properly updated
134grpjquota=<file> during journal replay. They replace the above
135 quota options. See documentation in the quota-tools
136 package for more details
137 (http://sourceforge.net/projects/linuxquota).
130 138
131bh (*) ext3 associates buffer heads to data pages to 139bh (*) ext3 associates buffer heads to data pages to
132nobh (a) cache disk block mapping information 140nobh (a) cache disk block mapping information
diff --git a/Documentation/filesystems/ext4.txt b/Documentation/filesystems/ext4.txt
index 18b5ec8cea45..bf4f4b7e11b3 100644
--- a/Documentation/filesystems/ext4.txt
+++ b/Documentation/filesystems/ext4.txt
@@ -282,9 +282,16 @@ stripe=n Number of filesystem blocks that mballoc will try
282 to use for allocation size and alignment. For RAID5/6 282 to use for allocation size and alignment. For RAID5/6
283 systems this should be the number of data 283 systems this should be the number of data
284 disks * RAID chunk size in file system blocks. 284 disks * RAID chunk size in file system blocks.
285delalloc (*) Deferring block allocation until write-out time. 285
286nodelalloc Disable delayed allocation. Blocks are allocation 286delalloc (*) Defer block allocation until just before ext4
287 when data is copied from user to page cache. 287 writes out the block(s) in question. This
288 allows ext4 to better allocation decisions
289 more efficiently.
290nodelalloc Disable delayed allocation. Blocks are allocated
291 when the data is copied from userspace to the
292 page cache, either via the write(2) system call
293 or when an mmap'ed page which was previously
294 unallocated is written for the first time.
288 295
289max_batch_time=usec Maximum amount of time ext4 should wait for 296max_batch_time=usec Maximum amount of time ext4 should wait for
290 additional filesystem operations to be batch 297 additional filesystem operations to be batch
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt
index b5aee7838a00..2c48f945546b 100644
--- a/Documentation/filesystems/proc.txt
+++ b/Documentation/filesystems/proc.txt
@@ -1113,7 +1113,6 @@ Table 1-12: Files in /proc/fs/ext4/<devname>
1113.............................................................................. 1113..............................................................................
1114 File Content 1114 File Content
1115 mb_groups details of multiblock allocator buddy cache of free blocks 1115 mb_groups details of multiblock allocator buddy cache of free blocks
1116 mb_history multiblock allocation history
1117.............................................................................. 1116..............................................................................
1118 1117
1119 1118
diff --git a/Documentation/filesystems/vfat.txt b/Documentation/filesystems/vfat.txt
index b58b84b50fa2..eed520fd0c8e 100644
--- a/Documentation/filesystems/vfat.txt
+++ b/Documentation/filesystems/vfat.txt
@@ -102,7 +102,7 @@ shortname=lower|win95|winnt|mixed
102 winnt: emulate the Windows NT rule for display/create. 102 winnt: emulate the Windows NT rule for display/create.
103 mixed: emulate the Windows NT rule for display, 103 mixed: emulate the Windows NT rule for display,
104 emulate the Windows 95 rule for create. 104 emulate the Windows 95 rule for create.
105 Default setting is `lower'. 105 Default setting is `mixed'.
106 106
107tz=UTC -- Interpret timestamps as UTC rather than local time. 107tz=UTC -- Interpret timestamps as UTC rather than local time.
108 This option disables the conversion of timestamps 108 This option disables the conversion of timestamps
diff --git a/Documentation/hwmon/ltc4215 b/Documentation/hwmon/ltc4215
index 2e6a21eb656c..c196a1846259 100644
--- a/Documentation/hwmon/ltc4215
+++ b/Documentation/hwmon/ltc4215
@@ -22,12 +22,13 @@ Usage Notes
22----------- 22-----------
23 23
24This driver does not probe for LTC4215 devices, due to the fact that some 24This driver does not probe for LTC4215 devices, due to the fact that some
25of the possible addresses are unfriendly to probing. You will need to use 25of the possible addresses are unfriendly to probing. You will have to
26the "force" parameter to tell the driver where to find the device. 26instantiate the devices explicitly.
27 27
28Example: the following will load the driver for an LTC4215 at address 0x44 28Example: the following will load the driver for an LTC4215 at address 0x44
29on I2C bus #0: 29on I2C bus #0:
30$ modprobe ltc4215 force=0,0x44 30$ modprobe ltc4215
31$ echo ltc4215 0x44 > /sys/bus/i2c/devices/i2c-0/new_device
31 32
32 33
33Sysfs entries 34Sysfs entries
diff --git a/Documentation/hwmon/ltc4245 b/Documentation/hwmon/ltc4245
index bae7a3adc5d8..02838a47d862 100644
--- a/Documentation/hwmon/ltc4245
+++ b/Documentation/hwmon/ltc4245
@@ -23,12 +23,13 @@ Usage Notes
23----------- 23-----------
24 24
25This driver does not probe for LTC4245 devices, due to the fact that some 25This driver does not probe for LTC4245 devices, due to the fact that some
26of the possible addresses are unfriendly to probing. You will need to use 26of the possible addresses are unfriendly to probing. You will have to
27the "force" parameter to tell the driver where to find the device. 27instantiate the devices explicitly.
28 28
29Example: the following will load the driver for an LTC4245 at address 0x23 29Example: the following will load the driver for an LTC4245 at address 0x23
30on I2C bus #1: 30on I2C bus #1:
31$ modprobe ltc4245 force=1,0x23 31$ modprobe ltc4245
32$ echo ltc4245 0x23 > /sys/bus/i2c/devices/i2c-1/new_device
32 33
33 34
34Sysfs entries 35Sysfs entries
diff --git a/Documentation/i2c/instantiating-devices b/Documentation/i2c/instantiating-devices
index c740b7b41088..e89490270aba 100644
--- a/Documentation/i2c/instantiating-devices
+++ b/Documentation/i2c/instantiating-devices
@@ -188,7 +188,7 @@ segment, the address is sufficient to uniquely identify the device to be
188deleted. 188deleted.
189 189
190Example: 190Example:
191# echo eeprom 0x50 > /sys/class/i2c-adapter/i2c-3/new_device 191# echo eeprom 0x50 > /sys/bus/i2c/devices/i2c-3/new_device
192 192
193While this interface should only be used when in-kernel device declaration 193While this interface should only be used when in-kernel device declaration
194can't be done, there is a variety of cases where it can be helpful: 194can't be done, there is a variety of cases where it can be helpful:
diff --git a/Documentation/infiniband/user_mad.txt b/Documentation/infiniband/user_mad.txt
index 744687dd195b..8a366959f5cc 100644
--- a/Documentation/infiniband/user_mad.txt
+++ b/Documentation/infiniband/user_mad.txt
@@ -128,8 +128,8 @@ Setting IsSM Capability Bit
128 To create the appropriate character device files automatically with 128 To create the appropriate character device files automatically with
129 udev, a rule like 129 udev, a rule like
130 130
131 KERNEL="umad*", NAME="infiniband/%k" 131 KERNEL=="umad*", NAME="infiniband/%k"
132 KERNEL="issm*", NAME="infiniband/%k" 132 KERNEL=="issm*", NAME="infiniband/%k"
133 133
134 can be used. This will create device nodes named 134 can be used. This will create device nodes named
135 135
diff --git a/Documentation/infiniband/user_verbs.txt b/Documentation/infiniband/user_verbs.txt
index f847501e50b5..afe3f8da9018 100644
--- a/Documentation/infiniband/user_verbs.txt
+++ b/Documentation/infiniband/user_verbs.txt
@@ -58,7 +58,7 @@ Memory pinning
58 To create the appropriate character device files automatically with 58 To create the appropriate character device files automatically with
59 udev, a rule like 59 udev, a rule like
60 60
61 KERNEL="uverbs*", NAME="infiniband/%k" 61 KERNEL=="uverbs*", NAME="infiniband/%k"
62 62
63 can be used. This will create device nodes named 63 can be used. This will create device nodes named
64 64
diff --git a/Documentation/isdn/INTERFACE.CAPI b/Documentation/isdn/INTERFACE.CAPI
index 686e107923ec..5fe8de5cc727 100644
--- a/Documentation/isdn/INTERFACE.CAPI
+++ b/Documentation/isdn/INTERFACE.CAPI
@@ -60,10 +60,9 @@ open() operation on regular files or character devices.
60 60
61After a successful return from register_appl(), CAPI messages from the 61After a successful return from register_appl(), CAPI messages from the
62application may be passed to the driver for the device via calls to the 62application may be passed to the driver for the device via calls to the
63send_message() callback function. The CAPI message to send is stored in the 63send_message() callback function. Conversely, the driver may call Kernel
64data portion of an skb. Conversely, the driver may call Kernel CAPI's 64CAPI's capi_ctr_handle_message() function to pass a received CAPI message to
65capi_ctr_handle_message() function to pass a received CAPI message to Kernel 65Kernel CAPI for forwarding to an application, specifying its ApplID.
66CAPI for forwarding to an application, specifying its ApplID.
67 66
68Deregistration requests (CAPI operation CAPI_RELEASE) from applications are 67Deregistration requests (CAPI operation CAPI_RELEASE) from applications are
69forwarded as calls to the release_appl() callback function, passing the same 68forwarded as calls to the release_appl() callback function, passing the same
@@ -142,6 +141,7 @@ u16 (*send_message)(struct capi_ctr *ctrlr, struct sk_buff *skb)
142 to accepting or queueing the message. Errors occurring during the 141 to accepting or queueing the message. Errors occurring during the
143 actual processing of the message should be signaled with an 142 actual processing of the message should be signaled with an
144 appropriate reply message. 143 appropriate reply message.
144 May be called in process or interrupt context.
145 Calls to this function are not serialized by Kernel CAPI, ie. it must 145 Calls to this function are not serialized by Kernel CAPI, ie. it must
146 be prepared to be re-entered. 146 be prepared to be re-entered.
147 147
@@ -154,7 +154,8 @@ read_proc_t *ctr_read_proc
154 system entry, /proc/capi/controllers/<n>; will be called with a 154 system entry, /proc/capi/controllers/<n>; will be called with a
155 pointer to the device's capi_ctr structure as the last (data) argument 155 pointer to the device's capi_ctr structure as the last (data) argument
156 156
157Note: Callback functions are never called in interrupt context. 157Note: Callback functions except send_message() are never called in interrupt
158context.
158 159
159- to be filled in before calling capi_ctr_ready(): 160- to be filled in before calling capi_ctr_ready():
160 161
@@ -171,14 +172,40 @@ u8 serial[CAPI_SERIAL_LEN]
171 value to return for CAPI_GET_SERIAL 172 value to return for CAPI_GET_SERIAL
172 173
173 174
1744.3 The _cmsg Structure 1754.3 SKBs
176
177CAPI messages are passed between Kernel CAPI and the driver via send_message()
178and capi_ctr_handle_message(), stored in the data portion of a socket buffer
179(skb). Each skb contains a single CAPI message coded according to the CAPI 2.0
180standard.
181
182For the data transfer messages, DATA_B3_REQ and DATA_B3_IND, the actual
183payload data immediately follows the CAPI message itself within the same skb.
184The Data and Data64 parameters are not used for processing. The Data64
185parameter may be omitted by setting the length field of the CAPI message to 22
186instead of 30.
187
188
1894.4 The _cmsg Structure
175 190
176(declared in <linux/isdn/capiutil.h>) 191(declared in <linux/isdn/capiutil.h>)
177 192
178The _cmsg structure stores the contents of a CAPI 2.0 message in an easily 193The _cmsg structure stores the contents of a CAPI 2.0 message in an easily
179accessible form. It contains members for all possible CAPI 2.0 parameters, of 194accessible form. It contains members for all possible CAPI 2.0 parameters,
180which only those appearing in the message type currently being processed are 195including subparameters of the Additional Info and B Protocol structured
181actually used. Unused members should be set to zero. 196parameters, with the following exceptions:
197
198* second Calling party number (CONNECT_IND)
199
200* Data64 (DATA_B3_REQ and DATA_B3_IND)
201
202* Sending complete (subparameter of Additional Info, CONNECT_REQ and INFO_REQ)
203
204* Global Configuration (subparameter of B Protocol, CONNECT_REQ, CONNECT_RESP
205 and SELECT_B_PROTOCOL_REQ)
206
207Only those parameters appearing in the message type currently being processed
208are actually used. Unused members should be set to zero.
182 209
183Members are named after the CAPI 2.0 standard names of the parameters they 210Members are named after the CAPI 2.0 standard names of the parameters they
184represent. See <linux/isdn/capiutil.h> for the exact spelling. Member data 211represent. See <linux/isdn/capiutil.h> for the exact spelling. Member data
@@ -190,18 +217,19 @@ u16 for CAPI parameters of type 'word'
190 217
191u32 for CAPI parameters of type 'dword' 218u32 for CAPI parameters of type 'dword'
192 219
193_cstruct for CAPI parameters of type 'struct' not containing any 220_cstruct for CAPI parameters of type 'struct'
194 variably-sized (struct) subparameters (eg. 'Called Party Number')
195 The member is a pointer to a buffer containing the parameter in 221 The member is a pointer to a buffer containing the parameter in
196 CAPI encoding (length + content). It may also be NULL, which will 222 CAPI encoding (length + content). It may also be NULL, which will
197 be taken to represent an empty (zero length) parameter. 223 be taken to represent an empty (zero length) parameter.
224 Subparameters are stored in encoded form within the content part.
198 225
199_cmstruct for CAPI parameters of type 'struct' containing 'struct' 226_cmstruct alternative representation for CAPI parameters of type 'struct'
200 subparameters ('Additional Info' and 'B Protocol') 227 (used only for the 'Additional Info' and 'B Protocol' parameters)
201 The representation is a single byte containing one of the values: 228 The representation is a single byte containing one of the values:
202 CAPI_DEFAULT: the parameter is empty 229 CAPI_DEFAULT: The parameter is empty/absent.
203 CAPI_COMPOSE: the values of the subparameters are stored 230 CAPI_COMPOSE: The parameter is present.
204 individually in the corresponding _cmsg structure members 231 Subparameter values are stored individually in the corresponding
232 _cmsg structure members.
205 233
206Functions capi_cmsg2message() and capi_message2cmsg() are provided to convert 234Functions capi_cmsg2message() and capi_message2cmsg() are provided to convert
207messages between their transport encoding described in the CAPI 2.0 standard 235messages between their transport encoding described in the CAPI 2.0 standard
@@ -297,3 +325,26 @@ char *capi_cmd2str(u8 Command, u8 Subcommand)
297 be NULL if the command/subcommand is not one of those defined in the 325 be NULL if the command/subcommand is not one of those defined in the
298 CAPI 2.0 standard. 326 CAPI 2.0 standard.
299 327
328
3297. Debugging
330
331The module kernelcapi has a module parameter showcapimsgs controlling some
332debugging output produced by the module. It can only be set when the module is
333loaded, via a parameter "showcapimsgs=<n>" to the modprobe command, either on
334the command line or in the configuration file.
335
336If the lowest bit of showcapimsgs is set, kernelcapi logs controller and
337application up and down events.
338
339In addition, every registered CAPI controller has an associated traceflag
340parameter controlling how CAPI messages sent from and to tha controller are
341logged. The traceflag parameter is initialized with the value of the
342showcapimsgs parameter when the controller is registered, but can later be
343changed via the MANUFACTURER_REQ command KCAPI_CMD_TRACE.
344
345If the value of traceflag is non-zero, CAPI messages are logged.
346DATA_B3 messages are only logged if the value of traceflag is > 2.
347
348If the lowest bit of traceflag is set, only the command/subcommand and message
349length are logged. Otherwise, kernelcapi logs a readable representation of
350the entire message.
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 6fa7292947e5..9107b387e91f 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -671,6 +671,7 @@ and is between 256 and 4096 characters. It is defined in the file
671 earlyprintk= [X86,SH,BLACKFIN] 671 earlyprintk= [X86,SH,BLACKFIN]
672 earlyprintk=vga 672 earlyprintk=vga
673 earlyprintk=serial[,ttySn[,baudrate]] 673 earlyprintk=serial[,ttySn[,baudrate]]
674 earlyprintk=ttySn[,baudrate]
674 earlyprintk=dbgp[debugController#] 675 earlyprintk=dbgp[debugController#]
675 676
676 Append ",keep" to not disable it when the real console 677 Append ",keep" to not disable it when the real console
diff --git a/Documentation/i2c/chips/eeprom b/Documentation/misc-devices/eeprom
index f7e8104b5764..f7e8104b5764 100644
--- a/Documentation/i2c/chips/eeprom
+++ b/Documentation/misc-devices/eeprom
diff --git a/Documentation/i2c/chips/max6875 b/Documentation/misc-devices/max6875
index 10ca43cd1a72..1e89ee3ccc1b 100644
--- a/Documentation/i2c/chips/max6875
+++ b/Documentation/misc-devices/max6875
@@ -42,10 +42,12 @@ General Remarks
42 42
43Valid addresses for the MAX6875 are 0x50 and 0x52. 43Valid addresses for the MAX6875 are 0x50 and 0x52.
44Valid addresses for the MAX6874 are 0x50, 0x52, 0x54 and 0x56. 44Valid addresses for the MAX6874 are 0x50, 0x52, 0x54 and 0x56.
45The driver does not probe any address, so you must force the address. 45The driver does not probe any address, so you explicitly instantiate the
46devices.
46 47
47Example: 48Example:
48$ modprobe max6875 force=0,0x50 49$ modprobe max6875
50$ echo max6875 0x50 > /sys/bus/i2c/devices/i2c-0/new_device
49 51
50The MAX6874/MAX6875 ignores address bit 0, so this driver attaches to multiple 52The MAX6874/MAX6875 ignores address bit 0, so this driver attaches to multiple
51addresses. For example, for address 0x50, it also reserves 0x51. 53addresses. For example, for address 0x50, it also reserves 0x51.
diff --git a/Documentation/networking/pktgen.txt b/Documentation/networking/pktgen.txt
index c6cf4a3c16e0..61bb645d50e0 100644
--- a/Documentation/networking/pktgen.txt
+++ b/Documentation/networking/pktgen.txt
@@ -90,6 +90,11 @@ Examples:
90 pgset "dstmac 00:00:00:00:00:00" sets MAC destination address 90 pgset "dstmac 00:00:00:00:00:00" sets MAC destination address
91 pgset "srcmac 00:00:00:00:00:00" sets MAC source address 91 pgset "srcmac 00:00:00:00:00:00" sets MAC source address
92 92
93 pgset "queue_map_min 0" Sets the min value of tx queue interval
94 pgset "queue_map_max 7" Sets the max value of tx queue interval, for multiqueue devices
95 To select queue 1 of a given device,
96 use queue_map_min=1 and queue_map_max=1
97
93 pgset "src_mac_count 1" Sets the number of MACs we'll range through. 98 pgset "src_mac_count 1" Sets the number of MACs we'll range through.
94 The 'minimum' MAC is what you set with srcmac. 99 The 'minimum' MAC is what you set with srcmac.
95 100
@@ -101,6 +106,9 @@ Examples:
101 IPDST_RND, UDPSRC_RND, 106 IPDST_RND, UDPSRC_RND,
102 UDPDST_RND, MACSRC_RND, MACDST_RND 107 UDPDST_RND, MACSRC_RND, MACDST_RND
103 MPLS_RND, VID_RND, SVID_RND 108 MPLS_RND, VID_RND, SVID_RND
109 QUEUE_MAP_RND # queue map random
110 QUEUE_MAP_CPU # queue map mirrors smp_processor_id()
111
104 112
105 pgset "udp_src_min 9" set UDP source port min, If < udp_src_max, then 113 pgset "udp_src_min 9" set UDP source port min, If < udp_src_max, then
106 cycle through the port range. 114 cycle through the port range.
diff --git a/Documentation/networking/timestamping/timestamping.c b/Documentation/networking/timestamping/timestamping.c
index 43d143104210..a7936fe8444a 100644
--- a/Documentation/networking/timestamping/timestamping.c
+++ b/Documentation/networking/timestamping/timestamping.c
@@ -381,7 +381,7 @@ int main(int argc, char **argv)
381 memset(&hwtstamp, 0, sizeof(hwtstamp)); 381 memset(&hwtstamp, 0, sizeof(hwtstamp));
382 strncpy(hwtstamp.ifr_name, interface, sizeof(hwtstamp.ifr_name)); 382 strncpy(hwtstamp.ifr_name, interface, sizeof(hwtstamp.ifr_name));
383 hwtstamp.ifr_data = (void *)&hwconfig; 383 hwtstamp.ifr_data = (void *)&hwconfig;
384 memset(&hwconfig, 0, sizeof(&hwconfig)); 384 memset(&hwconfig, 0, sizeof(hwconfig));
385 hwconfig.tx_type = 385 hwconfig.tx_type =
386 (so_timestamping_flags & SOF_TIMESTAMPING_TX_HARDWARE) ? 386 (so_timestamping_flags & SOF_TIMESTAMPING_TX_HARDWARE) ?
387 HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF; 387 HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
diff --git a/Documentation/scsi/hptiop.txt b/Documentation/scsi/hptiop.txt
index a6eb4add1be6..9605179711f4 100644
--- a/Documentation/scsi/hptiop.txt
+++ b/Documentation/scsi/hptiop.txt
@@ -3,6 +3,25 @@ HIGHPOINT ROCKETRAID 3xxx/4xxx ADAPTER DRIVER (hptiop)
3Controller Register Map 3Controller Register Map
4------------------------- 4-------------------------
5 5
6For RR44xx Intel IOP based adapters, the controller IOP is accessed via PCI BAR0 and BAR2:
7
8 BAR0 offset Register
9 0x11C5C Link Interface IRQ Set
10 0x11C60 Link Interface IRQ Clear
11
12 BAR2 offset Register
13 0x10 Inbound Message Register 0
14 0x14 Inbound Message Register 1
15 0x18 Outbound Message Register 0
16 0x1C Outbound Message Register 1
17 0x20 Inbound Doorbell Register
18 0x24 Inbound Interrupt Status Register
19 0x28 Inbound Interrupt Mask Register
20 0x30 Outbound Interrupt Status Register
21 0x34 Outbound Interrupt Mask Register
22 0x40 Inbound Queue Port
23 0x44 Outbound Queue Port
24
6For Intel IOP based adapters, the controller IOP is accessed via PCI BAR0: 25For Intel IOP based adapters, the controller IOP is accessed via PCI BAR0:
7 26
8 BAR0 offset Register 27 BAR0 offset Register
@@ -93,7 +112,7 @@ The driver exposes following sysfs attributes:
93 112
94 113
95----------------------------------------------------------------------------- 114-----------------------------------------------------------------------------
96Copyright (C) 2006-2007 HighPoint Technologies, Inc. All Rights Reserved. 115Copyright (C) 2006-2009 HighPoint Technologies, Inc. All Rights Reserved.
97 116
98 This file is distributed in the hope that it will be useful, 117 This file is distributed in the hope that it will be useful,
99 but WITHOUT ANY WARRANTY; without even the implied warranty of 118 but WITHOUT ANY WARRANTY; without even the implied warranty of
diff --git a/Documentation/sound/alsa/HD-Audio-Models.txt b/Documentation/sound/alsa/HD-Audio-Models.txt
index f1708b79f963..4c7f9aee5c4e 100644
--- a/Documentation/sound/alsa/HD-Audio-Models.txt
+++ b/Documentation/sound/alsa/HD-Audio-Models.txt
@@ -209,6 +209,7 @@ AD1884A / AD1883 / AD1984A / AD1984B
209 laptop laptop with HP jack sensing 209 laptop laptop with HP jack sensing
210 mobile mobile devices with HP jack sensing 210 mobile mobile devices with HP jack sensing
211 thinkpad Lenovo Thinkpad X300 211 thinkpad Lenovo Thinkpad X300
212 touchsmart HP Touchsmart
212 213
213AD1884 214AD1884
214====== 215======
@@ -358,6 +359,7 @@ STAC9227/9228/9229/927x
358 5stack-no-fp D965 5stack without front panel 359 5stack-no-fp D965 5stack without front panel
359 dell-3stack Dell Dimension E520 360 dell-3stack Dell Dimension E520
360 dell-bios Fixes with Dell BIOS setup 361 dell-bios Fixes with Dell BIOS setup
362 volknob Fixes with volume-knob widget 0x24
361 auto BIOS setup (default) 363 auto BIOS setup (default)
362 364
363STAC92HD71B* 365STAC92HD71B*
diff --git a/Documentation/vm/ksm.txt b/Documentation/vm/ksm.txt
index 72a22f65960e..262d8e6793a3 100644
--- a/Documentation/vm/ksm.txt
+++ b/Documentation/vm/ksm.txt
@@ -52,15 +52,15 @@ The KSM daemon is controlled by sysfs files in /sys/kernel/mm/ksm/,
52readable by all but writable only by root: 52readable by all but writable only by root:
53 53
54max_kernel_pages - set to maximum number of kernel pages that KSM may use 54max_kernel_pages - set to maximum number of kernel pages that KSM may use
55 e.g. "echo 2000 > /sys/kernel/mm/ksm/max_kernel_pages" 55 e.g. "echo 100000 > /sys/kernel/mm/ksm/max_kernel_pages"
56 Value 0 imposes no limit on the kernel pages KSM may use; 56 Value 0 imposes no limit on the kernel pages KSM may use;
57 but note that any process using MADV_MERGEABLE can cause 57 but note that any process using MADV_MERGEABLE can cause
58 KSM to allocate these pages, unswappable until it exits. 58 KSM to allocate these pages, unswappable until it exits.
59 Default: 2000 (chosen for demonstration purposes) 59 Default: quarter of memory (chosen to not pin too much)
60 60
61pages_to_scan - how many present pages to scan before ksmd goes to sleep 61pages_to_scan - how many present pages to scan before ksmd goes to sleep
62 e.g. "echo 200 > /sys/kernel/mm/ksm/pages_to_scan" 62 e.g. "echo 100 > /sys/kernel/mm/ksm/pages_to_scan"
63 Default: 200 (chosen for demonstration purposes) 63 Default: 100 (chosen for demonstration purposes)
64 64
65sleep_millisecs - how many milliseconds ksmd should sleep before next scan 65sleep_millisecs - how many milliseconds ksmd should sleep before next scan
66 e.g. "echo 20 > /sys/kernel/mm/ksm/sleep_millisecs" 66 e.g. "echo 20 > /sys/kernel/mm/ksm/sleep_millisecs"
@@ -70,7 +70,8 @@ run - set 0 to stop ksmd from running but keep merged pages,
70 set 1 to run ksmd e.g. "echo 1 > /sys/kernel/mm/ksm/run", 70 set 1 to run ksmd e.g. "echo 1 > /sys/kernel/mm/ksm/run",
71 set 2 to stop ksmd and unmerge all pages currently merged, 71 set 2 to stop ksmd and unmerge all pages currently merged,
72 but leave mergeable areas registered for next run 72 but leave mergeable areas registered for next run
73 Default: 1 (for immediate use by apps which register) 73 Default: 0 (must be changed to 1 to activate KSM,
74 except if CONFIG_SYSFS is disabled)
74 75
75The effectiveness of KSM and MADV_MERGEABLE is shown in /sys/kernel/mm/ksm/: 76The effectiveness of KSM and MADV_MERGEABLE is shown in /sys/kernel/mm/ksm/:
76 77
@@ -86,4 +87,4 @@ pages_volatile embraces several different kinds of activity, but a high
86proportion there would also indicate poor use of madvise MADV_MERGEABLE. 87proportion there would also indicate poor use of madvise MADV_MERGEABLE.
87 88
88Izik Eidus, 89Izik Eidus,
89Hugh Dickins, 30 July 2009 90Hugh Dickins, 24 Sept 2009
diff --git a/Documentation/vm/page-types.c b/Documentation/vm/page-types.c
index fa1a30d9e9d5..3ec4f2a22585 100644
--- a/Documentation/vm/page-types.c
+++ b/Documentation/vm/page-types.c
@@ -2,7 +2,10 @@
2 * page-types: Tool for querying page flags 2 * page-types: Tool for querying page flags
3 * 3 *
4 * Copyright (C) 2009 Intel corporation 4 * Copyright (C) 2009 Intel corporation
5 * Copyright (C) 2009 Wu Fengguang <fengguang.wu@intel.com> 5 *
6 * Authors: Wu Fengguang <fengguang.wu@intel.com>
7 *
8 * Released under the General Public License (GPL).
6 */ 9 */
7 10
8#define _LARGEFILE64_SOURCE 11#define _LARGEFILE64_SOURCE
@@ -69,7 +72,9 @@
69#define KPF_COMPOUND_TAIL 16 72#define KPF_COMPOUND_TAIL 16
70#define KPF_HUGE 17 73#define KPF_HUGE 17
71#define KPF_UNEVICTABLE 18 74#define KPF_UNEVICTABLE 18
75#define KPF_HWPOISON 19
72#define KPF_NOPAGE 20 76#define KPF_NOPAGE 20
77#define KPF_KSM 21
73 78
74/* [32-] kernel hacking assistances */ 79/* [32-] kernel hacking assistances */
75#define KPF_RESERVED 32 80#define KPF_RESERVED 32
@@ -116,7 +121,9 @@ static char *page_flag_names[] = {
116 [KPF_COMPOUND_TAIL] = "T:compound_tail", 121 [KPF_COMPOUND_TAIL] = "T:compound_tail",
117 [KPF_HUGE] = "G:huge", 122 [KPF_HUGE] = "G:huge",
118 [KPF_UNEVICTABLE] = "u:unevictable", 123 [KPF_UNEVICTABLE] = "u:unevictable",
124 [KPF_HWPOISON] = "X:hwpoison",
119 [KPF_NOPAGE] = "n:nopage", 125 [KPF_NOPAGE] = "n:nopage",
126 [KPF_KSM] = "x:ksm",
120 127
121 [KPF_RESERVED] = "r:reserved", 128 [KPF_RESERVED] = "r:reserved",
122 [KPF_MLOCKED] = "m:mlocked", 129 [KPF_MLOCKED] = "m:mlocked",
@@ -152,9 +159,6 @@ static unsigned long opt_size[MAX_ADDR_RANGES];
152static int nr_vmas; 159static int nr_vmas;
153static unsigned long pg_start[MAX_VMAS]; 160static unsigned long pg_start[MAX_VMAS];
154static unsigned long pg_end[MAX_VMAS]; 161static unsigned long pg_end[MAX_VMAS];
155static unsigned long voffset;
156
157static int pagemap_fd;
158 162
159#define MAX_BIT_FILTERS 64 163#define MAX_BIT_FILTERS 64
160static int nr_bit_filters; 164static int nr_bit_filters;
@@ -163,9 +167,16 @@ static uint64_t opt_bits[MAX_BIT_FILTERS];
163 167
164static int page_size; 168static int page_size;
165 169
166#define PAGES_BATCH (64 << 10) /* 64k pages */ 170static int pagemap_fd;
167static int kpageflags_fd; 171static int kpageflags_fd;
168 172
173static int opt_hwpoison;
174static int opt_unpoison;
175
176static char *hwpoison_debug_fs = "/debug/hwpoison";
177static int hwpoison_inject_fd;
178static int hwpoison_forget_fd;
179
169#define HASH_SHIFT 13 180#define HASH_SHIFT 13
170#define HASH_SIZE (1 << HASH_SHIFT) 181#define HASH_SIZE (1 << HASH_SHIFT)
171#define HASH_MASK (HASH_SIZE - 1) 182#define HASH_MASK (HASH_SIZE - 1)
@@ -207,6 +218,74 @@ static void fatal(const char *x, ...)
207 exit(EXIT_FAILURE); 218 exit(EXIT_FAILURE);
208} 219}
209 220
221int checked_open(const char *pathname, int flags)
222{
223 int fd = open(pathname, flags);
224
225 if (fd < 0) {
226 perror(pathname);
227 exit(EXIT_FAILURE);
228 }
229
230 return fd;
231}
232
233/*
234 * pagemap/kpageflags routines
235 */
236
237static unsigned long do_u64_read(int fd, char *name,
238 uint64_t *buf,
239 unsigned long index,
240 unsigned long count)
241{
242 long bytes;
243
244 if (index > ULONG_MAX / 8)
245 fatal("index overflow: %lu\n", index);
246
247 if (lseek(fd, index * 8, SEEK_SET) < 0) {
248 perror(name);
249 exit(EXIT_FAILURE);
250 }
251
252 bytes = read(fd, buf, count * 8);
253 if (bytes < 0) {
254 perror(name);
255 exit(EXIT_FAILURE);
256 }
257 if (bytes % 8)
258 fatal("partial read: %lu bytes\n", bytes);
259
260 return bytes / 8;
261}
262
263static unsigned long kpageflags_read(uint64_t *buf,
264 unsigned long index,
265 unsigned long pages)
266{
267 return do_u64_read(kpageflags_fd, PROC_KPAGEFLAGS, buf, index, pages);
268}
269
270static unsigned long pagemap_read(uint64_t *buf,
271 unsigned long index,
272 unsigned long pages)
273{
274 return do_u64_read(pagemap_fd, "/proc/pid/pagemap", buf, index, pages);
275}
276
277static unsigned long pagemap_pfn(uint64_t val)
278{
279 unsigned long pfn;
280
281 if (val & PM_PRESENT)
282 pfn = PM_PFRAME(val);
283 else
284 pfn = 0;
285
286 return pfn;
287}
288
210 289
211/* 290/*
212 * page flag names 291 * page flag names
@@ -255,7 +334,8 @@ static char *page_flag_longname(uint64_t flags)
255 * page list and summary 334 * page list and summary
256 */ 335 */
257 336
258static void show_page_range(unsigned long offset, uint64_t flags) 337static void show_page_range(unsigned long voffset,
338 unsigned long offset, uint64_t flags)
259{ 339{
260 static uint64_t flags0; 340 static uint64_t flags0;
261 static unsigned long voff; 341 static unsigned long voff;
@@ -281,7 +361,8 @@ static void show_page_range(unsigned long offset, uint64_t flags)
281 count = 1; 361 count = 1;
282} 362}
283 363
284static void show_page(unsigned long offset, uint64_t flags) 364static void show_page(unsigned long voffset,
365 unsigned long offset, uint64_t flags)
285{ 366{
286 if (opt_pid) 367 if (opt_pid)
287 printf("%lx\t", voffset); 368 printf("%lx\t", voffset);
@@ -362,6 +443,62 @@ static uint64_t well_known_flags(uint64_t flags)
362 return flags; 443 return flags;
363} 444}
364 445
446static uint64_t kpageflags_flags(uint64_t flags)
447{
448 flags = expand_overloaded_flags(flags);
449
450 if (!opt_raw)
451 flags = well_known_flags(flags);
452
453 return flags;
454}
455
456/*
457 * page actions
458 */
459
460static void prepare_hwpoison_fd(void)
461{
462 char buf[100];
463
464 if (opt_hwpoison && !hwpoison_inject_fd) {
465 sprintf(buf, "%s/corrupt-pfn", hwpoison_debug_fs);
466 hwpoison_inject_fd = checked_open(buf, O_WRONLY);
467 }
468
469 if (opt_unpoison && !hwpoison_forget_fd) {
470 sprintf(buf, "%s/renew-pfn", hwpoison_debug_fs);
471 hwpoison_forget_fd = checked_open(buf, O_WRONLY);
472 }
473}
474
475static int hwpoison_page(unsigned long offset)
476{
477 char buf[100];
478 int len;
479
480 len = sprintf(buf, "0x%lx\n", offset);
481 len = write(hwpoison_inject_fd, buf, len);
482 if (len < 0) {
483 perror("hwpoison inject");
484 return len;
485 }
486 return 0;
487}
488
489static int unpoison_page(unsigned long offset)
490{
491 char buf[100];
492 int len;
493
494 len = sprintf(buf, "0x%lx\n", offset);
495 len = write(hwpoison_forget_fd, buf, len);
496 if (len < 0) {
497 perror("hwpoison forget");
498 return len;
499 }
500 return 0;
501}
365 502
366/* 503/*
367 * page frame walker 504 * page frame walker
@@ -394,104 +531,83 @@ static int hash_slot(uint64_t flags)
394 exit(EXIT_FAILURE); 531 exit(EXIT_FAILURE);
395} 532}
396 533
397static void add_page(unsigned long offset, uint64_t flags) 534static void add_page(unsigned long voffset,
535 unsigned long offset, uint64_t flags)
398{ 536{
399 flags = expand_overloaded_flags(flags); 537 flags = kpageflags_flags(flags);
400
401 if (!opt_raw)
402 flags = well_known_flags(flags);
403 538
404 if (!bit_mask_ok(flags)) 539 if (!bit_mask_ok(flags))
405 return; 540 return;
406 541
542 if (opt_hwpoison)
543 hwpoison_page(offset);
544 if (opt_unpoison)
545 unpoison_page(offset);
546
407 if (opt_list == 1) 547 if (opt_list == 1)
408 show_page_range(offset, flags); 548 show_page_range(voffset, offset, flags);
409 else if (opt_list == 2) 549 else if (opt_list == 2)
410 show_page(offset, flags); 550 show_page(voffset, offset, flags);
411 551
412 nr_pages[hash_slot(flags)]++; 552 nr_pages[hash_slot(flags)]++;
413 total_pages++; 553 total_pages++;
414} 554}
415 555
416static void walk_pfn(unsigned long index, unsigned long count) 556#define KPAGEFLAGS_BATCH (64 << 10) /* 64k pages */
557static void walk_pfn(unsigned long voffset,
558 unsigned long index,
559 unsigned long count)
417{ 560{
561 uint64_t buf[KPAGEFLAGS_BATCH];
418 unsigned long batch; 562 unsigned long batch;
419 unsigned long n; 563 unsigned long pages;
420 unsigned long i; 564 unsigned long i;
421 565
422 if (index > ULONG_MAX / KPF_BYTES)
423 fatal("index overflow: %lu\n", index);
424
425 lseek(kpageflags_fd, index * KPF_BYTES, SEEK_SET);
426
427 while (count) { 566 while (count) {
428 uint64_t kpageflags_buf[KPF_BYTES * PAGES_BATCH]; 567 batch = min_t(unsigned long, count, KPAGEFLAGS_BATCH);
429 568 pages = kpageflags_read(buf, index, batch);
430 batch = min_t(unsigned long, count, PAGES_BATCH); 569 if (pages == 0)
431 n = read(kpageflags_fd, kpageflags_buf, batch * KPF_BYTES);
432 if (n == 0)
433 break; 570 break;
434 if (n < 0) {
435 perror(PROC_KPAGEFLAGS);
436 exit(EXIT_FAILURE);
437 }
438 571
439 if (n % KPF_BYTES != 0) 572 for (i = 0; i < pages; i++)
440 fatal("partial read: %lu bytes\n", n); 573 add_page(voffset + i, index + i, buf[i]);
441 n = n / KPF_BYTES;
442 574
443 for (i = 0; i < n; i++) 575 index += pages;
444 add_page(index + i, kpageflags_buf[i]); 576 count -= pages;
445
446 index += batch;
447 count -= batch;
448 } 577 }
449} 578}
450 579
451 580#define PAGEMAP_BATCH (64 << 10)
452#define PAGEMAP_BATCH 4096 581static void walk_vma(unsigned long index, unsigned long count)
453static unsigned long task_pfn(unsigned long pgoff)
454{ 582{
455 static uint64_t buf[PAGEMAP_BATCH]; 583 uint64_t buf[PAGEMAP_BATCH];
456 static unsigned long start; 584 unsigned long batch;
457 static long count; 585 unsigned long pages;
458 uint64_t pfn; 586 unsigned long pfn;
587 unsigned long i;
459 588
460 if (pgoff < start || pgoff >= start + count) { 589 while (count) {
461 if (lseek64(pagemap_fd, 590 batch = min_t(unsigned long, count, PAGEMAP_BATCH);
462 (uint64_t)pgoff * PM_ENTRY_BYTES, 591 pages = pagemap_read(buf, index, batch);
463 SEEK_SET) < 0) { 592 if (pages == 0)
464 perror("pagemap seek"); 593 break;
465 exit(EXIT_FAILURE);
466 }
467 count = read(pagemap_fd, buf, sizeof(buf));
468 if (count == 0)
469 return 0;
470 if (count < 0) {
471 perror("pagemap read");
472 exit(EXIT_FAILURE);
473 }
474 if (count % PM_ENTRY_BYTES) {
475 fatal("pagemap read not aligned.\n");
476 exit(EXIT_FAILURE);
477 }
478 count /= PM_ENTRY_BYTES;
479 start = pgoff;
480 }
481 594
482 pfn = buf[pgoff - start]; 595 for (i = 0; i < pages; i++) {
483 if (pfn & PM_PRESENT) 596 pfn = pagemap_pfn(buf[i]);
484 pfn = PM_PFRAME(pfn); 597 if (pfn)
485 else 598 walk_pfn(index + i, pfn, 1);
486 pfn = 0; 599 }
487 600
488 return pfn; 601 index += pages;
602 count -= pages;
603 }
489} 604}
490 605
491static void walk_task(unsigned long index, unsigned long count) 606static void walk_task(unsigned long index, unsigned long count)
492{ 607{
493 int i = 0;
494 const unsigned long end = index + count; 608 const unsigned long end = index + count;
609 unsigned long start;
610 int i = 0;
495 611
496 while (index < end) { 612 while (index < end) {
497 613
@@ -501,15 +617,11 @@ static void walk_task(unsigned long index, unsigned long count)
501 if (pg_start[i] >= end) 617 if (pg_start[i] >= end)
502 return; 618 return;
503 619
504 voffset = max_t(unsigned long, pg_start[i], index); 620 start = max_t(unsigned long, pg_start[i], index);
505 index = min_t(unsigned long, pg_end[i], end); 621 index = min_t(unsigned long, pg_end[i], end);
506 622
507 assert(voffset < index); 623 assert(start < index);
508 for (; voffset < index; voffset++) { 624 walk_vma(start, index - start);
509 unsigned long pfn = task_pfn(voffset);
510 if (pfn)
511 walk_pfn(pfn, 1);
512 }
513 } 625 }
514} 626}
515 627
@@ -527,18 +639,14 @@ static void walk_addr_ranges(void)
527{ 639{
528 int i; 640 int i;
529 641
530 kpageflags_fd = open(PROC_KPAGEFLAGS, O_RDONLY); 642 kpageflags_fd = checked_open(PROC_KPAGEFLAGS, O_RDONLY);
531 if (kpageflags_fd < 0) {
532 perror(PROC_KPAGEFLAGS);
533 exit(EXIT_FAILURE);
534 }
535 643
536 if (!nr_addr_ranges) 644 if (!nr_addr_ranges)
537 add_addr_range(0, ULONG_MAX); 645 add_addr_range(0, ULONG_MAX);
538 646
539 for (i = 0; i < nr_addr_ranges; i++) 647 for (i = 0; i < nr_addr_ranges; i++)
540 if (!opt_pid) 648 if (!opt_pid)
541 walk_pfn(opt_offset[i], opt_size[i]); 649 walk_pfn(0, opt_offset[i], opt_size[i]);
542 else 650 else
543 walk_task(opt_offset[i], opt_size[i]); 651 walk_task(opt_offset[i], opt_size[i]);
544 652
@@ -575,6 +683,8 @@ static void usage(void)
575" -l|--list Show page details in ranges\n" 683" -l|--list Show page details in ranges\n"
576" -L|--list-each Show page details one by one\n" 684" -L|--list-each Show page details one by one\n"
577" -N|--no-summary Don't show summay info\n" 685" -N|--no-summary Don't show summay info\n"
686" -X|--hwpoison hwpoison pages\n"
687" -x|--unpoison unpoison pages\n"
578" -h|--help Show this usage message\n" 688" -h|--help Show this usage message\n"
579"addr-spec:\n" 689"addr-spec:\n"
580" N one page at offset N (unit: pages)\n" 690" N one page at offset N (unit: pages)\n"
@@ -624,11 +734,7 @@ static void parse_pid(const char *str)
624 opt_pid = parse_number(str); 734 opt_pid = parse_number(str);
625 735
626 sprintf(buf, "/proc/%d/pagemap", opt_pid); 736 sprintf(buf, "/proc/%d/pagemap", opt_pid);
627 pagemap_fd = open(buf, O_RDONLY); 737 pagemap_fd = checked_open(buf, O_RDONLY);
628 if (pagemap_fd < 0) {
629 perror(buf);
630 exit(EXIT_FAILURE);
631 }
632 738
633 sprintf(buf, "/proc/%d/maps", opt_pid); 739 sprintf(buf, "/proc/%d/maps", opt_pid);
634 file = fopen(buf, "r"); 740 file = fopen(buf, "r");
@@ -788,6 +894,8 @@ static struct option opts[] = {
788 { "list" , 0, NULL, 'l' }, 894 { "list" , 0, NULL, 'l' },
789 { "list-each" , 0, NULL, 'L' }, 895 { "list-each" , 0, NULL, 'L' },
790 { "no-summary", 0, NULL, 'N' }, 896 { "no-summary", 0, NULL, 'N' },
897 { "hwpoison" , 0, NULL, 'X' },
898 { "unpoison" , 0, NULL, 'x' },
791 { "help" , 0, NULL, 'h' }, 899 { "help" , 0, NULL, 'h' },
792 { NULL , 0, NULL, 0 } 900 { NULL , 0, NULL, 0 }
793}; 901};
@@ -799,7 +907,7 @@ int main(int argc, char *argv[])
799 page_size = getpagesize(); 907 page_size = getpagesize();
800 908
801 while ((c = getopt_long(argc, argv, 909 while ((c = getopt_long(argc, argv,
802 "rp:f:a:b:lLNh", opts, NULL)) != -1) { 910 "rp:f:a:b:lLNXxh", opts, NULL)) != -1) {
803 switch (c) { 911 switch (c) {
804 case 'r': 912 case 'r':
805 opt_raw = 1; 913 opt_raw = 1;
@@ -825,6 +933,14 @@ int main(int argc, char *argv[])
825 case 'N': 933 case 'N':
826 opt_no_summary = 1; 934 opt_no_summary = 1;
827 break; 935 break;
936 case 'X':
937 opt_hwpoison = 1;
938 prepare_hwpoison_fd();
939 break;
940 case 'x':
941 opt_unpoison = 1;
942 prepare_hwpoison_fd();
943 break;
828 case 'h': 944 case 'h':
829 usage(); 945 usage();
830 exit(0); 946 exit(0);
@@ -844,7 +960,7 @@ int main(int argc, char *argv[])
844 walk_addr_ranges(); 960 walk_addr_ranges();
845 961
846 if (opt_list == 1) 962 if (opt_list == 1)
847 show_page_range(0, 0); /* drain the buffer */ 963 show_page_range(0, 0, 0); /* drain the buffer */
848 964
849 if (opt_no_summary) 965 if (opt_no_summary)
850 return 0; 966 return 0;
diff --git a/Documentation/vm/pagemap.txt b/Documentation/vm/pagemap.txt
index 600a304a828c..df09b9650a81 100644
--- a/Documentation/vm/pagemap.txt
+++ b/Documentation/vm/pagemap.txt
@@ -57,7 +57,9 @@ There are three components to pagemap:
57 16. COMPOUND_TAIL 57 16. COMPOUND_TAIL
58 16. HUGE 58 16. HUGE
59 18. UNEVICTABLE 59 18. UNEVICTABLE
60 19. HWPOISON
60 20. NOPAGE 61 20. NOPAGE
62 21. KSM
61 63
62Short descriptions to the page flags: 64Short descriptions to the page flags:
63 65
@@ -86,9 +88,15 @@ Short descriptions to the page flags:
8617. HUGE 8817. HUGE
87 this is an integral part of a HugeTLB page 89 this is an integral part of a HugeTLB page
88 90
9119. HWPOISON
92 hardware detected memory corruption on this page: don't touch the data!
93
8920. NOPAGE 9420. NOPAGE
90 no page frame exists at the requested address 95 no page frame exists at the requested address
91 96
9721. KSM
98 identical memory pages dynamically shared between one or more processes
99
92 [IO related page flags] 100 [IO related page flags]
93 1. ERROR IO error occurred 101 1. ERROR IO error occurred
94 3. UPTODATE page has up-to-date data 102 3. UPTODATE page has up-to-date data
diff --git a/Documentation/w1/masters/ds2482 b/Documentation/w1/masters/ds2482
index 9210d6fa5024..299b91c7609f 100644
--- a/Documentation/w1/masters/ds2482
+++ b/Documentation/w1/masters/ds2482
@@ -24,8 +24,8 @@ General Remarks
24 24
25Valid addresses are 0x18, 0x19, 0x1a, and 0x1b. 25Valid addresses are 0x18, 0x19, 0x1a, and 0x1b.
26However, the device cannot be detected without writing to the i2c bus, so no 26However, the device cannot be detected without writing to the i2c bus, so no
27detection is done. 27detection is done. You should instantiate the device explicitly.
28You should force the device address.
29 28
30$ modprobe ds2482 force=0,0x18 29$ modprobe ds2482
30$ echo ds2482 0x18 > /sys/bus/i2c/devices/i2c-0/new_device
31 31
diff --git a/MAINTAINERS b/MAINTAINERS
index c450f3abb8c9..88241154f4ce 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -257,6 +257,13 @@ W: http://www.lesswatts.org/projects/acpi/
257S: Supported 257S: Supported
258F: drivers/acpi/fan.c 258F: drivers/acpi/fan.c
259 259
260ACPI PROCESSOR AGGREGATOR DRIVER
261M: Shaohua Li <shaohua.li@intel.com>
262L: linux-acpi@vger.kernel.org
263W: http://www.lesswatts.org/projects/acpi/
264S: Supported
265F: drivers/acpi/acpi_pad.c
266
260ACPI THERMAL DRIVER 267ACPI THERMAL DRIVER
261M: Zhang Rui <rui.zhang@intel.com> 268M: Zhang Rui <rui.zhang@intel.com>
262L: linux-acpi@vger.kernel.org 269L: linux-acpi@vger.kernel.org
@@ -570,6 +577,11 @@ M: Mike Rapoport <mike@compulab.co.il>
570L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) 577L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
571S: Maintained 578S: Maintained
572 579
580ARM/CONTEC MICRO9 MACHINE SUPPORT
581M: Hubert Feurstein <hubert.feurstein@contec.at>
582S: Maintained
583F: arch/arm/mach-ep93xx/micro9.c
584
573ARM/CORGI MACHINE SUPPORT 585ARM/CORGI MACHINE SUPPORT
574M: Richard Purdie <rpurdie@rpsys.net> 586M: Richard Purdie <rpurdie@rpsys.net>
575S: Maintained 587S: Maintained
@@ -646,24 +658,24 @@ ARM/INTEL IOP32X ARM ARCHITECTURE
646M: Lennert Buytenhek <kernel@wantstofly.org> 658M: Lennert Buytenhek <kernel@wantstofly.org>
647M: Dan Williams <dan.j.williams@intel.com> 659M: Dan Williams <dan.j.williams@intel.com>
648L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) 660L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
649S: Supported 661S: Maintained
650 662
651ARM/INTEL IOP33X ARM ARCHITECTURE 663ARM/INTEL IOP33X ARM ARCHITECTURE
652M: Dan Williams <dan.j.williams@intel.com> 664M: Dan Williams <dan.j.williams@intel.com>
653L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) 665L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
654S: Supported 666S: Maintained
655 667
656ARM/INTEL IOP13XX ARM ARCHITECTURE 668ARM/INTEL IOP13XX ARM ARCHITECTURE
657M: Lennert Buytenhek <kernel@wantstofly.org> 669M: Lennert Buytenhek <kernel@wantstofly.org>
658M: Dan Williams <dan.j.williams@intel.com> 670M: Dan Williams <dan.j.williams@intel.com>
659L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) 671L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
660S: Supported 672S: Maintained
661 673
662ARM/INTEL IQ81342EX MACHINE SUPPORT 674ARM/INTEL IQ81342EX MACHINE SUPPORT
663M: Lennert Buytenhek <kernel@wantstofly.org> 675M: Lennert Buytenhek <kernel@wantstofly.org>
664M: Dan Williams <dan.j.williams@intel.com> 676M: Dan Williams <dan.j.williams@intel.com>
665L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) 677L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
666S: Supported 678S: Maintained
667 679
668ARM/INTEL IXP2000 ARM ARCHITECTURE 680ARM/INTEL IXP2000 ARM ARCHITECTURE
669M: Lennert Buytenhek <kernel@wantstofly.org> 681M: Lennert Buytenhek <kernel@wantstofly.org>
@@ -691,7 +703,7 @@ ARM/INTEL XSC3 (MANZANO) ARM CORE
691M: Lennert Buytenhek <kernel@wantstofly.org> 703M: Lennert Buytenhek <kernel@wantstofly.org>
692M: Dan Williams <dan.j.williams@intel.com> 704M: Dan Williams <dan.j.williams@intel.com>
693L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) 705L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
694S: Supported 706S: Maintained
695 707
696ARM/IP FABRICS DOUBLE ESPRESSO MACHINE SUPPORT 708ARM/IP FABRICS DOUBLE ESPRESSO MACHINE SUPPORT
697M: Lennert Buytenhek <kernel@wantstofly.org> 709M: Lennert Buytenhek <kernel@wantstofly.org>
@@ -741,23 +753,36 @@ M: Dirk Opfer <dirk@opfer-online.de>
741S: Maintained 753S: Maintained
742 754
743ARM/PALMTX,PALMT5,PALMLD,PALMTE2,PALMTC SUPPORT 755ARM/PALMTX,PALMT5,PALMLD,PALMTE2,PALMTC SUPPORT
744P: Marek Vasut 756M: Marek Vasut <marek.vasut@gmail.com>
745M: marek.vasut@gmail.com
746L: linux-arm-kernel@lists.infradead.org 757L: linux-arm-kernel@lists.infradead.org
747W: http://hackndev.com 758W: http://hackndev.com
748S: Maintained 759S: Maintained
760F: arch/arm/mach-pxa/include/mach/palmtx.h
761F: arch/arm/mach-pxa/palmtx.c
762F: arch/arm/mach-pxa/include/mach/palmt5.h
763F: arch/arm/mach-pxa/palmt5.c
764F: arch/arm/mach-pxa/include/mach/palmld.h
765F: arch/arm/mach-pxa/palmld.c
766F: arch/arm/mach-pxa/include/mach/palmte2.h
767F: arch/arm/mach-pxa/palmte2.c
768F: arch/arm/mach-pxa/include/mach/palmtc.h
769F: arch/arm/mach-pxa/palmtc.c
749 770
750ARM/PALM TREO 680 SUPPORT 771ARM/PALM TREO 680 SUPPORT
751M: Tomas Cech <sleep_walker@suse.cz> 772M: Tomas Cech <sleep_walker@suse.cz>
752L: linux-arm-kernel@lists.infradead.org 773L: linux-arm-kernel@lists.infradead.org
753W: http://hackndev.com 774W: http://hackndev.com
754S: Maintained 775S: Maintained
776F: arch/arm/mach-pxa/include/mach/treo680.h
777F: arch/arm/mach-pxa/treo680.c
755 778
756ARM/PALMZ72 SUPPORT 779ARM/PALMZ72 SUPPORT
757M: Sergey Lapin <slapin@ossfans.org> 780M: Sergey Lapin <slapin@ossfans.org>
758L: linux-arm-kernel@lists.infradead.org 781L: linux-arm-kernel@lists.infradead.org
759W: http://hackndev.com 782W: http://hackndev.com
760S: Maintained 783S: Maintained
784F: arch/arm/mach-pxa/include/mach/palmz72.h
785F: arch/arm/mach-pxa/palmz72.c
761 786
762ARM/PLEB SUPPORT 787ARM/PLEB SUPPORT
763M: Peter Chubb <pleb@gelato.unsw.edu.au> 788M: Peter Chubb <pleb@gelato.unsw.edu.au>
@@ -1211,6 +1236,13 @@ L: netdev@vger.kernel.org
1211S: Supported 1236S: Supported
1212F: drivers/net/tg3.* 1237F: drivers/net/tg3.*
1213 1238
1239BROCADE BFA FC SCSI DRIVER
1240P: Jing Huang
1241M: huangj@brocade.com
1242L: linux-scsi@vger.kernel.org
1243S: Supported
1244F: drivers/scsi/bfa/
1245
1214BSG (block layer generic sg v4 driver) 1246BSG (block layer generic sg v4 driver)
1215M: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> 1247M: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
1216L: linux-scsi@vger.kernel.org 1248L: linux-scsi@vger.kernel.org
@@ -2038,7 +2070,7 @@ S: Maintained
2038F: fs/* 2070F: fs/*
2039 2071
2040FINTEK F75375S HARDWARE MONITOR AND FAN CONTROLLER DRIVER 2072FINTEK F75375S HARDWARE MONITOR AND FAN CONTROLLER DRIVER
2041M: Riku Voipio <riku.vipio@iki.fi> 2073M: Riku Voipio <riku.voipio@iki.fi>
2042L: lm-sensors@lm-sensors.org 2074L: lm-sensors@lm-sensors.org
2043S: Maintained 2075S: Maintained
2044F: drivers/hwmon/f75375s.c 2076F: drivers/hwmon/f75375s.c
@@ -2583,6 +2615,7 @@ L: linux1394-devel@lists.sourceforge.net
2583W: http://www.linux1394.org/ 2615W: http://www.linux1394.org/
2584T: git git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6.git 2616T: git git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6.git
2585S: Maintained 2617S: Maintained
2618F: Documentation/debugging-via-ohci1394.txt
2586F: drivers/ieee1394/ 2619F: drivers/ieee1394/
2587 2620
2588IEEE 1394 RAW I/O DRIVER 2621IEEE 1394 RAW I/O DRIVER
@@ -2682,7 +2715,7 @@ F: include/linux/intel-iommu.h
2682 2715
2683INTEL IOP-ADMA DMA DRIVER 2716INTEL IOP-ADMA DMA DRIVER
2684M: Dan Williams <dan.j.williams@intel.com> 2717M: Dan Williams <dan.j.williams@intel.com>
2685S: Supported 2718S: Maintained
2686F: drivers/dma/iop-adma.c 2719F: drivers/dma/iop-adma.c
2687 2720
2688INTEL IXP4XX QMGR, NPE, ETHERNET and HSS SUPPORT 2721INTEL IXP4XX QMGR, NPE, ETHERNET and HSS SUPPORT
@@ -3623,10 +3656,18 @@ F: Documentation/blockdev/nbd.txt
3623F: drivers/block/nbd.c 3656F: drivers/block/nbd.c
3624F: include/linux/nbd.h 3657F: include/linux/nbd.h
3625 3658
3659NETWORK DROP MONITOR
3660M: Neil Horman <nhorman@tuxdriver.com>
3661L: netdev@vger.kernel.org
3662S: Maintained
3663W: https://fedorahosted.org/dropwatch/
3664F: net/core/drop_monitor.c
3665
3626NETWORKING [GENERAL] 3666NETWORKING [GENERAL]
3627M: "David S. Miller" <davem@davemloft.net> 3667M: "David S. Miller" <davem@davemloft.net>
3628L: netdev@vger.kernel.org 3668L: netdev@vger.kernel.org
3629W: http://www.linuxfoundation.org/en/Net 3669W: http://www.linuxfoundation.org/en/Net
3670W: http://patchwork.ozlabs.org/project/netdev/list/
3630T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.git 3671T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.git
3631S: Maintained 3672S: Maintained
3632F: net/ 3673F: net/
@@ -3953,6 +3994,7 @@ F: drivers/block/paride/
3953PARISC ARCHITECTURE 3994PARISC ARCHITECTURE
3954M: Kyle McMartin <kyle@mcmartin.ca> 3995M: Kyle McMartin <kyle@mcmartin.ca>
3955M: Helge Deller <deller@gmx.de> 3996M: Helge Deller <deller@gmx.de>
3997M: "James E.J. Bottomley" <jejb@parisc-linux.org>
3956L: linux-parisc@vger.kernel.org 3998L: linux-parisc@vger.kernel.org
3957W: http://www.parisc-linux.org/ 3999W: http://www.parisc-linux.org/
3958T: git git://git.kernel.org/pub/scm/linux/kernel/git/kyle/parisc-2.6.git 4000T: git git://git.kernel.org/pub/scm/linux/kernel/git/kyle/parisc-2.6.git
@@ -4036,6 +4078,13 @@ M: Peter Zijlstra <a.p.zijlstra@chello.nl>
4036M: Paul Mackerras <paulus@samba.org> 4078M: Paul Mackerras <paulus@samba.org>
4037M: Ingo Molnar <mingo@elte.hu> 4079M: Ingo Molnar <mingo@elte.hu>
4038S: Supported 4080S: Supported
4081F: kernel/perf_event.c
4082F: include/linux/perf_event.h
4083F: arch/*/*/kernel/perf_event.c
4084F: arch/*/include/asm/perf_event.h
4085F: arch/*/lib/perf_event.c
4086F: arch/*/kernel/perf_callchain.c
4087F: tools/perf/
4039 4088
4040PERSONALITY HANDLING 4089PERSONALITY HANDLING
4041M: Christoph Hellwig <hch@infradead.org> 4090M: Christoph Hellwig <hch@infradead.org>
@@ -4618,6 +4667,14 @@ F: drivers/ata/
4618F: include/linux/ata.h 4667F: include/linux/ata.h
4619F: include/linux/libata.h 4668F: include/linux/libata.h
4620 4669
4670SERVER ENGINES 10Gbps iSCSI - BladeEngine 2 DRIVER
4671P: Jayamohan Kallickal
4672M: jayamohank@serverengines.com
4673L: linux-scsi@vger.kernel.org
4674W: http://www.serverengines.com
4675S: Supported
4676F: drivers/scsi/be2iscsi/
4677
4621SERVER ENGINES 10Gbps NIC - BladeEngine 2 DRIVER 4678SERVER ENGINES 10Gbps NIC - BladeEngine 2 DRIVER
4622M: Sathya Perla <sathyap@serverengines.com> 4679M: Sathya Perla <sathyap@serverengines.com>
4623M: Subbu Seetharaman <subbus@serverengines.com> 4680M: Subbu Seetharaman <subbus@serverengines.com>
@@ -5608,6 +5665,13 @@ S: Maintained
5608F: drivers/vlynq/vlynq.c 5665F: drivers/vlynq/vlynq.c
5609F: include/linux/vlynq.h 5666F: include/linux/vlynq.h
5610 5667
5668VMWARE VMXNET3 ETHERNET DRIVER
5669M: Shreyas Bhatewara <sbhatewara@vmware.com>
5670M: VMware, Inc. <pv-drivers@vmware.com>
5671L: netdev@vger.kernel.org
5672S: Maintained
5673F: drivers/net/vmxnet3/
5674
5611VOLTAGE AND CURRENT REGULATOR FRAMEWORK 5675VOLTAGE AND CURRENT REGULATOR FRAMEWORK
5612M: Liam Girdwood <lrg@slimlogic.co.uk> 5676M: Liam Girdwood <lrg@slimlogic.co.uk>
5613M: Mark Brown <broonie@opensource.wolfsonmicro.com> 5677M: Mark Brown <broonie@opensource.wolfsonmicro.com>
diff --git a/Makefile b/Makefile
index 00444a8e304f..326791575b0a 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
1VERSION = 2 1VERSION = 2
2PATCHLEVEL = 6 2PATCHLEVEL = 6
3SUBLEVEL = 32 3SUBLEVEL = 32
4EXTRAVERSION = -rc2 4EXTRAVERSION = -rc4
5NAME = Man-Eating Seals of Antiquity 5NAME = Man-Eating Seals of Antiquity
6 6
7# *DOCUMENTATION* 7# *DOCUMENTATION*
@@ -179,46 +179,9 @@ SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
179# Alternatively CROSS_COMPILE can be set in the environment. 179# Alternatively CROSS_COMPILE can be set in the environment.
180# Default value for CROSS_COMPILE is not to prefix executables 180# Default value for CROSS_COMPILE is not to prefix executables
181# Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile 181# Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile
182#
183# To force ARCH and CROSS_COMPILE settings include kernel.* files
184# in the kernel tree - do not patch this file.
185export KBUILD_BUILDHOST := $(SUBARCH) 182export KBUILD_BUILDHOST := $(SUBARCH)
186 183ARCH ?= $(SUBARCH)
187# Kbuild save the ARCH and CROSS_COMPILE setting in kernel.* files. 184CROSS_COMPILE ?=
188# Restore these settings and check that user did not specify
189# conflicting values.
190
191saved_arch := $(shell cat include/generated/kernel.arch 2> /dev/null)
192saved_cross := $(shell cat include/generated/kernel.cross 2> /dev/null)
193
194ifneq ($(CROSS_COMPILE),)
195 ifneq ($(saved_cross),)
196 ifneq ($(CROSS_COMPILE),$(saved_cross))
197 $(error CROSS_COMPILE changed from \
198 "$(saved_cross)" to \
199 to "$(CROSS_COMPILE)". \
200 Use "make mrproper" to fix it up)
201 endif
202 endif
203else
204 CROSS_COMPILE := $(saved_cross)
205endif
206
207ifneq ($(ARCH),)
208 ifneq ($(saved_arch),)
209 ifneq ($(saved_arch),$(ARCH))
210 $(error ARCH changed from \
211 "$(saved_arch)" to "$(ARCH)". \
212 Use "make mrproper" to fix it up)
213 endif
214 endif
215else
216 ifneq ($(saved_arch),)
217 ARCH := $(saved_arch)
218 else
219 ARCH := $(SUBARCH)
220 endif
221endif
222 185
223# Architecture as present in compile.h 186# Architecture as present in compile.h
224UTS_MACHINE := $(ARCH) 187UTS_MACHINE := $(ARCH)
@@ -483,11 +446,6 @@ ifeq ($(config-targets),1)
483include $(srctree)/arch/$(SRCARCH)/Makefile 446include $(srctree)/arch/$(SRCARCH)/Makefile
484export KBUILD_DEFCONFIG KBUILD_KCONFIG 447export KBUILD_DEFCONFIG KBUILD_KCONFIG
485 448
486# save ARCH & CROSS_COMPILE settings
487$(shell mkdir -p include/generated && \
488 echo $(ARCH) > include/generated/kernel.arch && \
489 echo $(CROSS_COMPILE) > include/generated/kernel.cross)
490
491config: scripts_basic outputmakefile FORCE 449config: scripts_basic outputmakefile FORCE
492 $(Q)mkdir -p include/linux include/config 450 $(Q)mkdir -p include/linux include/config
493 $(Q)$(MAKE) $(build)=scripts/kconfig $@ 451 $(Q)$(MAKE) $(build)=scripts/kconfig $@
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
index ef12794c3c68..8ba7044c554d 100644
--- a/arch/arm/common/sa1111.c
+++ b/arch/arm/common/sa1111.c
@@ -1032,6 +1032,7 @@ unsigned int sa1111_pll_clock(struct sa1111_dev *sadev)
1032 1032
1033 return __sa1111_pll_clock(sachip); 1033 return __sa1111_pll_clock(sachip);
1034} 1034}
1035EXPORT_SYMBOL(sa1111_pll_clock);
1035 1036
1036/** 1037/**
1037 * sa1111_select_audio_mode - select I2S or AC link mode 1038 * sa1111_select_audio_mode - select I2S or AC link mode
@@ -1059,6 +1060,7 @@ void sa1111_select_audio_mode(struct sa1111_dev *sadev, int mode)
1059 1060
1060 spin_unlock_irqrestore(&sachip->lock, flags); 1061 spin_unlock_irqrestore(&sachip->lock, flags);
1061} 1062}
1063EXPORT_SYMBOL(sa1111_select_audio_mode);
1062 1064
1063/** 1065/**
1064 * sa1111_set_audio_rate - set the audio sample rate 1066 * sa1111_set_audio_rate - set the audio sample rate
@@ -1083,6 +1085,7 @@ int sa1111_set_audio_rate(struct sa1111_dev *sadev, int rate)
1083 1085
1084 return 0; 1086 return 0;
1085} 1087}
1088EXPORT_SYMBOL(sa1111_set_audio_rate);
1086 1089
1087/** 1090/**
1088 * sa1111_get_audio_rate - get the audio sample rate 1091 * sa1111_get_audio_rate - get the audio sample rate
@@ -1100,6 +1103,7 @@ int sa1111_get_audio_rate(struct sa1111_dev *sadev)
1100 1103
1101 return __sa1111_pll_clock(sachip) / (256 * div); 1104 return __sa1111_pll_clock(sachip) / (256 * div);
1102} 1105}
1106EXPORT_SYMBOL(sa1111_get_audio_rate);
1103 1107
1104void sa1111_set_io_dir(struct sa1111_dev *sadev, 1108void sa1111_set_io_dir(struct sa1111_dev *sadev,
1105 unsigned int bits, unsigned int dir, 1109 unsigned int bits, unsigned int dir,
@@ -1128,6 +1132,7 @@ void sa1111_set_io_dir(struct sa1111_dev *sadev,
1128 MODIFY_BITS(gpio + SA1111_GPIO_PCSDR, (bits >> 16) & 255, sleep_dir >> 16); 1132 MODIFY_BITS(gpio + SA1111_GPIO_PCSDR, (bits >> 16) & 255, sleep_dir >> 16);
1129 spin_unlock_irqrestore(&sachip->lock, flags); 1133 spin_unlock_irqrestore(&sachip->lock, flags);
1130} 1134}
1135EXPORT_SYMBOL(sa1111_set_io_dir);
1131 1136
1132void sa1111_set_io(struct sa1111_dev *sadev, unsigned int bits, unsigned int v) 1137void sa1111_set_io(struct sa1111_dev *sadev, unsigned int bits, unsigned int v)
1133{ 1138{
@@ -1142,6 +1147,7 @@ void sa1111_set_io(struct sa1111_dev *sadev, unsigned int bits, unsigned int v)
1142 MODIFY_BITS(gpio + SA1111_GPIO_PCDWR, (bits >> 16) & 255, v >> 16); 1147 MODIFY_BITS(gpio + SA1111_GPIO_PCDWR, (bits >> 16) & 255, v >> 16);
1143 spin_unlock_irqrestore(&sachip->lock, flags); 1148 spin_unlock_irqrestore(&sachip->lock, flags);
1144} 1149}
1150EXPORT_SYMBOL(sa1111_set_io);
1145 1151
1146void sa1111_set_sleep_io(struct sa1111_dev *sadev, unsigned int bits, unsigned int v) 1152void sa1111_set_sleep_io(struct sa1111_dev *sadev, unsigned int bits, unsigned int v)
1147{ 1153{
@@ -1156,6 +1162,7 @@ void sa1111_set_sleep_io(struct sa1111_dev *sadev, unsigned int bits, unsigned i
1156 MODIFY_BITS(gpio + SA1111_GPIO_PCSSR, (bits >> 16) & 255, v >> 16); 1162 MODIFY_BITS(gpio + SA1111_GPIO_PCSSR, (bits >> 16) & 255, v >> 16);
1157 spin_unlock_irqrestore(&sachip->lock, flags); 1163 spin_unlock_irqrestore(&sachip->lock, flags);
1158} 1164}
1165EXPORT_SYMBOL(sa1111_set_sleep_io);
1159 1166
1160/* 1167/*
1161 * Individual device operations. 1168 * Individual device operations.
@@ -1176,6 +1183,7 @@ void sa1111_enable_device(struct sa1111_dev *sadev)
1176 sa1111_writel(val | sadev->skpcr_mask, sachip->base + SA1111_SKPCR); 1183 sa1111_writel(val | sadev->skpcr_mask, sachip->base + SA1111_SKPCR);
1177 spin_unlock_irqrestore(&sachip->lock, flags); 1184 spin_unlock_irqrestore(&sachip->lock, flags);
1178} 1185}
1186EXPORT_SYMBOL(sa1111_enable_device);
1179 1187
1180/** 1188/**
1181 * sa1111_disable_device - disable an on-chip SA1111 function block 1189 * sa1111_disable_device - disable an on-chip SA1111 function block
@@ -1192,6 +1200,7 @@ void sa1111_disable_device(struct sa1111_dev *sadev)
1192 sa1111_writel(val & ~sadev->skpcr_mask, sachip->base + SA1111_SKPCR); 1200 sa1111_writel(val & ~sadev->skpcr_mask, sachip->base + SA1111_SKPCR);
1193 spin_unlock_irqrestore(&sachip->lock, flags); 1201 spin_unlock_irqrestore(&sachip->lock, flags);
1194} 1202}
1203EXPORT_SYMBOL(sa1111_disable_device);
1195 1204
1196/* 1205/*
1197 * SA1111 "Register Access Bus." 1206 * SA1111 "Register Access Bus."
@@ -1259,17 +1268,20 @@ struct bus_type sa1111_bus_type = {
1259 .suspend = sa1111_bus_suspend, 1268 .suspend = sa1111_bus_suspend,
1260 .resume = sa1111_bus_resume, 1269 .resume = sa1111_bus_resume,
1261}; 1270};
1271EXPORT_SYMBOL(sa1111_bus_type);
1262 1272
1263int sa1111_driver_register(struct sa1111_driver *driver) 1273int sa1111_driver_register(struct sa1111_driver *driver)
1264{ 1274{
1265 driver->drv.bus = &sa1111_bus_type; 1275 driver->drv.bus = &sa1111_bus_type;
1266 return driver_register(&driver->drv); 1276 return driver_register(&driver->drv);
1267} 1277}
1278EXPORT_SYMBOL(sa1111_driver_register);
1268 1279
1269void sa1111_driver_unregister(struct sa1111_driver *driver) 1280void sa1111_driver_unregister(struct sa1111_driver *driver)
1270{ 1281{
1271 driver_unregister(&driver->drv); 1282 driver_unregister(&driver->drv);
1272} 1283}
1284EXPORT_SYMBOL(sa1111_driver_unregister);
1273 1285
1274static int __init sa1111_init(void) 1286static int __init sa1111_init(void)
1275{ 1287{
@@ -1290,16 +1302,3 @@ module_exit(sa1111_exit);
1290 1302
1291MODULE_DESCRIPTION("Intel Corporation SA1111 core driver"); 1303MODULE_DESCRIPTION("Intel Corporation SA1111 core driver");
1292MODULE_LICENSE("GPL"); 1304MODULE_LICENSE("GPL");
1293
1294EXPORT_SYMBOL(sa1111_select_audio_mode);
1295EXPORT_SYMBOL(sa1111_set_audio_rate);
1296EXPORT_SYMBOL(sa1111_get_audio_rate);
1297EXPORT_SYMBOL(sa1111_set_io_dir);
1298EXPORT_SYMBOL(sa1111_set_io);
1299EXPORT_SYMBOL(sa1111_set_sleep_io);
1300EXPORT_SYMBOL(sa1111_enable_device);
1301EXPORT_SYMBOL(sa1111_disable_device);
1302EXPORT_SYMBOL(sa1111_pll_clock);
1303EXPORT_SYMBOL(sa1111_bus_type);
1304EXPORT_SYMBOL(sa1111_driver_register);
1305EXPORT_SYMBOL(sa1111_driver_unregister);
diff --git a/arch/arm/configs/h3600_defconfig b/arch/arm/configs/h3600_defconfig
index 1502957db2c3..f6aed7747d4d 100644
--- a/arch/arm/configs/h3600_defconfig
+++ b/arch/arm/configs/h3600_defconfig
@@ -90,7 +90,6 @@ CONFIG_ARCH_SA1100=y
90# CONFIG_SA1100_COLLIE is not set 90# CONFIG_SA1100_COLLIE is not set
91# CONFIG_SA1100_H3100 is not set 91# CONFIG_SA1100_H3100 is not set
92CONFIG_SA1100_H3600=y 92CONFIG_SA1100_H3600=y
93CONFIG_SA1100_H3XXX=y
94# CONFIG_SA1100_BADGE4 is not set 93# CONFIG_SA1100_BADGE4 is not set
95# CONFIG_SA1100_JORNADA720 is not set 94# CONFIG_SA1100_JORNADA720 is not set
96# CONFIG_SA1100_HACKKIT is not set 95# CONFIG_SA1100_HACKKIT is not set
diff --git a/arch/arm/configs/iop33x_defconfig b/arch/arm/configs/iop33x_defconfig
index eec488298267..ed2d59d01829 100644
--- a/arch/arm/configs/iop33x_defconfig
+++ b/arch/arm/configs/iop33x_defconfig
@@ -1,29 +1,26 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.24-rc5 3# Linux kernel version: 2.6.31-rc6
4# Wed Dec 12 16:11:27 2007 4# Tue Aug 18 13:41:41 2009
5# 5#
6CONFIG_ARM=y 6CONFIG_ARM=y
7CONFIG_SYS_SUPPORTS_APM_EMULATION=y 7CONFIG_SYS_SUPPORTS_APM_EMULATION=y
8# CONFIG_GENERIC_GPIO is not set 8CONFIG_GENERIC_GPIO=y
9# CONFIG_GENERIC_TIME is not set
10# CONFIG_GENERIC_CLOCKEVENTS is not set
11CONFIG_MMU=y 9CONFIG_MMU=y
12# CONFIG_NO_IOPORT is not set
13CONFIG_GENERIC_HARDIRQS=y 10CONFIG_GENERIC_HARDIRQS=y
14CONFIG_STACKTRACE_SUPPORT=y 11CONFIG_STACKTRACE_SUPPORT=y
12CONFIG_HAVE_LATENCYTOP_SUPPORT=y
15CONFIG_LOCKDEP_SUPPORT=y 13CONFIG_LOCKDEP_SUPPORT=y
16CONFIG_TRACE_IRQFLAGS_SUPPORT=y 14CONFIG_TRACE_IRQFLAGS_SUPPORT=y
17CONFIG_HARDIRQS_SW_RESEND=y 15CONFIG_HARDIRQS_SW_RESEND=y
18CONFIG_GENERIC_IRQ_PROBE=y 16CONFIG_GENERIC_IRQ_PROBE=y
19CONFIG_RWSEM_GENERIC_SPINLOCK=y 17CONFIG_RWSEM_GENERIC_SPINLOCK=y
20# CONFIG_ARCH_HAS_ILOG2_U32 is not set
21# CONFIG_ARCH_HAS_ILOG2_U64 is not set
22CONFIG_GENERIC_HWEIGHT=y 18CONFIG_GENERIC_HWEIGHT=y
23CONFIG_GENERIC_CALIBRATE_DELAY=y 19CONFIG_GENERIC_CALIBRATE_DELAY=y
24CONFIG_ZONE_DMA=y 20CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
25CONFIG_VECTORS_BASE=0xffff0000 21CONFIG_VECTORS_BASE=0xffff0000
26CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" 22CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
23CONFIG_CONSTRUCTORS=y
27 24
28# 25#
29# General setup 26# General setup
@@ -40,21 +37,39 @@ CONFIG_SYSVIPC_SYSCTL=y
40CONFIG_BSD_PROCESS_ACCT=y 37CONFIG_BSD_PROCESS_ACCT=y
41# CONFIG_BSD_PROCESS_ACCT_V3 is not set 38# CONFIG_BSD_PROCESS_ACCT_V3 is not set
42# CONFIG_TASKSTATS is not set 39# CONFIG_TASKSTATS is not set
43# CONFIG_USER_NS is not set
44# CONFIG_PID_NS is not set
45# CONFIG_AUDIT is not set 40# CONFIG_AUDIT is not set
41
42#
43# RCU Subsystem
44#
45# CONFIG_CLASSIC_RCU is not set
46CONFIG_TREE_RCU=y
47# CONFIG_PREEMPT_RCU is not set
48# CONFIG_RCU_TRACE is not set
49CONFIG_RCU_FANOUT=32
50# CONFIG_RCU_FANOUT_EXACT is not set
51# CONFIG_TREE_RCU_TRACE is not set
52# CONFIG_PREEMPT_RCU_TRACE is not set
46# CONFIG_IKCONFIG is not set 53# CONFIG_IKCONFIG is not set
47CONFIG_LOG_BUF_SHIFT=14 54CONFIG_LOG_BUF_SHIFT=14
55# CONFIG_GROUP_SCHED is not set
48# CONFIG_CGROUPS is not set 56# CONFIG_CGROUPS is not set
49CONFIG_FAIR_GROUP_SCHED=y 57# CONFIG_SYSFS_DEPRECATED_V2 is not set
50CONFIG_FAIR_USER_SCHED=y
51# CONFIG_FAIR_CGROUP_SCHED is not set
52CONFIG_SYSFS_DEPRECATED=y
53# CONFIG_RELAY is not set 58# CONFIG_RELAY is not set
59CONFIG_NAMESPACES=y
60# CONFIG_UTS_NS is not set
61# CONFIG_IPC_NS is not set
62# CONFIG_USER_NS is not set
63# CONFIG_PID_NS is not set
64# CONFIG_NET_NS is not set
54CONFIG_BLK_DEV_INITRD=y 65CONFIG_BLK_DEV_INITRD=y
55CONFIG_INITRAMFS_SOURCE="" 66CONFIG_INITRAMFS_SOURCE=""
67CONFIG_RD_GZIP=y
68CONFIG_RD_BZIP2=y
69CONFIG_RD_LZMA=y
56CONFIG_CC_OPTIMIZE_FOR_SIZE=y 70CONFIG_CC_OPTIMIZE_FOR_SIZE=y
57CONFIG_SYSCTL=y 71CONFIG_SYSCTL=y
72CONFIG_ANON_INODES=y
58# CONFIG_EMBEDDED is not set 73# CONFIG_EMBEDDED is not set
59CONFIG_UID16=y 74CONFIG_UID16=y
60CONFIG_SYSCTL_SYSCALL=y 75CONFIG_SYSCTL_SYSCALL=y
@@ -67,29 +82,48 @@ CONFIG_BUG=y
67CONFIG_ELF_CORE=y 82CONFIG_ELF_CORE=y
68CONFIG_BASE_FULL=y 83CONFIG_BASE_FULL=y
69CONFIG_FUTEX=y 84CONFIG_FUTEX=y
70CONFIG_ANON_INODES=y
71CONFIG_EPOLL=y 85CONFIG_EPOLL=y
72CONFIG_SIGNALFD=y 86CONFIG_SIGNALFD=y
87CONFIG_TIMERFD=y
73CONFIG_EVENTFD=y 88CONFIG_EVENTFD=y
74CONFIG_SHMEM=y 89CONFIG_SHMEM=y
90CONFIG_AIO=y
91
92#
93# Performance Counters
94#
75CONFIG_VM_EVENT_COUNTERS=y 95CONFIG_VM_EVENT_COUNTERS=y
96CONFIG_PCI_QUIRKS=y
97# CONFIG_STRIP_ASM_SYMS is not set
98CONFIG_COMPAT_BRK=y
76CONFIG_SLAB=y 99CONFIG_SLAB=y
77# CONFIG_SLUB is not set 100# CONFIG_SLUB is not set
78# CONFIG_SLOB is not set 101# CONFIG_SLOB is not set
102# CONFIG_PROFILING is not set
103# CONFIG_MARKERS is not set
104CONFIG_HAVE_OPROFILE=y
105# CONFIG_KPROBES is not set
106CONFIG_HAVE_KPROBES=y
107CONFIG_HAVE_KRETPROBES=y
108
109#
110# GCOV-based kernel profiling
111#
112# CONFIG_SLOW_WORK is not set
113CONFIG_HAVE_GENERIC_DMA_COHERENT=y
114CONFIG_SLABINFO=y
79CONFIG_RT_MUTEXES=y 115CONFIG_RT_MUTEXES=y
80# CONFIG_TINY_SHMEM is not set
81CONFIG_BASE_SMALL=0 116CONFIG_BASE_SMALL=0
82CONFIG_MODULES=y 117CONFIG_MODULES=y
118# CONFIG_MODULE_FORCE_LOAD is not set
83CONFIG_MODULE_UNLOAD=y 119CONFIG_MODULE_UNLOAD=y
84# CONFIG_MODULE_FORCE_UNLOAD is not set 120# CONFIG_MODULE_FORCE_UNLOAD is not set
85# CONFIG_MODVERSIONS is not set 121# CONFIG_MODVERSIONS is not set
86# CONFIG_MODULE_SRCVERSION_ALL is not set 122# CONFIG_MODULE_SRCVERSION_ALL is not set
87CONFIG_KMOD=y
88CONFIG_BLOCK=y 123CONFIG_BLOCK=y
89# CONFIG_LBD is not set 124CONFIG_LBDAF=y
90# CONFIG_BLK_DEV_IO_TRACE is not set
91# CONFIG_LSF is not set
92# CONFIG_BLK_DEV_BSG is not set 125# CONFIG_BLK_DEV_BSG is not set
126# CONFIG_BLK_DEV_INTEGRITY is not set
93 127
94# 128#
95# IO Schedulers 129# IO Schedulers
@@ -103,6 +137,7 @@ CONFIG_IOSCHED_CFQ=y
103CONFIG_DEFAULT_CFQ=y 137CONFIG_DEFAULT_CFQ=y
104# CONFIG_DEFAULT_NOOP is not set 138# CONFIG_DEFAULT_NOOP is not set
105CONFIG_DEFAULT_IOSCHED="cfq" 139CONFIG_DEFAULT_IOSCHED="cfq"
140# CONFIG_FREEZER is not set
106 141
107# 142#
108# System Type 143# System Type
@@ -112,15 +147,15 @@ CONFIG_DEFAULT_IOSCHED="cfq"
112# CONFIG_ARCH_REALVIEW is not set 147# CONFIG_ARCH_REALVIEW is not set
113# CONFIG_ARCH_VERSATILE is not set 148# CONFIG_ARCH_VERSATILE is not set
114# CONFIG_ARCH_AT91 is not set 149# CONFIG_ARCH_AT91 is not set
115# CONFIG_ARCH_CLPS7500 is not set
116# CONFIG_ARCH_CLPS711X is not set 150# CONFIG_ARCH_CLPS711X is not set
117# CONFIG_ARCH_CO285 is not set 151# CONFIG_ARCH_GEMINI is not set
118# CONFIG_ARCH_EBSA110 is not set 152# CONFIG_ARCH_EBSA110 is not set
119# CONFIG_ARCH_EP93XX is not set 153# CONFIG_ARCH_EP93XX is not set
120# CONFIG_ARCH_FOOTBRIDGE is not set 154# CONFIG_ARCH_FOOTBRIDGE is not set
155# CONFIG_ARCH_MXC is not set
156# CONFIG_ARCH_STMP3XXX is not set
121# CONFIG_ARCH_NETX is not set 157# CONFIG_ARCH_NETX is not set
122# CONFIG_ARCH_H720X is not set 158# CONFIG_ARCH_H720X is not set
123# CONFIG_ARCH_IMX is not set
124# CONFIG_ARCH_IOP13XX is not set 159# CONFIG_ARCH_IOP13XX is not set
125# CONFIG_ARCH_IOP32X is not set 160# CONFIG_ARCH_IOP32X is not set
126CONFIG_ARCH_IOP33X=y 161CONFIG_ARCH_IOP33X=y
@@ -128,19 +163,26 @@ CONFIG_ARCH_IOP33X=y
128# CONFIG_ARCH_IXP2000 is not set 163# CONFIG_ARCH_IXP2000 is not set
129# CONFIG_ARCH_IXP4XX is not set 164# CONFIG_ARCH_IXP4XX is not set
130# CONFIG_ARCH_L7200 is not set 165# CONFIG_ARCH_L7200 is not set
166# CONFIG_ARCH_KIRKWOOD is not set
167# CONFIG_ARCH_LOKI is not set
168# CONFIG_ARCH_MV78XX0 is not set
169# CONFIG_ARCH_ORION5X is not set
170# CONFIG_ARCH_MMP is not set
131# CONFIG_ARCH_KS8695 is not set 171# CONFIG_ARCH_KS8695 is not set
132# CONFIG_ARCH_NS9XXX is not set 172# CONFIG_ARCH_NS9XXX is not set
133# CONFIG_ARCH_MXC is not set 173# CONFIG_ARCH_W90X900 is not set
134# CONFIG_ARCH_PNX4008 is not set 174# CONFIG_ARCH_PNX4008 is not set
135# CONFIG_ARCH_PXA is not set 175# CONFIG_ARCH_PXA is not set
176# CONFIG_ARCH_MSM is not set
136# CONFIG_ARCH_RPC is not set 177# CONFIG_ARCH_RPC is not set
137# CONFIG_ARCH_SA1100 is not set 178# CONFIG_ARCH_SA1100 is not set
138# CONFIG_ARCH_S3C2410 is not set 179# CONFIG_ARCH_S3C2410 is not set
180# CONFIG_ARCH_S3C64XX is not set
139# CONFIG_ARCH_SHARK is not set 181# CONFIG_ARCH_SHARK is not set
140# CONFIG_ARCH_LH7A40X is not set 182# CONFIG_ARCH_LH7A40X is not set
183# CONFIG_ARCH_U300 is not set
141# CONFIG_ARCH_DAVINCI is not set 184# CONFIG_ARCH_DAVINCI is not set
142# CONFIG_ARCH_OMAP is not set 185# CONFIG_ARCH_OMAP is not set
143CONFIG_IOP3XX_ATU=y
144 186
145# 187#
146# IOP33x Implementation Options 188# IOP33x Implementation Options
@@ -151,14 +193,6 @@ CONFIG_IOP3XX_ATU=y
151# 193#
152CONFIG_ARCH_IQ80331=y 194CONFIG_ARCH_IQ80331=y
153CONFIG_MACH_IQ80332=y 195CONFIG_MACH_IQ80332=y
154
155#
156# Boot options
157#
158
159#
160# Power management
161#
162CONFIG_PLAT_IOP=y 196CONFIG_PLAT_IOP=y
163 197
164# 198#
@@ -168,6 +202,7 @@ CONFIG_CPU_32=y
168CONFIG_CPU_XSCALE=y 202CONFIG_CPU_XSCALE=y
169CONFIG_CPU_32v5=y 203CONFIG_CPU_32v5=y
170CONFIG_CPU_ABRT_EV5T=y 204CONFIG_CPU_ABRT_EV5T=y
205CONFIG_CPU_PABRT_NOIFAR=y
171CONFIG_CPU_CACHE_VIVT=y 206CONFIG_CPU_CACHE_VIVT=y
172CONFIG_CPU_TLB_V4WBI=y 207CONFIG_CPU_TLB_V4WBI=y
173CONFIG_CPU_CP15=y 208CONFIG_CPU_CP15=y
@@ -178,7 +213,6 @@ CONFIG_CPU_CP15_MMU=y
178# 213#
179# CONFIG_ARM_THUMB is not set 214# CONFIG_ARM_THUMB is not set
180# CONFIG_CPU_DCACHE_DISABLE is not set 215# CONFIG_CPU_DCACHE_DISABLE is not set
181# CONFIG_OUTER_CACHE is not set
182# CONFIG_IWMMXT is not set 216# CONFIG_IWMMXT is not set
183CONFIG_XSCALE_PMU=y 217CONFIG_XSCALE_PMU=y
184 218
@@ -190,41 +224,55 @@ CONFIG_PCI_SYSCALL=y
190# CONFIG_ARCH_SUPPORTS_MSI is not set 224# CONFIG_ARCH_SUPPORTS_MSI is not set
191CONFIG_PCI_LEGACY=y 225CONFIG_PCI_LEGACY=y
192# CONFIG_PCI_DEBUG is not set 226# CONFIG_PCI_DEBUG is not set
227# CONFIG_PCI_STUB is not set
228# CONFIG_PCI_IOV is not set
193# CONFIG_PCCARD is not set 229# CONFIG_PCCARD is not set
194 230
195# 231#
196# Kernel Features 232# Kernel Features
197# 233#
198# CONFIG_TICK_ONESHOT is not set 234CONFIG_VMSPLIT_3G=y
235# CONFIG_VMSPLIT_2G is not set
236# CONFIG_VMSPLIT_1G is not set
237CONFIG_PAGE_OFFSET=0xC0000000
199# CONFIG_PREEMPT is not set 238# CONFIG_PREEMPT is not set
200CONFIG_HZ=100 239CONFIG_HZ=100
201# CONFIG_AEABI is not set 240# CONFIG_AEABI is not set
202# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set 241# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
242# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
243# CONFIG_HIGHMEM is not set
203CONFIG_SELECT_MEMORY_MODEL=y 244CONFIG_SELECT_MEMORY_MODEL=y
204CONFIG_FLATMEM_MANUAL=y 245CONFIG_FLATMEM_MANUAL=y
205# CONFIG_DISCONTIGMEM_MANUAL is not set 246# CONFIG_DISCONTIGMEM_MANUAL is not set
206# CONFIG_SPARSEMEM_MANUAL is not set 247# CONFIG_SPARSEMEM_MANUAL is not set
207CONFIG_FLATMEM=y 248CONFIG_FLATMEM=y
208CONFIG_FLAT_NODE_MEM_MAP=y 249CONFIG_FLAT_NODE_MEM_MAP=y
209# CONFIG_SPARSEMEM_STATIC is not set 250CONFIG_PAGEFLAGS_EXTENDED=y
210# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
211CONFIG_SPLIT_PTLOCK_CPUS=4096 251CONFIG_SPLIT_PTLOCK_CPUS=4096
212# CONFIG_RESOURCES_64BIT is not set 252# CONFIG_PHYS_ADDR_T_64BIT is not set
213CONFIG_ZONE_DMA_FLAG=1 253CONFIG_ZONE_DMA_FLAG=0
214CONFIG_BOUNCE=y
215CONFIG_VIRT_TO_BUS=y 254CONFIG_VIRT_TO_BUS=y
255CONFIG_HAVE_MLOCK=y
256CONFIG_HAVE_MLOCKED_PAGE_BIT=y
257CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
216CONFIG_ALIGNMENT_TRAP=y 258CONFIG_ALIGNMENT_TRAP=y
259# CONFIG_UACCESS_WITH_MEMCPY is not set
217 260
218# 261#
219# Boot options 262# Boot options
220# 263#
221CONFIG_ZBOOT_ROM_TEXT=0x0 264CONFIG_ZBOOT_ROM_TEXT=0x0
222CONFIG_ZBOOT_ROM_BSS=0x0 265CONFIG_ZBOOT_ROM_BSS=0x0
223CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp cachepolicy=writealloc" 266CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp cachepolicy=writealloc iop3xx_init_atu=y"
224# CONFIG_XIP_KERNEL is not set 267# CONFIG_XIP_KERNEL is not set
225# CONFIG_KEXEC is not set 268# CONFIG_KEXEC is not set
226 269
227# 270#
271# CPU Power Management
272#
273# CONFIG_CPU_IDLE is not set
274
275#
228# Floating point emulation 276# Floating point emulation
229# 277#
230 278
@@ -239,6 +287,8 @@ CONFIG_FPE_NWFPE=y
239# Userspace binary formats 287# Userspace binary formats
240# 288#
241CONFIG_BINFMT_ELF=y 289CONFIG_BINFMT_ELF=y
290# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
291CONFIG_HAVE_AOUT=y
242CONFIG_BINFMT_AOUT=y 292CONFIG_BINFMT_AOUT=y
243# CONFIG_BINFMT_MISC is not set 293# CONFIG_BINFMT_MISC is not set
244# CONFIG_ARTHUR is not set 294# CONFIG_ARTHUR is not set
@@ -247,11 +297,7 @@ CONFIG_BINFMT_AOUT=y
247# Power management options 297# Power management options
248# 298#
249# CONFIG_PM is not set 299# CONFIG_PM is not set
250CONFIG_SUSPEND_UP_POSSIBLE=y 300CONFIG_ARCH_SUSPEND_POSSIBLE=y
251
252#
253# Networking
254#
255CONFIG_NET=y 301CONFIG_NET=y
256 302
257# 303#
@@ -264,6 +310,7 @@ CONFIG_XFRM=y
264# CONFIG_XFRM_USER is not set 310# CONFIG_XFRM_USER is not set
265# CONFIG_XFRM_SUB_POLICY is not set 311# CONFIG_XFRM_SUB_POLICY is not set
266# CONFIG_XFRM_MIGRATE is not set 312# CONFIG_XFRM_MIGRATE is not set
313# CONFIG_XFRM_STATISTICS is not set
267# CONFIG_NET_KEY is not set 314# CONFIG_NET_KEY is not set
268CONFIG_INET=y 315CONFIG_INET=y
269CONFIG_IP_MULTICAST=y 316CONFIG_IP_MULTICAST=y
@@ -310,6 +357,7 @@ CONFIG_IPV6=y
310# CONFIG_IPV6_SIT is not set 357# CONFIG_IPV6_SIT is not set
311# CONFIG_IPV6_TUNNEL is not set 358# CONFIG_IPV6_TUNNEL is not set
312# CONFIG_IPV6_MULTIPLE_TABLES is not set 359# CONFIG_IPV6_MULTIPLE_TABLES is not set
360# CONFIG_IPV6_MROUTE is not set
313# CONFIG_NETWORK_SECMARK is not set 361# CONFIG_NETWORK_SECMARK is not set
314# CONFIG_NETFILTER is not set 362# CONFIG_NETFILTER is not set
315# CONFIG_IP_DCCP is not set 363# CONFIG_IP_DCCP is not set
@@ -317,6 +365,7 @@ CONFIG_IPV6=y
317# CONFIG_TIPC is not set 365# CONFIG_TIPC is not set
318# CONFIG_ATM is not set 366# CONFIG_ATM is not set
319# CONFIG_BRIDGE is not set 367# CONFIG_BRIDGE is not set
368# CONFIG_NET_DSA is not set
320# CONFIG_VLAN_8021Q is not set 369# CONFIG_VLAN_8021Q is not set
321# CONFIG_DECNET is not set 370# CONFIG_DECNET is not set
322# CONFIG_LLC2 is not set 371# CONFIG_LLC2 is not set
@@ -326,24 +375,31 @@ CONFIG_IPV6=y
326# CONFIG_LAPB is not set 375# CONFIG_LAPB is not set
327# CONFIG_ECONET is not set 376# CONFIG_ECONET is not set
328# CONFIG_WAN_ROUTER is not set 377# CONFIG_WAN_ROUTER is not set
378# CONFIG_PHONET is not set
379# CONFIG_IEEE802154 is not set
329# CONFIG_NET_SCHED is not set 380# CONFIG_NET_SCHED is not set
381# CONFIG_DCB is not set
330 382
331# 383#
332# Network testing 384# Network testing
333# 385#
334# CONFIG_NET_PKTGEN is not set 386# CONFIG_NET_PKTGEN is not set
335# CONFIG_HAMRADIO is not set 387# CONFIG_HAMRADIO is not set
388# CONFIG_CAN is not set
336# CONFIG_IRDA is not set 389# CONFIG_IRDA is not set
337# CONFIG_BT is not set 390# CONFIG_BT is not set
338# CONFIG_AF_RXRPC is not set 391# CONFIG_AF_RXRPC is not set
392CONFIG_WIRELESS=y
393# CONFIG_CFG80211 is not set
394# CONFIG_WIRELESS_OLD_REGULATORY is not set
395# CONFIG_WIRELESS_EXT is not set
396# CONFIG_LIB80211 is not set
339 397
340# 398#
341# Wireless 399# CFG80211 needs to be enabled for MAC80211
342# 400#
343# CONFIG_CFG80211 is not set 401CONFIG_MAC80211_DEFAULT_PS_VALUE=0
344# CONFIG_WIRELESS_EXT is not set 402# CONFIG_WIMAX is not set
345# CONFIG_MAC80211 is not set
346# CONFIG_IEEE80211 is not set
347# CONFIG_RFKILL is not set 403# CONFIG_RFKILL is not set
348# CONFIG_NET_9P is not set 404# CONFIG_NET_9P is not set
349 405
@@ -357,7 +413,9 @@ CONFIG_IPV6=y
357CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" 413CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
358CONFIG_STANDALONE=y 414CONFIG_STANDALONE=y
359CONFIG_PREVENT_FIRMWARE_BUILD=y 415CONFIG_PREVENT_FIRMWARE_BUILD=y
360# CONFIG_FW_LOADER is not set 416CONFIG_FW_LOADER=y
417CONFIG_FIRMWARE_IN_KERNEL=y
418CONFIG_EXTRA_FIRMWARE=""
361# CONFIG_DEBUG_DRIVER is not set 419# CONFIG_DEBUG_DRIVER is not set
362# CONFIG_DEBUG_DEVRES is not set 420# CONFIG_DEBUG_DEVRES is not set
363# CONFIG_SYS_HYPERVISOR is not set 421# CONFIG_SYS_HYPERVISOR is not set
@@ -366,12 +424,14 @@ CONFIG_MTD=y
366# CONFIG_MTD_DEBUG is not set 424# CONFIG_MTD_DEBUG is not set
367# CONFIG_MTD_CONCAT is not set 425# CONFIG_MTD_CONCAT is not set
368CONFIG_MTD_PARTITIONS=y 426CONFIG_MTD_PARTITIONS=y
427# CONFIG_MTD_TESTS is not set
369CONFIG_MTD_REDBOOT_PARTS=y 428CONFIG_MTD_REDBOOT_PARTS=y
370CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 429CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
371CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y 430CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y
372CONFIG_MTD_REDBOOT_PARTS_READONLY=y 431CONFIG_MTD_REDBOOT_PARTS_READONLY=y
373# CONFIG_MTD_CMDLINE_PARTS is not set 432# CONFIG_MTD_CMDLINE_PARTS is not set
374# CONFIG_MTD_AFS_PARTS is not set 433# CONFIG_MTD_AFS_PARTS is not set
434# CONFIG_MTD_AR7_PARTS is not set
375 435
376# 436#
377# User Modules And Translation Layers 437# User Modules And Translation Layers
@@ -421,9 +481,7 @@ CONFIG_MTD_CFI_UTIL=y
421# 481#
422# CONFIG_MTD_COMPLEX_MAPPINGS is not set 482# CONFIG_MTD_COMPLEX_MAPPINGS is not set
423CONFIG_MTD_PHYSMAP=y 483CONFIG_MTD_PHYSMAP=y
424CONFIG_MTD_PHYSMAP_START=0x0 484# CONFIG_MTD_PHYSMAP_COMPAT is not set
425CONFIG_MTD_PHYSMAP_LEN=0x0
426CONFIG_MTD_PHYSMAP_BANKWIDTH=1
427# CONFIG_MTD_ARM_INTEGRATOR is not set 485# CONFIG_MTD_ARM_INTEGRATOR is not set
428# CONFIG_MTD_INTEL_VR_NOR is not set 486# CONFIG_MTD_INTEL_VR_NOR is not set
429# CONFIG_MTD_PLATRAM is not set 487# CONFIG_MTD_PLATRAM is not set
@@ -447,6 +505,11 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=1
447# CONFIG_MTD_ONENAND is not set 505# CONFIG_MTD_ONENAND is not set
448 506
449# 507#
508# LPDDR flash memory drivers
509#
510# CONFIG_MTD_LPDDR is not set
511
512#
450# UBI - Unsorted block images 513# UBI - Unsorted block images
451# 514#
452# CONFIG_MTD_UBI is not set 515# CONFIG_MTD_UBI is not set
@@ -463,14 +526,29 @@ CONFIG_BLK_DEV_NBD=y
463CONFIG_BLK_DEV_RAM=y 526CONFIG_BLK_DEV_RAM=y
464CONFIG_BLK_DEV_RAM_COUNT=16 527CONFIG_BLK_DEV_RAM_COUNT=16
465CONFIG_BLK_DEV_RAM_SIZE=8192 528CONFIG_BLK_DEV_RAM_SIZE=8192
466CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 529# CONFIG_BLK_DEV_XIP is not set
467# CONFIG_CDROM_PKTCDVD is not set 530# CONFIG_CDROM_PKTCDVD is not set
468# CONFIG_ATA_OVER_ETH is not set 531# CONFIG_ATA_OVER_ETH is not set
532# CONFIG_MG_DISK is not set
469CONFIG_MISC_DEVICES=y 533CONFIG_MISC_DEVICES=y
470# CONFIG_PHANTOM is not set 534# CONFIG_PHANTOM is not set
471# CONFIG_EEPROM_93CX6 is not set
472# CONFIG_SGI_IOC4 is not set 535# CONFIG_SGI_IOC4 is not set
473# CONFIG_TIFM_CORE is not set 536# CONFIG_TIFM_CORE is not set
537# CONFIG_ICS932S401 is not set
538# CONFIG_ENCLOSURE_SERVICES is not set
539# CONFIG_HP_ILO is not set
540# CONFIG_ISL29003 is not set
541# CONFIG_C2PORT is not set
542
543#
544# EEPROM support
545#
546# CONFIG_EEPROM_AT24 is not set
547# CONFIG_EEPROM_LEGACY is not set
548# CONFIG_EEPROM_MAX6875 is not set
549# CONFIG_EEPROM_93CX6 is not set
550# CONFIG_CB710_CORE is not set
551CONFIG_HAVE_IDE=y
474# CONFIG_IDE is not set 552# CONFIG_IDE is not set
475 553
476# 554#
@@ -492,10 +570,6 @@ CONFIG_BLK_DEV_SD=y
492# CONFIG_BLK_DEV_SR is not set 570# CONFIG_BLK_DEV_SR is not set
493CONFIG_CHR_DEV_SG=y 571CONFIG_CHR_DEV_SG=y
494# CONFIG_CHR_DEV_SCH is not set 572# CONFIG_CHR_DEV_SCH is not set
495
496#
497# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
498#
499# CONFIG_SCSI_MULTI_LUN is not set 573# CONFIG_SCSI_MULTI_LUN is not set
500# CONFIG_SCSI_CONSTANTS is not set 574# CONFIG_SCSI_CONSTANTS is not set
501# CONFIG_SCSI_LOGGING is not set 575# CONFIG_SCSI_LOGGING is not set
@@ -512,6 +586,8 @@ CONFIG_SCSI_WAIT_SCAN=m
512# CONFIG_SCSI_SRP_ATTRS is not set 586# CONFIG_SCSI_SRP_ATTRS is not set
513CONFIG_SCSI_LOWLEVEL=y 587CONFIG_SCSI_LOWLEVEL=y
514# CONFIG_ISCSI_TCP is not set 588# CONFIG_ISCSI_TCP is not set
589# CONFIG_SCSI_CXGB3_ISCSI is not set
590# CONFIG_SCSI_BNX2_ISCSI is not set
515# CONFIG_BLK_DEV_3W_XXXX_RAID is not set 591# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
516# CONFIG_SCSI_3W_9XXX is not set 592# CONFIG_SCSI_3W_9XXX is not set
517# CONFIG_SCSI_ACARD is not set 593# CONFIG_SCSI_ACARD is not set
@@ -520,13 +596,18 @@ CONFIG_SCSI_LOWLEVEL=y
520# CONFIG_SCSI_AIC7XXX_OLD is not set 596# CONFIG_SCSI_AIC7XXX_OLD is not set
521# CONFIG_SCSI_AIC79XX is not set 597# CONFIG_SCSI_AIC79XX is not set
522# CONFIG_SCSI_AIC94XX is not set 598# CONFIG_SCSI_AIC94XX is not set
599# CONFIG_SCSI_MVSAS is not set
523# CONFIG_SCSI_DPT_I2O is not set 600# CONFIG_SCSI_DPT_I2O is not set
524# CONFIG_SCSI_ADVANSYS is not set 601# CONFIG_SCSI_ADVANSYS is not set
525# CONFIG_SCSI_ARCMSR is not set 602# CONFIG_SCSI_ARCMSR is not set
526# CONFIG_MEGARAID_NEWGEN is not set 603# CONFIG_MEGARAID_NEWGEN is not set
527# CONFIG_MEGARAID_LEGACY is not set 604# CONFIG_MEGARAID_LEGACY is not set
528# CONFIG_MEGARAID_SAS is not set 605# CONFIG_MEGARAID_SAS is not set
606# CONFIG_SCSI_MPT2SAS is not set
529# CONFIG_SCSI_HPTIOP is not set 607# CONFIG_SCSI_HPTIOP is not set
608# CONFIG_LIBFC is not set
609# CONFIG_LIBFCOE is not set
610# CONFIG_FCOE is not set
530# CONFIG_SCSI_DMX3191D is not set 611# CONFIG_SCSI_DMX3191D is not set
531# CONFIG_SCSI_FUTURE_DOMAIN is not set 612# CONFIG_SCSI_FUTURE_DOMAIN is not set
532# CONFIG_SCSI_IPS is not set 613# CONFIG_SCSI_IPS is not set
@@ -543,15 +624,18 @@ CONFIG_SCSI_LOWLEVEL=y
543# CONFIG_SCSI_NSP32 is not set 624# CONFIG_SCSI_NSP32 is not set
544# CONFIG_SCSI_DEBUG is not set 625# CONFIG_SCSI_DEBUG is not set
545# CONFIG_SCSI_SRP is not set 626# CONFIG_SCSI_SRP is not set
627# CONFIG_SCSI_DH is not set
628# CONFIG_SCSI_OSD_INITIATOR is not set
546# CONFIG_ATA is not set 629# CONFIG_ATA is not set
547CONFIG_MD=y 630CONFIG_MD=y
548CONFIG_BLK_DEV_MD=y 631CONFIG_BLK_DEV_MD=y
632CONFIG_MD_AUTODETECT=y
549CONFIG_MD_LINEAR=y 633CONFIG_MD_LINEAR=y
550CONFIG_MD_RAID0=y 634CONFIG_MD_RAID0=y
551CONFIG_MD_RAID1=y 635CONFIG_MD_RAID1=y
552# CONFIG_MD_RAID10 is not set 636# CONFIG_MD_RAID10 is not set
553CONFIG_MD_RAID456=y 637CONFIG_MD_RAID456=y
554# CONFIG_MD_RAID5_RESHAPE is not set 638CONFIG_MD_RAID6_PQ=y
555# CONFIG_MD_MULTIPATH is not set 639# CONFIG_MD_MULTIPATH is not set
556# CONFIG_MD_FAULTY is not set 640# CONFIG_MD_FAULTY is not set
557CONFIG_BLK_DEV_DM=y 641CONFIG_BLK_DEV_DM=y
@@ -568,27 +652,34 @@ CONFIG_BLK_DEV_DM=y
568# 652#
569# IEEE 1394 (FireWire) support 653# IEEE 1394 (FireWire) support
570# 654#
655
656#
657# You can enable one or both FireWire driver stacks.
658#
659
660#
661# See the help texts for more information.
662#
571# CONFIG_FIREWIRE is not set 663# CONFIG_FIREWIRE is not set
572# CONFIG_IEEE1394 is not set 664# CONFIG_IEEE1394 is not set
573# CONFIG_I2O is not set 665# CONFIG_I2O is not set
574CONFIG_NETDEVICES=y 666CONFIG_NETDEVICES=y
575# CONFIG_NETDEVICES_MULTIQUEUE is not set
576# CONFIG_DUMMY is not set 667# CONFIG_DUMMY is not set
577# CONFIG_BONDING is not set 668# CONFIG_BONDING is not set
578# CONFIG_MACVLAN is not set 669# CONFIG_MACVLAN is not set
579# CONFIG_EQUALIZER is not set 670# CONFIG_EQUALIZER is not set
580# CONFIG_TUN is not set 671# CONFIG_TUN is not set
581# CONFIG_VETH is not set 672# CONFIG_VETH is not set
582# CONFIG_IP1000 is not set
583# CONFIG_ARCNET is not set 673# CONFIG_ARCNET is not set
584# CONFIG_NET_ETHERNET is not set 674# CONFIG_NET_ETHERNET is not set
585CONFIG_NETDEV_1000=y 675CONFIG_NETDEV_1000=y
586# CONFIG_ACENIC is not set 676# CONFIG_ACENIC is not set
587# CONFIG_DL2K is not set 677# CONFIG_DL2K is not set
588CONFIG_E1000=y 678CONFIG_E1000=y
589CONFIG_E1000_NAPI=y
590# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
591# CONFIG_E1000E is not set 679# CONFIG_E1000E is not set
680# CONFIG_IP1000 is not set
681# CONFIG_IGB is not set
682# CONFIG_IGBVF is not set
592# CONFIG_NS83820 is not set 683# CONFIG_NS83820 is not set
593# CONFIG_HAMACHI is not set 684# CONFIG_HAMACHI is not set
594# CONFIG_YELLOWFIN is not set 685# CONFIG_YELLOWFIN is not set
@@ -596,23 +687,34 @@ CONFIG_E1000_NAPI=y
596# CONFIG_SIS190 is not set 687# CONFIG_SIS190 is not set
597# CONFIG_SKGE is not set 688# CONFIG_SKGE is not set
598# CONFIG_SKY2 is not set 689# CONFIG_SKY2 is not set
599# CONFIG_SK98LIN is not set
600# CONFIG_VIA_VELOCITY is not set 690# CONFIG_VIA_VELOCITY is not set
601# CONFIG_TIGON3 is not set 691# CONFIG_TIGON3 is not set
602# CONFIG_BNX2 is not set 692# CONFIG_BNX2 is not set
693# CONFIG_CNIC is not set
603# CONFIG_QLA3XXX is not set 694# CONFIG_QLA3XXX is not set
604# CONFIG_ATL1 is not set 695# CONFIG_ATL1 is not set
696# CONFIG_ATL1E is not set
697# CONFIG_ATL1C is not set
698# CONFIG_JME is not set
605CONFIG_NETDEV_10000=y 699CONFIG_NETDEV_10000=y
606# CONFIG_CHELSIO_T1 is not set 700# CONFIG_CHELSIO_T1 is not set
701CONFIG_CHELSIO_T3_DEPENDS=y
607# CONFIG_CHELSIO_T3 is not set 702# CONFIG_CHELSIO_T3 is not set
703# CONFIG_ENIC is not set
608# CONFIG_IXGBE is not set 704# CONFIG_IXGBE is not set
609# CONFIG_IXGB is not set 705# CONFIG_IXGB is not set
610# CONFIG_S2IO is not set 706# CONFIG_S2IO is not set
707# CONFIG_VXGE is not set
611# CONFIG_MYRI10GE is not set 708# CONFIG_MYRI10GE is not set
612# CONFIG_NETXEN_NIC is not set 709# CONFIG_NETXEN_NIC is not set
613# CONFIG_NIU is not set 710# CONFIG_NIU is not set
711# CONFIG_MLX4_EN is not set
614# CONFIG_MLX4_CORE is not set 712# CONFIG_MLX4_CORE is not set
615# CONFIG_TEHUTI is not set 713# CONFIG_TEHUTI is not set
714# CONFIG_BNX2X is not set
715# CONFIG_QLGE is not set
716# CONFIG_SFC is not set
717# CONFIG_BE2NET is not set
616# CONFIG_TR is not set 718# CONFIG_TR is not set
617 719
618# 720#
@@ -620,13 +722,16 @@ CONFIG_NETDEV_10000=y
620# 722#
621# CONFIG_WLAN_PRE80211 is not set 723# CONFIG_WLAN_PRE80211 is not set
622# CONFIG_WLAN_80211 is not set 724# CONFIG_WLAN_80211 is not set
725
726#
727# Enable WiMAX (Networking options) to see the WiMAX drivers
728#
623# CONFIG_WAN is not set 729# CONFIG_WAN is not set
624# CONFIG_FDDI is not set 730# CONFIG_FDDI is not set
625# CONFIG_HIPPI is not set 731# CONFIG_HIPPI is not set
626# CONFIG_PPP is not set 732# CONFIG_PPP is not set
627# CONFIG_SLIP is not set 733# CONFIG_SLIP is not set
628# CONFIG_NET_FC is not set 734# CONFIG_NET_FC is not set
629# CONFIG_SHAPER is not set
630# CONFIG_NETCONSOLE is not set 735# CONFIG_NETCONSOLE is not set
631# CONFIG_NETPOLL is not set 736# CONFIG_NETPOLL is not set
632# CONFIG_NET_POLL_CONTROLLER is not set 737# CONFIG_NET_POLL_CONTROLLER is not set
@@ -670,10 +775,13 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
670# Character devices 775# Character devices
671# 776#
672CONFIG_VT=y 777CONFIG_VT=y
778CONFIG_CONSOLE_TRANSLATIONS=y
673CONFIG_VT_CONSOLE=y 779CONFIG_VT_CONSOLE=y
674CONFIG_HW_CONSOLE=y 780CONFIG_HW_CONSOLE=y
675# CONFIG_VT_HW_CONSOLE_BINDING is not set 781# CONFIG_VT_HW_CONSOLE_BINDING is not set
782CONFIG_DEVKMEM=y
676# CONFIG_SERIAL_NONSTANDARD is not set 783# CONFIG_SERIAL_NONSTANDARD is not set
784# CONFIG_NOZOMI is not set
677 785
678# 786#
679# Serial drivers 787# Serial drivers
@@ -692,11 +800,12 @@ CONFIG_SERIAL_CORE=y
692CONFIG_SERIAL_CORE_CONSOLE=y 800CONFIG_SERIAL_CORE_CONSOLE=y
693# CONFIG_SERIAL_JSM is not set 801# CONFIG_SERIAL_JSM is not set
694CONFIG_UNIX98_PTYS=y 802CONFIG_UNIX98_PTYS=y
803# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
695CONFIG_LEGACY_PTYS=y 804CONFIG_LEGACY_PTYS=y
696CONFIG_LEGACY_PTY_COUNT=256 805CONFIG_LEGACY_PTY_COUNT=256
697# CONFIG_IPMI_HANDLER is not set 806# CONFIG_IPMI_HANDLER is not set
698CONFIG_HW_RANDOM=y 807CONFIG_HW_RANDOM=y
699# CONFIG_NVRAM is not set 808# CONFIG_HW_RANDOM_TIMERIOMEM is not set
700# CONFIG_R3964 is not set 809# CONFIG_R3964 is not set
701# CONFIG_APPLICOM is not set 810# CONFIG_APPLICOM is not set
702# CONFIG_RAW_DRIVER is not set 811# CONFIG_RAW_DRIVER is not set
@@ -705,16 +814,14 @@ CONFIG_DEVPORT=y
705CONFIG_I2C=y 814CONFIG_I2C=y
706CONFIG_I2C_BOARDINFO=y 815CONFIG_I2C_BOARDINFO=y
707CONFIG_I2C_CHARDEV=y 816CONFIG_I2C_CHARDEV=y
817CONFIG_I2C_HELPER_AUTO=y
708 818
709# 819#
710# I2C Algorithms 820# I2C Hardware Bus support
711# 821#
712# CONFIG_I2C_ALGOBIT is not set
713# CONFIG_I2C_ALGOPCF is not set
714# CONFIG_I2C_ALGOPCA is not set
715 822
716# 823#
717# I2C Hardware Bus support 824# PC SMBus host controller drivers
718# 825#
719# CONFIG_I2C_ALI1535 is not set 826# CONFIG_I2C_ALI1535 is not set
720# CONFIG_I2C_ALI1563 is not set 827# CONFIG_I2C_ALI1563 is not set
@@ -722,50 +829,82 @@ CONFIG_I2C_CHARDEV=y
722# CONFIG_I2C_AMD756 is not set 829# CONFIG_I2C_AMD756 is not set
723# CONFIG_I2C_AMD8111 is not set 830# CONFIG_I2C_AMD8111 is not set
724# CONFIG_I2C_I801 is not set 831# CONFIG_I2C_I801 is not set
725# CONFIG_I2C_I810 is not set 832# CONFIG_I2C_ISCH is not set
726# CONFIG_I2C_PIIX4 is not set 833# CONFIG_I2C_PIIX4 is not set
727CONFIG_I2C_IOP3XX=y
728# CONFIG_I2C_NFORCE2 is not set 834# CONFIG_I2C_NFORCE2 is not set
729# CONFIG_I2C_OCORES is not set
730# CONFIG_I2C_PARPORT_LIGHT is not set
731# CONFIG_I2C_PROSAVAGE is not set
732# CONFIG_I2C_SAVAGE4 is not set
733# CONFIG_I2C_SIMTEC is not set
734# CONFIG_I2C_SIS5595 is not set 835# CONFIG_I2C_SIS5595 is not set
735# CONFIG_I2C_SIS630 is not set 836# CONFIG_I2C_SIS630 is not set
736# CONFIG_I2C_SIS96X is not set 837# CONFIG_I2C_SIS96X is not set
737# CONFIG_I2C_TAOS_EVM is not set
738# CONFIG_I2C_STUB is not set
739# CONFIG_I2C_VIA is not set 838# CONFIG_I2C_VIA is not set
740# CONFIG_I2C_VIAPRO is not set 839# CONFIG_I2C_VIAPRO is not set
840
841#
842# I2C system bus drivers (mostly embedded / system-on-chip)
843#
844# CONFIG_I2C_GPIO is not set
845CONFIG_I2C_IOP3XX=y
846# CONFIG_I2C_OCORES is not set
847# CONFIG_I2C_SIMTEC is not set
848
849#
850# External I2C/SMBus adapter drivers
851#
852# CONFIG_I2C_PARPORT_LIGHT is not set
853# CONFIG_I2C_TAOS_EVM is not set
854
855#
856# Graphics adapter I2C/DDC channel drivers
857#
741# CONFIG_I2C_VOODOO3 is not set 858# CONFIG_I2C_VOODOO3 is not set
742 859
743# 860#
861# Other I2C/SMBus bus drivers
862#
863# CONFIG_I2C_PCA_PLATFORM is not set
864# CONFIG_I2C_STUB is not set
865
866#
744# Miscellaneous I2C Chip support 867# Miscellaneous I2C Chip support
745# 868#
746# CONFIG_SENSORS_DS1337 is not set
747# CONFIG_SENSORS_DS1374 is not set
748# CONFIG_DS1682 is not set 869# CONFIG_DS1682 is not set
749# CONFIG_EEPROM_LEGACY is not set
750# CONFIG_SENSORS_PCF8574 is not set 870# CONFIG_SENSORS_PCF8574 is not set
871# CONFIG_PCF8575 is not set
751# CONFIG_SENSORS_PCA9539 is not set 872# CONFIG_SENSORS_PCA9539 is not set
752# CONFIG_SENSORS_PCF8591 is not set
753# CONFIG_SENSORS_MAX6875 is not set
754# CONFIG_SENSORS_TSL2550 is not set 873# CONFIG_SENSORS_TSL2550 is not set
755# CONFIG_I2C_DEBUG_CORE is not set 874# CONFIG_I2C_DEBUG_CORE is not set
756# CONFIG_I2C_DEBUG_ALGO is not set 875# CONFIG_I2C_DEBUG_ALGO is not set
757# CONFIG_I2C_DEBUG_BUS is not set 876# CONFIG_I2C_DEBUG_BUS is not set
758# CONFIG_I2C_DEBUG_CHIP is not set 877# CONFIG_I2C_DEBUG_CHIP is not set
878# CONFIG_SPI is not set
879CONFIG_ARCH_REQUIRE_GPIOLIB=y
880CONFIG_GPIOLIB=y
881# CONFIG_DEBUG_GPIO is not set
882# CONFIG_GPIO_SYSFS is not set
759 883
760# 884#
761# SPI support 885# Memory mapped GPIO expanders:
886#
887
888#
889# I2C GPIO expanders:
890#
891# CONFIG_GPIO_MAX732X is not set
892# CONFIG_GPIO_PCA953X is not set
893# CONFIG_GPIO_PCF857X is not set
894
895#
896# PCI GPIO expanders:
897#
898# CONFIG_GPIO_BT8XX is not set
899
900#
901# SPI GPIO expanders:
762# 902#
763# CONFIG_SPI is not set
764# CONFIG_SPI_MASTER is not set
765# CONFIG_W1 is not set 903# CONFIG_W1 is not set
766# CONFIG_POWER_SUPPLY is not set 904# CONFIG_POWER_SUPPLY is not set
767CONFIG_HWMON=y 905CONFIG_HWMON=y
768# CONFIG_HWMON_VID is not set 906# CONFIG_HWMON_VID is not set
907# CONFIG_SENSORS_AD7414 is not set
769# CONFIG_SENSORS_AD7418 is not set 908# CONFIG_SENSORS_AD7418 is not set
770# CONFIG_SENSORS_ADM1021 is not set 909# CONFIG_SENSORS_ADM1021 is not set
771# CONFIG_SENSORS_ADM1025 is not set 910# CONFIG_SENSORS_ADM1025 is not set
@@ -773,13 +912,17 @@ CONFIG_HWMON=y
773# CONFIG_SENSORS_ADM1029 is not set 912# CONFIG_SENSORS_ADM1029 is not set
774# CONFIG_SENSORS_ADM1031 is not set 913# CONFIG_SENSORS_ADM1031 is not set
775# CONFIG_SENSORS_ADM9240 is not set 914# CONFIG_SENSORS_ADM9240 is not set
915# CONFIG_SENSORS_ADT7462 is not set
776# CONFIG_SENSORS_ADT7470 is not set 916# CONFIG_SENSORS_ADT7470 is not set
917# CONFIG_SENSORS_ADT7473 is not set
918# CONFIG_SENSORS_ADT7475 is not set
777# CONFIG_SENSORS_ATXP1 is not set 919# CONFIG_SENSORS_ATXP1 is not set
778# CONFIG_SENSORS_DS1621 is not set 920# CONFIG_SENSORS_DS1621 is not set
779# CONFIG_SENSORS_I5K_AMB is not set 921# CONFIG_SENSORS_I5K_AMB is not set
780# CONFIG_SENSORS_F71805F is not set 922# CONFIG_SENSORS_F71805F is not set
781# CONFIG_SENSORS_F71882FG is not set 923# CONFIG_SENSORS_F71882FG is not set
782# CONFIG_SENSORS_F75375S is not set 924# CONFIG_SENSORS_F75375S is not set
925# CONFIG_SENSORS_G760A is not set
783# CONFIG_SENSORS_GL518SM is not set 926# CONFIG_SENSORS_GL518SM is not set
784# CONFIG_SENSORS_GL520SM is not set 927# CONFIG_SENSORS_GL520SM is not set
785# CONFIG_SENSORS_IT87 is not set 928# CONFIG_SENSORS_IT87 is not set
@@ -794,16 +937,23 @@ CONFIG_HWMON=y
794# CONFIG_SENSORS_LM90 is not set 937# CONFIG_SENSORS_LM90 is not set
795# CONFIG_SENSORS_LM92 is not set 938# CONFIG_SENSORS_LM92 is not set
796# CONFIG_SENSORS_LM93 is not set 939# CONFIG_SENSORS_LM93 is not set
940# CONFIG_SENSORS_LTC4215 is not set
941# CONFIG_SENSORS_LTC4245 is not set
942# CONFIG_SENSORS_LM95241 is not set
797# CONFIG_SENSORS_MAX1619 is not set 943# CONFIG_SENSORS_MAX1619 is not set
798# CONFIG_SENSORS_MAX6650 is not set 944# CONFIG_SENSORS_MAX6650 is not set
799# CONFIG_SENSORS_PC87360 is not set 945# CONFIG_SENSORS_PC87360 is not set
800# CONFIG_SENSORS_PC87427 is not set 946# CONFIG_SENSORS_PC87427 is not set
947# CONFIG_SENSORS_PCF8591 is not set
948# CONFIG_SENSORS_SHT15 is not set
801# CONFIG_SENSORS_SIS5595 is not set 949# CONFIG_SENSORS_SIS5595 is not set
802# CONFIG_SENSORS_DME1737 is not set 950# CONFIG_SENSORS_DME1737 is not set
803# CONFIG_SENSORS_SMSC47M1 is not set 951# CONFIG_SENSORS_SMSC47M1 is not set
804# CONFIG_SENSORS_SMSC47M192 is not set 952# CONFIG_SENSORS_SMSC47M192 is not set
805# CONFIG_SENSORS_SMSC47B397 is not set 953# CONFIG_SENSORS_SMSC47B397 is not set
954# CONFIG_SENSORS_ADS7828 is not set
806# CONFIG_SENSORS_THMC50 is not set 955# CONFIG_SENSORS_THMC50 is not set
956# CONFIG_SENSORS_TMP401 is not set
807# CONFIG_SENSORS_VIA686A is not set 957# CONFIG_SENSORS_VIA686A is not set
808# CONFIG_SENSORS_VT1211 is not set 958# CONFIG_SENSORS_VT1211 is not set
809# CONFIG_SENSORS_VT8231 is not set 959# CONFIG_SENSORS_VT8231 is not set
@@ -812,28 +962,38 @@ CONFIG_HWMON=y
812# CONFIG_SENSORS_W83792D is not set 962# CONFIG_SENSORS_W83792D is not set
813# CONFIG_SENSORS_W83793 is not set 963# CONFIG_SENSORS_W83793 is not set
814# CONFIG_SENSORS_W83L785TS is not set 964# CONFIG_SENSORS_W83L785TS is not set
965# CONFIG_SENSORS_W83L786NG is not set
815# CONFIG_SENSORS_W83627HF is not set 966# CONFIG_SENSORS_W83627HF is not set
816# CONFIG_SENSORS_W83627EHF is not set 967# CONFIG_SENSORS_W83627EHF is not set
817# CONFIG_HWMON_DEBUG_CHIP is not set 968# CONFIG_HWMON_DEBUG_CHIP is not set
969# CONFIG_THERMAL is not set
970# CONFIG_THERMAL_HWMON is not set
818# CONFIG_WATCHDOG is not set 971# CONFIG_WATCHDOG is not set
972CONFIG_SSB_POSSIBLE=y
819 973
820# 974#
821# Sonics Silicon Backplane 975# Sonics Silicon Backplane
822# 976#
823CONFIG_SSB_POSSIBLE=y
824# CONFIG_SSB is not set 977# CONFIG_SSB is not set
825 978
826# 979#
827# Multifunction device drivers 980# Multifunction device drivers
828# 981#
982# CONFIG_MFD_CORE is not set
829# CONFIG_MFD_SM501 is not set 983# CONFIG_MFD_SM501 is not set
830 984# CONFIG_MFD_ASIC3 is not set
831# 985# CONFIG_HTC_EGPIO is not set
832# Multimedia devices 986# CONFIG_HTC_PASIC3 is not set
833# 987# CONFIG_TPS65010 is not set
834# CONFIG_VIDEO_DEV is not set 988# CONFIG_TWL4030_CORE is not set
835# CONFIG_DVB_CORE is not set 989# CONFIG_MFD_TMIO is not set
836CONFIG_DAB=y 990# CONFIG_MFD_TC6393XB is not set
991# CONFIG_PMIC_DA903X is not set
992# CONFIG_MFD_WM8400 is not set
993# CONFIG_MFD_WM8350_I2C is not set
994# CONFIG_MFD_PCF50633 is not set
995# CONFIG_AB3100_CORE is not set
996# CONFIG_MEDIA_SUPPORT is not set
837 997
838# 998#
839# Graphics support 999# Graphics support
@@ -854,15 +1014,16 @@ CONFIG_DAB=y
854# 1014#
855# CONFIG_VGA_CONSOLE is not set 1015# CONFIG_VGA_CONSOLE is not set
856CONFIG_DUMMY_CONSOLE=y 1016CONFIG_DUMMY_CONSOLE=y
857
858#
859# Sound
860#
861# CONFIG_SOUND is not set 1017# CONFIG_SOUND is not set
862CONFIG_HID_SUPPORT=y 1018CONFIG_HID_SUPPORT=y
863CONFIG_HID=y 1019CONFIG_HID=y
864# CONFIG_HID_DEBUG is not set 1020# CONFIG_HID_DEBUG is not set
865# CONFIG_HIDRAW is not set 1021# CONFIG_HIDRAW is not set
1022# CONFIG_HID_PID is not set
1023
1024#
1025# Special HID drivers
1026#
866CONFIG_USB_SUPPORT=y 1027CONFIG_USB_SUPPORT=y
867CONFIG_USB_ARCH_HAS_HCD=y 1028CONFIG_USB_ARCH_HAS_HCD=y
868CONFIG_USB_ARCH_HAS_OHCI=y 1029CONFIG_USB_ARCH_HAS_OHCI=y
@@ -870,14 +1031,21 @@ CONFIG_USB_ARCH_HAS_EHCI=y
870# CONFIG_USB is not set 1031# CONFIG_USB is not set
871 1032
872# 1033#
873# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' 1034# Enable Host or Gadget support to see Inventra options
874# 1035#
875 1036
876# 1037#
877# USB Gadget Support 1038# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
878# 1039#
879# CONFIG_USB_GADGET is not set 1040# CONFIG_USB_GADGET is not set
1041
1042#
1043# OTG and related infrastructure
1044#
1045# CONFIG_UWB is not set
880# CONFIG_MMC is not set 1046# CONFIG_MMC is not set
1047# CONFIG_MEMSTICK is not set
1048# CONFIG_ACCESSIBILITY is not set
881# CONFIG_NEW_LEDS is not set 1049# CONFIG_NEW_LEDS is not set
882CONFIG_RTC_LIB=y 1050CONFIG_RTC_LIB=y
883# CONFIG_RTC_CLASS is not set 1051# CONFIG_RTC_CLASS is not set
@@ -893,6 +1061,12 @@ CONFIG_DMA_ENGINE=y
893# DMA Clients 1061# DMA Clients
894# 1062#
895CONFIG_NET_DMA=y 1063CONFIG_NET_DMA=y
1064# CONFIG_ASYNC_TX_DMA is not set
1065# CONFIG_DMATEST is not set
1066# CONFIG_AUXDISPLAY is not set
1067# CONFIG_REGULATOR is not set
1068# CONFIG_UIO is not set
1069# CONFIG_STAGING is not set
896 1070
897# 1071#
898# File systems 1072# File systems
@@ -901,10 +1075,11 @@ CONFIG_EXT2_FS=y
901# CONFIG_EXT2_FS_XATTR is not set 1075# CONFIG_EXT2_FS_XATTR is not set
902# CONFIG_EXT2_FS_XIP is not set 1076# CONFIG_EXT2_FS_XIP is not set
903CONFIG_EXT3_FS=y 1077CONFIG_EXT3_FS=y
1078# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
904CONFIG_EXT3_FS_XATTR=y 1079CONFIG_EXT3_FS_XATTR=y
905# CONFIG_EXT3_FS_POSIX_ACL is not set 1080# CONFIG_EXT3_FS_POSIX_ACL is not set
906# CONFIG_EXT3_FS_SECURITY is not set 1081# CONFIG_EXT3_FS_SECURITY is not set
907# CONFIG_EXT4DEV_FS is not set 1082# CONFIG_EXT4_FS is not set
908CONFIG_JBD=y 1083CONFIG_JBD=y
909CONFIG_FS_MBCACHE=y 1084CONFIG_FS_MBCACHE=y
910# CONFIG_REISERFS_FS is not set 1085# CONFIG_REISERFS_FS is not set
@@ -913,17 +1088,23 @@ CONFIG_FS_MBCACHE=y
913# CONFIG_XFS_FS is not set 1088# CONFIG_XFS_FS is not set
914# CONFIG_GFS2_FS is not set 1089# CONFIG_GFS2_FS is not set
915# CONFIG_OCFS2_FS is not set 1090# CONFIG_OCFS2_FS is not set
916# CONFIG_MINIX_FS is not set 1091# CONFIG_BTRFS_FS is not set
917# CONFIG_ROMFS_FS is not set 1092CONFIG_FILE_LOCKING=y
1093CONFIG_FSNOTIFY=y
1094CONFIG_DNOTIFY=y
918CONFIG_INOTIFY=y 1095CONFIG_INOTIFY=y
919CONFIG_INOTIFY_USER=y 1096CONFIG_INOTIFY_USER=y
920# CONFIG_QUOTA is not set 1097# CONFIG_QUOTA is not set
921CONFIG_DNOTIFY=y
922# CONFIG_AUTOFS_FS is not set 1098# CONFIG_AUTOFS_FS is not set
923# CONFIG_AUTOFS4_FS is not set 1099# CONFIG_AUTOFS4_FS is not set
924# CONFIG_FUSE_FS is not set 1100# CONFIG_FUSE_FS is not set
925 1101
926# 1102#
1103# Caches
1104#
1105# CONFIG_FSCACHE is not set
1106
1107#
927# CD-ROM/DVD Filesystems 1108# CD-ROM/DVD Filesystems
928# 1109#
929# CONFIG_ISO9660_FS is not set 1110# CONFIG_ISO9660_FS is not set
@@ -941,15 +1122,13 @@ CONFIG_DNOTIFY=y
941# 1122#
942CONFIG_PROC_FS=y 1123CONFIG_PROC_FS=y
943CONFIG_PROC_SYSCTL=y 1124CONFIG_PROC_SYSCTL=y
1125CONFIG_PROC_PAGE_MONITOR=y
944CONFIG_SYSFS=y 1126CONFIG_SYSFS=y
945CONFIG_TMPFS=y 1127CONFIG_TMPFS=y
946# CONFIG_TMPFS_POSIX_ACL is not set 1128# CONFIG_TMPFS_POSIX_ACL is not set
947# CONFIG_HUGETLB_PAGE is not set 1129# CONFIG_HUGETLB_PAGE is not set
948# CONFIG_CONFIGFS_FS is not set 1130# CONFIG_CONFIGFS_FS is not set
949 1131CONFIG_MISC_FILESYSTEMS=y
950#
951# Miscellaneous filesystems
952#
953# CONFIG_ADFS_FS is not set 1132# CONFIG_ADFS_FS is not set
954# CONFIG_AFFS_FS is not set 1133# CONFIG_AFFS_FS is not set
955# CONFIG_HFS_FS is not set 1134# CONFIG_HFS_FS is not set
@@ -959,29 +1138,31 @@ CONFIG_TMPFS=y
959# CONFIG_EFS_FS is not set 1138# CONFIG_EFS_FS is not set
960# CONFIG_JFFS2_FS is not set 1139# CONFIG_JFFS2_FS is not set
961CONFIG_CRAMFS=y 1140CONFIG_CRAMFS=y
1141# CONFIG_SQUASHFS is not set
962# CONFIG_VXFS_FS is not set 1142# CONFIG_VXFS_FS is not set
1143# CONFIG_MINIX_FS is not set
1144# CONFIG_OMFS_FS is not set
963# CONFIG_HPFS_FS is not set 1145# CONFIG_HPFS_FS is not set
964# CONFIG_QNX4FS_FS is not set 1146# CONFIG_QNX4FS_FS is not set
1147# CONFIG_ROMFS_FS is not set
965# CONFIG_SYSV_FS is not set 1148# CONFIG_SYSV_FS is not set
966# CONFIG_UFS_FS is not set 1149# CONFIG_UFS_FS is not set
1150# CONFIG_NILFS2_FS is not set
967CONFIG_NETWORK_FILESYSTEMS=y 1151CONFIG_NETWORK_FILESYSTEMS=y
968CONFIG_NFS_FS=y 1152CONFIG_NFS_FS=y
969CONFIG_NFS_V3=y 1153CONFIG_NFS_V3=y
970# CONFIG_NFS_V3_ACL is not set 1154# CONFIG_NFS_V3_ACL is not set
971# CONFIG_NFS_V4 is not set 1155# CONFIG_NFS_V4 is not set
972# CONFIG_NFS_DIRECTIO is not set 1156CONFIG_ROOT_NFS=y
973CONFIG_NFSD=y 1157CONFIG_NFSD=y
974CONFIG_NFSD_V3=y 1158CONFIG_NFSD_V3=y
975# CONFIG_NFSD_V3_ACL is not set 1159# CONFIG_NFSD_V3_ACL is not set
976# CONFIG_NFSD_V4 is not set 1160# CONFIG_NFSD_V4 is not set
977# CONFIG_NFSD_TCP is not set
978CONFIG_ROOT_NFS=y
979CONFIG_LOCKD=y 1161CONFIG_LOCKD=y
980CONFIG_LOCKD_V4=y 1162CONFIG_LOCKD_V4=y
981CONFIG_EXPORTFS=y 1163CONFIG_EXPORTFS=y
982CONFIG_NFS_COMMON=y 1164CONFIG_NFS_COMMON=y
983CONFIG_SUNRPC=y 1165CONFIG_SUNRPC=y
984# CONFIG_SUNRPC_BIND34 is not set
985# CONFIG_RPCSEC_GSS_KRB5 is not set 1166# CONFIG_RPCSEC_GSS_KRB5 is not set
986# CONFIG_RPCSEC_GSS_SPKM3 is not set 1167# CONFIG_RPCSEC_GSS_SPKM3 is not set
987# CONFIG_SMB_FS is not set 1168# CONFIG_SMB_FS is not set
@@ -1013,9 +1194,6 @@ CONFIG_MSDOS_PARTITION=y
1013# CONFIG_SYSV68_PARTITION is not set 1194# CONFIG_SYSV68_PARTITION is not set
1014# CONFIG_NLS is not set 1195# CONFIG_NLS is not set
1015# CONFIG_DLM is not set 1196# CONFIG_DLM is not set
1016CONFIG_INSTRUMENTATION=y
1017# CONFIG_PROFILING is not set
1018# CONFIG_MARKERS is not set
1019 1197
1020# 1198#
1021# Kernel hacking 1199# Kernel hacking
@@ -1023,6 +1201,7 @@ CONFIG_INSTRUMENTATION=y
1023# CONFIG_PRINTK_TIME is not set 1201# CONFIG_PRINTK_TIME is not set
1024CONFIG_ENABLE_WARN_DEPRECATED=y 1202CONFIG_ENABLE_WARN_DEPRECATED=y
1025CONFIG_ENABLE_MUST_CHECK=y 1203CONFIG_ENABLE_MUST_CHECK=y
1204CONFIG_FRAME_WARN=1024
1026CONFIG_MAGIC_SYSRQ=y 1205CONFIG_MAGIC_SYSRQ=y
1027# CONFIG_UNUSED_SYMBOLS is not set 1206# CONFIG_UNUSED_SYMBOLS is not set
1028# CONFIG_DEBUG_FS is not set 1207# CONFIG_DEBUG_FS is not set
@@ -1030,10 +1209,17 @@ CONFIG_MAGIC_SYSRQ=y
1030CONFIG_DEBUG_KERNEL=y 1209CONFIG_DEBUG_KERNEL=y
1031# CONFIG_DEBUG_SHIRQ is not set 1210# CONFIG_DEBUG_SHIRQ is not set
1032CONFIG_DETECT_SOFTLOCKUP=y 1211CONFIG_DETECT_SOFTLOCKUP=y
1212# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
1213CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
1214CONFIG_DETECT_HUNG_TASK=y
1215# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
1216CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
1033CONFIG_SCHED_DEBUG=y 1217CONFIG_SCHED_DEBUG=y
1034# CONFIG_SCHEDSTATS is not set 1218# CONFIG_SCHEDSTATS is not set
1035# CONFIG_TIMER_STATS is not set 1219# CONFIG_TIMER_STATS is not set
1220# CONFIG_DEBUG_OBJECTS is not set
1036# CONFIG_DEBUG_SLAB is not set 1221# CONFIG_DEBUG_SLAB is not set
1222# CONFIG_DEBUG_KMEMLEAK is not set
1037# CONFIG_DEBUG_RT_MUTEXES is not set 1223# CONFIG_DEBUG_RT_MUTEXES is not set
1038# CONFIG_RT_MUTEX_TESTER is not set 1224# CONFIG_RT_MUTEX_TESTER is not set
1039# CONFIG_DEBUG_SPINLOCK is not set 1225# CONFIG_DEBUG_SPINLOCK is not set
@@ -1047,16 +1233,41 @@ CONFIG_SCHED_DEBUG=y
1047CONFIG_DEBUG_BUGVERBOSE=y 1233CONFIG_DEBUG_BUGVERBOSE=y
1048# CONFIG_DEBUG_INFO is not set 1234# CONFIG_DEBUG_INFO is not set
1049# CONFIG_DEBUG_VM is not set 1235# CONFIG_DEBUG_VM is not set
1236# CONFIG_DEBUG_WRITECOUNT is not set
1237CONFIG_DEBUG_MEMORY_INIT=y
1050# CONFIG_DEBUG_LIST is not set 1238# CONFIG_DEBUG_LIST is not set
1051# CONFIG_DEBUG_SG is not set 1239# CONFIG_DEBUG_SG is not set
1240# CONFIG_DEBUG_NOTIFIERS is not set
1052CONFIG_FRAME_POINTER=y 1241CONFIG_FRAME_POINTER=y
1053# CONFIG_FORCED_INLINING is not set
1054# CONFIG_BOOT_PRINTK_DELAY is not set 1242# CONFIG_BOOT_PRINTK_DELAY is not set
1055# CONFIG_RCU_TORTURE_TEST is not set 1243# CONFIG_RCU_TORTURE_TEST is not set
1244# CONFIG_RCU_CPU_STALL_DETECTOR is not set
1245# CONFIG_BACKTRACE_SELF_TEST is not set
1246# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
1056# CONFIG_FAULT_INJECTION is not set 1247# CONFIG_FAULT_INJECTION is not set
1248# CONFIG_LATENCYTOP is not set
1249# CONFIG_SYSCTL_SYSCALL_CHECK is not set
1250# CONFIG_PAGE_POISONING is not set
1251CONFIG_HAVE_FUNCTION_TRACER=y
1252CONFIG_TRACING_SUPPORT=y
1253CONFIG_FTRACE=y
1254# CONFIG_FUNCTION_TRACER is not set
1255# CONFIG_SCHED_TRACER is not set
1256# CONFIG_ENABLE_DEFAULT_TRACERS is not set
1257# CONFIG_BOOT_TRACER is not set
1258CONFIG_BRANCH_PROFILE_NONE=y
1259# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
1260# CONFIG_PROFILE_ALL_BRANCHES is not set
1261# CONFIG_STACK_TRACER is not set
1262# CONFIG_KMEMTRACE is not set
1263# CONFIG_WORKQUEUE_TRACER is not set
1264# CONFIG_BLK_DEV_IO_TRACE is not set
1057# CONFIG_SAMPLES is not set 1265# CONFIG_SAMPLES is not set
1266CONFIG_HAVE_ARCH_KGDB=y
1267# CONFIG_KGDB is not set
1058CONFIG_DEBUG_USER=y 1268CONFIG_DEBUG_USER=y
1059# CONFIG_DEBUG_ERRORS is not set 1269# CONFIG_DEBUG_ERRORS is not set
1270# CONFIG_DEBUG_STACK_USAGE is not set
1060CONFIG_DEBUG_LL=y 1271CONFIG_DEBUG_LL=y
1061# CONFIG_DEBUG_ICEDCC is not set 1272# CONFIG_DEBUG_ICEDCC is not set
1062 1273
@@ -1065,24 +1276,117 @@ CONFIG_DEBUG_LL=y
1065# 1276#
1066# CONFIG_KEYS is not set 1277# CONFIG_KEYS is not set
1067# CONFIG_SECURITY is not set 1278# CONFIG_SECURITY is not set
1279# CONFIG_SECURITYFS is not set
1068# CONFIG_SECURITY_FILE_CAPABILITIES is not set 1280# CONFIG_SECURITY_FILE_CAPABILITIES is not set
1069CONFIG_XOR_BLOCKS=y 1281CONFIG_XOR_BLOCKS=y
1070CONFIG_ASYNC_CORE=y 1282CONFIG_ASYNC_CORE=y
1071CONFIG_ASYNC_MEMCPY=y 1283CONFIG_ASYNC_MEMCPY=y
1072CONFIG_ASYNC_XOR=y 1284CONFIG_ASYNC_XOR=y
1073# CONFIG_CRYPTO is not set 1285CONFIG_CRYPTO=y
1286
1287#
1288# Crypto core or helper
1289#
1290# CONFIG_CRYPTO_FIPS is not set
1291# CONFIG_CRYPTO_MANAGER is not set
1292# CONFIG_CRYPTO_MANAGER2 is not set
1293# CONFIG_CRYPTO_GF128MUL is not set
1294# CONFIG_CRYPTO_NULL is not set
1295# CONFIG_CRYPTO_CRYPTD is not set
1296# CONFIG_CRYPTO_AUTHENC is not set
1297# CONFIG_CRYPTO_TEST is not set
1298
1299#
1300# Authenticated Encryption with Associated Data
1301#
1302# CONFIG_CRYPTO_CCM is not set
1303# CONFIG_CRYPTO_GCM is not set
1304# CONFIG_CRYPTO_SEQIV is not set
1305
1306#
1307# Block modes
1308#
1309# CONFIG_CRYPTO_CBC is not set
1310# CONFIG_CRYPTO_CTR is not set
1311# CONFIG_CRYPTO_CTS is not set
1312# CONFIG_CRYPTO_ECB is not set
1313# CONFIG_CRYPTO_LRW is not set
1314# CONFIG_CRYPTO_PCBC is not set
1315# CONFIG_CRYPTO_XTS is not set
1316
1317#
1318# Hash modes
1319#
1320# CONFIG_CRYPTO_HMAC is not set
1321# CONFIG_CRYPTO_XCBC is not set
1322
1323#
1324# Digest
1325#
1326# CONFIG_CRYPTO_CRC32C is not set
1327# CONFIG_CRYPTO_MD4 is not set
1328# CONFIG_CRYPTO_MD5 is not set
1329# CONFIG_CRYPTO_MICHAEL_MIC is not set
1330# CONFIG_CRYPTO_RMD128 is not set
1331# CONFIG_CRYPTO_RMD160 is not set
1332# CONFIG_CRYPTO_RMD256 is not set
1333# CONFIG_CRYPTO_RMD320 is not set
1334# CONFIG_CRYPTO_SHA1 is not set
1335# CONFIG_CRYPTO_SHA256 is not set
1336# CONFIG_CRYPTO_SHA512 is not set
1337# CONFIG_CRYPTO_TGR192 is not set
1338# CONFIG_CRYPTO_WP512 is not set
1339
1340#
1341# Ciphers
1342#
1343# CONFIG_CRYPTO_AES is not set
1344# CONFIG_CRYPTO_ANUBIS is not set
1345# CONFIG_CRYPTO_ARC4 is not set
1346# CONFIG_CRYPTO_BLOWFISH is not set
1347# CONFIG_CRYPTO_CAMELLIA is not set
1348# CONFIG_CRYPTO_CAST5 is not set
1349# CONFIG_CRYPTO_CAST6 is not set
1350# CONFIG_CRYPTO_DES is not set
1351# CONFIG_CRYPTO_FCRYPT is not set
1352# CONFIG_CRYPTO_KHAZAD is not set
1353# CONFIG_CRYPTO_SALSA20 is not set
1354# CONFIG_CRYPTO_SEED is not set
1355# CONFIG_CRYPTO_SERPENT is not set
1356# CONFIG_CRYPTO_TEA is not set
1357# CONFIG_CRYPTO_TWOFISH is not set
1358
1359#
1360# Compression
1361#
1362# CONFIG_CRYPTO_DEFLATE is not set
1363# CONFIG_CRYPTO_ZLIB is not set
1364# CONFIG_CRYPTO_LZO is not set
1365
1366#
1367# Random Number Generation
1368#
1369# CONFIG_CRYPTO_ANSI_CPRNG is not set
1370CONFIG_CRYPTO_HW=y
1371# CONFIG_CRYPTO_DEV_HIFN_795X is not set
1372# CONFIG_BINARY_PRINTF is not set
1074 1373
1075# 1374#
1076# Library routines 1375# Library routines
1077# 1376#
1377CONFIG_GENERIC_FIND_LAST_BIT=y
1078# CONFIG_CRC_CCITT is not set 1378# CONFIG_CRC_CCITT is not set
1079# CONFIG_CRC16 is not set 1379# CONFIG_CRC16 is not set
1380# CONFIG_CRC_T10DIF is not set
1080# CONFIG_CRC_ITU_T is not set 1381# CONFIG_CRC_ITU_T is not set
1081# CONFIG_CRC32 is not set 1382# CONFIG_CRC32 is not set
1082# CONFIG_CRC7 is not set 1383# CONFIG_CRC7 is not set
1083# CONFIG_LIBCRC32C is not set 1384# CONFIG_LIBCRC32C is not set
1084CONFIG_ZLIB_INFLATE=y 1385CONFIG_ZLIB_INFLATE=y
1085CONFIG_PLIST=y 1386CONFIG_DECOMPRESS_GZIP=y
1387CONFIG_DECOMPRESS_BZIP2=y
1388CONFIG_DECOMPRESS_LZMA=y
1086CONFIG_HAS_IOMEM=y 1389CONFIG_HAS_IOMEM=y
1087CONFIG_HAS_IOPORT=y 1390CONFIG_HAS_IOPORT=y
1088CONFIG_HAS_DMA=y 1391CONFIG_HAS_DMA=y
1392CONFIG_NLATTR=y
diff --git a/arch/arm/configs/omap3_beagle_defconfig b/arch/arm/configs/omap3_beagle_defconfig
index 357d4021e2d0..b3c8cce0f8fb 100644
--- a/arch/arm/configs/omap3_beagle_defconfig
+++ b/arch/arm/configs/omap3_beagle_defconfig
@@ -969,7 +969,6 @@ CONFIG_USB_ETH_RNDIS=y
969# 969#
970CONFIG_USB_OTG_UTILS=y 970CONFIG_USB_OTG_UTILS=y
971# CONFIG_USB_GPIO_VBUS is not set 971# CONFIG_USB_GPIO_VBUS is not set
972# CONFIG_ISP1301_OMAP is not set
973CONFIG_TWL4030_USB=y 972CONFIG_TWL4030_USB=y
974# CONFIG_NOP_USB_XCEIV is not set 973# CONFIG_NOP_USB_XCEIV is not set
975CONFIG_MMC=y 974CONFIG_MMC=y
diff --git a/arch/arm/include/asm/bitops.h b/arch/arm/include/asm/bitops.h
index 63a481fbbed4..338ff19ae447 100644
--- a/arch/arm/include/asm/bitops.h
+++ b/arch/arm/include/asm/bitops.h
@@ -84,7 +84,7 @@ ____atomic_test_and_set_bit(unsigned int bit, volatile unsigned long *p)
84 *p = res | mask; 84 *p = res | mask;
85 raw_local_irq_restore(flags); 85 raw_local_irq_restore(flags);
86 86
87 return res & mask; 87 return (res & mask) != 0;
88} 88}
89 89
90static inline int 90static inline int
@@ -101,7 +101,7 @@ ____atomic_test_and_clear_bit(unsigned int bit, volatile unsigned long *p)
101 *p = res & ~mask; 101 *p = res & ~mask;
102 raw_local_irq_restore(flags); 102 raw_local_irq_restore(flags);
103 103
104 return res & mask; 104 return (res & mask) != 0;
105} 105}
106 106
107static inline int 107static inline int
@@ -118,7 +118,7 @@ ____atomic_test_and_change_bit(unsigned int bit, volatile unsigned long *p)
118 *p = res ^ mask; 118 *p = res ^ mask;
119 raw_local_irq_restore(flags); 119 raw_local_irq_restore(flags);
120 120
121 return res & mask; 121 return (res & mask) != 0;
122} 122}
123 123
124#include <asm-generic/bitops/non-atomic.h> 124#include <asm-generic/bitops/non-atomic.h>
diff --git a/arch/arm/include/asm/glue.h b/arch/arm/include/asm/glue.h
index a0e39d5d00c9..234a3fc1c78e 100644
--- a/arch/arm/include/asm/glue.h
+++ b/arch/arm/include/asm/glue.h
@@ -120,25 +120,39 @@
120#endif 120#endif
121 121
122/* 122/*
123 * Prefetch abort handler. If the CPU has an IFAR use that, otherwise 123 * Prefetch Abort Model
124 * use the address of the aborted instruction 124 * ================
125 *
126 * We have the following to choose from:
127 * legacy - no IFSR, no IFAR
128 * v6 - ARMv6: IFSR, no IFAR
129 * v7 - ARMv7: IFSR and IFAR
125 */ 130 */
131
126#undef CPU_PABORT_HANDLER 132#undef CPU_PABORT_HANDLER
127#undef MULTI_PABORT 133#undef MULTI_PABORT
128 134
129#ifdef CONFIG_CPU_PABRT_IFAR 135#ifdef CONFIG_CPU_PABRT_LEGACY
136# ifdef CPU_PABORT_HANDLER
137# define MULTI_PABORT 1
138# else
139# define CPU_PABORT_HANDLER legacy_pabort
140# endif
141#endif
142
143#ifdef CONFIG_CPU_PABRT_V6
130# ifdef CPU_PABORT_HANDLER 144# ifdef CPU_PABORT_HANDLER
131# define MULTI_PABORT 1 145# define MULTI_PABORT 1
132# else 146# else
133# define CPU_PABORT_HANDLER(reg, insn) mrc p15, 0, reg, cr6, cr0, 2 147# define CPU_PABORT_HANDLER v6_pabort
134# endif 148# endif
135#endif 149#endif
136 150
137#ifdef CONFIG_CPU_PABRT_NOIFAR 151#ifdef CONFIG_CPU_PABRT_V7
138# ifdef CPU_PABORT_HANDLER 152# ifdef CPU_PABORT_HANDLER
139# define MULTI_PABORT 1 153# define MULTI_PABORT 1
140# else 154# else
141# define CPU_PABORT_HANDLER(reg, insn) mov reg, insn 155# define CPU_PABORT_HANDLER v7_pabort
142# endif 156# endif
143#endif 157#endif
144 158
diff --git a/arch/arm/include/asm/hardware/iop3xx.h b/arch/arm/include/asm/hardware/iop3xx.h
index 4b8e7f559929..8d60ad267e3a 100644
--- a/arch/arm/include/asm/hardware/iop3xx.h
+++ b/arch/arm/include/asm/hardware/iop3xx.h
@@ -215,6 +215,7 @@ extern int iop3xx_get_init_atu(void);
215 * IOP3XX I/O and Mem space regions for PCI autoconfiguration 215 * IOP3XX I/O and Mem space regions for PCI autoconfiguration
216 */ 216 */
217#define IOP3XX_PCI_LOWER_MEM_PA 0x80000000 217#define IOP3XX_PCI_LOWER_MEM_PA 0x80000000
218#define IOP3XX_PCI_MEM_WINDOW_SIZE 0x08000000
218 219
219#define IOP3XX_PCI_IO_WINDOW_SIZE 0x00010000 220#define IOP3XX_PCI_IO_WINDOW_SIZE 0x00010000
220#define IOP3XX_PCI_LOWER_IO_PA 0x90000000 221#define IOP3XX_PCI_LOWER_IO_PA 0x90000000
diff --git a/arch/arm/include/asm/smp_plat.h b/arch/arm/include/asm/smp_plat.h
new file mode 100644
index 000000000000..59303e200845
--- /dev/null
+++ b/arch/arm/include/asm/smp_plat.h
@@ -0,0 +1,16 @@
1/*
2 * ARM specific SMP header, this contains our implementation
3 * details.
4 */
5#ifndef __ASMARM_SMP_PLAT_H
6#define __ASMARM_SMP_PLAT_H
7
8#include <asm/cputype.h>
9
10/* all SMP configurations have the extended CPUID registers */
11static inline int tlb_ops_need_broadcast(void)
12{
13 return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 2;
14}
15
16#endif
diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h
index 89f7eade20af..7020217fc49f 100644
--- a/arch/arm/include/asm/unistd.h
+++ b/arch/arm/include/asm/unistd.h
@@ -456,6 +456,7 @@
456 * Unimplemented (or alternatively implemented) syscalls 456 * Unimplemented (or alternatively implemented) syscalls
457 */ 457 */
458#define __IGNORE_fadvise64_64 1 458#define __IGNORE_fadvise64_64 1
459#define __IGNORE_migrate_pages 1
459 460
460#endif /* __KERNEL__ */ 461#endif /* __KERNEL__ */
461#endif /* __ASM_ARM_UNISTD_H */ 462#endif /* __ASM_ARM_UNISTD_H */
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 0a2ba51cf35d..322410be573c 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -311,22 +311,16 @@ __pabt_svc:
311 tst r3, #PSR_I_BIT 311 tst r3, #PSR_I_BIT
312 biceq r9, r9, #PSR_I_BIT 312 biceq r9, r9, #PSR_I_BIT
313 313
314 @
315 @ set args, then call main handler
316 @
317 @ r0 - address of faulting instruction
318 @ r1 - pointer to registers on stack
319 @
320#ifdef MULTI_PABORT
321 mov r0, r2 @ pass address of aborted instruction. 314 mov r0, r2 @ pass address of aborted instruction.
315#ifdef MULTI_PABORT
322 ldr r4, .LCprocfns 316 ldr r4, .LCprocfns
323 mov lr, pc 317 mov lr, pc
324 ldr pc, [r4, #PROCESSOR_PABT_FUNC] 318 ldr pc, [r4, #PROCESSOR_PABT_FUNC]
325#else 319#else
326 CPU_PABORT_HANDLER(r0, r2) 320 bl CPU_PABORT_HANDLER
327#endif 321#endif
328 msr cpsr_c, r9 @ Maybe enable interrupts 322 msr cpsr_c, r9 @ Maybe enable interrupts
329 mov r1, sp @ regs 323 mov r2, sp @ regs
330 bl do_PrefetchAbort @ call abort handler 324 bl do_PrefetchAbort @ call abort handler
331 325
332 @ 326 @
@@ -701,16 +695,16 @@ ENDPROC(__und_usr_unknown)
701__pabt_usr: 695__pabt_usr:
702 usr_entry 696 usr_entry
703 697
704#ifdef MULTI_PABORT
705 mov r0, r2 @ pass address of aborted instruction. 698 mov r0, r2 @ pass address of aborted instruction.
699#ifdef MULTI_PABORT
706 ldr r4, .LCprocfns 700 ldr r4, .LCprocfns
707 mov lr, pc 701 mov lr, pc
708 ldr pc, [r4, #PROCESSOR_PABT_FUNC] 702 ldr pc, [r4, #PROCESSOR_PABT_FUNC]
709#else 703#else
710 CPU_PABORT_HANDLER(r0, r2) 704 bl CPU_PABORT_HANDLER
711#endif 705#endif
712 enable_irq @ Enable interrupts 706 enable_irq @ Enable interrupts
713 mov r1, sp @ regs 707 mov r2, sp @ regs
714 bl do_PrefetchAbort @ call abort handler 708 bl do_PrefetchAbort @ call abort handler
715 UNWIND(.fnend ) 709 UNWIND(.fnend )
716 /* fall through */ 710 /* fall through */
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 807cfebb0f44..f0fe95b7085d 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -126,7 +126,7 @@ ENTRY(__gnu_mcount_nc)
126 cmp r0, r2 126 cmp r0, r2
127 bne gnu_trace 127 bne gnu_trace
128 ldmia sp!, {r0-r3, ip, lr} 128 ldmia sp!, {r0-r3, ip, lr}
129 bx ip 129 mov pc, ip
130 130
131gnu_trace: 131gnu_trace:
132 ldr r1, [sp, #20] @ lr of instrumented routine 132 ldr r1, [sp, #20] @ lr of instrumented routine
@@ -135,7 +135,7 @@ gnu_trace:
135 mov lr, pc 135 mov lr, pc
136 mov pc, r2 136 mov pc, r2
137 ldmia sp!, {r0-r3, ip, lr} 137 ldmia sp!, {r0-r3, ip, lr}
138 bx ip 138 mov pc, ip
139 139
140ENTRY(mcount) 140ENTRY(mcount)
141 stmdb sp!, {r0-r3, lr} 141 stmdb sp!, {r0-r3, lr}
@@ -425,13 +425,6 @@ sys_mmap2:
425#endif 425#endif
426ENDPROC(sys_mmap2) 426ENDPROC(sys_mmap2)
427 427
428ENTRY(pabort_ifar)
429 mrc p15, 0, r0, cr6, cr0, 2
430ENTRY(pabort_noifar)
431 mov pc, lr
432ENDPROC(pabort_ifar)
433ENDPROC(pabort_noifar)
434
435#ifdef CONFIG_OABI_COMPAT 428#ifdef CONFIG_OABI_COMPAT
436 429
437/* 430/*
diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S
index 93ad576b2d74..885a7214418d 100644
--- a/arch/arm/kernel/head-common.S
+++ b/arch/arm/kernel/head-common.S
@@ -13,6 +13,7 @@
13 13
14#define ATAG_CORE 0x54410001 14#define ATAG_CORE 0x54410001
15#define ATAG_CORE_SIZE ((2*4 + 3*4) >> 2) 15#define ATAG_CORE_SIZE ((2*4 + 3*4) >> 2)
16#define ATAG_CORE_SIZE_EMPTY ((2*4) >> 2)
16 17
17 .align 2 18 .align 2
18 .type __switch_data, %object 19 .type __switch_data, %object
@@ -251,7 +252,8 @@ __vet_atags:
251 bne 1f 252 bne 1f
252 253
253 ldr r5, [r2, #0] @ is first tag ATAG_CORE? 254 ldr r5, [r2, #0] @ is first tag ATAG_CORE?
254 subs r5, r5, #ATAG_CORE_SIZE 255 cmp r5, #ATAG_CORE_SIZE
256 cmpne r5, #ATAG_CORE_SIZE_EMPTY
255 bne 1f 257 bne 1f
256 ldr r5, [r2, #4] 258 ldr r5, [r2, #4]
257 ldr r6, =ATAG_CORE 259 ldr r6, =ATAG_CORE
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index e0d32770bb3d..57162af53dc9 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -36,6 +36,7 @@
36#include <asm/tlbflush.h> 36#include <asm/tlbflush.h>
37#include <asm/ptrace.h> 37#include <asm/ptrace.h>
38#include <asm/localtimer.h> 38#include <asm/localtimer.h>
39#include <asm/smp_plat.h>
39 40
40/* 41/*
41 * as from 2.5, kernels no longer have an init_tasks structure 42 * as from 2.5, kernels no longer have an init_tasks structure
@@ -153,7 +154,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
153/* 154/*
154 * __cpu_disable runs on the processor to be shutdown. 155 * __cpu_disable runs on the processor to be shutdown.
155 */ 156 */
156int __cpuexit __cpu_disable(void) 157int __cpu_disable(void)
157{ 158{
158 unsigned int cpu = smp_processor_id(); 159 unsigned int cpu = smp_processor_id();
159 struct task_struct *p; 160 struct task_struct *p;
@@ -200,7 +201,7 @@ int __cpuexit __cpu_disable(void)
200 * called on the thread which is asking for a CPU to be shutdown - 201 * called on the thread which is asking for a CPU to be shutdown -
201 * waits until shutdown has completed, or it is timed out. 202 * waits until shutdown has completed, or it is timed out.
202 */ 203 */
203void __cpuexit __cpu_die(unsigned int cpu) 204void __cpu_die(unsigned int cpu)
204{ 205{
205 if (!platform_cpu_kill(cpu)) 206 if (!platform_cpu_kill(cpu))
206 printk("CPU%u: unable to kill\n", cpu); 207 printk("CPU%u: unable to kill\n", cpu);
@@ -214,7 +215,7 @@ void __cpuexit __cpu_die(unsigned int cpu)
214 * of the other hotplug-cpu capable cores, so presumably coming 215 * of the other hotplug-cpu capable cores, so presumably coming
215 * out of idle fixes this. 216 * out of idle fixes this.
216 */ 217 */
217void __cpuexit cpu_die(void) 218void __ref cpu_die(void)
218{ 219{
219 unsigned int cpu = smp_processor_id(); 220 unsigned int cpu = smp_processor_id();
220 221
@@ -586,12 +587,6 @@ struct tlb_args {
586 unsigned long ta_end; 587 unsigned long ta_end;
587}; 588};
588 589
589/* all SMP configurations have the extended CPUID registers */
590static inline int tlb_ops_need_broadcast(void)
591{
592 return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 2;
593}
594
595static inline void ipi_flush_tlb_all(void *ignored) 590static inline void ipi_flush_tlb_all(void *ignored)
596{ 591{
597 local_flush_tlb_all(); 592 local_flush_tlb_all();
diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c
index d8c88c633c6f..a73a34dccf2a 100644
--- a/arch/arm/kernel/smp_twd.c
+++ b/arch/arm/kernel/smp_twd.c
@@ -166,10 +166,12 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk)
166 clockevents_register_device(clk); 166 clockevents_register_device(clk);
167} 167}
168 168
169#ifdef CONFIG_HOTPLUG_CPU
169/* 170/*
170 * take a local timer down 171 * take a local timer down
171 */ 172 */
172void __cpuexit twd_timer_stop(void) 173void twd_timer_stop(void)
173{ 174{
174 __raw_writel(0, twd_base + TWD_TIMER_CONTROL); 175 __raw_writel(0, twd_base + TWD_TIMER_CONTROL);
175} 176}
177#endif
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index 4cdc4a0bd02d..d38cdf2c8276 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -21,6 +21,7 @@
21#include <linux/interrupt.h> 21#include <linux/interrupt.h>
22#include <linux/time.h> 22#include <linux/time.h>
23#include <linux/init.h> 23#include <linux/init.h>
24#include <linux/sched.h>
24#include <linux/smp.h> 25#include <linux/smp.h>
25#include <linux/timex.h> 26#include <linux/timex.h>
26#include <linux/errno.h> 27#include <linux/errno.h>
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 57eb0f6f6005..f838f36eb702 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -45,21 +45,21 @@ static int __init user_debug_setup(char *str)
45__setup("user_debug=", user_debug_setup); 45__setup("user_debug=", user_debug_setup);
46#endif 46#endif
47 47
48static void dump_mem(const char *str, unsigned long bottom, unsigned long top); 48static void dump_mem(const char *, const char *, unsigned long, unsigned long);
49 49
50void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame) 50void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame)
51{ 51{
52#ifdef CONFIG_KALLSYMS 52#ifdef CONFIG_KALLSYMS
53 printk("[<%08lx>] ", where); 53 char sym1[KSYM_SYMBOL_LEN], sym2[KSYM_SYMBOL_LEN];
54 print_symbol("(%s) ", where); 54 sprint_symbol(sym1, where);
55 printk("from [<%08lx>] ", from); 55 sprint_symbol(sym2, from);
56 print_symbol("(%s)\n", from); 56 printk("[<%08lx>] (%s) from [<%08lx>] (%s)\n", where, sym1, from, sym2);
57#else 57#else
58 printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from); 58 printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from);
59#endif 59#endif
60 60
61 if (in_exception_text(where)) 61 if (in_exception_text(where))
62 dump_mem("Exception stack", frame + 4, frame + 4 + sizeof(struct pt_regs)); 62 dump_mem("", "Exception stack", frame + 4, frame + 4 + sizeof(struct pt_regs));
63} 63}
64 64
65#ifndef CONFIG_ARM_UNWIND 65#ifndef CONFIG_ARM_UNWIND
@@ -81,9 +81,10 @@ static int verify_stack(unsigned long sp)
81/* 81/*
82 * Dump out the contents of some memory nicely... 82 * Dump out the contents of some memory nicely...
83 */ 83 */
84static void dump_mem(const char *str, unsigned long bottom, unsigned long top) 84static void dump_mem(const char *lvl, const char *str, unsigned long bottom,
85 unsigned long top)
85{ 86{
86 unsigned long p = bottom & ~31; 87 unsigned long first;
87 mm_segment_t fs; 88 mm_segment_t fs;
88 int i; 89 int i;
89 90
@@ -95,33 +96,37 @@ static void dump_mem(const char *str, unsigned long bottom, unsigned long top)
95 fs = get_fs(); 96 fs = get_fs();
96 set_fs(KERNEL_DS); 97 set_fs(KERNEL_DS);
97 98
98 printk("%s(0x%08lx to 0x%08lx)\n", str, bottom, top); 99 printk("%s%s(0x%08lx to 0x%08lx)\n", lvl, str, bottom, top);
99 100
100 for (p = bottom & ~31; p < top;) { 101 for (first = bottom & ~31; first < top; first += 32) {
101 printk("%04lx: ", p & 0xffff); 102 unsigned long p;
103 char str[sizeof(" 12345678") * 8 + 1];
102 104
103 for (i = 0; i < 8; i++, p += 4) { 105 memset(str, ' ', sizeof(str));
104 unsigned int val; 106 str[sizeof(str) - 1] = '\0';
105 107
106 if (p < bottom || p >= top) 108 for (p = first, i = 0; i < 8 && p < top; i++, p += 4) {
107 printk(" "); 109 if (p >= bottom && p < top) {
108 else { 110 unsigned long val;
109 __get_user(val, (unsigned long *)p); 111 if (__get_user(val, (unsigned long *)p) == 0)
110 printk("%08x ", val); 112 sprintf(str + i * 9, " %08lx", val);
113 else
114 sprintf(str + i * 9, " ????????");
111 } 115 }
112 } 116 }
113 printk ("\n"); 117 printk("%s%04lx:%s\n", lvl, first & 0xffff, str);
114 } 118 }
115 119
116 set_fs(fs); 120 set_fs(fs);
117} 121}
118 122
119static void dump_instr(struct pt_regs *regs) 123static void dump_instr(const char *lvl, struct pt_regs *regs)
120{ 124{
121 unsigned long addr = instruction_pointer(regs); 125 unsigned long addr = instruction_pointer(regs);
122 const int thumb = thumb_mode(regs); 126 const int thumb = thumb_mode(regs);
123 const int width = thumb ? 4 : 8; 127 const int width = thumb ? 4 : 8;
124 mm_segment_t fs; 128 mm_segment_t fs;
129 char str[sizeof("00000000 ") * 5 + 2 + 1], *p = str;
125 int i; 130 int i;
126 131
127 /* 132 /*
@@ -132,7 +137,6 @@ static void dump_instr(struct pt_regs *regs)
132 fs = get_fs(); 137 fs = get_fs();
133 set_fs(KERNEL_DS); 138 set_fs(KERNEL_DS);
134 139
135 printk("Code: ");
136 for (i = -4; i < 1; i++) { 140 for (i = -4; i < 1; i++) {
137 unsigned int val, bad; 141 unsigned int val, bad;
138 142
@@ -142,13 +146,14 @@ static void dump_instr(struct pt_regs *regs)
142 bad = __get_user(val, &((u32 *)addr)[i]); 146 bad = __get_user(val, &((u32 *)addr)[i]);
143 147
144 if (!bad) 148 if (!bad)
145 printk(i == 0 ? "(%0*x) " : "%0*x ", width, val); 149 p += sprintf(p, i == 0 ? "(%0*x) " : "%0*x ",
150 width, val);
146 else { 151 else {
147 printk("bad PC value."); 152 p += sprintf(p, "bad PC value");
148 break; 153 break;
149 } 154 }
150 } 155 }
151 printk("\n"); 156 printk("%sCode: %s\n", lvl, str);
152 157
153 set_fs(fs); 158 set_fs(fs);
154} 159}
@@ -224,18 +229,19 @@ static void __die(const char *str, int err, struct thread_info *thread, struct p
224 struct task_struct *tsk = thread->task; 229 struct task_struct *tsk = thread->task;
225 static int die_counter; 230 static int die_counter;
226 231
227 printk("Internal error: %s: %x [#%d]" S_PREEMPT S_SMP "\n", 232 printk(KERN_EMERG "Internal error: %s: %x [#%d]" S_PREEMPT S_SMP "\n",
228 str, err, ++die_counter); 233 str, err, ++die_counter);
234 sysfs_printk_last_file();
229 print_modules(); 235 print_modules();
230 __show_regs(regs); 236 __show_regs(regs);
231 printk("Process %s (pid: %d, stack limit = 0x%p)\n", 237 printk(KERN_EMERG "Process %.*s (pid: %d, stack limit = 0x%p)\n",
232 tsk->comm, task_pid_nr(tsk), thread + 1); 238 TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk), thread + 1);
233 239
234 if (!user_mode(regs) || in_interrupt()) { 240 if (!user_mode(regs) || in_interrupt()) {
235 dump_mem("Stack: ", regs->ARM_sp, 241 dump_mem(KERN_EMERG, "Stack: ", regs->ARM_sp,
236 THREAD_SIZE + (unsigned long)task_stack_page(tsk)); 242 THREAD_SIZE + (unsigned long)task_stack_page(tsk));
237 dump_backtrace(regs, tsk); 243 dump_backtrace(regs, tsk);
238 dump_instr(regs); 244 dump_instr(KERN_EMERG, regs);
239 } 245 }
240} 246}
241 247
@@ -250,13 +256,14 @@ NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
250 256
251 oops_enter(); 257 oops_enter();
252 258
253 console_verbose();
254 spin_lock_irq(&die_lock); 259 spin_lock_irq(&die_lock);
260 console_verbose();
255 bust_spinlocks(1); 261 bust_spinlocks(1);
256 __die(str, err, thread, regs); 262 __die(str, err, thread, regs);
257 bust_spinlocks(0); 263 bust_spinlocks(0);
258 add_taint(TAINT_DIE); 264 add_taint(TAINT_DIE);
259 spin_unlock_irq(&die_lock); 265 spin_unlock_irq(&die_lock);
266 oops_exit();
260 267
261 if (in_interrupt()) 268 if (in_interrupt())
262 panic("Fatal exception in interrupt"); 269 panic("Fatal exception in interrupt");
@@ -264,7 +271,6 @@ NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
264 if (panic_on_oops) 271 if (panic_on_oops)
265 panic("Fatal exception"); 272 panic("Fatal exception");
266 273
267 oops_exit();
268 do_exit(SIGSEGV); 274 do_exit(SIGSEGV);
269} 275}
270 276
@@ -349,7 +355,7 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
349 if (user_debug & UDBG_UNDEFINED) { 355 if (user_debug & UDBG_UNDEFINED) {
350 printk(KERN_INFO "%s (%d): undefined instruction: pc=%p\n", 356 printk(KERN_INFO "%s (%d): undefined instruction: pc=%p\n",
351 current->comm, task_pid_nr(current), pc); 357 current->comm, task_pid_nr(current), pc);
352 dump_instr(regs); 358 dump_instr(KERN_INFO, regs);
353 } 359 }
354#endif 360#endif
355 361
@@ -400,7 +406,7 @@ static int bad_syscall(int n, struct pt_regs *regs)
400 if (user_debug & UDBG_SYSCALL) { 406 if (user_debug & UDBG_SYSCALL) {
401 printk(KERN_ERR "[%d] %s: obsolete system call %08x.\n", 407 printk(KERN_ERR "[%d] %s: obsolete system call %08x.\n",
402 task_pid_nr(current), current->comm, n); 408 task_pid_nr(current), current->comm, n);
403 dump_instr(regs); 409 dump_instr(KERN_ERR, regs);
404 } 410 }
405#endif 411#endif
406 412
@@ -418,12 +424,14 @@ static int bad_syscall(int n, struct pt_regs *regs)
418static inline void 424static inline void
419do_cache_op(unsigned long start, unsigned long end, int flags) 425do_cache_op(unsigned long start, unsigned long end, int flags)
420{ 426{
427 struct mm_struct *mm = current->active_mm;
421 struct vm_area_struct *vma; 428 struct vm_area_struct *vma;
422 429
423 if (end < start || flags) 430 if (end < start || flags)
424 return; 431 return;
425 432
426 vma = find_vma(current->active_mm, start); 433 down_read(&mm->mmap_sem);
434 vma = find_vma(mm, start);
427 if (vma && vma->vm_start < end) { 435 if (vma && vma->vm_start < end) {
428 if (start < vma->vm_start) 436 if (start < vma->vm_start)
429 start = vma->vm_start; 437 start = vma->vm_start;
@@ -432,6 +440,7 @@ do_cache_op(unsigned long start, unsigned long end, int flags)
432 440
433 flush_cache_user_range(vma, start, end); 441 flush_cache_user_range(vma, start, end);
434 } 442 }
443 up_read(&mm->mmap_sem);
435} 444}
436 445
437/* 446/*
@@ -576,7 +585,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
576 if (user_debug & UDBG_SYSCALL) { 585 if (user_debug & UDBG_SYSCALL) {
577 printk("[%d] %s: arm syscall %d\n", 586 printk("[%d] %s: arm syscall %d\n",
578 task_pid_nr(current), current->comm, no); 587 task_pid_nr(current), current->comm, no);
579 dump_instr(regs); 588 dump_instr("", regs);
580 if (user_mode(regs)) { 589 if (user_mode(regs)) {
581 __show_regs(regs); 590 __show_regs(regs);
582 c_backtrace(regs->ARM_fp, processor_mode(regs)); 591 c_backtrace(regs->ARM_fp, processor_mode(regs));
@@ -653,7 +662,7 @@ baddataabort(int code, unsigned long instr, struct pt_regs *regs)
653 if (user_debug & UDBG_BADABORT) { 662 if (user_debug & UDBG_BADABORT) {
654 printk(KERN_ERR "[%d] %s: bad data abort: code %d instr 0x%08lx\n", 663 printk(KERN_ERR "[%d] %s: bad data abort: code %d instr 0x%08lx\n",
655 task_pid_nr(current), current->comm, code, instr); 664 task_pid_nr(current), current->comm, code, instr);
656 dump_instr(regs); 665 dump_instr(KERN_ERR, regs);
657 show_pte(current->mm, addr); 666 show_pte(current->mm, addr);
658 } 667 }
659#endif 668#endif
diff --git a/arch/arm/mach-bcmring/core.c b/arch/arm/mach-bcmring/core.c
index 492c649f451e..e590bbe0a7b4 100644
--- a/arch/arm/mach-bcmring/core.c
+++ b/arch/arm/mach-bcmring/core.c
@@ -31,7 +31,6 @@
31#include <linux/clocksource.h> 31#include <linux/clocksource.h>
32#include <linux/clockchips.h> 32#include <linux/clockchips.h>
33 33
34#include <linux/amba/bus.h>
35#include <mach/csp/mm_addr.h> 34#include <mach/csp/mm_addr.h>
36#include <mach/hardware.h> 35#include <mach/hardware.h>
37#include <asm/clkdev.h> 36#include <asm/clkdev.h>
@@ -45,7 +44,6 @@
45#include <asm/mach/irq.h> 44#include <asm/mach/irq.h>
46#include <asm/mach/time.h> 45#include <asm/mach/time.h>
47#include <asm/mach/map.h> 46#include <asm/mach/map.h>
48#include <asm/mach/mmc.h>
49 47
50#include <cfg_global.h> 48#include <cfg_global.h>
51 49
@@ -273,12 +271,12 @@ static struct irqaction bcmring_timer_irq = {
273 .handler = bcmring_timer_interrupt, 271 .handler = bcmring_timer_interrupt,
274}; 272};
275 273
276static cycle_t bcmring_get_cycles_timer1(void) 274static cycle_t bcmring_get_cycles_timer1(struct clocksource *cs)
277{ 275{
278 return ~readl(TIMER1_VA_BASE + TIMER_VALUE); 276 return ~readl(TIMER1_VA_BASE + TIMER_VALUE);
279} 277}
280 278
281static cycle_t bcmring_get_cycles_timer3(void) 279static cycle_t bcmring_get_cycles_timer3(struct clocksource *cs)
282{ 280{
283 return ~readl(TIMER3_VA_BASE + TIMER_VALUE); 281 return ~readl(TIMER3_VA_BASE + TIMER_VALUE);
284} 282}
diff --git a/arch/arm/mach-bcmring/include/mach/system.h b/arch/arm/mach-bcmring/include/mach/system.h
index cdbf93c694a6..38b37060d426 100644
--- a/arch/arm/mach-bcmring/include/mach/system.h
+++ b/arch/arm/mach-bcmring/include/mach/system.h
@@ -29,7 +29,7 @@ static inline void arch_idle(void)
29 cpu_do_idle(); 29 cpu_do_idle();
30} 30}
31 31
32static inline void arch_reset(char mode, char *cmd) 32static inline void arch_reset(char mode, const char *cmd)
33{ 33{
34 printk("arch_reset:%c %x\n", mode, bcmring_arch_warm_reboot); 34 printk("arch_reset:%c %x\n", mode, bcmring_arch_warm_reboot);
35 35
diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c
index a1d5e7dac741..52dd8046b305 100644
--- a/arch/arm/mach-davinci/board-dm365-evm.c
+++ b/arch/arm/mach-davinci/board-dm365-evm.c
@@ -35,7 +35,6 @@
35#include <mach/common.h> 35#include <mach/common.h>
36#include <mach/i2c.h> 36#include <mach/i2c.h>
37#include <mach/serial.h> 37#include <mach/serial.h>
38#include <mach/common.h>
39#include <mach/mmc.h> 38#include <mach/mmc.h>
40#include <mach/nand.h> 39#include <mach/nand.h>
41 40
diff --git a/arch/arm/mach-ep93xx/Kconfig b/arch/arm/mach-ep93xx/Kconfig
index d7291c682a64..9167c3d2a5ed 100644
--- a/arch/arm/mach-ep93xx/Kconfig
+++ b/arch/arm/mach-ep93xx/Kconfig
@@ -17,13 +17,31 @@ config EP93XX_SDCE3_SYNC_PHYS_OFFSET
17 bool "0x00000000 - SDCE3/SyncBoot" 17 bool "0x00000000 - SDCE3/SyncBoot"
18 help 18 help
19 Select this option if you want support for EP93xx boards with the 19 Select this option if you want support for EP93xx boards with the
20 first SDRAM bank at 0x00000000 20 first SDRAM bank at 0x00000000.
21 21
22config EP93XX_SDCE0_PHYS_OFFSET 22config EP93XX_SDCE0_PHYS_OFFSET
23 bool "0xc0000000 - SDCEO" 23 bool "0xc0000000 - SDCEO"
24 help 24 help
25 Select this option if you want support for EP93xx boards with the 25 Select this option if you want support for EP93xx boards with the
26 first SDRAM bank at 0xc0000000 26 first SDRAM bank at 0xc0000000.
27
28config EP93XX_SDCE1_PHYS_OFFSET
29 bool "0xd0000000 - SDCE1"
30 help
31 Select this option if you want support for EP93xx boards with the
32 first SDRAM bank at 0xd0000000.
33
34config EP93XX_SDCE2_PHYS_OFFSET
35 bool "0xe0000000 - SDCE2"
36 help
37 Select this option if you want support for EP93xx boards with the
38 first SDRAM bank at 0xe0000000.
39
40config EP93XX_SDCE3_ASYNC_PHYS_OFFSET
41 bool "0xf0000000 - SDCE3/AsyncBoot"
42 help
43 Select this option if you want support for EP93xx boards with the
44 first SDRAM bank at 0xf0000000.
27 45
28endchoice 46endchoice
29 47
@@ -112,28 +130,36 @@ config MACH_MICRO9
112 bool 130 bool
113 131
114config MACH_MICRO9H 132config MACH_MICRO9H
115 bool "Support Contec Hypercontrol Micro9-H" 133 bool "Support Contec Micro9-High"
116 depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET 134 depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET
117 select MACH_MICRO9 135 select MACH_MICRO9
118 help 136 help
119 Say 'Y' here if you want your kernel to support the 137 Say 'Y' here if you want your kernel to support the
120 Contec Hypercontrol Micro9-H board. 138 Contec Micro9-High board.
121 139
122config MACH_MICRO9M 140config MACH_MICRO9M
123 bool "Support Contec Hypercontrol Micro9-M" 141 bool "Support Contec Micro9-Mid"
124 depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET 142 depends on EP93XX_SDCE3_ASYNC_PHYS_OFFSET
125 select MACH_MICRO9 143 select MACH_MICRO9
126 help 144 help
127 Say 'Y' here if you want your kernel to support the 145 Say 'Y' here if you want your kernel to support the
128 Contec Hypercontrol Micro9-M board. 146 Contec Micro9-Mid board.
129 147
130config MACH_MICRO9L 148config MACH_MICRO9L
131 bool "Support Contec Hypercontrol Micro9-L" 149 bool "Support Contec Micro9-Lite"
132 depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET 150 depends on EP93XX_SDCE3_SYNC_PHYS_OFFSET
133 select MACH_MICRO9 151 select MACH_MICRO9
134 help 152 help
135 Say 'Y' here if you want your kernel to support the 153 Say 'Y' here if you want your kernel to support the
136 Contec Hypercontrol Micro9-L board. 154 Contec Micro9-Lite board.
155
156config MACH_MICRO9S
157 bool "Support Contec Micro9-Slim"
158 depends on EP93XX_SDCE3_ASYNC_PHYS_OFFSET
159 select MACH_MICRO9
160 help
161 Say 'Y' here if you want your kernel to support the
162 Contec Micro9-Slim board.
137 163
138config MACH_TS72XX 164config MACH_TS72XX
139 bool "Support Technologic Systems TS-72xx SBC" 165 bool "Support Technologic Systems TS-72xx SBC"
diff --git a/arch/arm/mach-ep93xx/Makefile.boot b/arch/arm/mach-ep93xx/Makefile.boot
index 27a085a8f12a..0ad33f15c622 100644
--- a/arch/arm/mach-ep93xx/Makefile.boot
+++ b/arch/arm/mach-ep93xx/Makefile.boot
@@ -3,3 +3,12 @@ params_phys-$(CONFIG_EP93XX_SDCE3_SYNC_PHYS_OFFSET) := 0x00000100
3 3
4 zreladdr-$(CONFIG_EP93XX_SDCE0_PHYS_OFFSET) := 0xc0008000 4 zreladdr-$(CONFIG_EP93XX_SDCE0_PHYS_OFFSET) := 0xc0008000
5params_phys-$(CONFIG_EP93XX_SDCE0_PHYS_OFFSET) := 0xc0000100 5params_phys-$(CONFIG_EP93XX_SDCE0_PHYS_OFFSET) := 0xc0000100
6
7 zreladdr-$(CONFIG_EP93XX_SDCE1_PHYS_OFFSET) := 0xd0008000
8params_phys-$(CONFIG_EP93XX_SDCE1_PHYS_OFFSET) := 0xd0000100
9
10 zreladdr-$(CONFIG_EP93XX_SDCE2_PHYS_OFFSET) := 0xe0008000
11params_phys-$(CONFIG_EP93XX_SDCE2_PHYS_OFFSET) := 0xe0000100
12
13 zreladdr-$(CONFIG_EP93XX_SDCE3_ASYNC_PHYS_OFFSET) := 0xf0008000
14params_phys-$(CONFIG_EP93XX_SDCE3_ASYNC_PHYS_OFFSET) := 0xf0000100
diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c
index dda19cd76194..1d0f9d8aff2e 100644
--- a/arch/arm/mach-ep93xx/clock.c
+++ b/arch/arm/mach-ep93xx/clock.c
@@ -16,13 +16,16 @@
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/string.h> 17#include <linux/string.h>
18#include <linux/io.h> 18#include <linux/io.h>
19#include <linux/spinlock.h>
20
21#include <mach/hardware.h>
19 22
20#include <asm/clkdev.h> 23#include <asm/clkdev.h>
21#include <asm/div64.h> 24#include <asm/div64.h>
22#include <mach/hardware.h>
23 25
24 26
25struct clk { 27struct clk {
28 struct clk *parent;
26 unsigned long rate; 29 unsigned long rate;
27 int users; 30 int users;
28 int sw_locked; 31 int sw_locked;
@@ -39,40 +42,60 @@ static unsigned long get_uart_rate(struct clk *clk);
39static int set_keytchclk_rate(struct clk *clk, unsigned long rate); 42static int set_keytchclk_rate(struct clk *clk, unsigned long rate);
40static int set_div_rate(struct clk *clk, unsigned long rate); 43static int set_div_rate(struct clk *clk, unsigned long rate);
41 44
45
46static struct clk clk_xtali = {
47 .rate = EP93XX_EXT_CLK_RATE,
48};
42static struct clk clk_uart1 = { 49static struct clk clk_uart1 = {
50 .parent = &clk_xtali,
43 .sw_locked = 1, 51 .sw_locked = 1,
44 .enable_reg = EP93XX_SYSCON_DEVCFG, 52 .enable_reg = EP93XX_SYSCON_DEVCFG,
45 .enable_mask = EP93XX_SYSCON_DEVCFG_U1EN, 53 .enable_mask = EP93XX_SYSCON_DEVCFG_U1EN,
46 .get_rate = get_uart_rate, 54 .get_rate = get_uart_rate,
47}; 55};
48static struct clk clk_uart2 = { 56static struct clk clk_uart2 = {
57 .parent = &clk_xtali,
49 .sw_locked = 1, 58 .sw_locked = 1,
50 .enable_reg = EP93XX_SYSCON_DEVCFG, 59 .enable_reg = EP93XX_SYSCON_DEVCFG,
51 .enable_mask = EP93XX_SYSCON_DEVCFG_U2EN, 60 .enable_mask = EP93XX_SYSCON_DEVCFG_U2EN,
52 .get_rate = get_uart_rate, 61 .get_rate = get_uart_rate,
53}; 62};
54static struct clk clk_uart3 = { 63static struct clk clk_uart3 = {
64 .parent = &clk_xtali,
55 .sw_locked = 1, 65 .sw_locked = 1,
56 .enable_reg = EP93XX_SYSCON_DEVCFG, 66 .enable_reg = EP93XX_SYSCON_DEVCFG,
57 .enable_mask = EP93XX_SYSCON_DEVCFG_U3EN, 67 .enable_mask = EP93XX_SYSCON_DEVCFG_U3EN,
58 .get_rate = get_uart_rate, 68 .get_rate = get_uart_rate,
59}; 69};
60static struct clk clk_pll1; 70static struct clk clk_pll1 = {
61static struct clk clk_f; 71 .parent = &clk_xtali,
62static struct clk clk_h; 72};
63static struct clk clk_p; 73static struct clk clk_f = {
64static struct clk clk_pll2; 74 .parent = &clk_pll1,
75};
76static struct clk clk_h = {
77 .parent = &clk_pll1,
78};
79static struct clk clk_p = {
80 .parent = &clk_pll1,
81};
82static struct clk clk_pll2 = {
83 .parent = &clk_xtali,
84};
65static struct clk clk_usb_host = { 85static struct clk clk_usb_host = {
86 .parent = &clk_pll2,
66 .enable_reg = EP93XX_SYSCON_PWRCNT, 87 .enable_reg = EP93XX_SYSCON_PWRCNT,
67 .enable_mask = EP93XX_SYSCON_PWRCNT_USH_EN, 88 .enable_mask = EP93XX_SYSCON_PWRCNT_USH_EN,
68}; 89};
69static struct clk clk_keypad = { 90static struct clk clk_keypad = {
91 .parent = &clk_xtali,
70 .sw_locked = 1, 92 .sw_locked = 1,
71 .enable_reg = EP93XX_SYSCON_KEYTCHCLKDIV, 93 .enable_reg = EP93XX_SYSCON_KEYTCHCLKDIV,
72 .enable_mask = EP93XX_SYSCON_KEYTCHCLKDIV_KEN, 94 .enable_mask = EP93XX_SYSCON_KEYTCHCLKDIV_KEN,
73 .set_rate = set_keytchclk_rate, 95 .set_rate = set_keytchclk_rate,
74}; 96};
75static struct clk clk_pwm = { 97static struct clk clk_pwm = {
98 .parent = &clk_xtali,
76 .rate = EP93XX_EXT_CLK_RATE, 99 .rate = EP93XX_EXT_CLK_RATE,
77}; 100};
78 101
@@ -85,50 +108,62 @@ static struct clk clk_video = {
85 108
86/* DMA Clocks */ 109/* DMA Clocks */
87static struct clk clk_m2p0 = { 110static struct clk clk_m2p0 = {
111 .parent = &clk_h,
88 .enable_reg = EP93XX_SYSCON_PWRCNT, 112 .enable_reg = EP93XX_SYSCON_PWRCNT,
89 .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P0, 113 .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P0,
90}; 114};
91static struct clk clk_m2p1 = { 115static struct clk clk_m2p1 = {
116 .parent = &clk_h,
92 .enable_reg = EP93XX_SYSCON_PWRCNT, 117 .enable_reg = EP93XX_SYSCON_PWRCNT,
93 .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P1, 118 .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P1,
94}; 119};
95static struct clk clk_m2p2 = { 120static struct clk clk_m2p2 = {
121 .parent = &clk_h,
96 .enable_reg = EP93XX_SYSCON_PWRCNT, 122 .enable_reg = EP93XX_SYSCON_PWRCNT,
97 .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P2, 123 .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P2,
98}; 124};
99static struct clk clk_m2p3 = { 125static struct clk clk_m2p3 = {
126 .parent = &clk_h,
100 .enable_reg = EP93XX_SYSCON_PWRCNT, 127 .enable_reg = EP93XX_SYSCON_PWRCNT,
101 .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P3, 128 .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P3,
102}; 129};
103static struct clk clk_m2p4 = { 130static struct clk clk_m2p4 = {
131 .parent = &clk_h,
104 .enable_reg = EP93XX_SYSCON_PWRCNT, 132 .enable_reg = EP93XX_SYSCON_PWRCNT,
105 .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P4, 133 .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P4,
106}; 134};
107static struct clk clk_m2p5 = { 135static struct clk clk_m2p5 = {
136 .parent = &clk_h,
108 .enable_reg = EP93XX_SYSCON_PWRCNT, 137 .enable_reg = EP93XX_SYSCON_PWRCNT,
109 .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P5, 138 .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P5,
110}; 139};
111static struct clk clk_m2p6 = { 140static struct clk clk_m2p6 = {
141 .parent = &clk_h,
112 .enable_reg = EP93XX_SYSCON_PWRCNT, 142 .enable_reg = EP93XX_SYSCON_PWRCNT,
113 .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P6, 143 .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P6,
114}; 144};
115static struct clk clk_m2p7 = { 145static struct clk clk_m2p7 = {
146 .parent = &clk_h,
116 .enable_reg = EP93XX_SYSCON_PWRCNT, 147 .enable_reg = EP93XX_SYSCON_PWRCNT,
117 .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P7, 148 .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P7,
118}; 149};
119static struct clk clk_m2p8 = { 150static struct clk clk_m2p8 = {
151 .parent = &clk_h,
120 .enable_reg = EP93XX_SYSCON_PWRCNT, 152 .enable_reg = EP93XX_SYSCON_PWRCNT,
121 .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P8, 153 .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P8,
122}; 154};
123static struct clk clk_m2p9 = { 155static struct clk clk_m2p9 = {
156 .parent = &clk_h,
124 .enable_reg = EP93XX_SYSCON_PWRCNT, 157 .enable_reg = EP93XX_SYSCON_PWRCNT,
125 .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P9, 158 .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2P9,
126}; 159};
127static struct clk clk_m2m0 = { 160static struct clk clk_m2m0 = {
161 .parent = &clk_h,
128 .enable_reg = EP93XX_SYSCON_PWRCNT, 162 .enable_reg = EP93XX_SYSCON_PWRCNT,
129 .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2M0, 163 .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2M0,
130}; 164};
131static struct clk clk_m2m1 = { 165static struct clk clk_m2m1 = {
166 .parent = &clk_h,
132 .enable_reg = EP93XX_SYSCON_PWRCNT, 167 .enable_reg = EP93XX_SYSCON_PWRCNT,
133 .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2M1, 168 .enable_mask = EP93XX_SYSCON_PWRCNT_DMA_M2M1,
134}; 169};
@@ -137,6 +172,7 @@ static struct clk clk_m2m1 = {
137 { .dev_id = dev, .con_id = con, .clk = ck } 172 { .dev_id = dev, .con_id = con, .clk = ck }
138 173
139static struct clk_lookup clocks[] = { 174static struct clk_lookup clocks[] = {
175 INIT_CK(NULL, "xtali", &clk_xtali),
140 INIT_CK("apb:uart1", NULL, &clk_uart1), 176 INIT_CK("apb:uart1", NULL, &clk_uart1),
141 INIT_CK("apb:uart2", NULL, &clk_uart2), 177 INIT_CK("apb:uart2", NULL, &clk_uart2),
142 INIT_CK("apb:uart3", NULL, &clk_uart3), 178 INIT_CK("apb:uart3", NULL, &clk_uart3),
@@ -163,48 +199,84 @@ static struct clk_lookup clocks[] = {
163 INIT_CK(NULL, "m2m1", &clk_m2m1), 199 INIT_CK(NULL, "m2m1", &clk_m2m1),
164}; 200};
165 201
202static DEFINE_SPINLOCK(clk_lock);
203
204static void __clk_enable(struct clk *clk)
205{
206 if (!clk->users++) {
207 if (clk->parent)
208 __clk_enable(clk->parent);
209
210 if (clk->enable_reg) {
211 u32 v;
212
213 v = __raw_readl(clk->enable_reg);
214 v |= clk->enable_mask;
215 if (clk->sw_locked)
216 ep93xx_syscon_swlocked_write(v, clk->enable_reg);
217 else
218 __raw_writel(v, clk->enable_reg);
219 }
220 }
221}
166 222
167int clk_enable(struct clk *clk) 223int clk_enable(struct clk *clk)
168{ 224{
169 if (!clk->users++ && clk->enable_reg) { 225 unsigned long flags;
170 u32 value;
171 226
172 value = __raw_readl(clk->enable_reg); 227 if (!clk)
173 value |= clk->enable_mask; 228 return -EINVAL;
174 if (clk->sw_locked) 229
175 ep93xx_syscon_swlocked_write(value, clk->enable_reg); 230 spin_lock_irqsave(&clk_lock, flags);
176 else 231 __clk_enable(clk);
177 __raw_writel(value, clk->enable_reg); 232 spin_unlock_irqrestore(&clk_lock, flags);
178 }
179 233
180 return 0; 234 return 0;
181} 235}
182EXPORT_SYMBOL(clk_enable); 236EXPORT_SYMBOL(clk_enable);
183 237
184void clk_disable(struct clk *clk) 238static void __clk_disable(struct clk *clk)
185{ 239{
186 if (!--clk->users && clk->enable_reg) { 240 if (!--clk->users) {
187 u32 value; 241 if (clk->enable_reg) {
242 u32 v;
243
244 v = __raw_readl(clk->enable_reg);
245 v &= ~clk->enable_mask;
246 if (clk->sw_locked)
247 ep93xx_syscon_swlocked_write(v, clk->enable_reg);
248 else
249 __raw_writel(v, clk->enable_reg);
250 }
188 251
189 value = __raw_readl(clk->enable_reg); 252 if (clk->parent)
190 value &= ~clk->enable_mask; 253 __clk_disable(clk->parent);
191 if (clk->sw_locked)
192 ep93xx_syscon_swlocked_write(value, clk->enable_reg);
193 else
194 __raw_writel(value, clk->enable_reg);
195 } 254 }
196} 255}
256
257void clk_disable(struct clk *clk)
258{
259 unsigned long flags;
260
261 if (!clk)
262 return;
263
264 spin_lock_irqsave(&clk_lock, flags);
265 __clk_disable(clk);
266 spin_unlock_irqrestore(&clk_lock, flags);
267}
197EXPORT_SYMBOL(clk_disable); 268EXPORT_SYMBOL(clk_disable);
198 269
199static unsigned long get_uart_rate(struct clk *clk) 270static unsigned long get_uart_rate(struct clk *clk)
200{ 271{
272 unsigned long rate = clk_get_rate(clk->parent);
201 u32 value; 273 u32 value;
202 274
203 value = __raw_readl(EP93XX_SYSCON_PWRCNT); 275 value = __raw_readl(EP93XX_SYSCON_PWRCNT);
204 if (value & EP93XX_SYSCON_PWRCNT_UARTBAUD) 276 if (value & EP93XX_SYSCON_PWRCNT_UARTBAUD)
205 return EP93XX_EXT_CLK_RATE; 277 return rate;
206 else 278 else
207 return EP93XX_EXT_CLK_RATE / 2; 279 return rate / 2;
208} 280}
209 281
210unsigned long clk_get_rate(struct clk *clk) 282unsigned long clk_get_rate(struct clk *clk)
@@ -244,16 +316,16 @@ static int set_keytchclk_rate(struct clk *clk, unsigned long rate)
244 return 0; 316 return 0;
245} 317}
246 318
247static unsigned long calc_clk_div(unsigned long rate, int *psel, int *esel, 319static int calc_clk_div(struct clk *clk, unsigned long rate,
248 int *pdiv, int *div) 320 int *psel, int *esel, int *pdiv, int *div)
249{ 321{
250 unsigned long max_rate, best_rate = 0, 322 struct clk *mclk;
251 actual_rate = 0, mclk_rate = 0, rate_err = -1; 323 unsigned long max_rate, actual_rate, mclk_rate, rate_err = -1;
252 int i, found = 0, __div = 0, __pdiv = 0; 324 int i, found = 0, __div = 0, __pdiv = 0;
253 325
254 /* Don't exceed the maximum rate */ 326 /* Don't exceed the maximum rate */
255 max_rate = max(max(clk_pll1.rate / 4, clk_pll2.rate / 4), 327 max_rate = max(max(clk_pll1.rate / 4, clk_pll2.rate / 4),
256 (unsigned long)EP93XX_EXT_CLK_RATE / 4); 328 clk_xtali.rate / 4);
257 rate = min(rate, max_rate); 329 rate = min(rate, max_rate);
258 330
259 /* 331 /*
@@ -267,11 +339,12 @@ static unsigned long calc_clk_div(unsigned long rate, int *psel, int *esel,
267 */ 339 */
268 for (i = 0; i < 3; i++) { 340 for (i = 0; i < 3; i++) {
269 if (i == 0) 341 if (i == 0)
270 mclk_rate = EP93XX_EXT_CLK_RATE * 2; 342 mclk = &clk_xtali;
271 else if (i == 1) 343 else if (i == 1)
272 mclk_rate = clk_pll1.rate * 2; 344 mclk = &clk_pll1;
273 else if (i == 2) 345 else
274 mclk_rate = clk_pll2.rate * 2; 346 mclk = &clk_pll2;
347 mclk_rate = mclk->rate * 2;
275 348
276 /* Try each predivider value */ 349 /* Try each predivider value */
277 for (__pdiv = 4; __pdiv <= 6; __pdiv++) { 350 for (__pdiv = 4; __pdiv <= 6; __pdiv++) {
@@ -286,7 +359,8 @@ static unsigned long calc_clk_div(unsigned long rate, int *psel, int *esel,
286 *div = __div; 359 *div = __div;
287 *psel = (i == 2); 360 *psel = (i == 2);
288 *esel = (i != 0); 361 *esel = (i != 0);
289 best_rate = actual_rate; 362 clk->parent = mclk;
363 clk->rate = actual_rate;
290 rate_err = abs(actual_rate - rate); 364 rate_err = abs(actual_rate - rate);
291 found = 1; 365 found = 1;
292 } 366 }
@@ -294,21 +368,19 @@ static unsigned long calc_clk_div(unsigned long rate, int *psel, int *esel,
294 } 368 }
295 369
296 if (!found) 370 if (!found)
297 return 0; 371 return -EINVAL;
298 372
299 return best_rate; 373 return 0;
300} 374}
301 375
302static int set_div_rate(struct clk *clk, unsigned long rate) 376static int set_div_rate(struct clk *clk, unsigned long rate)
303{ 377{
304 unsigned long actual_rate; 378 int err, psel = 0, esel = 0, pdiv = 0, div = 0;
305 int psel = 0, esel = 0, pdiv = 0, div = 0;
306 u32 val; 379 u32 val;
307 380
308 actual_rate = calc_clk_div(rate, &psel, &esel, &pdiv, &div); 381 err = calc_clk_div(clk, rate, &psel, &esel, &pdiv, &div);
309 if (actual_rate == 0) 382 if (err)
310 return -EINVAL; 383 return err;
311 clk->rate = actual_rate;
312 384
313 /* Clear the esel, psel, pdiv and div bits */ 385 /* Clear the esel, psel, pdiv and div bits */
314 val = __raw_readl(clk->enable_reg); 386 val = __raw_readl(clk->enable_reg);
@@ -344,7 +416,7 @@ static unsigned long calc_pll_rate(u32 config_word)
344 unsigned long long rate; 416 unsigned long long rate;
345 int i; 417 int i;
346 418
347 rate = EP93XX_EXT_CLK_RATE; 419 rate = clk_xtali.rate;
348 rate *= ((config_word >> 11) & 0x1f) + 1; /* X1FBD */ 420 rate *= ((config_word >> 11) & 0x1f) + 1; /* X1FBD */
349 rate *= ((config_word >> 5) & 0x3f) + 1; /* X2FBD */ 421 rate *= ((config_word >> 5) & 0x3f) + 1; /* X2FBD */
350 do_div(rate, (config_word & 0x1f) + 1); /* X2IPD */ 422 do_div(rate, (config_word & 0x1f) + 1); /* X2IPD */
@@ -377,7 +449,7 @@ static int __init ep93xx_clock_init(void)
377 449
378 value = __raw_readl(EP93XX_SYSCON_CLOCK_SET1); 450 value = __raw_readl(EP93XX_SYSCON_CLOCK_SET1);
379 if (!(value & 0x00800000)) { /* PLL1 bypassed? */ 451 if (!(value & 0x00800000)) { /* PLL1 bypassed? */
380 clk_pll1.rate = EP93XX_EXT_CLK_RATE; 452 clk_pll1.rate = clk_xtali.rate;
381 } else { 453 } else {
382 clk_pll1.rate = calc_pll_rate(value); 454 clk_pll1.rate = calc_pll_rate(value);
383 } 455 }
@@ -388,7 +460,7 @@ static int __init ep93xx_clock_init(void)
388 460
389 value = __raw_readl(EP93XX_SYSCON_CLOCK_SET2); 461 value = __raw_readl(EP93XX_SYSCON_CLOCK_SET2);
390 if (!(value & 0x00080000)) { /* PLL2 bypassed? */ 462 if (!(value & 0x00080000)) { /* PLL2 bypassed? */
391 clk_pll2.rate = EP93XX_EXT_CLK_RATE; 463 clk_pll2.rate = clk_xtali.rate;
392 } else if (value & 0x00040000) { /* PLL2 enabled? */ 464 } else if (value & 0x00040000) { /* PLL2 enabled? */
393 clk_pll2.rate = calc_pll_rate(value); 465 clk_pll2.rate = calc_pll_rate(value);
394 } else { 466 } else {
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index f7ebed942f66..f95dc160c34b 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -550,13 +550,11 @@ void __init ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr)
550 platform_device_register(&ep93xx_eth_device); 550 platform_device_register(&ep93xx_eth_device);
551} 551}
552 552
553static struct i2c_gpio_platform_data ep93xx_i2c_data = { 553
554 .sda_pin = EP93XX_GPIO_LINE_EEDAT, 554/*************************************************************************
555 .sda_is_open_drain = 0, 555 * EP93xx i2c peripheral handling
556 .scl_pin = EP93XX_GPIO_LINE_EECLK, 556 *************************************************************************/
557 .scl_is_open_drain = 0, 557static struct i2c_gpio_platform_data ep93xx_i2c_data;
558 .udelay = 2,
559};
560 558
561static struct platform_device ep93xx_i2c_device = { 559static struct platform_device ep93xx_i2c_device = {
562 .name = "i2c-gpio", 560 .name = "i2c-gpio",
@@ -564,8 +562,25 @@ static struct platform_device ep93xx_i2c_device = {
564 .dev.platform_data = &ep93xx_i2c_data, 562 .dev.platform_data = &ep93xx_i2c_data,
565}; 563};
566 564
567void __init ep93xx_register_i2c(struct i2c_board_info *devices, int num) 565void __init ep93xx_register_i2c(struct i2c_gpio_platform_data *data,
566 struct i2c_board_info *devices, int num)
568{ 567{
568 /*
569 * Set the EEPROM interface pin drive type control.
570 * Defines the driver type for the EECLK and EEDAT pins as either
571 * open drain, which will require an external pull-up, or a normal
572 * CMOS driver.
573 */
574 if (data->sda_is_open_drain && data->sda_pin != EP93XX_GPIO_LINE_EEDAT)
575 pr_warning("ep93xx: sda != EEDAT, open drain has no effect\n");
576 if (data->scl_is_open_drain && data->scl_pin != EP93XX_GPIO_LINE_EECLK)
577 pr_warning("ep93xx: scl != EECLK, open drain has no effect\n");
578
579 __raw_writel((data->sda_is_open_drain << 1) |
580 (data->scl_is_open_drain << 0),
581 EP93XX_GPIO_EEDRIVE);
582
583 ep93xx_i2c_data = *data;
569 i2c_register_board_info(0, devices, num); 584 i2c_register_board_info(0, devices, num);
570 platform_device_register(&ep93xx_i2c_device); 585 platform_device_register(&ep93xx_i2c_device);
571} 586}
diff --git a/arch/arm/mach-ep93xx/edb93xx.c b/arch/arm/mach-ep93xx/edb93xx.c
index 73145ae5d3fa..ca71cf1a72a0 100644
--- a/arch/arm/mach-ep93xx/edb93xx.c
+++ b/arch/arm/mach-ep93xx/edb93xx.c
@@ -27,8 +27,10 @@
27#include <linux/kernel.h> 27#include <linux/kernel.h>
28#include <linux/init.h> 28#include <linux/init.h>
29#include <linux/platform_device.h> 29#include <linux/platform_device.h>
30#include <linux/i2c.h>
31#include <linux/mtd/physmap.h> 30#include <linux/mtd/physmap.h>
31#include <linux/gpio.h>
32#include <linux/i2c.h>
33#include <linux/i2c-gpio.h>
32 34
33#include <mach/hardware.h> 35#include <mach/hardware.h>
34 36
@@ -76,13 +78,26 @@ static struct ep93xx_eth_data edb93xx_eth_data = {
76 .phy_id = 1, 78 .phy_id = 1,
77}; 79};
78 80
79static struct i2c_board_info __initdata edb93xxa_i2c_data[] = { 81
82/*************************************************************************
83 * EDB93xx i2c peripheral handling
84 *************************************************************************/
85static struct i2c_gpio_platform_data edb93xx_i2c_gpio_data = {
86 .sda_pin = EP93XX_GPIO_LINE_EEDAT,
87 .sda_is_open_drain = 0,
88 .scl_pin = EP93XX_GPIO_LINE_EECLK,
89 .scl_is_open_drain = 0,
90 .udelay = 0, /* default to 100 kHz */
91 .timeout = 0, /* default to 100 ms */
92};
93
94static struct i2c_board_info __initdata edb93xxa_i2c_board_info[] = {
80 { 95 {
81 I2C_BOARD_INFO("isl1208", 0x6f), 96 I2C_BOARD_INFO("isl1208", 0x6f),
82 }, 97 },
83}; 98};
84 99
85static struct i2c_board_info __initdata edb93xx_i2c_data[] = { 100static struct i2c_board_info __initdata edb93xx_i2c_board_info[] = {
86 { 101 {
87 I2C_BOARD_INFO("ds1337", 0x68), 102 I2C_BOARD_INFO("ds1337", 0x68),
88 }, 103 },
@@ -92,12 +107,14 @@ static void __init edb93xx_register_i2c(void)
92{ 107{
93 if (machine_is_edb9302a() || machine_is_edb9307a() || 108 if (machine_is_edb9302a() || machine_is_edb9307a() ||
94 machine_is_edb9315a()) { 109 machine_is_edb9315a()) {
95 ep93xx_register_i2c(edb93xxa_i2c_data, 110 ep93xx_register_i2c(&edb93xx_i2c_gpio_data,
96 ARRAY_SIZE(edb93xxa_i2c_data)); 111 edb93xxa_i2c_board_info,
112 ARRAY_SIZE(edb93xxa_i2c_board_info));
97 } else if (machine_is_edb9307() || machine_is_edb9312() || 113 } else if (machine_is_edb9307() || machine_is_edb9312() ||
98 machine_is_edb9315()) { 114 machine_is_edb9315()) {
99 ep93xx_register_i2c(edb93xx_i2c_data, 115 ep93xx_register_i2c(&edb93xx_i2c_gpio_data
100 ARRAY_SIZE(edb93xx_i2c_data)); 116 edb93xx_i2c_board_info,
117 ARRAY_SIZE(edb93xx_i2c_board_info));
101 } 118 }
102} 119}
103 120
diff --git a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
index 0fbf87b16338..b1f937eda29c 100644
--- a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
+++ b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
@@ -52,25 +52,27 @@
52#define EP93XX_AHB_VIRT_BASE 0xfef00000 52#define EP93XX_AHB_VIRT_BASE 0xfef00000
53#define EP93XX_AHB_SIZE 0x00100000 53#define EP93XX_AHB_SIZE 0x00100000
54 54
55#define EP93XX_AHB_PHYS(x) (EP93XX_AHB_PHYS_BASE + (x))
55#define EP93XX_AHB_IOMEM(x) IOMEM(EP93XX_AHB_VIRT_BASE + (x)) 56#define EP93XX_AHB_IOMEM(x) IOMEM(EP93XX_AHB_VIRT_BASE + (x))
56 57
57#define EP93XX_APB_PHYS_BASE 0x80800000 58#define EP93XX_APB_PHYS_BASE 0x80800000
58#define EP93XX_APB_VIRT_BASE 0xfed00000 59#define EP93XX_APB_VIRT_BASE 0xfed00000
59#define EP93XX_APB_SIZE 0x00200000 60#define EP93XX_APB_SIZE 0x00200000
60 61
62#define EP93XX_APB_PHYS(x) (EP93XX_APB_PHYS_BASE + (x))
61#define EP93XX_APB_IOMEM(x) IOMEM(EP93XX_APB_VIRT_BASE + (x)) 63#define EP93XX_APB_IOMEM(x) IOMEM(EP93XX_APB_VIRT_BASE + (x))
62 64
63 65
64/* AHB peripherals */ 66/* AHB peripherals */
65#define EP93XX_DMA_BASE EP93XX_AHB_IOMEM(0x00000000) 67#define EP93XX_DMA_BASE EP93XX_AHB_IOMEM(0x00000000)
66 68
67#define EP93XX_ETHERNET_PHYS_BASE (EP93XX_AHB_PHYS_BASE + 0x00010000) 69#define EP93XX_ETHERNET_PHYS_BASE EP93XX_AHB_PHYS(0x00010000)
68#define EP93XX_ETHERNET_BASE EP93XX_AHB_IOMEM(0x00010000) 70#define EP93XX_ETHERNET_BASE EP93XX_AHB_IOMEM(0x00010000)
69 71
70#define EP93XX_USB_PHYS_BASE (EP93XX_AHB_PHYS_BASE + 0x00020000) 72#define EP93XX_USB_PHYS_BASE EP93XX_AHB_PHYS(0x00020000)
71#define EP93XX_USB_BASE EP93XX_AHB_IOMEM(0x00020000) 73#define EP93XX_USB_BASE EP93XX_AHB_IOMEM(0x00020000)
72 74
73#define EP93XX_RASTER_PHYS_BASE (EP93XX_AHB_PHYS_BASE + 0x00030000) 75#define EP93XX_RASTER_PHYS_BASE EP93XX_AHB_PHYS(0x00030000)
74#define EP93XX_RASTER_BASE EP93XX_AHB_IOMEM(0x00030000) 76#define EP93XX_RASTER_BASE EP93XX_AHB_IOMEM(0x00030000)
75 77
76#define EP93XX_GRAPHICS_ACCEL_BASE EP93XX_AHB_IOMEM(0x00040000) 78#define EP93XX_GRAPHICS_ACCEL_BASE EP93XX_AHB_IOMEM(0x00040000)
@@ -112,21 +114,10 @@
112 114
113#define EP93XX_GPIO_BASE EP93XX_APB_IOMEM(0x00040000) 115#define EP93XX_GPIO_BASE EP93XX_APB_IOMEM(0x00040000)
114#define EP93XX_GPIO_REG(x) (EP93XX_GPIO_BASE + (x)) 116#define EP93XX_GPIO_REG(x) (EP93XX_GPIO_BASE + (x))
115#define EP93XX_GPIO_F_INT_TYPE1 EP93XX_GPIO_REG(0x4c)
116#define EP93XX_GPIO_F_INT_TYPE2 EP93XX_GPIO_REG(0x50)
117#define EP93XX_GPIO_F_INT_ACK EP93XX_GPIO_REG(0x54)
118#define EP93XX_GPIO_F_INT_ENABLE EP93XX_GPIO_REG(0x58)
119#define EP93XX_GPIO_F_INT_STATUS EP93XX_GPIO_REG(0x5c) 117#define EP93XX_GPIO_F_INT_STATUS EP93XX_GPIO_REG(0x5c)
120#define EP93XX_GPIO_A_INT_TYPE1 EP93XX_GPIO_REG(0x90)
121#define EP93XX_GPIO_A_INT_TYPE2 EP93XX_GPIO_REG(0x94)
122#define EP93XX_GPIO_A_INT_ACK EP93XX_GPIO_REG(0x98)
123#define EP93XX_GPIO_A_INT_ENABLE EP93XX_GPIO_REG(0x9c)
124#define EP93XX_GPIO_A_INT_STATUS EP93XX_GPIO_REG(0xa0) 118#define EP93XX_GPIO_A_INT_STATUS EP93XX_GPIO_REG(0xa0)
125#define EP93XX_GPIO_B_INT_TYPE1 EP93XX_GPIO_REG(0xac)
126#define EP93XX_GPIO_B_INT_TYPE2 EP93XX_GPIO_REG(0xb0)
127#define EP93XX_GPIO_B_INT_ACK EP93XX_GPIO_REG(0xb4)
128#define EP93XX_GPIO_B_INT_ENABLE EP93XX_GPIO_REG(0xb8)
129#define EP93XX_GPIO_B_INT_STATUS EP93XX_GPIO_REG(0xbc) 119#define EP93XX_GPIO_B_INT_STATUS EP93XX_GPIO_REG(0xbc)
120#define EP93XX_GPIO_EEDRIVE EP93XX_GPIO_REG(0xc8)
130 121
131#define EP93XX_AAC_BASE EP93XX_APB_IOMEM(0x00080000) 122#define EP93XX_AAC_BASE EP93XX_APB_IOMEM(0x00080000)
132 123
@@ -134,13 +125,13 @@
134 125
135#define EP93XX_IRDA_BASE EP93XX_APB_IOMEM(0x000b0000) 126#define EP93XX_IRDA_BASE EP93XX_APB_IOMEM(0x000b0000)
136 127
137#define EP93XX_UART1_PHYS_BASE (EP93XX_APB_PHYS_BASE + 0x000c0000) 128#define EP93XX_UART1_PHYS_BASE EP93XX_APB_PHYS(0x000c0000)
138#define EP93XX_UART1_BASE EP93XX_APB_IOMEM(0x000c0000) 129#define EP93XX_UART1_BASE EP93XX_APB_IOMEM(0x000c0000)
139 130
140#define EP93XX_UART2_PHYS_BASE (EP93XX_APB_PHYS_BASE + 0x000d0000) 131#define EP93XX_UART2_PHYS_BASE EP93XX_APB_PHYS(0x000d0000)
141#define EP93XX_UART2_BASE EP93XX_APB_IOMEM(0x000d0000) 132#define EP93XX_UART2_BASE EP93XX_APB_IOMEM(0x000d0000)
142 133
143#define EP93XX_UART3_PHYS_BASE (EP93XX_APB_PHYS_BASE + 0x000e0000) 134#define EP93XX_UART3_PHYS_BASE EP93XX_APB_PHYS(0x000e0000)
144#define EP93XX_UART3_BASE EP93XX_APB_IOMEM(0x000e0000) 135#define EP93XX_UART3_BASE EP93XX_APB_IOMEM(0x000e0000)
145 136
146#define EP93XX_KEY_MATRIX_BASE EP93XX_APB_IOMEM(0x000f0000) 137#define EP93XX_KEY_MATRIX_BASE EP93XX_APB_IOMEM(0x000f0000)
@@ -148,10 +139,10 @@
148#define EP93XX_ADC_BASE EP93XX_APB_IOMEM(0x00100000) 139#define EP93XX_ADC_BASE EP93XX_APB_IOMEM(0x00100000)
149#define EP93XX_TOUCHSCREEN_BASE EP93XX_APB_IOMEM(0x00100000) 140#define EP93XX_TOUCHSCREEN_BASE EP93XX_APB_IOMEM(0x00100000)
150 141
151#define EP93XX_PWM_PHYS_BASE (EP93XX_APB_PHYS_BASE + 0x00110000) 142#define EP93XX_PWM_PHYS_BASE EP93XX_APB_PHYS(0x00110000)
152#define EP93XX_PWM_BASE EP93XX_APB_IOMEM(0x00110000) 143#define EP93XX_PWM_BASE EP93XX_APB_IOMEM(0x00110000)
153 144
154#define EP93XX_RTC_PHYS_BASE (EP93XX_APB_PHYS_BASE + 0x00120000) 145#define EP93XX_RTC_PHYS_BASE EP93XX_APB_PHYS(0x00120000)
155#define EP93XX_RTC_BASE EP93XX_APB_IOMEM(0x00120000) 146#define EP93XX_RTC_BASE EP93XX_APB_IOMEM(0x00120000)
156 147
157#define EP93XX_SYSCON_BASE EP93XX_APB_IOMEM(0x00130000) 148#define EP93XX_SYSCON_BASE EP93XX_APB_IOMEM(0x00130000)
@@ -218,6 +209,17 @@
218#define EP93XX_SYSCON_KEYTCHCLKDIV_ADIV (1<<16) 209#define EP93XX_SYSCON_KEYTCHCLKDIV_ADIV (1<<16)
219#define EP93XX_SYSCON_KEYTCHCLKDIV_KEN (1<<15) 210#define EP93XX_SYSCON_KEYTCHCLKDIV_KEN (1<<15)
220#define EP93XX_SYSCON_KEYTCHCLKDIV_KDIV (1<<0) 211#define EP93XX_SYSCON_KEYTCHCLKDIV_KDIV (1<<0)
212#define EP93XX_SYSCON_SYSCFG EP93XX_SYSCON_REG(0x9c)
213#define EP93XX_SYSCON_SYSCFG_REV_MASK (0xf0000000)
214#define EP93XX_SYSCON_SYSCFG_REV_SHIFT (28)
215#define EP93XX_SYSCON_SYSCFG_SBOOT (1<<8)
216#define EP93XX_SYSCON_SYSCFG_LCSN7 (1<<7)
217#define EP93XX_SYSCON_SYSCFG_LCSN6 (1<<6)
218#define EP93XX_SYSCON_SYSCFG_LASDO (1<<5)
219#define EP93XX_SYSCON_SYSCFG_LEEDA (1<<4)
220#define EP93XX_SYSCON_SYSCFG_LEECLK (1<<3)
221#define EP93XX_SYSCON_SYSCFG_LCSN2 (1<<1)
222#define EP93XX_SYSCON_SYSCFG_LCSN1 (1<<0)
221#define EP93XX_SYSCON_SWLOCK EP93XX_SYSCON_REG(0xc0) 223#define EP93XX_SYSCON_SWLOCK EP93XX_SYSCON_REG(0xc0)
222 224
223#define EP93XX_WATCHDOG_BASE EP93XX_APB_IOMEM(0x00140000) 225#define EP93XX_WATCHDOG_BASE EP93XX_APB_IOMEM(0x00140000)
diff --git a/arch/arm/mach-ep93xx/include/mach/gpio.h b/arch/arm/mach-ep93xx/include/mach/gpio.h
index 0a1498ae899a..c991b149bdf2 100644
--- a/arch/arm/mach-ep93xx/include/mach/gpio.h
+++ b/arch/arm/mach-ep93xx/include/mach/gpio.h
@@ -114,17 +114,9 @@ extern void ep93xx_gpio_int_debounce(unsigned int irq, int enable);
114 * B0..B7 (7..15) to irq 72..79, and 114 * B0..B7 (7..15) to irq 72..79, and
115 * F0..F7 (16..24) to irq 80..87. 115 * F0..F7 (16..24) to irq 80..87.
116 */ 116 */
117static inline int gpio_to_irq(unsigned gpio) 117#define gpio_to_irq(gpio) \
118{ 118 (((gpio) <= EP93XX_GPIO_LINE_MAX_IRQ) ? (64 + (gpio)) : -EINVAL)
119 if (gpio <= EP93XX_GPIO_LINE_MAX_IRQ) 119
120 return 64 + gpio; 120#define irq_to_gpio(irq) ((irq) - gpio_to_irq(0))
121
122 return -EINVAL;
123}
124
125static inline int irq_to_gpio(unsigned irq)
126{
127 return irq - gpio_to_irq(0);
128}
129 121
130#endif 122#endif
diff --git a/arch/arm/mach-ep93xx/include/mach/memory.h b/arch/arm/mach-ep93xx/include/mach/memory.h
index 925b12ea0990..554064e90307 100644
--- a/arch/arm/mach-ep93xx/include/mach/memory.h
+++ b/arch/arm/mach-ep93xx/include/mach/memory.h
@@ -9,6 +9,12 @@
9#define PHYS_OFFSET UL(0x00000000) 9#define PHYS_OFFSET UL(0x00000000)
10#elif defined(CONFIG_EP93XX_SDCE0_PHYS_OFFSET) 10#elif defined(CONFIG_EP93XX_SDCE0_PHYS_OFFSET)
11#define PHYS_OFFSET UL(0xc0000000) 11#define PHYS_OFFSET UL(0xc0000000)
12#elif defined(CONFIG_EP93XX_SDCE1_PHYS_OFFSET)
13#define PHYS_OFFSET UL(0xd0000000)
14#elif defined(CONFIG_EP93XX_SDCE2_PHYS_OFFSET)
15#define PHYS_OFFSET UL(0xe0000000)
16#elif defined(CONFIG_EP93XX_SDCE3_ASYNC_PHYS_OFFSET)
17#define PHYS_OFFSET UL(0xf0000000)
12#else 18#else
13#error "Kconfig bug: No EP93xx PHYS_OFFSET set" 19#error "Kconfig bug: No EP93xx PHYS_OFFSET set"
14#endif 20#endif
diff --git a/arch/arm/mach-ep93xx/include/mach/platform.h b/arch/arm/mach-ep93xx/include/mach/platform.h
index 01a0f0838e5b..a3ec33fd79d4 100644
--- a/arch/arm/mach-ep93xx/include/mach/platform.h
+++ b/arch/arm/mach-ep93xx/include/mach/platform.h
@@ -4,6 +4,7 @@
4 4
5#ifndef __ASSEMBLY__ 5#ifndef __ASSEMBLY__
6 6
7struct i2c_gpio_platform_data;
7struct i2c_board_info; 8struct i2c_board_info;
8struct platform_device; 9struct platform_device;
9struct ep93xxfb_mach_info; 10struct ep93xxfb_mach_info;
@@ -33,7 +34,8 @@ static inline void ep93xx_devcfg_clear_bits(unsigned int bits)
33} 34}
34 35
35void ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr); 36void ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr);
36void ep93xx_register_i2c(struct i2c_board_info *devices, int num); 37void ep93xx_register_i2c(struct i2c_gpio_platform_data *data,
38 struct i2c_board_info *devices, int num);
37void ep93xx_register_fb(struct ep93xxfb_mach_info *data); 39void ep93xx_register_fb(struct ep93xxfb_mach_info *data);
38void ep93xx_register_pwm(int pwm0, int pwm1); 40void ep93xx_register_pwm(int pwm0, int pwm1);
39int ep93xx_pwm_acquire_gpio(struct platform_device *pdev); 41int ep93xx_pwm_acquire_gpio(struct platform_device *pdev);
diff --git a/arch/arm/mach-ep93xx/micro9.c b/arch/arm/mach-ep93xx/micro9.c
index 0a313e82fb74..d83b80478b09 100644
--- a/arch/arm/mach-ep93xx/micro9.c
+++ b/arch/arm/mach-ep93xx/micro9.c
@@ -2,7 +2,9 @@
2 * linux/arch/arm/mach-ep93xx/micro9.c 2 * linux/arch/arm/mach-ep93xx/micro9.c
3 * 3 *
4 * Copyright (C) 2006 Contec Steuerungstechnik & Automation GmbH 4 * Copyright (C) 2006 Contec Steuerungstechnik & Automation GmbH
5 * Manfred Gruber <manfred.gruber@contec.at> 5 * Manfred Gruber <m.gruber@tirol.com>
6 * Copyright (C) 2009 Contec Steuerungstechnik & Automation GmbH
7 * Hubert Feurstein <hubert.feurstein@contec.at>
6 * 8 *
7 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as 10 * it under the terms of the GNU General Public License version 2 as
@@ -20,104 +22,124 @@
20#include <asm/mach/arch.h> 22#include <asm/mach/arch.h>
21 23
22 24
23static struct ep93xx_eth_data micro9_eth_data = { 25/*************************************************************************
24 .phy_id = 0x1f, 26 * Micro9 NOR Flash
25}; 27 *
26 28 * Micro9-High has up to 64MB of 32-bit flash on CS1
27static void __init micro9_init(void) 29 * Micro9-Mid has up to 64MB of either 32-bit or 16-bit flash on CS1
28{ 30 * Micro9-Lite uses a seperate MTD map driver for flash support
29 ep93xx_register_eth(&micro9_eth_data, 1); 31 * Micro9-Slim has up to 64MB of either 32-bit or 16-bit flash on CS1
30} 32 *************************************************************************/
31 33static struct physmap_flash_data micro9_flash_data;
32/* 34
33 * Micro9-H 35static struct resource micro9_flash_resource = {
34 */
35#ifdef CONFIG_MACH_MICRO9H
36static struct physmap_flash_data micro9h_flash_data = {
37 .width = 4,
38};
39
40static struct resource micro9h_flash_resource = {
41 .start = EP93XX_CS1_PHYS_BASE, 36 .start = EP93XX_CS1_PHYS_BASE,
42 .end = EP93XX_CS1_PHYS_BASE + SZ_64M - 1, 37 .end = EP93XX_CS1_PHYS_BASE + SZ_64M - 1,
43 .flags = IORESOURCE_MEM, 38 .flags = IORESOURCE_MEM,
44}; 39};
45 40
46static struct platform_device micro9h_flash = { 41static struct platform_device micro9_flash = {
47 .name = "physmap-flash", 42 .name = "physmap-flash",
48 .id = 0, 43 .id = 0,
49 .dev = { 44 .dev = {
50 .platform_data = &micro9h_flash_data, 45 .platform_data = &micro9_flash_data,
51 }, 46 },
52 .num_resources = 1, 47 .num_resources = 1,
53 .resource = &micro9h_flash_resource, 48 .resource = &micro9_flash_resource,
54}; 49};
55 50
56static void __init micro9h_init(void) 51static void __init __micro9_register_flash(unsigned int width)
52{
53 micro9_flash_data.width = width;
54
55 platform_device_register(&micro9_flash);
56}
57
58static unsigned int __init micro9_detect_bootwidth(void)
59{
60 u32 v;
61
62 /* Detect the bus width of the external flash memory */
63 v = __raw_readl(EP93XX_SYSCON_SYSCFG);
64 if (v & EP93XX_SYSCON_SYSCFG_LCSN7)
65 return 4; /* 32-bit */
66 else
67 return 2; /* 16-bit */
68}
69
70static void __init micro9_register_flash(void)
57{ 71{
58 platform_device_register(&micro9h_flash); 72 if (machine_is_micro9())
73 __micro9_register_flash(4);
74 else if (machine_is_micro9m() || machine_is_micro9s())
75 __micro9_register_flash(micro9_detect_bootwidth());
59} 76}
60 77
61static void __init micro9h_init_machine(void) 78
79/*************************************************************************
80 * Micro9 Ethernet
81 *************************************************************************/
82static struct ep93xx_eth_data micro9_eth_data = {
83 .phy_id = 0x1f,
84};
85
86
87static void __init micro9_init_machine(void)
62{ 88{
63 ep93xx_init_devices(); 89 ep93xx_init_devices();
64 micro9_init(); 90 ep93xx_register_eth(&micro9_eth_data, 1);
65 micro9h_init(); 91 micro9_register_flash();
66} 92}
67 93
68MACHINE_START(MICRO9, "Contec Hypercontrol Micro9-H") 94
69 /* Maintainer: Manfred Gruber <manfred.gruber@contec.at> */ 95#ifdef CONFIG_MACH_MICRO9H
96MACHINE_START(MICRO9, "Contec Micro9-High")
97 /* Maintainer: Hubert Feurstein <hubert.feurstein@contec.at> */
70 .phys_io = EP93XX_APB_PHYS_BASE, 98 .phys_io = EP93XX_APB_PHYS_BASE,
71 .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc, 99 .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
72 .boot_params = EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100, 100 .boot_params = EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
73 .map_io = ep93xx_map_io, 101 .map_io = ep93xx_map_io,
74 .init_irq = ep93xx_init_irq, 102 .init_irq = ep93xx_init_irq,
75 .timer = &ep93xx_timer, 103 .timer = &ep93xx_timer,
76 .init_machine = micro9h_init_machine, 104 .init_machine = micro9_init_machine,
77MACHINE_END 105MACHINE_END
78#endif 106#endif
79 107
80/*
81 * Micro9-M
82 */
83#ifdef CONFIG_MACH_MICRO9M 108#ifdef CONFIG_MACH_MICRO9M
84static void __init micro9m_init_machine(void) 109MACHINE_START(MICRO9M, "Contec Micro9-Mid")
85{ 110 /* Maintainer: Hubert Feurstein <hubert.feurstein@contec.at> */
86 ep93xx_init_devices();
87 micro9_init();
88}
89
90MACHINE_START(MICRO9M, "Contec Hypercontrol Micro9-M")
91 /* Maintainer: Manfred Gruber <manfred.gruber@contec.at> */
92 .phys_io = EP93XX_APB_PHYS_BASE, 111 .phys_io = EP93XX_APB_PHYS_BASE,
93 .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc, 112 .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
94 .boot_params = EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100, 113 .boot_params = EP93XX_SDCE3_PHYS_BASE_ASYNC + 0x100,
95 .map_io = ep93xx_map_io, 114 .map_io = ep93xx_map_io,
96 .init_irq = ep93xx_init_irq, 115 .init_irq = ep93xx_init_irq,
97 .timer = &ep93xx_timer, 116 .timer = &ep93xx_timer,
98 .init_machine = micro9m_init_machine, 117 .init_machine = micro9_init_machine,
99MACHINE_END 118MACHINE_END
100#endif 119#endif
101 120
102/*
103 * Micro9-L
104 */
105#ifdef CONFIG_MACH_MICRO9L 121#ifdef CONFIG_MACH_MICRO9L
106static void __init micro9l_init_machine(void) 122MACHINE_START(MICRO9L, "Contec Micro9-Lite")
107{ 123 /* Maintainer: Hubert Feurstein <hubert.feurstein@contec.at> */
108 ep93xx_init_devices();
109 micro9_init();
110}
111
112MACHINE_START(MICRO9L, "Contec Hypercontrol Micro9-L")
113 /* Maintainer: Manfred Gruber <manfred.gruber@contec.at> */
114 .phys_io = EP93XX_APB_PHYS_BASE, 124 .phys_io = EP93XX_APB_PHYS_BASE,
115 .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc, 125 .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
116 .boot_params = EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100, 126 .boot_params = EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100,
117 .map_io = ep93xx_map_io, 127 .map_io = ep93xx_map_io,
118 .init_irq = ep93xx_init_irq, 128 .init_irq = ep93xx_init_irq,
119 .timer = &ep93xx_timer, 129 .timer = &ep93xx_timer,
120 .init_machine = micro9l_init_machine, 130 .init_machine = micro9_init_machine,
121MACHINE_END 131MACHINE_END
122#endif 132#endif
123 133
134#ifdef CONFIG_MACH_MICRO9S
135MACHINE_START(MICRO9S, "Contec Micro9-Slim")
136 /* Maintainer: Hubert Feurstein <hubert.feurstein@contec.at> */
137 .phys_io = EP93XX_APB_PHYS_BASE,
138 .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
139 .boot_params = EP93XX_SDCE3_PHYS_BASE_ASYNC + 0x100,
140 .map_io = ep93xx_map_io,
141 .init_irq = ep93xx_init_irq,
142 .timer = &ep93xx_timer,
143 .init_machine = micro9_init_machine,
144MACHINE_END
145#endif
diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c
index f1d72b225450..148d25fc636f 100644
--- a/arch/arm/mach-integrator/pci_v3.c
+++ b/arch/arm/mach-integrator/pci_v3.c
@@ -31,6 +31,7 @@
31 31
32#include <mach/hardware.h> 32#include <mach/hardware.h>
33#include <asm/irq.h> 33#include <asm/irq.h>
34#include <asm/signal.h>
34#include <asm/system.h> 35#include <asm/system.h>
35#include <asm/mach/pci.h> 36#include <asm/mach/pci.h>
36#include <asm/irq_regs.h> 37#include <asm/irq_regs.h>
@@ -486,7 +487,7 @@ int __init pci_v3_setup(int nr, struct pci_sys_data *sys)
486 return ret; 487 return ret;
487} 488}
488 489
489struct pci_bus *pci_v3_scan_bus(int nr, struct pci_sys_data *sys) 490struct pci_bus * __init pci_v3_scan_bus(int nr, struct pci_sys_data *sys)
490{ 491{
491 return pci_scan_bus(sys->busnr, &pci_v3_ops, sys); 492 return pci_scan_bus(sys->busnr, &pci_v3_ops, sys);
492} 493}
diff --git a/arch/arm/mach-iop32x/include/mach/iop32x.h b/arch/arm/mach-iop32x/include/mach/iop32x.h
index abd9eb49f103..941f363aca56 100644
--- a/arch/arm/mach-iop32x/include/mach/iop32x.h
+++ b/arch/arm/mach-iop32x/include/mach/iop32x.h
@@ -31,7 +31,5 @@
31#define IOP32X_MAX_RAM_SIZE 0x40000000UL 31#define IOP32X_MAX_RAM_SIZE 0x40000000UL
32#define IOP3XX_MAX_RAM_SIZE IOP32X_MAX_RAM_SIZE 32#define IOP3XX_MAX_RAM_SIZE IOP32X_MAX_RAM_SIZE
33#define IOP3XX_PCI_LOWER_MEM_BA 0x80000000 33#define IOP3XX_PCI_LOWER_MEM_BA 0x80000000
34#define IOP32X_PCI_MEM_WINDOW_SIZE 0x04000000
35#define IOP3XX_PCI_MEM_WINDOW_SIZE IOP32X_PCI_MEM_WINDOW_SIZE
36 34
37#endif 35#endif
diff --git a/arch/arm/mach-iop33x/include/mach/iop33x.h b/arch/arm/mach-iop33x/include/mach/iop33x.h
index 24567316ec88..a89c0a234bff 100644
--- a/arch/arm/mach-iop33x/include/mach/iop33x.h
+++ b/arch/arm/mach-iop33x/include/mach/iop33x.h
@@ -36,8 +36,6 @@
36#define IOP33X_MAX_RAM_SIZE 0x80000000UL 36#define IOP33X_MAX_RAM_SIZE 0x80000000UL
37#define IOP3XX_MAX_RAM_SIZE IOP33X_MAX_RAM_SIZE 37#define IOP3XX_MAX_RAM_SIZE IOP33X_MAX_RAM_SIZE
38#define IOP3XX_PCI_LOWER_MEM_BA (PHYS_OFFSET + IOP33X_MAX_RAM_SIZE) 38#define IOP3XX_PCI_LOWER_MEM_BA (PHYS_OFFSET + IOP33X_MAX_RAM_SIZE)
39#define IOP33X_PCI_MEM_WINDOW_SIZE 0x08000000
40#define IOP3XX_PCI_MEM_WINDOW_SIZE IOP33X_PCI_MEM_WINDOW_SIZE
41 39
42 40
43#endif 41#endif
diff --git a/arch/arm/mach-ns9xxx/clock.c b/arch/arm/mach-ns9xxx/clock.c
index 44ed20d4a388..cf81cbc57544 100644
--- a/arch/arm/mach-ns9xxx/clock.c
+++ b/arch/arm/mach-ns9xxx/clock.c
@@ -195,7 +195,7 @@ static int clk_debugfs_open(struct inode *inode, struct file *file)
195 return single_open(file, clk_debugfs_show, NULL); 195 return single_open(file, clk_debugfs_show, NULL);
196} 196}
197 197
198static struct file_operations clk_debugfs_operations = { 198static const struct file_operations clk_debugfs_operations = {
199 .open = clk_debugfs_open, 199 .open = clk_debugfs_open,
200 .read = seq_read, 200 .read = seq_read,
201 .llseek = seq_lseek, 201 .llseek = seq_lseek,
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c
index b45ad312c587..2b0eb1ba5d7f 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -38,49 +38,49 @@
38 38
39static int board_keymap[] = { 39static int board_keymap[] = {
40 KEY(0, 0, KEY_Q), 40 KEY(0, 0, KEY_Q),
41 KEY(0, 1, KEY_W), 41 KEY(0, 1, KEY_O),
42 KEY(0, 2, KEY_E), 42 KEY(0, 2, KEY_P),
43 KEY(0, 3, KEY_R), 43 KEY(0, 3, KEY_COMMA),
44 KEY(0, 4, KEY_T), 44 KEY(0, 4, KEY_BACKSPACE),
45 KEY(0, 5, KEY_Y), 45 KEY(0, 6, KEY_A),
46 KEY(0, 6, KEY_U), 46 KEY(0, 7, KEY_S),
47 KEY(0, 7, KEY_I), 47 KEY(1, 0, KEY_W),
48 KEY(1, 0, KEY_O),
49 KEY(1, 1, KEY_D), 48 KEY(1, 1, KEY_D),
50 KEY(1, 2, KEY_DOT), 49 KEY(1, 2, KEY_F),
51 KEY(1, 3, KEY_V), 50 KEY(1, 3, KEY_G),
52 KEY(1, 4, KEY_DOWN), 51 KEY(1, 4, KEY_H),
53 KEY(2, 0, KEY_P), 52 KEY(1, 5, KEY_J),
54 KEY(2, 1, KEY_F), 53 KEY(1, 6, KEY_K),
54 KEY(1, 7, KEY_L),
55 KEY(2, 0, KEY_E),
56 KEY(2, 1, KEY_DOT),
55 KEY(2, 2, KEY_UP), 57 KEY(2, 2, KEY_UP),
56 KEY(2, 3, KEY_B), 58 KEY(2, 3, KEY_ENTER),
57 KEY(2, 4, KEY_RIGHT), 59 KEY(2, 5, KEY_Z),
58 KEY(3, 0, KEY_COMMA), 60 KEY(2, 6, KEY_X),
59 KEY(3, 1, KEY_G), 61 KEY(2, 7, KEY_C),
60 KEY(3, 2, KEY_ENTER), 62 KEY(3, 0, KEY_R),
63 KEY(3, 1, KEY_V),
64 KEY(3, 2, KEY_B),
61 KEY(3, 3, KEY_N), 65 KEY(3, 3, KEY_N),
62 KEY(4, 0, KEY_BACKSPACE), 66 KEY(3, 4, KEY_M),
63 KEY(4, 1, KEY_H), 67 KEY(3, 5, KEY_SPACE),
64 KEY(4, 3, KEY_M), 68 KEY(3, 6, KEY_SPACE),
69 KEY(3, 7, KEY_LEFT),
70 KEY(4, 0, KEY_T),
71 KEY(4, 1, KEY_DOWN),
72 KEY(4, 2, KEY_RIGHT),
65 KEY(4, 4, KEY_LEFTCTRL), 73 KEY(4, 4, KEY_LEFTCTRL),
66 KEY(5, 1, KEY_J), 74 KEY(4, 5, KEY_RIGHTALT),
67 KEY(5, 2, KEY_Z), 75 KEY(4, 6, KEY_LEFTSHIFT),
68 KEY(5, 3, KEY_SPACE), 76 KEY(5, 0, KEY_Y),
69 KEY(5, 4, KEY_LEFTSHIFT), 77 KEY(6, 0, KEY_U),
70 KEY(6, 0, KEY_A), 78 KEY(7, 0, KEY_I),
71 KEY(6, 1, KEY_K), 79 KEY(7, 1, KEY_F7),
72 KEY(6, 2, KEY_X), 80 KEY(7, 2, KEY_F8),
73 KEY(6, 3, KEY_SPACE), 81 KEY(0xff, 2, KEY_F9),
74 KEY(6, 4, KEY_FN), 82 KEY(0xff, 4, KEY_F10),
75 KEY(7, 0, KEY_S), 83 KEY(0xff, 5, KEY_F11),
76 KEY(7, 1, KEY_L),
77 KEY(7, 2, KEY_C),
78 KEY(7, 3, KEY_LEFT),
79 KEY(0xff, 0, KEY_F6),
80 KEY(0xff, 1, KEY_F7),
81 KEY(0xff, 2, KEY_F8),
82 KEY(0xff, 4, KEY_F9),
83 KEY(0xff, 5, KEY_F10),
84}; 84};
85 85
86static struct matrix_keymap_data board_map_data = { 86static struct matrix_keymap_data board_map_data = {
@@ -444,7 +444,7 @@ static int __init rx51_i2c_init(void)
444 rx51_twldata.vaux3 = &rx51_vaux3_cam; 444 rx51_twldata.vaux3 = &rx51_vaux3_cam;
445 rx51_twldata.vmmc2 = &rx51_vmmc2; 445 rx51_twldata.vmmc2 = &rx51_vmmc2;
446 } 446 }
447 omap_register_i2c_bus(1, 2600, rx51_peripherals_i2c_board_info_1, 447 omap_register_i2c_bus(1, 2200, rx51_peripherals_i2c_board_info_1,
448 ARRAY_SIZE(rx51_peripherals_i2c_board_info_1)); 448 ARRAY_SIZE(rx51_peripherals_i2c_board_info_1));
449 omap_register_i2c_bus(2, 100, NULL, 0); 449 omap_register_i2c_bus(2, 100, NULL, 0);
450 omap_register_i2c_bus(3, 400, NULL, 0); 450 omap_register_i2c_bus(3, 400, NULL, 0);
diff --git a/arch/arm/mach-omap2/board-zoom2.c b/arch/arm/mach-omap2/board-zoom2.c
index b7b32208ced7..fd3369d5e5cb 100644
--- a/arch/arm/mach-omap2/board-zoom2.c
+++ b/arch/arm/mach-omap2/board-zoom2.c
@@ -25,6 +25,7 @@
25#include <mach/keypad.h> 25#include <mach/keypad.h>
26 26
27#include "mmc-twl4030.h" 27#include "mmc-twl4030.h"
28#include "sdram-micron-mt46h32m32lf-6.h"
28 29
29/* Zoom2 has Qwerty keyboard*/ 30/* Zoom2 has Qwerty keyboard*/
30static int board_keymap[] = { 31static int board_keymap[] = {
@@ -213,7 +214,8 @@ static void __init omap_zoom2_init_irq(void)
213{ 214{
214 omap_board_config = zoom2_config; 215 omap_board_config = zoom2_config;
215 omap_board_config_size = ARRAY_SIZE(zoom2_config); 216 omap_board_config_size = ARRAY_SIZE(zoom2_config);
216 omap2_init_common_hw(NULL, NULL); 217 omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
218 mt46h32m32lf6_sdrc_params);
217 omap_init_irq(); 219 omap_init_irq();
218 omap_gpio_init(); 220 omap_gpio_init();
219} 221}
diff --git a/arch/arm/mach-omap2/clock24xx.c b/arch/arm/mach-omap2/clock24xx.c
index bc5d3ac66611..e2dbedd581e8 100644
--- a/arch/arm/mach-omap2/clock24xx.c
+++ b/arch/arm/mach-omap2/clock24xx.c
@@ -769,6 +769,7 @@ int __init omap2_clk_init(void)
769 if (c->cpu & cpu_mask) { 769 if (c->cpu & cpu_mask) {
770 clkdev_add(&c->lk); 770 clkdev_add(&c->lk);
771 clk_register(c->lk.clk); 771 clk_register(c->lk.clk);
772 omap2_init_clk_clkdm(c->lk.clk);
772 } 773 }
773 774
774 /* Check the MPU rate set by bootloader */ 775 /* Check the MPU rate set by bootloader */
diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
index fafcd32e6907..489556eecbd1 100644
--- a/arch/arm/mach-omap2/clock34xx.c
+++ b/arch/arm/mach-omap2/clock34xx.c
@@ -338,6 +338,13 @@ static struct omap_clk omap34xx_clks[] = {
338 */ 338 */
339#define SDRC_MPURATE_LOOPS 96 339#define SDRC_MPURATE_LOOPS 96
340 340
341/*
342 * DPLL5_FREQ_FOR_USBHOST: USBHOST and USBTLL are the only clocks
343 * that are sourced by DPLL5, and both of these require this clock
344 * to be at 120 MHz for proper operation.
345 */
346#define DPLL5_FREQ_FOR_USBHOST 120000000
347
341/** 348/**
342 * omap3430es2_clk_ssi_find_idlest - return CM_IDLEST info for SSI 349 * omap3430es2_clk_ssi_find_idlest - return CM_IDLEST info for SSI
343 * @clk: struct clk * being enabled 350 * @clk: struct clk * being enabled
@@ -1056,6 +1063,28 @@ void omap2_clk_prepare_for_reboot(void)
1056#endif 1063#endif
1057} 1064}
1058 1065
1066static void omap3_clk_lock_dpll5(void)
1067{
1068 struct clk *dpll5_clk;
1069 struct clk *dpll5_m2_clk;
1070
1071 dpll5_clk = clk_get(NULL, "dpll5_ck");
1072 clk_set_rate(dpll5_clk, DPLL5_FREQ_FOR_USBHOST);
1073 clk_enable(dpll5_clk);
1074
1075 /* Enable autoidle to allow it to enter low power bypass */
1076 omap3_dpll_allow_idle(dpll5_clk);
1077
1078 /* Program dpll5_m2_clk divider for no division */
1079 dpll5_m2_clk = clk_get(NULL, "dpll5_m2_ck");
1080 clk_enable(dpll5_m2_clk);
1081 clk_set_rate(dpll5_m2_clk, DPLL5_FREQ_FOR_USBHOST);
1082
1083 clk_disable(dpll5_m2_clk);
1084 clk_disable(dpll5_clk);
1085 return;
1086}
1087
1059/* REVISIT: Move this init stuff out into clock.c */ 1088/* REVISIT: Move this init stuff out into clock.c */
1060 1089
1061/* 1090/*
@@ -1148,6 +1177,12 @@ int __init omap2_clk_init(void)
1148 */ 1177 */
1149 clk_enable_init_clocks(); 1178 clk_enable_init_clocks();
1150 1179
1180 /*
1181 * Lock DPLL5 and put it in autoidle.
1182 */
1183 if (omap_rev() >= OMAP3430_REV_ES2_0)
1184 omap3_clk_lock_dpll5();
1185
1151 /* Avoid sleeping during omap2_clk_prepare_for_reboot() */ 1186 /* Avoid sleeping during omap2_clk_prepare_for_reboot() */
1152 /* REVISIT: not yet ready for 343x */ 1187 /* REVISIT: not yet ready for 343x */
1153#if 0 1188#if 0
diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
index 4ef7b4f5474e..58aff8485df9 100644
--- a/arch/arm/mach-omap2/clockdomain.c
+++ b/arch/arm/mach-omap2/clockdomain.c
@@ -137,6 +137,36 @@ static void _clkdm_del_autodeps(struct clockdomain *clkdm)
137 } 137 }
138} 138}
139 139
140/*
141 * _omap2_clkdm_set_hwsup - set the hwsup idle transition bit
142 * @clkdm: struct clockdomain *
143 * @enable: int 0 to disable, 1 to enable
144 *
145 * Internal helper for actually switching the bit that controls hwsup
146 * idle transitions for clkdm.
147 */
148static void _omap2_clkdm_set_hwsup(struct clockdomain *clkdm, int enable)
149{
150 u32 v;
151
152 if (cpu_is_omap24xx()) {
153 if (enable)
154 v = OMAP24XX_CLKSTCTRL_ENABLE_AUTO;
155 else
156 v = OMAP24XX_CLKSTCTRL_DISABLE_AUTO;
157 } else if (cpu_is_omap34xx()) {
158 if (enable)
159 v = OMAP34XX_CLKSTCTRL_ENABLE_AUTO;
160 else
161 v = OMAP34XX_CLKSTCTRL_DISABLE_AUTO;
162 } else {
163 BUG();
164 }
165
166 cm_rmw_mod_reg_bits(clkdm->clktrctrl_mask,
167 v << __ffs(clkdm->clktrctrl_mask),
168 clkdm->pwrdm.ptr->prcm_offs, CM_CLKSTCTRL);
169}
140 170
141static struct clockdomain *_clkdm_lookup(const char *name) 171static struct clockdomain *_clkdm_lookup(const char *name)
142{ 172{
@@ -456,8 +486,6 @@ int omap2_clkdm_wakeup(struct clockdomain *clkdm)
456 */ 486 */
457void omap2_clkdm_allow_idle(struct clockdomain *clkdm) 487void omap2_clkdm_allow_idle(struct clockdomain *clkdm)
458{ 488{
459 u32 v;
460
461 if (!clkdm) 489 if (!clkdm)
462 return; 490 return;
463 491
@@ -473,18 +501,7 @@ void omap2_clkdm_allow_idle(struct clockdomain *clkdm)
473 if (atomic_read(&clkdm->usecount) > 0) 501 if (atomic_read(&clkdm->usecount) > 0)
474 _clkdm_add_autodeps(clkdm); 502 _clkdm_add_autodeps(clkdm);
475 503
476 if (cpu_is_omap24xx()) 504 _omap2_clkdm_set_hwsup(clkdm, 1);
477 v = OMAP24XX_CLKSTCTRL_ENABLE_AUTO;
478 else if (cpu_is_omap34xx())
479 v = OMAP34XX_CLKSTCTRL_ENABLE_AUTO;
480 else
481 BUG();
482
483
484 cm_rmw_mod_reg_bits(clkdm->clktrctrl_mask,
485 v << __ffs(clkdm->clktrctrl_mask),
486 clkdm->pwrdm.ptr->prcm_offs,
487 CM_CLKSTCTRL);
488 505
489 pwrdm_clkdm_state_switch(clkdm); 506 pwrdm_clkdm_state_switch(clkdm);
490} 507}
@@ -500,8 +517,6 @@ void omap2_clkdm_allow_idle(struct clockdomain *clkdm)
500 */ 517 */
501void omap2_clkdm_deny_idle(struct clockdomain *clkdm) 518void omap2_clkdm_deny_idle(struct clockdomain *clkdm)
502{ 519{
503 u32 v;
504
505 if (!clkdm) 520 if (!clkdm)
506 return; 521 return;
507 522
@@ -514,16 +529,7 @@ void omap2_clkdm_deny_idle(struct clockdomain *clkdm)
514 pr_debug("clockdomain: disabling automatic idle transitions for %s\n", 529 pr_debug("clockdomain: disabling automatic idle transitions for %s\n",
515 clkdm->name); 530 clkdm->name);
516 531
517 if (cpu_is_omap24xx()) 532 _omap2_clkdm_set_hwsup(clkdm, 0);
518 v = OMAP24XX_CLKSTCTRL_DISABLE_AUTO;
519 else if (cpu_is_omap34xx())
520 v = OMAP34XX_CLKSTCTRL_DISABLE_AUTO;
521 else
522 BUG();
523
524 cm_rmw_mod_reg_bits(clkdm->clktrctrl_mask,
525 v << __ffs(clkdm->clktrctrl_mask),
526 clkdm->pwrdm.ptr->prcm_offs, CM_CLKSTCTRL);
527 533
528 if (atomic_read(&clkdm->usecount) > 0) 534 if (atomic_read(&clkdm->usecount) > 0)
529 _clkdm_del_autodeps(clkdm); 535 _clkdm_del_autodeps(clkdm);
@@ -569,10 +575,14 @@ int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk)
569 v = omap2_clkdm_clktrctrl_read(clkdm); 575 v = omap2_clkdm_clktrctrl_read(clkdm);
570 576
571 if ((cpu_is_omap34xx() && v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) || 577 if ((cpu_is_omap34xx() && v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) ||
572 (cpu_is_omap24xx() && v == OMAP24XX_CLKSTCTRL_ENABLE_AUTO)) 578 (cpu_is_omap24xx() && v == OMAP24XX_CLKSTCTRL_ENABLE_AUTO)) {
579 /* Disable HW transitions when we are changing deps */
580 _omap2_clkdm_set_hwsup(clkdm, 0);
573 _clkdm_add_autodeps(clkdm); 581 _clkdm_add_autodeps(clkdm);
574 else 582 _omap2_clkdm_set_hwsup(clkdm, 1);
583 } else {
575 omap2_clkdm_wakeup(clkdm); 584 omap2_clkdm_wakeup(clkdm);
585 }
576 586
577 pwrdm_wait_transition(clkdm->pwrdm.ptr); 587 pwrdm_wait_transition(clkdm->pwrdm.ptr);
578 pwrdm_clkdm_state_switch(clkdm); 588 pwrdm_clkdm_state_switch(clkdm);
@@ -623,10 +633,14 @@ int omap2_clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk)
623 v = omap2_clkdm_clktrctrl_read(clkdm); 633 v = omap2_clkdm_clktrctrl_read(clkdm);
624 634
625 if ((cpu_is_omap34xx() && v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) || 635 if ((cpu_is_omap34xx() && v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) ||
626 (cpu_is_omap24xx() && v == OMAP24XX_CLKSTCTRL_ENABLE_AUTO)) 636 (cpu_is_omap24xx() && v == OMAP24XX_CLKSTCTRL_ENABLE_AUTO)) {
637 /* Disable HW transitions when we are changing deps */
638 _omap2_clkdm_set_hwsup(clkdm, 0);
627 _clkdm_del_autodeps(clkdm); 639 _clkdm_del_autodeps(clkdm);
628 else 640 _omap2_clkdm_set_hwsup(clkdm, 1);
641 } else {
629 omap2_clkdm_sleep(clkdm); 642 omap2_clkdm_sleep(clkdm);
643 }
630 644
631 pwrdm_clkdm_state_switch(clkdm); 645 pwrdm_clkdm_state_switch(clkdm);
632 646
diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
index 1b4c1600f8d8..2fc4d6abbd0a 100644
--- a/arch/arm/mach-omap2/pm-debug.c
+++ b/arch/arm/mach-omap2/pm-debug.c
@@ -541,7 +541,7 @@ static int __init pm_dbg_init(void)
541 printk(KERN_ERR "%s: only OMAP3 supported\n", __func__); 541 printk(KERN_ERR "%s: only OMAP3 supported\n", __func__);
542 return -ENODEV; 542 return -ENODEV;
543 } 543 }
544 544
545 d = debugfs_create_dir("pm_debug", NULL); 545 d = debugfs_create_dir("pm_debug", NULL);
546 if (IS_ERR(d)) 546 if (IS_ERR(d))
547 return PTR_ERR(d); 547 return PTR_ERR(d);
@@ -551,7 +551,7 @@ static int __init pm_dbg_init(void)
551 (void) debugfs_create_file("time", S_IRUGO, 551 (void) debugfs_create_file("time", S_IRUGO,
552 d, (void *)DEBUG_FILE_TIMERS, &debug_fops); 552 d, (void *)DEBUG_FILE_TIMERS, &debug_fops);
553 553
554 pwrdm_for_each(pwrdms_setup, (void *)d); 554 pwrdm_for_each_nolock(pwrdms_setup, (void *)d);
555 555
556 pm_dbg_dir = debugfs_create_dir("registers", d); 556 pm_dbg_dir = debugfs_create_dir("registers", d);
557 if (IS_ERR(pm_dbg_dir)) 557 if (IS_ERR(pm_dbg_dir))
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 0ff5a6c53aa0..378c2f618358 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -51,97 +51,112 @@ static void (*_omap_sram_idle)(u32 *addr, int save_state);
51 51
52static struct powerdomain *mpu_pwrdm; 52static struct powerdomain *mpu_pwrdm;
53 53
54/* PRCM Interrupt Handler for wakeups */ 54/*
55static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id) 55 * PRCM Interrupt Handler Helper Function
56 *
57 * The purpose of this function is to clear any wake-up events latched
58 * in the PRCM PM_WKST_x registers. It is possible that a wake-up event
59 * may occur whilst attempting to clear a PM_WKST_x register and thus
60 * set another bit in this register. A while loop is used to ensure
61 * that any peripheral wake-up events occurring while attempting to
62 * clear the PM_WKST_x are detected and cleared.
63 */
64static int prcm_clear_mod_irqs(s16 module, u8 regs)
56{ 65{
57 u32 wkst, irqstatus_mpu; 66 u32 wkst, fclk, iclk, clken;
58 u32 fclk, iclk; 67 u16 wkst_off = (regs == 3) ? OMAP3430ES2_PM_WKST3 : PM_WKST1;
59 68 u16 fclk_off = (regs == 3) ? OMAP3430ES2_CM_FCLKEN3 : CM_FCLKEN1;
60 /* WKUP */ 69 u16 iclk_off = (regs == 3) ? CM_ICLKEN3 : CM_ICLKEN1;
61 wkst = prm_read_mod_reg(WKUP_MOD, PM_WKST); 70 u16 grpsel_off = (regs == 3) ?
71 OMAP3430ES2_PM_MPUGRPSEL3 : OMAP3430_PM_MPUGRPSEL;
72 int c = 0;
73
74 wkst = prm_read_mod_reg(module, wkst_off);
75 wkst &= prm_read_mod_reg(module, grpsel_off);
62 if (wkst) { 76 if (wkst) {
63 iclk = cm_read_mod_reg(WKUP_MOD, CM_ICLKEN); 77 iclk = cm_read_mod_reg(module, iclk_off);
64 fclk = cm_read_mod_reg(WKUP_MOD, CM_FCLKEN); 78 fclk = cm_read_mod_reg(module, fclk_off);
65 cm_set_mod_reg_bits(wkst, WKUP_MOD, CM_ICLKEN); 79 while (wkst) {
66 cm_set_mod_reg_bits(wkst, WKUP_MOD, CM_FCLKEN); 80 clken = wkst;
67 prm_write_mod_reg(wkst, WKUP_MOD, PM_WKST); 81 cm_set_mod_reg_bits(clken, module, iclk_off);
68 while (prm_read_mod_reg(WKUP_MOD, PM_WKST)) 82 /*
69 cpu_relax(); 83 * For USBHOST, we don't know whether HOST1 or
70 cm_write_mod_reg(iclk, WKUP_MOD, CM_ICLKEN); 84 * HOST2 woke us up, so enable both f-clocks
71 cm_write_mod_reg(fclk, WKUP_MOD, CM_FCLKEN); 85 */
86 if (module == OMAP3430ES2_USBHOST_MOD)
87 clken |= 1 << OMAP3430ES2_EN_USBHOST2_SHIFT;
88 cm_set_mod_reg_bits(clken, module, fclk_off);
89 prm_write_mod_reg(wkst, module, wkst_off);
90 wkst = prm_read_mod_reg(module, wkst_off);
91 c++;
92 }
93 cm_write_mod_reg(iclk, module, iclk_off);
94 cm_write_mod_reg(fclk, module, fclk_off);
72 } 95 }
73 96
74 /* CORE */ 97 return c;
75 wkst = prm_read_mod_reg(CORE_MOD, PM_WKST1); 98}
76 if (wkst) {
77 iclk = cm_read_mod_reg(CORE_MOD, CM_ICLKEN1);
78 fclk = cm_read_mod_reg(CORE_MOD, CM_FCLKEN1);
79 cm_set_mod_reg_bits(wkst, CORE_MOD, CM_ICLKEN1);
80 cm_set_mod_reg_bits(wkst, CORE_MOD, CM_FCLKEN1);
81 prm_write_mod_reg(wkst, CORE_MOD, PM_WKST1);
82 while (prm_read_mod_reg(CORE_MOD, PM_WKST1))
83 cpu_relax();
84 cm_write_mod_reg(iclk, CORE_MOD, CM_ICLKEN1);
85 cm_write_mod_reg(fclk, CORE_MOD, CM_FCLKEN1);
86 }
87 wkst = prm_read_mod_reg(CORE_MOD, OMAP3430ES2_PM_WKST3);
88 if (wkst) {
89 iclk = cm_read_mod_reg(CORE_MOD, CM_ICLKEN3);
90 fclk = cm_read_mod_reg(CORE_MOD, OMAP3430ES2_CM_FCLKEN3);
91 cm_set_mod_reg_bits(wkst, CORE_MOD, CM_ICLKEN3);
92 cm_set_mod_reg_bits(wkst, CORE_MOD, OMAP3430ES2_CM_FCLKEN3);
93 prm_write_mod_reg(wkst, CORE_MOD, OMAP3430ES2_PM_WKST3);
94 while (prm_read_mod_reg(CORE_MOD, OMAP3430ES2_PM_WKST3))
95 cpu_relax();
96 cm_write_mod_reg(iclk, CORE_MOD, CM_ICLKEN3);
97 cm_write_mod_reg(fclk, CORE_MOD, OMAP3430ES2_CM_FCLKEN3);
98 }
99 99
100 /* PER */ 100static int _prcm_int_handle_wakeup(void)
101 wkst = prm_read_mod_reg(OMAP3430_PER_MOD, PM_WKST); 101{
102 if (wkst) { 102 int c;
103 iclk = cm_read_mod_reg(OMAP3430_PER_MOD, CM_ICLKEN);
104 fclk = cm_read_mod_reg(OMAP3430_PER_MOD, CM_FCLKEN);
105 cm_set_mod_reg_bits(wkst, OMAP3430_PER_MOD, CM_ICLKEN);
106 cm_set_mod_reg_bits(wkst, OMAP3430_PER_MOD, CM_FCLKEN);
107 prm_write_mod_reg(wkst, OMAP3430_PER_MOD, PM_WKST);
108 while (prm_read_mod_reg(OMAP3430_PER_MOD, PM_WKST))
109 cpu_relax();
110 cm_write_mod_reg(iclk, OMAP3430_PER_MOD, CM_ICLKEN);
111 cm_write_mod_reg(fclk, OMAP3430_PER_MOD, CM_FCLKEN);
112 }
113 103
104 c = prcm_clear_mod_irqs(WKUP_MOD, 1);
105 c += prcm_clear_mod_irqs(CORE_MOD, 1);
106 c += prcm_clear_mod_irqs(OMAP3430_PER_MOD, 1);
114 if (omap_rev() > OMAP3430_REV_ES1_0) { 107 if (omap_rev() > OMAP3430_REV_ES1_0) {
115 /* USBHOST */ 108 c += prcm_clear_mod_irqs(CORE_MOD, 3);
116 wkst = prm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, PM_WKST); 109 c += prcm_clear_mod_irqs(OMAP3430ES2_USBHOST_MOD, 1);
117 if (wkst) {
118 iclk = cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
119 CM_ICLKEN);
120 fclk = cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
121 CM_FCLKEN);
122 cm_set_mod_reg_bits(wkst, OMAP3430ES2_USBHOST_MOD,
123 CM_ICLKEN);
124 cm_set_mod_reg_bits(wkst, OMAP3430ES2_USBHOST_MOD,
125 CM_FCLKEN);
126 prm_write_mod_reg(wkst, OMAP3430ES2_USBHOST_MOD,
127 PM_WKST);
128 while (prm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
129 PM_WKST))
130 cpu_relax();
131 cm_write_mod_reg(iclk, OMAP3430ES2_USBHOST_MOD,
132 CM_ICLKEN);
133 cm_write_mod_reg(fclk, OMAP3430ES2_USBHOST_MOD,
134 CM_FCLKEN);
135 }
136 } 110 }
137 111
138 irqstatus_mpu = prm_read_mod_reg(OCP_MOD, 112 return c;
139 OMAP3_PRM_IRQSTATUS_MPU_OFFSET); 113}
140 prm_write_mod_reg(irqstatus_mpu, OCP_MOD, 114
141 OMAP3_PRM_IRQSTATUS_MPU_OFFSET); 115/*
116 * PRCM Interrupt Handler
117 *
118 * The PRM_IRQSTATUS_MPU register indicates if there are any pending
119 * interrupts from the PRCM for the MPU. These bits must be cleared in
120 * order to clear the PRCM interrupt. The PRCM interrupt handler is
121 * implemented to simply clear the PRM_IRQSTATUS_MPU in order to clear
122 * the PRCM interrupt. Please note that bit 0 of the PRM_IRQSTATUS_MPU
123 * register indicates that a wake-up event is pending for the MPU and
124 * this bit can only be cleared if the all the wake-up events latched
125 * in the various PM_WKST_x registers have been cleared. The interrupt
126 * handler is implemented using a do-while loop so that if a wake-up
127 * event occurred during the processing of the prcm interrupt handler
128 * (setting a bit in the corresponding PM_WKST_x register and thus
129 * preventing us from clearing bit 0 of the PRM_IRQSTATUS_MPU register)
130 * this would be handled.
131 */
132static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id)
133{
134 u32 irqstatus_mpu;
135 int c = 0;
136
137 do {
138 irqstatus_mpu = prm_read_mod_reg(OCP_MOD,
139 OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
140
141 if (irqstatus_mpu & (OMAP3430_WKUP_ST | OMAP3430_IO_ST)) {
142 c = _prcm_int_handle_wakeup();
143
144 /*
145 * Is the MPU PRCM interrupt handler racing with the
146 * IVA2 PRCM interrupt handler ?
147 */
148 WARN(c == 0, "prcm: WARNING: PRCM indicated MPU wakeup "
149 "but no wakeup sources are marked\n");
150 } else {
151 /* XXX we need to expand our PRCM interrupt handler */
152 WARN(1, "prcm: WARNING: PRCM interrupt received, but "
153 "no code to handle it (%08x)\n", irqstatus_mpu);
154 }
155
156 prm_write_mod_reg(irqstatus_mpu, OCP_MOD,
157 OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
142 158
143 while (prm_read_mod_reg(OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET)) 159 } while (prm_read_mod_reg(OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET));
144 cpu_relax();
145 160
146 return IRQ_HANDLED; 161 return IRQ_HANDLED;
147} 162}
@@ -624,6 +639,16 @@ static void __init prcm_setup_regs(void)
624 prm_write_mod_reg(OMAP3430_IO_EN | OMAP3430_WKUP_EN, 639 prm_write_mod_reg(OMAP3430_IO_EN | OMAP3430_WKUP_EN,
625 OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET); 640 OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET);
626 641
642 /* Enable GPIO wakeups in PER */
643 prm_write_mod_reg(OMAP3430_EN_GPIO2 | OMAP3430_EN_GPIO3 |
644 OMAP3430_EN_GPIO4 | OMAP3430_EN_GPIO5 |
645 OMAP3430_EN_GPIO6, OMAP3430_PER_MOD, PM_WKEN);
646 /* and allow them to wake up MPU */
647 prm_write_mod_reg(OMAP3430_GRPSEL_GPIO2 | OMAP3430_EN_GPIO3 |
648 OMAP3430_GRPSEL_GPIO4 | OMAP3430_EN_GPIO5 |
649 OMAP3430_GRPSEL_GPIO6,
650 OMAP3430_PER_MOD, OMAP3430_PM_MPUGRPSEL);
651
627 /* Don't attach IVA interrupts */ 652 /* Don't attach IVA interrupts */
628 prm_write_mod_reg(0, WKUP_MOD, OMAP3430_PM_IVAGRPSEL); 653 prm_write_mod_reg(0, WKUP_MOD, OMAP3430_PM_IVAGRPSEL);
629 prm_write_mod_reg(0, CORE_MOD, OMAP3430_PM_IVAGRPSEL1); 654 prm_write_mod_reg(0, CORE_MOD, OMAP3430_PM_IVAGRPSEL1);
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index 2594cbff3947..f00289abd30f 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -273,35 +273,50 @@ struct powerdomain *pwrdm_lookup(const char *name)
273} 273}
274 274
275/** 275/**
276 * pwrdm_for_each - call function on each registered clockdomain 276 * pwrdm_for_each_nolock - call function on each registered clockdomain
277 * @fn: callback function * 277 * @fn: callback function *
278 * 278 *
279 * Call the supplied function for each registered powerdomain. The 279 * Call the supplied function for each registered powerdomain. The
280 * callback function can return anything but 0 to bail out early from 280 * callback function can return anything but 0 to bail out early from
281 * the iterator. The callback function is called with the pwrdm_rwlock 281 * the iterator. Returns the last return value of the callback function, which
282 * held for reading, so no powerdomain structure manipulation 282 * should be 0 for success or anything else to indicate failure; or -EINVAL if
283 * functions should be called from the callback, although hardware 283 * the function pointer is null.
284 * powerdomain control functions are fine. Returns the last return
285 * value of the callback function, which should be 0 for success or
286 * anything else to indicate failure; or -EINVAL if the function
287 * pointer is null.
288 */ 284 */
289int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm, void *user), 285int pwrdm_for_each_nolock(int (*fn)(struct powerdomain *pwrdm, void *user),
290 void *user) 286 void *user)
291{ 287{
292 struct powerdomain *temp_pwrdm; 288 struct powerdomain *temp_pwrdm;
293 unsigned long flags;
294 int ret = 0; 289 int ret = 0;
295 290
296 if (!fn) 291 if (!fn)
297 return -EINVAL; 292 return -EINVAL;
298 293
299 read_lock_irqsave(&pwrdm_rwlock, flags);
300 list_for_each_entry(temp_pwrdm, &pwrdm_list, node) { 294 list_for_each_entry(temp_pwrdm, &pwrdm_list, node) {
301 ret = (*fn)(temp_pwrdm, user); 295 ret = (*fn)(temp_pwrdm, user);
302 if (ret) 296 if (ret)
303 break; 297 break;
304 } 298 }
299
300 return ret;
301}
302
303/**
304 * pwrdm_for_each - call function on each registered clockdomain
305 * @fn: callback function *
306 *
307 * This function is the same as 'pwrdm_for_each_nolock()', but keeps the
308 * &pwrdm_rwlock locked for reading, so no powerdomain structure manipulation
309 * functions should be called from the callback, although hardware powerdomain
310 * control functions are fine.
311 */
312int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm, void *user),
313 void *user)
314{
315 unsigned long flags;
316 int ret;
317
318 read_lock_irqsave(&pwrdm_rwlock, flags);
319 ret = pwrdm_for_each_nolock(fn, user);
305 read_unlock_irqrestore(&pwrdm_rwlock, flags); 320 read_unlock_irqrestore(&pwrdm_rwlock, flags);
306 321
307 return ret; 322 return ret;
diff --git a/arch/arm/mach-pxa/cpufreq-pxa2xx.c b/arch/arm/mach-pxa/cpufreq-pxa2xx.c
index 3a8ee2272add..983cc8c20081 100644
--- a/arch/arm/mach-pxa/cpufreq-pxa2xx.c
+++ b/arch/arm/mach-pxa/cpufreq-pxa2xx.c
@@ -155,7 +155,7 @@ MODULE_PARM_DESC(pxa255_turbo_table, "Selects the frequency table (0 = run table
155 155
156static pxa_freqs_t pxa27x_freqs[] = { 156static pxa_freqs_t pxa27x_freqs[] = {
157 {104000, 104000, PXA27x_CCCR(1, 8, 2), 0, CCLKCFG2(1, 0, 1), 900000, 1705000 }, 157 {104000, 104000, PXA27x_CCCR(1, 8, 2), 0, CCLKCFG2(1, 0, 1), 900000, 1705000 },
158 {156000, 104000, PXA27x_CCCR(1, 8, 6), 0, CCLKCFG2(1, 1, 1), 1000000, 1705000 }, 158 {156000, 104000, PXA27x_CCCR(1, 8, 3), 0, CCLKCFG2(1, 0, 1), 1000000, 1705000 },
159 {208000, 208000, PXA27x_CCCR(0, 16, 2), 1, CCLKCFG2(0, 0, 1), 1180000, 1705000 }, 159 {208000, 208000, PXA27x_CCCR(0, 16, 2), 1, CCLKCFG2(0, 0, 1), 1180000, 1705000 },
160 {312000, 208000, PXA27x_CCCR(1, 16, 3), 1, CCLKCFG2(1, 0, 1), 1250000, 1705000 }, 160 {312000, 208000, PXA27x_CCCR(1, 16, 3), 1, CCLKCFG2(1, 0, 1), 1250000, 1705000 },
161 {416000, 208000, PXA27x_CCCR(1, 16, 4), 1, CCLKCFG2(1, 0, 1), 1350000, 1705000 }, 161 {416000, 208000, PXA27x_CCCR(1, 16, 4), 1, CCLKCFG2(1, 0, 1), 1350000, 1705000 },
diff --git a/arch/arm/mach-pxa/csb726.c b/arch/arm/mach-pxa/csb726.c
index 79141f862728..965480eb4fe6 100644
--- a/arch/arm/mach-pxa/csb726.c
+++ b/arch/arm/mach-pxa/csb726.c
@@ -238,7 +238,7 @@ static struct resource csb726_lan_resources[] = {
238}; 238};
239 239
240struct smsc911x_platform_config csb726_lan_config = { 240struct smsc911x_platform_config csb726_lan_config = {
241 .irq_type = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, 241 .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
242 .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL, 242 .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
243 .flags = SMSC911X_USE_32BIT, 243 .flags = SMSC911X_USE_32BIT,
244 .phy_interface = PHY_INTERFACE_MODE_MII, 244 .phy_interface = PHY_INTERFACE_MODE_MII,
diff --git a/arch/arm/mach-sa1100/Kconfig b/arch/arm/mach-sa1100/Kconfig
index 81ffff7ed498..4e5c07f4e456 100644
--- a/arch/arm/mach-sa1100/Kconfig
+++ b/arch/arm/mach-sa1100/Kconfig
@@ -71,11 +71,6 @@ config SA1100_H3600
71 <http://www.handhelds.org/Compaq/index.html#iPAQ_H3600> 71 <http://www.handhelds.org/Compaq/index.html#iPAQ_H3600>
72 <http://www.compaq.com/products/handhelds/pocketpc/> 72 <http://www.compaq.com/products/handhelds/pocketpc/>
73 73
74config SA1100_H3XXX
75 bool
76 depends on SA1100_H3100 || SA1100_H3600
77 default y
78
79config SA1100_BADGE4 74config SA1100_BADGE4
80 bool "HP Labs BadgePAD 4" 75 bool "HP Labs BadgePAD 4"
81 select SA1111 76 select SA1111
diff --git a/arch/arm/mach-sa1100/Makefile b/arch/arm/mach-sa1100/Makefile
index 8a5546e6d547..bb7b8198d0c4 100644
--- a/arch/arm/mach-sa1100/Makefile
+++ b/arch/arm/mach-sa1100/Makefile
@@ -25,6 +25,7 @@ led-$(CONFIG_SA1100_CERF) += leds-cerf.o
25 25
26obj-$(CONFIG_SA1100_COLLIE) += collie.o 26obj-$(CONFIG_SA1100_COLLIE) += collie.o
27 27
28obj-$(CONFIG_SA1100_H3100) += h3600.o
28obj-$(CONFIG_SA1100_H3600) += h3600.o 29obj-$(CONFIG_SA1100_H3600) += h3600.o
29 30
30obj-$(CONFIG_SA1100_HACKKIT) += hackkit.o 31obj-$(CONFIG_SA1100_HACKKIT) += hackkit.o
diff --git a/arch/arm/mach-sa1100/time.c b/arch/arm/mach-sa1100/time.c
index 95d92e8e56a8..b9cbb56d6e9d 100644
--- a/arch/arm/mach-sa1100/time.c
+++ b/arch/arm/mach-sa1100/time.c
@@ -77,7 +77,7 @@ static struct clock_event_device ckevt_sa1100_osmr0 = {
77 .set_mode = sa1100_osmr0_set_mode, 77 .set_mode = sa1100_osmr0_set_mode,
78}; 78};
79 79
80static cycle_t sa1100_read_oscr(void) 80static cycle_t sa1100_read_oscr(struct clocksource *s)
81{ 81{
82 return OSCR; 82 return OSCR;
83} 83}
diff --git a/arch/arm/mach-u300/gpio.c b/arch/arm/mach-u300/gpio.c
index 63c8f27fb15a..0b35826b7d1d 100644
--- a/arch/arm/mach-u300/gpio.c
+++ b/arch/arm/mach-u300/gpio.c
@@ -281,6 +281,16 @@ int gpio_unregister_callback(unsigned gpio)
281} 281}
282EXPORT_SYMBOL(gpio_unregister_callback); 282EXPORT_SYMBOL(gpio_unregister_callback);
283 283
284/* Non-zero means valid */
285int gpio_is_valid(int number)
286{
287 if (number >= 0 &&
288 number < (U300_GPIO_NUM_PORTS * U300_GPIO_PINS_PER_PORT))
289 return 1;
290 return 0;
291}
292EXPORT_SYMBOL(gpio_is_valid);
293
284int gpio_request(unsigned gpio, const char *label) 294int gpio_request(unsigned gpio, const char *label)
285{ 295{
286 if (gpio_pin[gpio].users) 296 if (gpio_pin[gpio].users)
diff --git a/arch/arm/mach-u300/include/mach/gpio.h b/arch/arm/mach-u300/include/mach/gpio.h
index c8174128d7eb..7b1fc984abb6 100644
--- a/arch/arm/mach-u300/include/mach/gpio.h
+++ b/arch/arm/mach-u300/include/mach/gpio.h
@@ -258,6 +258,7 @@
258#define PIN_TO_PORT(val) (val >> 3) 258#define PIN_TO_PORT(val) (val >> 3)
259 259
260/* These can be found in arch/arm/mach-u300/gpio.c */ 260/* These can be found in arch/arm/mach-u300/gpio.c */
261extern int gpio_is_valid(int number);
261extern int gpio_request(unsigned gpio, const char *label); 262extern int gpio_request(unsigned gpio, const char *label);
262extern void gpio_free(unsigned gpio); 263extern void gpio_free(unsigned gpio);
263extern int gpio_direction_input(unsigned gpio); 264extern int gpio_direction_input(unsigned gpio);
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 8d43e58f9244..e993140edd88 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -17,7 +17,7 @@ config CPU_ARM610
17 select CPU_CP15_MMU 17 select CPU_CP15_MMU
18 select CPU_COPY_V3 if MMU 18 select CPU_COPY_V3 if MMU
19 select CPU_TLB_V3 if MMU 19 select CPU_TLB_V3 if MMU
20 select CPU_PABRT_NOIFAR 20 select CPU_PABRT_LEGACY
21 help 21 help
22 The ARM610 is the successor to the ARM3 processor 22 The ARM610 is the successor to the ARM3 processor
23 and was produced by VLSI Technology Inc. 23 and was produced by VLSI Technology Inc.
@@ -31,7 +31,7 @@ config CPU_ARM7TDMI
31 depends on !MMU 31 depends on !MMU
32 select CPU_32v4T 32 select CPU_32v4T
33 select CPU_ABRT_LV4T 33 select CPU_ABRT_LV4T
34 select CPU_PABRT_NOIFAR 34 select CPU_PABRT_LEGACY
35 select CPU_CACHE_V4 35 select CPU_CACHE_V4
36 help 36 help
37 A 32-bit RISC microprocessor based on the ARM7 processor core 37 A 32-bit RISC microprocessor based on the ARM7 processor core
@@ -49,7 +49,7 @@ config CPU_ARM710
49 select CPU_CP15_MMU 49 select CPU_CP15_MMU
50 select CPU_COPY_V3 if MMU 50 select CPU_COPY_V3 if MMU
51 select CPU_TLB_V3 if MMU 51 select CPU_TLB_V3 if MMU
52 select CPU_PABRT_NOIFAR 52 select CPU_PABRT_LEGACY
53 help 53 help
54 A 32-bit RISC microprocessor based on the ARM7 processor core 54 A 32-bit RISC microprocessor based on the ARM7 processor core
55 designed by Advanced RISC Machines Ltd. The ARM710 is the 55 designed by Advanced RISC Machines Ltd. The ARM710 is the
@@ -64,7 +64,7 @@ config CPU_ARM720T
64 bool "Support ARM720T processor" if ARCH_INTEGRATOR 64 bool "Support ARM720T processor" if ARCH_INTEGRATOR
65 select CPU_32v4T 65 select CPU_32v4T
66 select CPU_ABRT_LV4T 66 select CPU_ABRT_LV4T
67 select CPU_PABRT_NOIFAR 67 select CPU_PABRT_LEGACY
68 select CPU_CACHE_V4 68 select CPU_CACHE_V4
69 select CPU_CACHE_VIVT 69 select CPU_CACHE_VIVT
70 select CPU_CP15_MMU 70 select CPU_CP15_MMU
@@ -83,7 +83,7 @@ config CPU_ARM740T
83 depends on !MMU 83 depends on !MMU
84 select CPU_32v4T 84 select CPU_32v4T
85 select CPU_ABRT_LV4T 85 select CPU_ABRT_LV4T
86 select CPU_PABRT_NOIFAR 86 select CPU_PABRT_LEGACY
87 select CPU_CACHE_V3 # although the core is v4t 87 select CPU_CACHE_V3 # although the core is v4t
88 select CPU_CP15_MPU 88 select CPU_CP15_MPU
89 help 89 help
@@ -100,7 +100,7 @@ config CPU_ARM9TDMI
100 depends on !MMU 100 depends on !MMU
101 select CPU_32v4T 101 select CPU_32v4T
102 select CPU_ABRT_NOMMU 102 select CPU_ABRT_NOMMU
103 select CPU_PABRT_NOIFAR 103 select CPU_PABRT_LEGACY
104 select CPU_CACHE_V4 104 select CPU_CACHE_V4
105 help 105 help
106 A 32-bit RISC microprocessor based on the ARM9 processor core 106 A 32-bit RISC microprocessor based on the ARM9 processor core
@@ -114,7 +114,7 @@ config CPU_ARM920T
114 bool "Support ARM920T processor" if ARCH_INTEGRATOR 114 bool "Support ARM920T processor" if ARCH_INTEGRATOR
115 select CPU_32v4T 115 select CPU_32v4T
116 select CPU_ABRT_EV4T 116 select CPU_ABRT_EV4T
117 select CPU_PABRT_NOIFAR 117 select CPU_PABRT_LEGACY
118 select CPU_CACHE_V4WT 118 select CPU_CACHE_V4WT
119 select CPU_CACHE_VIVT 119 select CPU_CACHE_VIVT
120 select CPU_CP15_MMU 120 select CPU_CP15_MMU
@@ -135,7 +135,7 @@ config CPU_ARM922T
135 bool "Support ARM922T processor" if ARCH_INTEGRATOR 135 bool "Support ARM922T processor" if ARCH_INTEGRATOR
136 select CPU_32v4T 136 select CPU_32v4T
137 select CPU_ABRT_EV4T 137 select CPU_ABRT_EV4T
138 select CPU_PABRT_NOIFAR 138 select CPU_PABRT_LEGACY
139 select CPU_CACHE_V4WT 139 select CPU_CACHE_V4WT
140 select CPU_CACHE_VIVT 140 select CPU_CACHE_VIVT
141 select CPU_CP15_MMU 141 select CPU_CP15_MMU
@@ -154,7 +154,7 @@ config CPU_ARM925T
154 bool "Support ARM925T processor" if ARCH_OMAP1 154 bool "Support ARM925T processor" if ARCH_OMAP1
155 select CPU_32v4T 155 select CPU_32v4T
156 select CPU_ABRT_EV4T 156 select CPU_ABRT_EV4T
157 select CPU_PABRT_NOIFAR 157 select CPU_PABRT_LEGACY
158 select CPU_CACHE_V4WT 158 select CPU_CACHE_V4WT
159 select CPU_CACHE_VIVT 159 select CPU_CACHE_VIVT
160 select CPU_CP15_MMU 160 select CPU_CP15_MMU
@@ -173,7 +173,7 @@ config CPU_ARM926T
173 bool "Support ARM926T processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB 173 bool "Support ARM926T processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB
174 select CPU_32v5 174 select CPU_32v5
175 select CPU_ABRT_EV5TJ 175 select CPU_ABRT_EV5TJ
176 select CPU_PABRT_NOIFAR 176 select CPU_PABRT_LEGACY
177 select CPU_CACHE_VIVT 177 select CPU_CACHE_VIVT
178 select CPU_CP15_MMU 178 select CPU_CP15_MMU
179 select CPU_COPY_V4WB if MMU 179 select CPU_COPY_V4WB if MMU
@@ -191,7 +191,7 @@ config CPU_FA526
191 bool 191 bool
192 select CPU_32v4 192 select CPU_32v4
193 select CPU_ABRT_EV4 193 select CPU_ABRT_EV4
194 select CPU_PABRT_NOIFAR 194 select CPU_PABRT_LEGACY
195 select CPU_CACHE_VIVT 195 select CPU_CACHE_VIVT
196 select CPU_CP15_MMU 196 select CPU_CP15_MMU
197 select CPU_CACHE_FA 197 select CPU_CACHE_FA
@@ -210,7 +210,7 @@ config CPU_ARM940T
210 depends on !MMU 210 depends on !MMU
211 select CPU_32v4T 211 select CPU_32v4T
212 select CPU_ABRT_NOMMU 212 select CPU_ABRT_NOMMU
213 select CPU_PABRT_NOIFAR 213 select CPU_PABRT_LEGACY
214 select CPU_CACHE_VIVT 214 select CPU_CACHE_VIVT
215 select CPU_CP15_MPU 215 select CPU_CP15_MPU
216 help 216 help
@@ -228,7 +228,7 @@ config CPU_ARM946E
228 depends on !MMU 228 depends on !MMU
229 select CPU_32v5 229 select CPU_32v5
230 select CPU_ABRT_NOMMU 230 select CPU_ABRT_NOMMU
231 select CPU_PABRT_NOIFAR 231 select CPU_PABRT_LEGACY
232 select CPU_CACHE_VIVT 232 select CPU_CACHE_VIVT
233 select CPU_CP15_MPU 233 select CPU_CP15_MPU
234 help 234 help
@@ -244,7 +244,7 @@ config CPU_ARM1020
244 bool "Support ARM1020T (rev 0) processor" if ARCH_INTEGRATOR 244 bool "Support ARM1020T (rev 0) processor" if ARCH_INTEGRATOR
245 select CPU_32v5 245 select CPU_32v5
246 select CPU_ABRT_EV4T 246 select CPU_ABRT_EV4T
247 select CPU_PABRT_NOIFAR 247 select CPU_PABRT_LEGACY
248 select CPU_CACHE_V4WT 248 select CPU_CACHE_V4WT
249 select CPU_CACHE_VIVT 249 select CPU_CACHE_VIVT
250 select CPU_CP15_MMU 250 select CPU_CP15_MMU
@@ -262,7 +262,7 @@ config CPU_ARM1020E
262 bool "Support ARM1020E processor" if ARCH_INTEGRATOR 262 bool "Support ARM1020E processor" if ARCH_INTEGRATOR
263 select CPU_32v5 263 select CPU_32v5
264 select CPU_ABRT_EV4T 264 select CPU_ABRT_EV4T
265 select CPU_PABRT_NOIFAR 265 select CPU_PABRT_LEGACY
266 select CPU_CACHE_V4WT 266 select CPU_CACHE_V4WT
267 select CPU_CACHE_VIVT 267 select CPU_CACHE_VIVT
268 select CPU_CP15_MMU 268 select CPU_CP15_MMU
@@ -275,7 +275,7 @@ config CPU_ARM1022
275 bool "Support ARM1022E processor" if ARCH_INTEGRATOR 275 bool "Support ARM1022E processor" if ARCH_INTEGRATOR
276 select CPU_32v5 276 select CPU_32v5
277 select CPU_ABRT_EV4T 277 select CPU_ABRT_EV4T
278 select CPU_PABRT_NOIFAR 278 select CPU_PABRT_LEGACY
279 select CPU_CACHE_VIVT 279 select CPU_CACHE_VIVT
280 select CPU_CP15_MMU 280 select CPU_CP15_MMU
281 select CPU_COPY_V4WB if MMU # can probably do better 281 select CPU_COPY_V4WB if MMU # can probably do better
@@ -293,7 +293,7 @@ config CPU_ARM1026
293 bool "Support ARM1026EJ-S processor" if ARCH_INTEGRATOR 293 bool "Support ARM1026EJ-S processor" if ARCH_INTEGRATOR
294 select CPU_32v5 294 select CPU_32v5
295 select CPU_ABRT_EV5T # But need Jazelle, but EV5TJ ignores bit 10 295 select CPU_ABRT_EV5T # But need Jazelle, but EV5TJ ignores bit 10
296 select CPU_PABRT_NOIFAR 296 select CPU_PABRT_LEGACY
297 select CPU_CACHE_VIVT 297 select CPU_CACHE_VIVT
298 select CPU_CP15_MMU 298 select CPU_CP15_MMU
299 select CPU_COPY_V4WB if MMU # can probably do better 299 select CPU_COPY_V4WB if MMU # can probably do better
@@ -311,7 +311,7 @@ config CPU_SA110
311 select CPU_32v3 if ARCH_RPC 311 select CPU_32v3 if ARCH_RPC
312 select CPU_32v4 if !ARCH_RPC 312 select CPU_32v4 if !ARCH_RPC
313 select CPU_ABRT_EV4 313 select CPU_ABRT_EV4
314 select CPU_PABRT_NOIFAR 314 select CPU_PABRT_LEGACY
315 select CPU_CACHE_V4WB 315 select CPU_CACHE_V4WB
316 select CPU_CACHE_VIVT 316 select CPU_CACHE_VIVT
317 select CPU_CP15_MMU 317 select CPU_CP15_MMU
@@ -331,7 +331,7 @@ config CPU_SA1100
331 bool 331 bool
332 select CPU_32v4 332 select CPU_32v4
333 select CPU_ABRT_EV4 333 select CPU_ABRT_EV4
334 select CPU_PABRT_NOIFAR 334 select CPU_PABRT_LEGACY
335 select CPU_CACHE_V4WB 335 select CPU_CACHE_V4WB
336 select CPU_CACHE_VIVT 336 select CPU_CACHE_VIVT
337 select CPU_CP15_MMU 337 select CPU_CP15_MMU
@@ -342,7 +342,7 @@ config CPU_XSCALE
342 bool 342 bool
343 select CPU_32v5 343 select CPU_32v5
344 select CPU_ABRT_EV5T 344 select CPU_ABRT_EV5T
345 select CPU_PABRT_NOIFAR 345 select CPU_PABRT_LEGACY
346 select CPU_CACHE_VIVT 346 select CPU_CACHE_VIVT
347 select CPU_CP15_MMU 347 select CPU_CP15_MMU
348 select CPU_TLB_V4WBI if MMU 348 select CPU_TLB_V4WBI if MMU
@@ -352,7 +352,7 @@ config CPU_XSC3
352 bool 352 bool
353 select CPU_32v5 353 select CPU_32v5
354 select CPU_ABRT_EV5T 354 select CPU_ABRT_EV5T
355 select CPU_PABRT_NOIFAR 355 select CPU_PABRT_LEGACY
356 select CPU_CACHE_VIVT 356 select CPU_CACHE_VIVT
357 select CPU_CP15_MMU 357 select CPU_CP15_MMU
358 select CPU_TLB_V4WBI if MMU 358 select CPU_TLB_V4WBI if MMU
@@ -363,7 +363,7 @@ config CPU_MOHAWK
363 bool 363 bool
364 select CPU_32v5 364 select CPU_32v5
365 select CPU_ABRT_EV5T 365 select CPU_ABRT_EV5T
366 select CPU_PABRT_NOIFAR 366 select CPU_PABRT_LEGACY
367 select CPU_CACHE_VIVT 367 select CPU_CACHE_VIVT
368 select CPU_CP15_MMU 368 select CPU_CP15_MMU
369 select CPU_TLB_V4WBI if MMU 369 select CPU_TLB_V4WBI if MMU
@@ -374,7 +374,7 @@ config CPU_FEROCEON
374 bool 374 bool
375 select CPU_32v5 375 select CPU_32v5
376 select CPU_ABRT_EV5T 376 select CPU_ABRT_EV5T
377 select CPU_PABRT_NOIFAR 377 select CPU_PABRT_LEGACY
378 select CPU_CACHE_VIVT 378 select CPU_CACHE_VIVT
379 select CPU_CP15_MMU 379 select CPU_CP15_MMU
380 select CPU_COPY_FEROCEON if MMU 380 select CPU_COPY_FEROCEON if MMU
@@ -394,7 +394,7 @@ config CPU_V6
394 bool "Support ARM V6 processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX 394 bool "Support ARM V6 processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX
395 select CPU_32v6 395 select CPU_32v6
396 select CPU_ABRT_EV6 396 select CPU_ABRT_EV6
397 select CPU_PABRT_NOIFAR 397 select CPU_PABRT_V6
398 select CPU_CACHE_V6 398 select CPU_CACHE_V6
399 select CPU_CACHE_VIPT 399 select CPU_CACHE_VIPT
400 select CPU_CP15_MMU 400 select CPU_CP15_MMU
@@ -420,7 +420,7 @@ config CPU_V7
420 select CPU_32v6K 420 select CPU_32v6K
421 select CPU_32v7 421 select CPU_32v7
422 select CPU_ABRT_EV7 422 select CPU_ABRT_EV7
423 select CPU_PABRT_IFAR 423 select CPU_PABRT_V7
424 select CPU_CACHE_V7 424 select CPU_CACHE_V7
425 select CPU_CACHE_VIPT 425 select CPU_CACHE_VIPT
426 select CPU_CP15_MMU 426 select CPU_CP15_MMU
@@ -482,10 +482,13 @@ config CPU_ABRT_EV6
482config CPU_ABRT_EV7 482config CPU_ABRT_EV7
483 bool 483 bool
484 484
485config CPU_PABRT_IFAR 485config CPU_PABRT_LEGACY
486 bool 486 bool
487 487
488config CPU_PABRT_NOIFAR 488config CPU_PABRT_V6
489 bool
490
491config CPU_PABRT_V7
489 bool 492 bool
490 493
491# The cache model 494# The cache model
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index 63e3f6dd0e21..055cb2aa8134 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -27,6 +27,10 @@ obj-$(CONFIG_CPU_ABRT_EV5TJ) += abort-ev5tj.o
27obj-$(CONFIG_CPU_ABRT_EV6) += abort-ev6.o 27obj-$(CONFIG_CPU_ABRT_EV6) += abort-ev6.o
28obj-$(CONFIG_CPU_ABRT_EV7) += abort-ev7.o 28obj-$(CONFIG_CPU_ABRT_EV7) += abort-ev7.o
29 29
30obj-$(CONFIG_CPU_PABRT_LEGACY) += pabort-legacy.o
31obj-$(CONFIG_CPU_PABRT_V6) += pabort-v6.o
32obj-$(CONFIG_CPU_PABRT_V7) += pabort-v7.o
33
30obj-$(CONFIG_CPU_CACHE_V3) += cache-v3.o 34obj-$(CONFIG_CPU_CACHE_V3) += cache-v3.o
31obj-$(CONFIG_CPU_CACHE_V4) += cache-v4.o 35obj-$(CONFIG_CPU_CACHE_V4) += cache-v4.o
32obj-$(CONFIG_CPU_CACHE_V4WT) += cache-v4wt.o 36obj-$(CONFIG_CPU_CACHE_V4WT) += cache-v4wt.o
diff --git a/arch/arm/mm/cache-v6.S b/arch/arm/mm/cache-v6.S
index 8f5c13f4c936..295e25dd6381 100644
--- a/arch/arm/mm/cache-v6.S
+++ b/arch/arm/mm/cache-v6.S
@@ -12,6 +12,7 @@
12#include <linux/linkage.h> 12#include <linux/linkage.h>
13#include <linux/init.h> 13#include <linux/init.h>
14#include <asm/assembler.h> 14#include <asm/assembler.h>
15#include <asm/unwind.h>
15 16
16#include "proc-macros.S" 17#include "proc-macros.S"
17 18
@@ -121,11 +122,13 @@ ENTRY(v6_coherent_kern_range)
121 * - the Icache does not read data from the write buffer 122 * - the Icache does not read data from the write buffer
122 */ 123 */
123ENTRY(v6_coherent_user_range) 124ENTRY(v6_coherent_user_range)
124 125 UNWIND(.fnstart )
125#ifdef HARVARD_CACHE 126#ifdef HARVARD_CACHE
126 bic r0, r0, #CACHE_LINE_SIZE - 1 127 bic r0, r0, #CACHE_LINE_SIZE - 1
1271: mcr p15, 0, r0, c7, c10, 1 @ clean D line 1281:
129 USER( mcr p15, 0, r0, c7, c10, 1 ) @ clean D line
128 add r0, r0, #CACHE_LINE_SIZE 130 add r0, r0, #CACHE_LINE_SIZE
1312:
129 cmp r0, r1 132 cmp r0, r1
130 blo 1b 133 blo 1b
131#endif 134#endif
@@ -143,6 +146,19 @@ ENTRY(v6_coherent_user_range)
143 mov pc, lr 146 mov pc, lr
144 147
145/* 148/*
149 * Fault handling for the cache operation above. If the virtual address in r0
150 * isn't mapped, just try the next page.
151 */
1529001:
153 mov r0, r0, lsr #12
154 mov r0, r0, lsl #12
155 add r0, r0, #4096
156 b 2b
157 UNWIND(.fnend )
158ENDPROC(v6_coherent_user_range)
159ENDPROC(v6_coherent_kern_range)
160
161/*
146 * v6_flush_kern_dcache_page(kaddr) 162 * v6_flush_kern_dcache_page(kaddr)
147 * 163 *
148 * Ensure that the data held in the page kaddr is written back 164 * Ensure that the data held in the page kaddr is written back
diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S
index bda0ec31a4e2..e1bd9759617f 100644
--- a/arch/arm/mm/cache-v7.S
+++ b/arch/arm/mm/cache-v7.S
@@ -13,6 +13,7 @@
13#include <linux/linkage.h> 13#include <linux/linkage.h>
14#include <linux/init.h> 14#include <linux/init.h>
15#include <asm/assembler.h> 15#include <asm/assembler.h>
16#include <asm/unwind.h>
16 17
17#include "proc-macros.S" 18#include "proc-macros.S"
18 19
@@ -153,13 +154,16 @@ ENTRY(v7_coherent_kern_range)
153 * - the Icache does not read data from the write buffer 154 * - the Icache does not read data from the write buffer
154 */ 155 */
155ENTRY(v7_coherent_user_range) 156ENTRY(v7_coherent_user_range)
157 UNWIND(.fnstart )
156 dcache_line_size r2, r3 158 dcache_line_size r2, r3
157 sub r3, r2, #1 159 sub r3, r2, #1
158 bic r0, r0, r3 160 bic r0, r0, r3
1591: mcr p15, 0, r0, c7, c11, 1 @ clean D line to the point of unification 1611:
162 USER( mcr p15, 0, r0, c7, c11, 1 ) @ clean D line to the point of unification
160 dsb 163 dsb
161 mcr p15, 0, r0, c7, c5, 1 @ invalidate I line 164 USER( mcr p15, 0, r0, c7, c5, 1 ) @ invalidate I line
162 add r0, r0, r2 165 add r0, r0, r2
1662:
163 cmp r0, r1 167 cmp r0, r1
164 blo 1b 168 blo 1b
165 mov r0, #0 169 mov r0, #0
@@ -167,6 +171,17 @@ ENTRY(v7_coherent_user_range)
167 dsb 171 dsb
168 isb 172 isb
169 mov pc, lr 173 mov pc, lr
174
175/*
176 * Fault handling for the cache operation above. If the virtual address in r0
177 * isn't mapped, just try the next page.
178 */
1799001:
180 mov r0, r0, lsr #12
181 mov r0, r0, lsl #12
182 add r0, r0, #4096
183 b 2b
184 UNWIND(.fnend )
170ENDPROC(v7_coherent_kern_range) 185ENDPROC(v7_coherent_kern_range)
171ENDPROC(v7_coherent_user_range) 186ENDPROC(v7_coherent_user_range)
172 187
diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c
index bc0099d5ae85..d0d17b6a3703 100644
--- a/arch/arm/mm/fault-armv.c
+++ b/arch/arm/mm/fault-armv.c
@@ -153,14 +153,11 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte)
153 153
154 page = pfn_to_page(pfn); 154 page = pfn_to_page(pfn);
155 mapping = page_mapping(page); 155 mapping = page_mapping(page);
156 if (mapping) {
157#ifndef CONFIG_SMP 156#ifndef CONFIG_SMP
158 int dirty = test_and_clear_bit(PG_dcache_dirty, &page->flags); 157 if (test_and_clear_bit(PG_dcache_dirty, &page->flags))
159 158 __flush_dcache_page(mapping, page);
160 if (dirty)
161 __flush_dcache_page(mapping, page);
162#endif 159#endif
163 160 if (mapping) {
164 if (cache_is_vivt()) 161 if (cache_is_vivt())
165 make_coherent(mapping, vma, addr, pfn); 162 make_coherent(mapping, vma, addr, pfn);
166 else if (vma->vm_flags & VM_EXEC) 163 else if (vma->vm_flags & VM_EXEC)
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index 379f78556055..10e06801afb3 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -292,6 +292,11 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
292 * down_read() 292 * down_read()
293 */ 293 */
294 might_sleep(); 294 might_sleep();
295#ifdef CONFIG_DEBUG_VM
296 if (!user_mode(regs) &&
297 !search_exception_tables(regs->ARM_pc))
298 goto no_context;
299#endif
295 } 300 }
296 301
297 fault = __do_page_fault(mm, addr, fsr, tsk); 302 fault = __do_page_fault(mm, addr, fsr, tsk);
@@ -519,9 +524,58 @@ do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
519 arm_notify_die("", regs, &info, fsr, 0); 524 arm_notify_die("", regs, &info, fsr, 0);
520} 525}
521 526
527
528static struct fsr_info ifsr_info[] = {
529 { do_bad, SIGBUS, 0, "unknown 0" },
530 { do_bad, SIGBUS, 0, "unknown 1" },
531 { do_bad, SIGBUS, 0, "debug event" },
532 { do_bad, SIGSEGV, SEGV_ACCERR, "section access flag fault" },
533 { do_bad, SIGBUS, 0, "unknown 4" },
534 { do_translation_fault, SIGSEGV, SEGV_MAPERR, "section translation fault" },
535 { do_bad, SIGSEGV, SEGV_ACCERR, "page access flag fault" },
536 { do_page_fault, SIGSEGV, SEGV_MAPERR, "page translation fault" },
537 { do_bad, SIGBUS, 0, "external abort on non-linefetch" },
538 { do_bad, SIGSEGV, SEGV_ACCERR, "section domain fault" },
539 { do_bad, SIGBUS, 0, "unknown 10" },
540 { do_bad, SIGSEGV, SEGV_ACCERR, "page domain fault" },
541 { do_bad, SIGBUS, 0, "external abort on translation" },
542 { do_sect_fault, SIGSEGV, SEGV_ACCERR, "section permission fault" },
543 { do_bad, SIGBUS, 0, "external abort on translation" },
544 { do_page_fault, SIGSEGV, SEGV_ACCERR, "page permission fault" },
545 { do_bad, SIGBUS, 0, "unknown 16" },
546 { do_bad, SIGBUS, 0, "unknown 17" },
547 { do_bad, SIGBUS, 0, "unknown 18" },
548 { do_bad, SIGBUS, 0, "unknown 19" },
549 { do_bad, SIGBUS, 0, "unknown 20" },
550 { do_bad, SIGBUS, 0, "unknown 21" },
551 { do_bad, SIGBUS, 0, "unknown 22" },
552 { do_bad, SIGBUS, 0, "unknown 23" },
553 { do_bad, SIGBUS, 0, "unknown 24" },
554 { do_bad, SIGBUS, 0, "unknown 25" },
555 { do_bad, SIGBUS, 0, "unknown 26" },
556 { do_bad, SIGBUS, 0, "unknown 27" },
557 { do_bad, SIGBUS, 0, "unknown 28" },
558 { do_bad, SIGBUS, 0, "unknown 29" },
559 { do_bad, SIGBUS, 0, "unknown 30" },
560 { do_bad, SIGBUS, 0, "unknown 31" },
561};
562
522asmlinkage void __exception 563asmlinkage void __exception
523do_PrefetchAbort(unsigned long addr, struct pt_regs *regs) 564do_PrefetchAbort(unsigned long addr, unsigned int ifsr, struct pt_regs *regs)
524{ 565{
525 do_translation_fault(addr, FSR_LNX_PF, regs); 566 const struct fsr_info *inf = ifsr_info + fsr_fs(ifsr);
567 struct siginfo info;
568
569 if (!inf->fn(addr, ifsr | FSR_LNX_PF, regs))
570 return;
571
572 printk(KERN_ALERT "Unhandled prefetch abort: %s (0x%03x) at 0x%08lx\n",
573 inf->name, ifsr, addr);
574
575 info.si_signo = inf->sig;
576 info.si_errno = 0;
577 info.si_code = inf->code;
578 info.si_addr = (void __user *)addr;
579 arm_notify_die("", regs, &info, ifsr, 0);
526} 580}
527 581
diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c
index 73cae57fa707..30f82fb5918c 100644
--- a/arch/arm/mm/highmem.c
+++ b/arch/arm/mm/highmem.c
@@ -46,6 +46,8 @@ void *kmap_atomic(struct page *page, enum km_type type)
46 if (!PageHighMem(page)) 46 if (!PageHighMem(page))
47 return page_address(page); 47 return page_address(page);
48 48
49 debug_kmap_atomic(type);
50
49 kmap = kmap_high_get(page); 51 kmap = kmap_high_get(page);
50 if (kmap) 52 if (kmap)
51 return kmap; 53 return kmap;
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 877c492f8e10..40940d7ce4ff 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -483,7 +483,7 @@ free_memmap(int node, unsigned long start_pfn, unsigned long end_pfn)
483 /* 483 /*
484 * Convert start_pfn/end_pfn to a struct page pointer. 484 * Convert start_pfn/end_pfn to a struct page pointer.
485 */ 485 */
486 start_pg = pfn_to_page(start_pfn); 486 start_pg = pfn_to_page(start_pfn - 1) + 1;
487 end_pg = pfn_to_page(end_pfn); 487 end_pg = pfn_to_page(end_pfn);
488 488
489 /* 489 /*
diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
index f7457fea6de8..2b7996401b0f 100644
--- a/arch/arm/mm/mmap.c
+++ b/arch/arm/mm/mmap.c
@@ -124,7 +124,7 @@ int valid_phys_addr_range(unsigned long addr, size_t size)
124{ 124{
125 if (addr < PHYS_OFFSET) 125 if (addr < PHYS_OFFSET)
126 return 0; 126 return 0;
127 if (addr + size >= __pa(high_memory - 1)) 127 if (addr + size > __pa(high_memory - 1) + 1)
128 return 0; 128 return 0;
129 129
130 return 1; 130 return 1;
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 4426ee67ceca..02243eeccf50 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -21,6 +21,7 @@
21#include <asm/cachetype.h> 21#include <asm/cachetype.h>
22#include <asm/setup.h> 22#include <asm/setup.h>
23#include <asm/sizes.h> 23#include <asm/sizes.h>
24#include <asm/smp_plat.h>
24#include <asm/tlb.h> 25#include <asm/tlb.h>
25#include <asm/highmem.h> 26#include <asm/highmem.h>
26 27
@@ -709,10 +710,6 @@ static void __init sanity_check_meminfo(void)
709 if (meminfo.nr_banks >= NR_BANKS) { 710 if (meminfo.nr_banks >= NR_BANKS) {
710 printk(KERN_CRIT "NR_BANKS too low, " 711 printk(KERN_CRIT "NR_BANKS too low, "
711 "ignoring high memory\n"); 712 "ignoring high memory\n");
712 } else if (cache_is_vipt_aliasing()) {
713 printk(KERN_CRIT "HIGHMEM is not yet supported "
714 "with VIPT aliasing cache, "
715 "ignoring high memory\n");
716 } else { 713 } else {
717 memmove(bank + 1, bank, 714 memmove(bank + 1, bank,
718 (meminfo.nr_banks - i) * sizeof(*bank)); 715 (meminfo.nr_banks - i) * sizeof(*bank));
@@ -726,6 +723,8 @@ static void __init sanity_check_meminfo(void)
726 bank->size = VMALLOC_MIN - __va(bank->start); 723 bank->size = VMALLOC_MIN - __va(bank->start);
727 } 724 }
728#else 725#else
726 bank->highmem = highmem;
727
729 /* 728 /*
730 * Check whether this memory bank would entirely overlap 729 * Check whether this memory bank would entirely overlap
731 * the vmalloc area. 730 * the vmalloc area.
@@ -754,6 +753,38 @@ static void __init sanity_check_meminfo(void)
754#endif 753#endif
755 j++; 754 j++;
756 } 755 }
756#ifdef CONFIG_HIGHMEM
757 if (highmem) {
758 const char *reason = NULL;
759
760 if (cache_is_vipt_aliasing()) {
761 /*
762 * Interactions between kmap and other mappings
763 * make highmem support with aliasing VIPT caches
764 * rather difficult.
765 */
766 reason = "with VIPT aliasing cache";
767#ifdef CONFIG_SMP
768 } else if (tlb_ops_need_broadcast()) {
769 /*
770 * kmap_high needs to occasionally flush TLB entries,
771 * however, if the TLB entries need to be broadcast
772 * we may deadlock:
773 * kmap_high(irqs off)->flush_all_zero_pkmaps->
774 * flush_tlb_kernel_range->smp_call_function_many
775 * (must not be called with irqs off)
776 */
777 reason = "without hardware TLB ops broadcasting";
778#endif
779 }
780 if (reason) {
781 printk(KERN_CRIT "HIGHMEM is not supported %s, ignoring high memory\n",
782 reason);
783 while (j > 0 && meminfo.bank[j - 1].highmem)
784 j--;
785 }
786 }
787#endif
757 meminfo.nr_banks = j; 788 meminfo.nr_banks = j;
758} 789}
759 790
diff --git a/arch/arm/mm/pabort-legacy.S b/arch/arm/mm/pabort-legacy.S
new file mode 100644
index 000000000000..87970eba88ea
--- /dev/null
+++ b/arch/arm/mm/pabort-legacy.S
@@ -0,0 +1,19 @@
1#include <linux/linkage.h>
2#include <asm/assembler.h>
3
4/*
5 * Function: legacy_pabort
6 *
7 * Params : r0 = address of aborted instruction
8 *
9 * Returns : r0 = address of abort
10 * : r1 = Simulated IFSR with section translation fault status
11 *
12 * Purpose : obtain information about current prefetch abort.
13 */
14
15 .align 5
16ENTRY(legacy_pabort)
17 mov r1, #5
18 mov pc, lr
19ENDPROC(legacy_pabort)
diff --git a/arch/arm/mm/pabort-v6.S b/arch/arm/mm/pabort-v6.S
new file mode 100644
index 000000000000..06e3d1ef2115
--- /dev/null
+++ b/arch/arm/mm/pabort-v6.S
@@ -0,0 +1,19 @@
1#include <linux/linkage.h>
2#include <asm/assembler.h>
3
4/*
5 * Function: v6_pabort
6 *
7 * Params : r0 = address of aborted instruction
8 *
9 * Returns : r0 = address of abort
10 * : r1 = IFSR
11 *
12 * Purpose : obtain information about current prefetch abort.
13 */
14
15 .align 5
16ENTRY(v6_pabort)
17 mrc p15, 0, r1, c5, c0, 1 @ get IFSR
18 mov pc, lr
19ENDPROC(v6_pabort)
diff --git a/arch/arm/mm/pabort-v7.S b/arch/arm/mm/pabort-v7.S
new file mode 100644
index 000000000000..a8b3b300a18d
--- /dev/null
+++ b/arch/arm/mm/pabort-v7.S
@@ -0,0 +1,20 @@
1#include <linux/linkage.h>
2#include <asm/assembler.h>
3
4/*
5 * Function: v6_pabort
6 *
7 * Params : r0 = address of aborted instruction
8 *
9 * Returns : r0 = address of abort
10 * : r1 = IFSR
11 *
12 * Purpose : obtain information about current prefetch abort.
13 */
14
15 .align 5
16ENTRY(v7_pabort)
17 mrc p15, 0, r0, c6, c0, 2 @ get IFAR
18 mrc p15, 0, r1, c5, c0, 1 @ get IFSR
19 mov pc, lr
20ENDPROC(v7_pabort)
diff --git a/arch/arm/mm/proc-arm1020.S b/arch/arm/mm/proc-arm1020.S
index b5551bf010aa..d9fb4b98c49f 100644
--- a/arch/arm/mm/proc-arm1020.S
+++ b/arch/arm/mm/proc-arm1020.S
@@ -449,7 +449,7 @@ arm1020_crval:
449 .type arm1020_processor_functions, #object 449 .type arm1020_processor_functions, #object
450arm1020_processor_functions: 450arm1020_processor_functions:
451 .word v4t_early_abort 451 .word v4t_early_abort
452 .word pabort_noifar 452 .word legacy_pabort
453 .word cpu_arm1020_proc_init 453 .word cpu_arm1020_proc_init
454 .word cpu_arm1020_proc_fin 454 .word cpu_arm1020_proc_fin
455 .word cpu_arm1020_reset 455 .word cpu_arm1020_reset
diff --git a/arch/arm/mm/proc-arm1020e.S b/arch/arm/mm/proc-arm1020e.S
index 8bc6740c29eb..7453b75dcea5 100644
--- a/arch/arm/mm/proc-arm1020e.S
+++ b/arch/arm/mm/proc-arm1020e.S
@@ -430,7 +430,7 @@ arm1020e_crval:
430 .type arm1020e_processor_functions, #object 430 .type arm1020e_processor_functions, #object
431arm1020e_processor_functions: 431arm1020e_processor_functions:
432 .word v4t_early_abort 432 .word v4t_early_abort
433 .word pabort_noifar 433 .word legacy_pabort
434 .word cpu_arm1020e_proc_init 434 .word cpu_arm1020e_proc_init
435 .word cpu_arm1020e_proc_fin 435 .word cpu_arm1020e_proc_fin
436 .word cpu_arm1020e_reset 436 .word cpu_arm1020e_reset
diff --git a/arch/arm/mm/proc-arm1022.S b/arch/arm/mm/proc-arm1022.S
index 2cd03e66c0a3..8eb72d75a8b6 100644
--- a/arch/arm/mm/proc-arm1022.S
+++ b/arch/arm/mm/proc-arm1022.S
@@ -413,7 +413,7 @@ arm1022_crval:
413 .type arm1022_processor_functions, #object 413 .type arm1022_processor_functions, #object
414arm1022_processor_functions: 414arm1022_processor_functions:
415 .word v4t_early_abort 415 .word v4t_early_abort
416 .word pabort_noifar 416 .word legacy_pabort
417 .word cpu_arm1022_proc_init 417 .word cpu_arm1022_proc_init
418 .word cpu_arm1022_proc_fin 418 .word cpu_arm1022_proc_fin
419 .word cpu_arm1022_reset 419 .word cpu_arm1022_reset
diff --git a/arch/arm/mm/proc-arm1026.S b/arch/arm/mm/proc-arm1026.S
index ad961a897f6e..3b59f0d67139 100644
--- a/arch/arm/mm/proc-arm1026.S
+++ b/arch/arm/mm/proc-arm1026.S
@@ -408,7 +408,7 @@ arm1026_crval:
408 .type arm1026_processor_functions, #object 408 .type arm1026_processor_functions, #object
409arm1026_processor_functions: 409arm1026_processor_functions:
410 .word v5t_early_abort 410 .word v5t_early_abort
411 .word pabort_noifar 411 .word legacy_pabort
412 .word cpu_arm1026_proc_init 412 .word cpu_arm1026_proc_init
413 .word cpu_arm1026_proc_fin 413 .word cpu_arm1026_proc_fin
414 .word cpu_arm1026_reset 414 .word cpu_arm1026_reset
diff --git a/arch/arm/mm/proc-arm6_7.S b/arch/arm/mm/proc-arm6_7.S
index 80d6e1de069a..3f9cd3d8f6d5 100644
--- a/arch/arm/mm/proc-arm6_7.S
+++ b/arch/arm/mm/proc-arm6_7.S
@@ -278,7 +278,7 @@ __arm7_setup: mov r0, #0
278 .type arm6_processor_functions, #object 278 .type arm6_processor_functions, #object
279ENTRY(arm6_processor_functions) 279ENTRY(arm6_processor_functions)
280 .word cpu_arm6_data_abort 280 .word cpu_arm6_data_abort
281 .word pabort_noifar 281 .word legacy_pabort
282 .word cpu_arm6_proc_init 282 .word cpu_arm6_proc_init
283 .word cpu_arm6_proc_fin 283 .word cpu_arm6_proc_fin
284 .word cpu_arm6_reset 284 .word cpu_arm6_reset
@@ -295,7 +295,7 @@ ENTRY(arm6_processor_functions)
295 .type arm7_processor_functions, #object 295 .type arm7_processor_functions, #object
296ENTRY(arm7_processor_functions) 296ENTRY(arm7_processor_functions)
297 .word cpu_arm7_data_abort 297 .word cpu_arm7_data_abort
298 .word pabort_noifar 298 .word legacy_pabort
299 .word cpu_arm7_proc_init 299 .word cpu_arm7_proc_init
300 .word cpu_arm7_proc_fin 300 .word cpu_arm7_proc_fin
301 .word cpu_arm7_reset 301 .word cpu_arm7_reset
diff --git a/arch/arm/mm/proc-arm720.S b/arch/arm/mm/proc-arm720.S
index 85ae18695f10..0b62de244666 100644
--- a/arch/arm/mm/proc-arm720.S
+++ b/arch/arm/mm/proc-arm720.S
@@ -181,7 +181,7 @@ arm720_crval:
181 .type arm720_processor_functions, #object 181 .type arm720_processor_functions, #object
182ENTRY(arm720_processor_functions) 182ENTRY(arm720_processor_functions)
183 .word v4t_late_abort 183 .word v4t_late_abort
184 .word pabort_noifar 184 .word legacy_pabort
185 .word cpu_arm720_proc_init 185 .word cpu_arm720_proc_init
186 .word cpu_arm720_proc_fin 186 .word cpu_arm720_proc_fin
187 .word cpu_arm720_reset 187 .word cpu_arm720_reset
diff --git a/arch/arm/mm/proc-arm740.S b/arch/arm/mm/proc-arm740.S
index 4f95bee63e95..01860cdeb2ec 100644
--- a/arch/arm/mm/proc-arm740.S
+++ b/arch/arm/mm/proc-arm740.S
@@ -126,7 +126,7 @@ __arm740_setup:
126 .type arm740_processor_functions, #object 126 .type arm740_processor_functions, #object
127ENTRY(arm740_processor_functions) 127ENTRY(arm740_processor_functions)
128 .word v4t_late_abort 128 .word v4t_late_abort
129 .word pabort_noifar 129 .word legacy_pabort
130 .word cpu_arm740_proc_init 130 .word cpu_arm740_proc_init
131 .word cpu_arm740_proc_fin 131 .word cpu_arm740_proc_fin
132 .word cpu_arm740_reset 132 .word cpu_arm740_reset
diff --git a/arch/arm/mm/proc-arm7tdmi.S b/arch/arm/mm/proc-arm7tdmi.S
index 93e05fa7bed4..1201b9863829 100644
--- a/arch/arm/mm/proc-arm7tdmi.S
+++ b/arch/arm/mm/proc-arm7tdmi.S
@@ -64,7 +64,7 @@ __arm7tdmi_setup:
64 .type arm7tdmi_processor_functions, #object 64 .type arm7tdmi_processor_functions, #object
65ENTRY(arm7tdmi_processor_functions) 65ENTRY(arm7tdmi_processor_functions)
66 .word v4t_late_abort 66 .word v4t_late_abort
67 .word pabort_noifar 67 .word legacy_pabort
68 .word cpu_arm7tdmi_proc_init 68 .word cpu_arm7tdmi_proc_init
69 .word cpu_arm7tdmi_proc_fin 69 .word cpu_arm7tdmi_proc_fin
70 .word cpu_arm7tdmi_reset 70 .word cpu_arm7tdmi_reset
diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S
index 914d688394fc..2b7c197cc58d 100644
--- a/arch/arm/mm/proc-arm920.S
+++ b/arch/arm/mm/proc-arm920.S
@@ -395,7 +395,7 @@ arm920_crval:
395 .type arm920_processor_functions, #object 395 .type arm920_processor_functions, #object
396arm920_processor_functions: 396arm920_processor_functions:
397 .word v4t_early_abort 397 .word v4t_early_abort
398 .word pabort_noifar 398 .word legacy_pabort
399 .word cpu_arm920_proc_init 399 .word cpu_arm920_proc_init
400 .word cpu_arm920_proc_fin 400 .word cpu_arm920_proc_fin
401 .word cpu_arm920_reset 401 .word cpu_arm920_reset
diff --git a/arch/arm/mm/proc-arm922.S b/arch/arm/mm/proc-arm922.S
index 51c9c9859e58..06a1aa4e3398 100644
--- a/arch/arm/mm/proc-arm922.S
+++ b/arch/arm/mm/proc-arm922.S
@@ -399,7 +399,7 @@ arm922_crval:
399 .type arm922_processor_functions, #object 399 .type arm922_processor_functions, #object
400arm922_processor_functions: 400arm922_processor_functions:
401 .word v4t_early_abort 401 .word v4t_early_abort
402 .word pabort_noifar 402 .word legacy_pabort
403 .word cpu_arm922_proc_init 403 .word cpu_arm922_proc_init
404 .word cpu_arm922_proc_fin 404 .word cpu_arm922_proc_fin
405 .word cpu_arm922_reset 405 .word cpu_arm922_reset
diff --git a/arch/arm/mm/proc-arm925.S b/arch/arm/mm/proc-arm925.S
index 2724526d89c1..cb53435a85ae 100644
--- a/arch/arm/mm/proc-arm925.S
+++ b/arch/arm/mm/proc-arm925.S
@@ -462,7 +462,7 @@ arm925_crval:
462 .type arm925_processor_functions, #object 462 .type arm925_processor_functions, #object
463arm925_processor_functions: 463arm925_processor_functions:
464 .word v4t_early_abort 464 .word v4t_early_abort
465 .word pabort_noifar 465 .word legacy_pabort
466 .word cpu_arm925_proc_init 466 .word cpu_arm925_proc_init
467 .word cpu_arm925_proc_fin 467 .word cpu_arm925_proc_fin
468 .word cpu_arm925_reset 468 .word cpu_arm925_reset
diff --git a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S
index 54466937bff9..1c4848704bb3 100644
--- a/arch/arm/mm/proc-arm926.S
+++ b/arch/arm/mm/proc-arm926.S
@@ -415,7 +415,7 @@ arm926_crval:
415 .type arm926_processor_functions, #object 415 .type arm926_processor_functions, #object
416arm926_processor_functions: 416arm926_processor_functions:
417 .word v5tj_early_abort 417 .word v5tj_early_abort
418 .word pabort_noifar 418 .word legacy_pabort
419 .word cpu_arm926_proc_init 419 .word cpu_arm926_proc_init
420 .word cpu_arm926_proc_fin 420 .word cpu_arm926_proc_fin
421 .word cpu_arm926_reset 421 .word cpu_arm926_reset
diff --git a/arch/arm/mm/proc-arm940.S b/arch/arm/mm/proc-arm940.S
index f595117caf55..5b0f8464c8f2 100644
--- a/arch/arm/mm/proc-arm940.S
+++ b/arch/arm/mm/proc-arm940.S
@@ -322,7 +322,7 @@ __arm940_setup:
322 .type arm940_processor_functions, #object 322 .type arm940_processor_functions, #object
323ENTRY(arm940_processor_functions) 323ENTRY(arm940_processor_functions)
324 .word nommu_early_abort 324 .word nommu_early_abort
325 .word pabort_noifar 325 .word legacy_pabort
326 .word cpu_arm940_proc_init 326 .word cpu_arm940_proc_init
327 .word cpu_arm940_proc_fin 327 .word cpu_arm940_proc_fin
328 .word cpu_arm940_reset 328 .word cpu_arm940_reset
diff --git a/arch/arm/mm/proc-arm946.S b/arch/arm/mm/proc-arm946.S
index e03f6ff1fb26..40c0449a139b 100644
--- a/arch/arm/mm/proc-arm946.S
+++ b/arch/arm/mm/proc-arm946.S
@@ -377,7 +377,7 @@ __arm946_setup:
377 .type arm946_processor_functions, #object 377 .type arm946_processor_functions, #object
378ENTRY(arm946_processor_functions) 378ENTRY(arm946_processor_functions)
379 .word nommu_early_abort 379 .word nommu_early_abort
380 .word pabort_noifar 380 .word legacy_pabort
381 .word cpu_arm946_proc_init 381 .word cpu_arm946_proc_init
382 .word cpu_arm946_proc_fin 382 .word cpu_arm946_proc_fin
383 .word cpu_arm946_reset 383 .word cpu_arm946_reset
diff --git a/arch/arm/mm/proc-arm9tdmi.S b/arch/arm/mm/proc-arm9tdmi.S
index be6c11d2b3fb..28545c29dbcd 100644
--- a/arch/arm/mm/proc-arm9tdmi.S
+++ b/arch/arm/mm/proc-arm9tdmi.S
@@ -64,7 +64,7 @@ __arm9tdmi_setup:
64 .type arm9tdmi_processor_functions, #object 64 .type arm9tdmi_processor_functions, #object
65ENTRY(arm9tdmi_processor_functions) 65ENTRY(arm9tdmi_processor_functions)
66 .word nommu_early_abort 66 .word nommu_early_abort
67 .word pabort_noifar 67 .word legacy_pabort
68 .word cpu_arm9tdmi_proc_init 68 .word cpu_arm9tdmi_proc_init
69 .word cpu_arm9tdmi_proc_fin 69 .word cpu_arm9tdmi_proc_fin
70 .word cpu_arm9tdmi_reset 70 .word cpu_arm9tdmi_reset
diff --git a/arch/arm/mm/proc-fa526.S b/arch/arm/mm/proc-fa526.S
index 08b8a955d5d7..08f5ac237ad4 100644
--- a/arch/arm/mm/proc-fa526.S
+++ b/arch/arm/mm/proc-fa526.S
@@ -191,7 +191,7 @@ fa526_cr1_set:
191 .type fa526_processor_functions, #object 191 .type fa526_processor_functions, #object
192fa526_processor_functions: 192fa526_processor_functions:
193 .word v4_early_abort 193 .word v4_early_abort
194 .word pabort_noifar 194 .word legacy_pabort
195 .word cpu_fa526_proc_init 195 .word cpu_fa526_proc_init
196 .word cpu_fa526_proc_fin 196 .word cpu_fa526_proc_fin
197 .word cpu_fa526_reset 197 .word cpu_fa526_reset
diff --git a/arch/arm/mm/proc-feroceon.S b/arch/arm/mm/proc-feroceon.S
index 0fe1f8fc3488..d0d7795200fc 100644
--- a/arch/arm/mm/proc-feroceon.S
+++ b/arch/arm/mm/proc-feroceon.S
@@ -499,7 +499,7 @@ feroceon_crval:
499 .type feroceon_processor_functions, #object 499 .type feroceon_processor_functions, #object
500feroceon_processor_functions: 500feroceon_processor_functions:
501 .word v5t_early_abort 501 .word v5t_early_abort
502 .word pabort_noifar 502 .word legacy_pabort
503 .word cpu_feroceon_proc_init 503 .word cpu_feroceon_proc_init
504 .word cpu_feroceon_proc_fin 504 .word cpu_feroceon_proc_fin
505 .word cpu_feroceon_reset 505 .word cpu_feroceon_reset
diff --git a/arch/arm/mm/proc-mohawk.S b/arch/arm/mm/proc-mohawk.S
index 540f5078496b..52b5fd74fbb3 100644
--- a/arch/arm/mm/proc-mohawk.S
+++ b/arch/arm/mm/proc-mohawk.S
@@ -359,7 +359,7 @@ mohawk_crval:
359 .type mohawk_processor_functions, #object 359 .type mohawk_processor_functions, #object
360mohawk_processor_functions: 360mohawk_processor_functions:
361 .word v5t_early_abort 361 .word v5t_early_abort
362 .word pabort_noifar 362 .word legacy_pabort
363 .word cpu_mohawk_proc_init 363 .word cpu_mohawk_proc_init
364 .word cpu_mohawk_proc_fin 364 .word cpu_mohawk_proc_fin
365 .word cpu_mohawk_reset 365 .word cpu_mohawk_reset
diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S
index 90a7e5279f29..7b706b389906 100644
--- a/arch/arm/mm/proc-sa110.S
+++ b/arch/arm/mm/proc-sa110.S
@@ -199,7 +199,7 @@ sa110_crval:
199 .type sa110_processor_functions, #object 199 .type sa110_processor_functions, #object
200ENTRY(sa110_processor_functions) 200ENTRY(sa110_processor_functions)
201 .word v4_early_abort 201 .word v4_early_abort
202 .word pabort_noifar 202 .word legacy_pabort
203 .word cpu_sa110_proc_init 203 .word cpu_sa110_proc_init
204 .word cpu_sa110_proc_fin 204 .word cpu_sa110_proc_fin
205 .word cpu_sa110_reset 205 .word cpu_sa110_reset
diff --git a/arch/arm/mm/proc-sa1100.S b/arch/arm/mm/proc-sa1100.S
index 451e2d953e2a..ee7700242c19 100644
--- a/arch/arm/mm/proc-sa1100.S
+++ b/arch/arm/mm/proc-sa1100.S
@@ -214,7 +214,7 @@ sa1100_crval:
214 .type sa1100_processor_functions, #object 214 .type sa1100_processor_functions, #object
215ENTRY(sa1100_processor_functions) 215ENTRY(sa1100_processor_functions)
216 .word v4_early_abort 216 .word v4_early_abort
217 .word pabort_noifar 217 .word legacy_pabort
218 .word cpu_sa1100_proc_init 218 .word cpu_sa1100_proc_init
219 .word cpu_sa1100_proc_fin 219 .word cpu_sa1100_proc_fin
220 .word cpu_sa1100_reset 220 .word cpu_sa1100_reset
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index 524ddae92595..194737d60a22 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -191,7 +191,7 @@ v6_crval:
191 .type v6_processor_functions, #object 191 .type v6_processor_functions, #object
192ENTRY(v6_processor_functions) 192ENTRY(v6_processor_functions)
193 .word v6_early_abort 193 .word v6_early_abort
194 .word pabort_noifar 194 .word v6_pabort
195 .word cpu_v6_proc_init 195 .word cpu_v6_proc_init
196 .word cpu_v6_proc_fin 196 .word cpu_v6_proc_fin
197 .word cpu_v6_reset 197 .word cpu_v6_reset
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index f3fa1c32fe92..23ebcf6eab9f 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -295,7 +295,7 @@ __v7_setup_stack:
295 .type v7_processor_functions, #object 295 .type v7_processor_functions, #object
296ENTRY(v7_processor_functions) 296ENTRY(v7_processor_functions)
297 .word v7_early_abort 297 .word v7_early_abort
298 .word pabort_ifar 298 .word v7_pabort
299 .word cpu_v7_proc_init 299 .word cpu_v7_proc_init
300 .word cpu_v7_proc_fin 300 .word cpu_v7_proc_fin
301 .word cpu_v7_reset 301 .word cpu_v7_reset
diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S
index 33515c214b92..2028f3702881 100644
--- a/arch/arm/mm/proc-xsc3.S
+++ b/arch/arm/mm/proc-xsc3.S
@@ -428,7 +428,7 @@ xsc3_crval:
428 .type xsc3_processor_functions, #object 428 .type xsc3_processor_functions, #object
429ENTRY(xsc3_processor_functions) 429ENTRY(xsc3_processor_functions)
430 .word v5t_early_abort 430 .word v5t_early_abort
431 .word pabort_noifar 431 .word legacy_pabort
432 .word cpu_xsc3_proc_init 432 .word cpu_xsc3_proc_init
433 .word cpu_xsc3_proc_fin 433 .word cpu_xsc3_proc_fin
434 .word cpu_xsc3_reset 434 .word cpu_xsc3_reset
diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S
index 423394260bcb..f056c283682d 100644
--- a/arch/arm/mm/proc-xscale.S
+++ b/arch/arm/mm/proc-xscale.S
@@ -511,7 +511,7 @@ xscale_crval:
511 .type xscale_processor_functions, #object 511 .type xscale_processor_functions, #object
512ENTRY(xscale_processor_functions) 512ENTRY(xscale_processor_functions)
513 .word v5t_early_abort 513 .word v5t_early_abort
514 .word pabort_noifar 514 .word legacy_pabort
515 .word cpu_xscale_proc_init 515 .word cpu_xscale_proc_init
516 .word cpu_xscale_proc_fin 516 .word cpu_xscale_proc_fin
517 .word cpu_xscale_reset 517 .word cpu_xscale_reset
diff --git a/arch/arm/plat-iop/pci.c b/arch/arm/plat-iop/pci.c
index 77fa7cc7d162..ce31f316ac75 100644
--- a/arch/arm/plat-iop/pci.c
+++ b/arch/arm/plat-iop/pci.c
@@ -257,7 +257,8 @@ void __init iop3xx_atu_setup(void)
257 *IOP3XX_OUMWTVR0 = 0; 257 *IOP3XX_OUMWTVR0 = 0;
258 258
259 /* Outbound window 1 */ 259 /* Outbound window 1 */
260 *IOP3XX_OMWTVR1 = IOP3XX_PCI_LOWER_MEM_BA + IOP3XX_PCI_MEM_WINDOW_SIZE; 260 *IOP3XX_OMWTVR1 = IOP3XX_PCI_LOWER_MEM_BA +
261 IOP3XX_PCI_MEM_WINDOW_SIZE / 2;
261 *IOP3XX_OUMWTVR1 = 0; 262 *IOP3XX_OUMWTVR1 = 0;
262 263
263 /* BAR 3 ( Disabled ) */ 264 /* BAR 3 ( Disabled ) */
diff --git a/arch/arm/plat-iop/time.c b/arch/arm/plat-iop/time.c
index 3695bbe3ee28..8da95d57c21f 100644
--- a/arch/arm/plat-iop/time.c
+++ b/arch/arm/plat-iop/time.c
@@ -85,7 +85,7 @@ void __init iop_init_time(unsigned long tick_rate)
85{ 85{
86 u32 timer_ctl; 86 u32 timer_ctl;
87 87
88 ticks_per_jiffy = (tick_rate + HZ/2) / HZ; 88 ticks_per_jiffy = DIV_ROUND_CLOSEST(tick_rate, HZ);
89 ticks_per_usec = tick_rate / 1000000; 89 ticks_per_usec = tick_rate / 1000000;
90 next_jiffy_time = 0xffffffff; 90 next_jiffy_time = 0xffffffff;
91 iop_tick_rate = tick_rate; 91 iop_tick_rate = tick_rate;
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index fd3154ae69b1..0eb676d7e807 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -829,10 +829,10 @@ EXPORT_SYMBOL(omap_free_dma);
829 * 829 *
830 * @param arb_rate 830 * @param arb_rate
831 * @param max_fifo_depth 831 * @param max_fifo_depth
832 * @param tparams - Number of thereads to reserve : DMA_THREAD_RESERVE_NORM 832 * @param tparams - Number of threads to reserve : DMA_THREAD_RESERVE_NORM
833 * DMA_THREAD_RESERVE_ONET 833 * DMA_THREAD_RESERVE_ONET
834 * DMA_THREAD_RESERVE_TWOT 834 * DMA_THREAD_RESERVE_TWOT
835 * DMA_THREAD_RESERVE_THREET 835 * DMA_THREAD_RESERVE_THREET
836 */ 836 */
837void 837void
838omap_dma_set_global_params(int arb_rate, int max_fifo_depth, int tparams) 838omap_dma_set_global_params(int arb_rate, int max_fifo_depth, int tparams)
@@ -844,11 +844,14 @@ omap_dma_set_global_params(int arb_rate, int max_fifo_depth, int tparams)
844 return; 844 return;
845 } 845 }
846 846
847 if (max_fifo_depth == 0)
848 max_fifo_depth = 1;
847 if (arb_rate == 0) 849 if (arb_rate == 0)
848 arb_rate = 1; 850 arb_rate = 1;
849 851
850 reg = (arb_rate & 0xff) << 16; 852 reg = 0xff & max_fifo_depth;
851 reg |= (0xff & max_fifo_depth); 853 reg |= (0x3 & tparams) << 12;
854 reg |= (arb_rate & 0xff) << 16;
852 855
853 dma_write(reg, GCR); 856 dma_write(reg, GCR);
854} 857}
diff --git a/arch/arm/plat-omap/include/mach/cpu.h b/arch/arm/plat-omap/include/mach/cpu.h
index 11e73d9e8928..f129efb3075e 100644
--- a/arch/arm/plat-omap/include/mach/cpu.h
+++ b/arch/arm/plat-omap/include/mach/cpu.h
@@ -303,32 +303,21 @@ IS_OMAP_TYPE(3430, 0x3430)
303#define cpu_is_omap2430() 0 303#define cpu_is_omap2430() 0
304#define cpu_is_omap3430() 0 304#define cpu_is_omap3430() 0
305 305
306#if defined(MULTI_OMAP1)
307# if defined(CONFIG_ARCH_OMAP730)
308# undef cpu_is_omap730
309# define cpu_is_omap730() is_omap730()
310# endif
311# if defined(CONFIG_ARCH_OMAP850)
312# undef cpu_is_omap850
313# define cpu_is_omap850() is_omap850()
314# endif
315#else
316# if defined(CONFIG_ARCH_OMAP730)
317# undef cpu_is_omap730
318# define cpu_is_omap730() 1
319# endif
320#endif
321#else
322# if defined(CONFIG_ARCH_OMAP850)
323# undef cpu_is_omap850
324# define cpu_is_omap850() 1
325# endif
326#endif
327
328/* 306/*
329 * Whether we have MULTI_OMAP1 or not, we still need to distinguish 307 * Whether we have MULTI_OMAP1 or not, we still need to distinguish
330 * between 330 vs. 1510 and 1611B/5912 vs. 1710. 308 * between 730 vs 850, 330 vs. 1510 and 1611B/5912 vs. 1710.
331 */ 309 */
310
311#if defined(CONFIG_ARCH_OMAP730)
312# undef cpu_is_omap730
313# define cpu_is_omap730() is_omap730()
314#endif
315
316#if defined(CONFIG_ARCH_OMAP850)
317# undef cpu_is_omap850
318# define cpu_is_omap850() is_omap850()
319#endif
320
332#if defined(CONFIG_ARCH_OMAP15XX) 321#if defined(CONFIG_ARCH_OMAP15XX)
333# undef cpu_is_omap310 322# undef cpu_is_omap310
334# undef cpu_is_omap1510 323# undef cpu_is_omap1510
@@ -433,3 +422,5 @@ IS_OMAP_TYPE(3430, 0x3430)
433 422
434int omap_chip_is(struct omap_chip_id oci); 423int omap_chip_is(struct omap_chip_id oci);
435void omap2_check_revision(void); 424void omap2_check_revision(void);
425
426#endif
diff --git a/arch/arm/plat-omap/include/mach/powerdomain.h b/arch/arm/plat-omap/include/mach/powerdomain.h
index 6271d8556a40..fa6461423bd0 100644
--- a/arch/arm/plat-omap/include/mach/powerdomain.h
+++ b/arch/arm/plat-omap/include/mach/powerdomain.h
@@ -135,6 +135,8 @@ struct powerdomain *pwrdm_lookup(const char *name);
135 135
136int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm, void *user), 136int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm, void *user),
137 void *user); 137 void *user);
138int pwrdm_for_each_nolock(int (*fn)(struct powerdomain *pwrdm, void *user),
139 void *user);
138 140
139int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm); 141int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm);
140int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm); 142int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm);
diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c
index 57f7122a0919..dc3fac3dd0ea 100644
--- a/arch/arm/plat-omap/iovmm.c
+++ b/arch/arm/plat-omap/iovmm.c
@@ -47,7 +47,7 @@
47 * 'va': mpu virtual address 47 * 'va': mpu virtual address
48 * 48 *
49 * 'c': contiguous memory area 49 * 'c': contiguous memory area
50 * 'd': dicontiguous memory area 50 * 'd': discontiguous memory area
51 * 'a': anonymous memory allocation 51 * 'a': anonymous memory allocation
52 * '()': optional feature 52 * '()': optional feature
53 * 53 *
@@ -363,8 +363,9 @@ void *da_to_va(struct iommu *obj, u32 da)
363 goto out; 363 goto out;
364 } 364 }
365 va = area->va; 365 va = area->va;
366 mutex_unlock(&obj->mmap_lock);
367out: 366out:
367 mutex_unlock(&obj->mmap_lock);
368
368 return va; 369 return va;
369} 370}
370EXPORT_SYMBOL_GPL(da_to_va); 371EXPORT_SYMBOL_GPL(da_to_va);
@@ -398,7 +399,7 @@ static inline void sgtable_drain_vmalloc(struct sg_table *sgt)
398{ 399{
399 /* 400 /*
400 * Actually this is not necessary at all, just exists for 401 * Actually this is not necessary at all, just exists for
401 * consistency of the code readibility. 402 * consistency of the code readability.
402 */ 403 */
403 BUG_ON(!sgt); 404 BUG_ON(!sgt);
404} 405}
@@ -434,7 +435,7 @@ static inline void sgtable_drain_kmalloc(struct sg_table *sgt)
434{ 435{
435 /* 436 /*
436 * Actually this is not necessary at all, just exists for 437 * Actually this is not necessary at all, just exists for
437 * consistency of the code readibility 438 * consistency of the code readability
438 */ 439 */
439 BUG_ON(!sgt); 440 BUG_ON(!sgt);
440} 441}
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
index 88ac9768f1c1..e664b912d7bb 100644
--- a/arch/arm/plat-omap/mcbsp.c
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -595,7 +595,7 @@ void omap_mcbsp_stop(unsigned int id, int tx, int rx)
595 rx &= 1; 595 rx &= 1;
596 if (cpu_is_omap2430() || cpu_is_omap34xx()) { 596 if (cpu_is_omap2430() || cpu_is_omap34xx()) {
597 w = OMAP_MCBSP_READ(io_base, RCCR); 597 w = OMAP_MCBSP_READ(io_base, RCCR);
598 w |= (tx ? RDISABLE : 0); 598 w |= (rx ? RDISABLE : 0);
599 OMAP_MCBSP_WRITE(io_base, RCCR, w); 599 OMAP_MCBSP_WRITE(io_base, RCCR, w);
600 } 600 }
601 w = OMAP_MCBSP_READ(io_base, SPCR1); 601 w = OMAP_MCBSP_READ(io_base, SPCR1);
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
index 925f64711c37..75d1f26e5b17 100644
--- a/arch/arm/plat-omap/sram.c
+++ b/arch/arm/plat-omap/sram.c
@@ -270,7 +270,8 @@ void * omap_sram_push(void * start, unsigned long size)
270 omap_sram_ceil -= size; 270 omap_sram_ceil -= size;
271 omap_sram_ceil = ROUND_DOWN(omap_sram_ceil, sizeof(void *)); 271 omap_sram_ceil = ROUND_DOWN(omap_sram_ceil, sizeof(void *));
272 memcpy((void *)omap_sram_ceil, start, size); 272 memcpy((void *)omap_sram_ceil, start, size);
273 flush_icache_range((unsigned long)start, (unsigned long)(start + size)); 273 flush_icache_range((unsigned long)omap_sram_ceil,
274 (unsigned long)(omap_sram_ceil + size));
274 275
275 return (void *)omap_sram_ceil; 276 return (void *)omap_sram_ceil;
276} 277}
diff --git a/arch/arm/plat-s3c24xx/adc.c b/arch/arm/plat-s3c24xx/adc.c
index 11117a7ba911..4d36b784fb8b 100644
--- a/arch/arm/plat-s3c24xx/adc.c
+++ b/arch/arm/plat-s3c24xx/adc.c
@@ -14,6 +14,7 @@
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/platform_device.h> 16#include <linux/platform_device.h>
17#include <linux/sched.h>
17#include <linux/list.h> 18#include <linux/list.h>
18#include <linux/err.h> 19#include <linux/err.h>
19#include <linux/clk.h> 20#include <linux/clk.h>
diff --git a/arch/arm/plat-s3c24xx/include/plat/mci.h b/arch/arm/plat-s3c24xx/include/plat/mci.h
index 2d0852ac3b27..c2cef6139683 100644
--- a/arch/arm/plat-s3c24xx/include/plat/mci.h
+++ b/arch/arm/plat-s3c24xx/include/plat/mci.h
@@ -2,8 +2,11 @@
2#define _ARCH_MCI_H 2#define _ARCH_MCI_H
3 3
4struct s3c24xx_mci_pdata { 4struct s3c24xx_mci_pdata {
5 unsigned int no_wprotect : 1;
6 unsigned int no_detect : 1;
5 unsigned int wprotect_invert : 1; 7 unsigned int wprotect_invert : 1;
6 unsigned int detect_invert : 1; /* set => detect active high. */ 8 unsigned int detect_invert : 1; /* set => detect active high. */
9 unsigned int use_dma : 1;
7 10
8 unsigned int gpio_detect; 11 unsigned int gpio_detect;
9 unsigned int gpio_wprotect; 12 unsigned int gpio_wprotect;
diff --git a/arch/blackfin/ADI_BSD.txt b/arch/blackfin/ADI_BSD.txt
new file mode 100644
index 000000000000..501d0b645943
--- /dev/null
+++ b/arch/blackfin/ADI_BSD.txt
@@ -0,0 +1,41 @@
1This BSD-Style License applies to a few files in ./arch/blackfin directory,
2and is included here, so people understand which code they can use outside
3the Linux kernel, in non-GPL based projects.
4
5Using the files released under the "ADI BSD" license, must comply with
6these license terms.
7
8--------------------------------------------------------------------------
9
10Copyright Analog Devices, Inc.
11
12All rights reserved.
13
14Redistribution and use in source and binary forms, with or without
15modification, are permitted provided that the following conditions
16are met:
17 - Redistributions of source code must retain the above copyright
18 notice, this list of conditions and the following disclaimer.
19 - Redistributions in binary form must reproduce the above copyright
20 notice, this list of conditions and the following disclaimer in
21 the documentation and/or other materials provided with the
22 distribution.
23 - Neither the name of Analog Devices, Inc. nor the names of its
24 contributors may be used to endorse or promote products derived
25 from this software without specific prior written permission.
26 - The use of this software may or may not infringe the patent rights
27 of one or more patent holders. This license does not release you
28 from the requirement that you obtain separate licenses from these
29 patent holders to use this software.
30
31THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
32IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
33MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
34IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
35INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
36BUT NOT LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF
37SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
38BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
39WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
40OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
41ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig
index 9a01d445eca8..ae6a60f10120 100644
--- a/arch/blackfin/Kconfig
+++ b/arch/blackfin/Kconfig
@@ -47,6 +47,9 @@ config GENERIC_HARDIRQS
47config GENERIC_IRQ_PROBE 47config GENERIC_IRQ_PROBE
48 def_bool y 48 def_bool y
49 49
50config GENERIC_HARDIRQS_NO__DO_IRQ
51 def_bool y
52
50config GENERIC_GPIO 53config GENERIC_GPIO
51 def_bool y 54 def_bool y
52 55
@@ -229,7 +232,7 @@ endchoice
229 232
230config SMP 233config SMP
231 depends on BF561 234 depends on BF561
232 select GENERIC_TIME 235 select GENERIC_CLOCKEVENTS
233 bool "Symmetric multi-processing support" 236 bool "Symmetric multi-processing support"
234 ---help--- 237 ---help---
235 This enables support for systems with more than one CPU, 238 This enables support for systems with more than one CPU,
@@ -613,12 +616,10 @@ comment "Kernel Timer/Scheduler"
613source kernel/Kconfig.hz 616source kernel/Kconfig.hz
614 617
615config GENERIC_TIME 618config GENERIC_TIME
616 bool "Generic time" 619 def_bool y
617 default y
618 620
619config GENERIC_CLOCKEVENTS 621config GENERIC_CLOCKEVENTS
620 bool "Generic clock events" 622 bool "Generic clock events"
621 depends on GENERIC_TIME
622 default y 623 default y
623 624
624choice 625choice
@@ -653,6 +654,10 @@ config GPTMR0_CLOCKSOURCE
653 depends on GENERIC_CLOCKEVENTS 654 depends on GENERIC_CLOCKEVENTS
654 depends on !TICKSOURCE_GPTMR0 655 depends on !TICKSOURCE_GPTMR0
655 656
657config ARCH_USES_GETTIMEOFFSET
658 depends on !GENERIC_CLOCKEVENTS
659 def_bool y
660
656source kernel/time/Kconfig 661source kernel/time/Kconfig
657 662
658comment "Misc" 663comment "Misc"
diff --git a/arch/blackfin/include/asm/atomic.h b/arch/blackfin/include/asm/atomic.h
index 88f36d599fe8..d27c6274247d 100644
--- a/arch/blackfin/include/asm/atomic.h
+++ b/arch/blackfin/include/asm/atomic.h
@@ -1,3 +1,9 @@
1/*
2 * Copyright 2004-2009 Analog Devices Inc.
3 *
4 * Licensed under the GPL-2 or later.
5 */
6
1#ifndef __ARCH_BLACKFIN_ATOMIC__ 7#ifndef __ARCH_BLACKFIN_ATOMIC__
2#define __ARCH_BLACKFIN_ATOMIC__ 8#define __ARCH_BLACKFIN_ATOMIC__
3 9
diff --git a/arch/blackfin/include/asm/bfin-global.h b/arch/blackfin/include/asm/bfin-global.h
index aef0594e7865..10064f902d20 100644
--- a/arch/blackfin/include/asm/bfin-global.h
+++ b/arch/blackfin/include/asm/bfin-global.h
@@ -1,29 +1,9 @@
1/* 1/*
2 * File: include/asm-blackfin/bfin-global.h 2 * Global extern defines for blackfin
3 * Based on:
4 * Author: *
5 * Created:
6 * Description: Global extern defines for blackfin
7 * 3 *
8 * Modified: 4 * Copyright 2006-2009 Analog Devices Inc.
9 * Copyright 2004-2006 Analog Devices Inc.
10 * 5 *
11 * Bugs: Enter bugs at http://blackfin.uclinux.org/ 6 * Licensed under the GPL-2 or later.
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, see the file COPYING, or write
25 * to the Free Software Foundation, Inc.,
26 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27 */ 7 */
28 8
29#ifndef _BFIN_GLOBAL_H_ 9#ifndef _BFIN_GLOBAL_H_
diff --git a/arch/blackfin/include/asm/bfin5xx_spi.h b/arch/blackfin/include/asm/bfin5xx_spi.h
index c281c6328276..ed4f8c6db0cd 100644
--- a/arch/blackfin/include/asm/bfin5xx_spi.h
+++ b/arch/blackfin/include/asm/bfin5xx_spi.h
@@ -3,8 +3,6 @@
3 * 3 *
4 * Copyright 2004-2008 Analog Devices Inc. 4 * Copyright 2004-2008 Analog Devices Inc.
5 * 5 *
6 * Enter bugs at http://blackfin.uclinux.org/
7 *
8 * Licensed under the GPL-2 or later. 6 * Licensed under the GPL-2 or later.
9 */ 7 */
10 8
diff --git a/arch/blackfin/include/asm/bfin_rotary.h b/arch/blackfin/include/asm/bfin_rotary.h
index 425ece64fd5e..abdb2af52902 100644
--- a/arch/blackfin/include/asm/bfin_rotary.h
+++ b/arch/blackfin/include/asm/bfin_rotary.h
@@ -1,6 +1,10 @@
1/* 1/*
2 * board initialization should put one of these structures into platform_data 2 * board initialization should put one of these structures into platform_data
3 * and place the bfin-rotary onto platform_bus named "bfin-rotary". 3 * and place the bfin-rotary onto platform_bus named "bfin-rotary".
4 *
5 * Copyright 2008 Analog Devices Inc.
6 *
7 * Licensed under the GPL-2 or later.
4 */ 8 */
5 9
6#ifndef _BFIN_ROTARY_H 10#ifndef _BFIN_ROTARY_H
diff --git a/arch/blackfin/include/asm/bfin_simple_timer.h b/arch/blackfin/include/asm/bfin_simple_timer.h
index fccbb595464a..5248c133bc68 100644
--- a/arch/blackfin/include/asm/bfin_simple_timer.h
+++ b/arch/blackfin/include/asm/bfin_simple_timer.h
@@ -1,3 +1,9 @@
1/*
2 * Copyright 2006-2008 Analog Devices Inc.
3 *
4 * Licensed under the GPL-2 or later.
5 */
6
1#ifndef _bfin_simple_timer_h_ 7#ifndef _bfin_simple_timer_h_
2#define _bfin_simple_timer_h_ 8#define _bfin_simple_timer_h_
3 9
diff --git a/arch/blackfin/include/asm/bitops.h b/arch/blackfin/include/asm/bitops.h
index daffa71576d4..a2ff3fb3568d 100644
--- a/arch/blackfin/include/asm/bitops.h
+++ b/arch/blackfin/include/asm/bitops.h
@@ -1,3 +1,9 @@
1/*
2 * Copyright 2004-2009 Analog Devices Inc.
3 *
4 * Licensed under the GPL-2 or later.
5 */
6
1#ifndef _BLACKFIN_BITOPS_H 7#ifndef _BLACKFIN_BITOPS_H
2#define _BLACKFIN_BITOPS_H 8#define _BLACKFIN_BITOPS_H
3 9
diff --git a/arch/blackfin/include/asm/blackfin.h b/arch/blackfin/include/asm/blackfin.h
index 4d4439583396..eb7c1441d8f9 100644
--- a/arch/blackfin/include/asm/blackfin.h
+++ b/arch/blackfin/include/asm/blackfin.h
@@ -1,6 +1,9 @@
1/* 1/*
2 * Common header file for blackfin family of processors. 2 * Common header file for Blackfin family of processors.
3 * 3 *
4 * Copyright 2004-2009 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2 or later.
4 */ 7 */
5 8
6#ifndef _BLACKFIN_H_ 9#ifndef _BLACKFIN_H_
diff --git a/arch/blackfin/include/asm/bug.h b/arch/blackfin/include/asm/bug.h
index 655e49540e41..6f4548a13555 100644
--- a/arch/blackfin/include/asm/bug.h
+++ b/arch/blackfin/include/asm/bug.h
@@ -1,3 +1,9 @@
1/*
2 * Copyright 2004-2009 Analog Devices Inc.
3 *
4 * Licensed under the GPL-2 or later.
5 */
6
1#ifndef _BLACKFIN_BUG_H 7#ifndef _BLACKFIN_BUG_H
2#define _BLACKFIN_BUG_H 8#define _BLACKFIN_BUG_H
3 9
diff --git a/arch/blackfin/include/asm/byteorder.h b/arch/blackfin/include/asm/byteorder.h
index 3e69106a4d37..9558416d578b 100644
--- a/arch/blackfin/include/asm/byteorder.h
+++ b/arch/blackfin/include/asm/byteorder.h
@@ -1,6 +1 @@
1#ifndef _BLACKFIN_BYTEORDER_H
2#define _BLACKFIN_BYTEORDER_H
3
4#include <linux/byteorder/little_endian.h> #include <linux/byteorder/little_endian.h>
5
6#endif /* _BLACKFIN_BYTEORDER_H */
diff --git a/arch/blackfin/include/asm/cache.h b/arch/blackfin/include/asm/cache.h
index 477050ad5c53..8542bc31f63c 100644
--- a/arch/blackfin/include/asm/cache.h
+++ b/arch/blackfin/include/asm/cache.h
@@ -1,6 +1,9 @@
1/* 1/*
2 * include/asm-blackfin/cache.h 2 * Copyright 2004-2009 Analog Devices Inc.
3 *
4 * Licensed under the GPL-2 or later.
3 */ 5 */
6
4#ifndef __ARCH_BLACKFIN_CACHE_H 7#ifndef __ARCH_BLACKFIN_CACHE_H
5#define __ARCH_BLACKFIN_CACHE_H 8#define __ARCH_BLACKFIN_CACHE_H
6 9
@@ -35,10 +38,10 @@
35 38
36#if defined(CONFIG_SMP) && \ 39#if defined(CONFIG_SMP) && \
37 !defined(CONFIG_BFIN_CACHE_COHERENT) 40 !defined(CONFIG_BFIN_CACHE_COHERENT)
38# if defined(CONFIG_BFIN_ICACHEABLE) || defined(CONFIG_BFIN_L2_ICACHEABLE) 41# if defined(CONFIG_BFIN_EXTMEM_ICACHEABLE) || defined(CONFIG_BFIN_L2_ICACHEABLE)
39# define __ARCH_SYNC_CORE_ICACHE 42# define __ARCH_SYNC_CORE_ICACHE
40# endif 43# endif
41# if defined(CONFIG_BFIN_DCACHEABLE) || defined(CONFIG_BFIN_L2_DCACHEABLE) 44# if defined(CONFIG_BFIN_EXTMEM_DCACHEABLE) || defined(CONFIG_BFIN_L2_DCACHEABLE)
42# define __ARCH_SYNC_CORE_DCACHE 45# define __ARCH_SYNC_CORE_DCACHE
43# endif 46# endif
44#ifndef __ASSEMBLY__ 47#ifndef __ASSEMBLY__
diff --git a/arch/blackfin/include/asm/cacheflush.h b/arch/blackfin/include/asm/cacheflush.h
index 7e55549e180f..af03a36c7a4e 100644
--- a/arch/blackfin/include/asm/cacheflush.h
+++ b/arch/blackfin/include/asm/cacheflush.h
@@ -1,30 +1,9 @@
1/* 1/*
2 * File: include/asm-blackfin/cacheflush.h 2 * Blackfin low-level cache routines
3 * Based on: include/asm-m68knommu/cacheflush.h
4 * Author: LG Soft India
5 * Copyright (C) 2004 Analog Devices Inc.
6 * Created: Tue Sep 21 2004
7 * Description: Blackfin low-level cache routines adapted from the i386
8 * and PPC versions by Greg Ungerer (gerg@snapgear.com)
9 * 3 *
10 * Modified: 4 * Copyright 2004-2009 Analog Devices Inc.
11 * 5 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/ 6 * Licensed under the GPL-2 or later.
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2, or (at your option)
17 * any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; see the file COPYING.
26 * If not, write to the Free Software Foundation,
27 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28 */ 7 */
29 8
30#ifndef _BLACKFIN_CACHEFLUSH_H 9#ifndef _BLACKFIN_CACHEFLUSH_H
diff --git a/arch/blackfin/include/asm/cdef_LPBlackfin.h b/arch/blackfin/include/asm/cdef_LPBlackfin.h
index 35f841bce57d..8778e0f03730 100644
--- a/arch/blackfin/include/asm/cdef_LPBlackfin.h
+++ b/arch/blackfin/include/asm/cdef_LPBlackfin.h
@@ -1,30 +1,8 @@
1 /* 1/*
2 * File: include/asm-blackfin/mach-common/cdef_LPBlackfin.h 2 * Copyright 2005-2008 Analog Devices Inc.
3 * Based on: 3 *
4 * Author: unknown 4 * Licensed under the GPL-2 or later.
5 * COPYRIGHT 2005 Analog Devices 5 */
6 * Created: ?
7 * Description:
8 *
9 * Modified:
10 *
11 * Bugs: Enter bugs at http://blackfin.uclinux.org/
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2, or (at your option)
16 * any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; see the file COPYING.
25 * If not, write to the Free Software Foundation,
26 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 */
28 6
29#ifndef _CDEF_LPBLACKFIN_H 7#ifndef _CDEF_LPBLACKFIN_H
30#define _CDEF_LPBLACKFIN_H 8#define _CDEF_LPBLACKFIN_H
diff --git a/arch/blackfin/include/asm/checksum.h b/arch/blackfin/include/asm/checksum.h
index 793581fc9556..a23415be0de1 100644
--- a/arch/blackfin/include/asm/checksum.h
+++ b/arch/blackfin/include/asm/checksum.h
@@ -1,9 +1,14 @@
1/*
2 * Copyright 2004-2009 Analog Devices Inc.
3 * akbar.hussain@lineo.com
4 *
5 * Licensed under the GPL-2 or later.
6 */
7
1#ifndef _BFIN_CHECKSUM_H 8#ifndef _BFIN_CHECKSUM_H
2#define _BFIN_CHECKSUM_H 9#define _BFIN_CHECKSUM_H
3 10
4/* 11/*
5 * MODIFIED FOR BFIN April 30, 2001 akbar.hussain@lineo.com
6 *
7 * computes the checksum of a memory block at buff, length len, 12 * computes the checksum of a memory block at buff, length len,
8 * and adds in "sum" (32-bit) 13 * and adds in "sum" (32-bit)
9 * 14 *
diff --git a/arch/blackfin/include/asm/clocks.h b/arch/blackfin/include/asm/clocks.h
index 033bba92d61c..f80dad5ff257 100644
--- a/arch/blackfin/include/asm/clocks.h
+++ b/arch/blackfin/include/asm/clocks.h
@@ -1,30 +1,9 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-common/clocks.h 2 * Common Clock definitions for various kernel files
3 * Based on: include/asm-blackfin/mach-bf537/bf537.h
4 * Author: Robin Getz <rgetz@blackfin.uclinux.org>
5 * 3 *
6 * Created: 25Jul07 4 * Copyright 2007-2008 Analog Devices Inc.
7 * Description: Common Clock definitions for various kernel files
8 * 5 *
9 * Modified: 6 * Licensed under the GPL-2 or later.
10 * Copyright 2004-2007 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 7 */
29 8
30#ifndef _BFIN_CLOCKS_H 9#ifndef _BFIN_CLOCKS_H
diff --git a/arch/blackfin/include/asm/context.S b/arch/blackfin/include/asm/context.S
index f8a664f022b1..5dffaf582a22 100644
--- a/arch/blackfin/include/asm/context.S
+++ b/arch/blackfin/include/asm/context.S
@@ -1,30 +1,7 @@
1/* 1/*
2 * File: arch/blackfin/kernel/context.S 2 * Copyright 2007-2009 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the GPL-2 or later.
7 * Description:
8 *
9 * Modified:
10 * Copyright 2004-2007 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 5 */
29 6
30/* 7/*
diff --git a/arch/blackfin/include/asm/cplb.h b/arch/blackfin/include/asm/cplb.h
index d18d16837a6d..fda96261ed62 100644
--- a/arch/blackfin/include/asm/cplb.h
+++ b/arch/blackfin/include/asm/cplb.h
@@ -1,30 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/cplb.h 2 * Copyright 2004-2009 Analog Devices Inc.
3 * Based on: include/asm-blackfin/mach-bf537/bf537.h
4 * Author: Robin Getz <rgetz@blackfin.uclinux.org>
5 * 3 *
6 * Created: 2000 4 * Licensed under the GPL-2 or later.
7 * Description: Common CPLB definitions for CPLB init
8 *
9 * Modified:
10 * Copyright 2004-2007 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 5 */
29 6
30#ifndef _CPLB_H 7#ifndef _CPLB_H
diff --git a/arch/blackfin/include/asm/cplbinit.h b/arch/blackfin/include/asm/cplbinit.h
index 05b14a631d0c..f315c83a015d 100644
--- a/arch/blackfin/include/asm/cplbinit.h
+++ b/arch/blackfin/include/asm/cplbinit.h
@@ -1,30 +1,9 @@
1/* 1/*
2 * File: include/asm-blackfin/cplbinit.h 2 * Common CPLB definitions for CPLB init
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Copyright 2006-2008 Analog Devices Inc.
7 * Description:
8 * 5 *
9 * Modified: 6 * Licensed under the GPL-2 or later.
10 * Copyright 2004-2006 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 7 */
29 8
30#ifndef __ASM_CPLBINIT_H__ 9#ifndef __ASM_CPLBINIT_H__
diff --git a/arch/blackfin/include/asm/cpu.h b/arch/blackfin/include/asm/cpu.h
index fadfa82f93b2..b191dc662bd8 100644
--- a/arch/blackfin/include/asm/cpu.h
+++ b/arch/blackfin/include/asm/cpu.h
@@ -1,23 +1,8 @@
1/* 1/*
2 * File: arch/blackfin/include/asm/cpu.h. 2 * Copyright 2007-2009 Analog Devices Inc.
3 * Author: Philippe Gerum <rpm@xenomai.org> 3 * Philippe Gerum <rpm@xenomai.org>
4 * 4 *
5 * Copyright 2007 Analog Devices Inc. 5 * Licensed under the GPL-2 or later.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see the file COPYING, or write
19 * to the Free Software Foundation, Inc.,
20 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 */ 6 */
22 7
23#ifndef __ASM_BLACKFIN_CPU_H 8#ifndef __ASM_BLACKFIN_CPU_H
diff --git a/arch/blackfin/include/asm/def_LPBlackfin.h b/arch/blackfin/include/asm/def_LPBlackfin.h
index 6341eebff3dc..25906468622f 100644
--- a/arch/blackfin/include/asm/def_LPBlackfin.h
+++ b/arch/blackfin/include/asm/def_LPBlackfin.h
@@ -1,32 +1,10 @@
1 /* 1/*
2 * File: include/asm-blackfin/mach-common/def_LPBlackfin.h 2 * Blackfin core register bit & address definitions
3 * Based on: 3 *
4 * Author: unknown 4 * Copyright 2005-2008 Analog Devices Inc.
5 * COPYRIGHT 2005 Analog Devices 5 *
6 * Created: ? 6 * Licensed under the ADI BSD license or GPL-2 (or later).
7 * Description: 7 */
8 *
9 * Modified:
10 *
11 * Bugs: Enter bugs at http://blackfin.uclinux.org/
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2, or (at your option)
16 * any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; see the file COPYING.
25 * If not, write to the Free Software Foundation,
26 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 */
28
29/* LP Blackfin CORE REGISTER BIT & ADDRESS DEFINITIONS FOR ADSP-BF532/33 */
30 8
31#ifndef _DEF_LPBLACKFIN_H 9#ifndef _DEF_LPBLACKFIN_H
32#define _DEF_LPBLACKFIN_H 10#define _DEF_LPBLACKFIN_H
diff --git a/arch/blackfin/include/asm/dma-mapping.h b/arch/blackfin/include/asm/dma-mapping.h
index ed6b1f3cccce..7a23d824ac96 100644
--- a/arch/blackfin/include/asm/dma-mapping.h
+++ b/arch/blackfin/include/asm/dma-mapping.h
@@ -1,3 +1,9 @@
1/*
2 * Copyright 2004-2009 Analog Devices Inc.
3 *
4 * Licensed under the GPL-2 or later.
5 */
6
1#ifndef _BLACKFIN_DMA_MAPPING_H 7#ifndef _BLACKFIN_DMA_MAPPING_H
2#define _BLACKFIN_DMA_MAPPING_H 8#define _BLACKFIN_DMA_MAPPING_H
3 9
diff --git a/arch/blackfin/include/asm/dpmc.h b/arch/blackfin/include/asm/dpmc.h
index 96e8208f929a..925e66cb2d49 100644
--- a/arch/blackfin/include/asm/dpmc.h
+++ b/arch/blackfin/include/asm/dpmc.h
@@ -1,9 +1,11 @@
1/* 1/*
2 * include/asm-blackfin/dpmc.h - Miscellaneous IOCTL commands for Dynamic Power 2 * Miscellaneous IOCTL commands for Dynamic Power Management Controller Driver
3 * Management Controller Driver. 3 *
4 * Copyright (C) 2004-2008 Analog Device Inc. 4 * Copyright (C) 2004-2008 Analog Device Inc.
5 * 5 *
6 * Licensed under the GPL-2
6 */ 7 */
8
7#ifndef _BLACKFIN_DPMC_H_ 9#ifndef _BLACKFIN_DPMC_H_
8#define _BLACKFIN_DPMC_H_ 10#define _BLACKFIN_DPMC_H_
9 11
diff --git a/arch/blackfin/include/asm/early_printk.h b/arch/blackfin/include/asm/early_printk.h
index 53a762b6fcd2..68a910db8864 100644
--- a/arch/blackfin/include/asm/early_printk.h
+++ b/arch/blackfin/include/asm/early_printk.h
@@ -1,27 +1,11 @@
1/* 1/*
2 * File: include/asm-blackfin/early_printk.h 2 * function prototpyes for early printk
3 * Author: Robin Getz <rgetz@blackfin.uclinux.org
4 * 3 *
5 * Created: 14Aug2007 4 * Copyright 2007-2009 Analog Devices Inc.
6 * Description: function prototpyes for early printk
7 * 5 *
8 * Modified: 6 * Licensed under the GPL-2 or later.
9 * Copyright 2004-2007 Analog Devices Inc.
10 *
11 * Bugs: Enter bugs at http://blackfin.uclinux.org/
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 */ 7 */
23 8
24
25#ifndef __ASM_EARLY_PRINTK_H__ 9#ifndef __ASM_EARLY_PRINTK_H__
26#define __ASM_EARLY_PRINTK_H__ 10#define __ASM_EARLY_PRINTK_H__
27 11
diff --git a/arch/blackfin/include/asm/elf.h b/arch/blackfin/include/asm/elf.h
index c823e8ebbfa1..8e0764c81eaf 100644
--- a/arch/blackfin/include/asm/elf.h
+++ b/arch/blackfin/include/asm/elf.h
@@ -1,4 +1,8 @@
1/* Changes made by LG Soft Oct 2004*/ 1/*
2 * Copyright 2004-2009 Analog Devices Inc.
3 *
4 * Licensed under the GPL-2 or later.
5 */
2 6
3#ifndef __ASMBFIN_ELF_H 7#ifndef __ASMBFIN_ELF_H
4#define __ASMBFIN_ELF_H 8#define __ASMBFIN_ELF_H
diff --git a/arch/blackfin/include/asm/entry.h b/arch/blackfin/include/asm/entry.h
index 55b808fced71..a6886f6e4819 100644
--- a/arch/blackfin/include/asm/entry.h
+++ b/arch/blackfin/include/asm/entry.h
@@ -1,3 +1,9 @@
1/*
2 * Copyright 2004-2009 Analog Devices Inc.
3 *
4 * Licensed under the GPL-2 or later.
5 */
6
1#ifndef __BFIN_ENTRY_H 7#ifndef __BFIN_ENTRY_H
2#define __BFIN_ENTRY_H 8#define __BFIN_ENTRY_H
3 9
diff --git a/arch/blackfin/include/asm/fcntl.h b/arch/blackfin/include/asm/fcntl.h
index 9c4037127857..8727b2b382f1 100644
--- a/arch/blackfin/include/asm/fcntl.h
+++ b/arch/blackfin/include/asm/fcntl.h
@@ -1,3 +1,9 @@
1/*
2 * Copyright 2004-2008 Analog Devices Inc.
3 *
4 * Licensed under the GPL-2 or later.
5 */
6
1#ifndef _BFIN_FCNTL_H 7#ifndef _BFIN_FCNTL_H
2#define _BFIN_FCNTL_H 8#define _BFIN_FCNTL_H
3 9
diff --git a/arch/blackfin/include/asm/fixed_code.h b/arch/blackfin/include/asm/fixed_code.h
index 32c4d495d847..73fe53e7fd24 100644
--- a/arch/blackfin/include/asm/fixed_code.h
+++ b/arch/blackfin/include/asm/fixed_code.h
@@ -1,5 +1,11 @@
1/* This file defines the fixed addresses where userspace programs can find 1/*
2 atomic code sequences. */ 2 * This file defines the fixed addresses where userspace programs
3 * can find atomic code sequences.
4 *
5 * Copyright 2007-2008 Analog Devices Inc.
6 *
7 * Licensed under the GPL-2 or later.
8 */
3 9
4#ifndef __BFIN_ASM_FIXED_CODE_H__ 10#ifndef __BFIN_ASM_FIXED_CODE_H__
5#define __BFIN_ASM_FIXED_CODE_H__ 11#define __BFIN_ASM_FIXED_CODE_H__
diff --git a/arch/blackfin/include/asm/flat.h b/arch/blackfin/include/asm/flat.h
index 733a178d782d..c1314c56dd18 100644
--- a/arch/blackfin/include/asm/flat.h
+++ b/arch/blackfin/include/asm/flat.h
@@ -1,8 +1,9 @@
1/* 1/*
2 * include/asm-blackfin/flat.h -- uClinux flat-format executables 2 * uClinux flat-format executables
3 * 3 *
4 * Copyright (C) 2003, 4 * Copyright 2003-2009 Analog Devices Inc.
5 * 5 *
6 * Licensed under the GPL-2
6 */ 7 */
7 8
8#ifndef __BLACKFIN_FLAT_H__ 9#ifndef __BLACKFIN_FLAT_H__
diff --git a/arch/blackfin/include/asm/gpio.h b/arch/blackfin/include/asm/gpio.h
index fe139619351f..5b44d05ca53e 100644
--- a/arch/blackfin/include/asm/gpio.h
+++ b/arch/blackfin/include/asm/gpio.h
@@ -1,30 +1,7 @@
1/* 1/*
2 * File: arch/blackfin/kernel/bfin_gpio.h 2 * Copyright 2006-2009 Analog Devices Inc.
3 * Based on:
4 * Author: Michael Hennerich (hennerich@blackfin.uclinux.org)
5 * 3 *
6 * Created: 4 * Licensed under the GPL-2 or later.
7 * Description:
8 *
9 * Modified:
10 * Copyright 2004-2008 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 5 */
29 6
30#ifndef __ARCH_BLACKFIN_GPIO_H__ 7#ifndef __ARCH_BLACKFIN_GPIO_H__
diff --git a/arch/blackfin/include/asm/hardirq.h b/arch/blackfin/include/asm/hardirq.h
index 0b78b873df51..c078dd78d998 100644
--- a/arch/blackfin/include/asm/hardirq.h
+++ b/arch/blackfin/include/asm/hardirq.h
@@ -1,3 +1,9 @@
1/*
2 * Copyright 2004-2009 Analog Devices Inc.
3 *
4 * Licensed under the GPL-2 or later.
5 */
6
1#ifndef __BFIN_HARDIRQ_H 7#ifndef __BFIN_HARDIRQ_H
2#define __BFIN_HARDIRQ_H 8#define __BFIN_HARDIRQ_H
3 9
diff --git a/arch/blackfin/include/asm/io.h b/arch/blackfin/include/asm/io.h
index 37053eca200e..d1f5029189a7 100644
--- a/arch/blackfin/include/asm/io.h
+++ b/arch/blackfin/include/asm/io.h
@@ -1,3 +1,9 @@
1/*
2 * Copyright 2004-2009 Analog Devices Inc.
3 *
4 * Licensed under the GPL-2 or later.
5 */
6
1#ifndef _BFIN_IO_H 7#ifndef _BFIN_IO_H
2#define _BFIN_IO_H 8#define _BFIN_IO_H
3 9
diff --git a/arch/blackfin/include/asm/irq.h b/arch/blackfin/include/asm/irq.h
index 42a15f5ce0d0..e7c0623f9091 100644
--- a/arch/blackfin/include/asm/irq.h
+++ b/arch/blackfin/include/asm/irq.h
@@ -1,17 +1,10 @@
1/* 1/*
2 * This file is subject to the terms and conditions of the GNU General Public 2 * Copyright 2004-2009 Analog Devices Inc.
3 * License. See the file COPYING in the main directory of this archive 3 * 2003 HuTao
4 * for more details. 4 * 2002 Arcturus Networks Inc. (www.arcturusnetworks.com
5 * Ted Ma <mated@sympatico.ca>
5 * 6 *
6 * Changed by HuTao Apr18, 2003 7 * Licensed under the GPL-2
7 *
8 * Copyright was missing when I got the code so took from MIPS arch ...MaTed---
9 * Copyright (C) 1994 by Waldorf GMBH, written by Ralf Baechle
10 * Copyright (C) 1995, 96, 97, 98, 99, 2000, 2001 by Ralf Baechle
11 *
12 * Adapted for BlackFin (ADI) by Ted Ma <mated@sympatico.ca>
13 * Copyright (c) 2002 Arcturus Networks Inc. (www.arcturusnetworks.com)
14 * Copyright (c) 2002 Lineo, Inc. <mattw@lineo.com>
15 */ 8 */
16 9
17#ifndef _BFIN_IRQ_H_ 10#ifndef _BFIN_IRQ_H_
@@ -19,6 +12,8 @@
19 12
20#include <linux/irqflags.h> 13#include <linux/irqflags.h>
21 14
15#include <mach/anomaly.h>
16
22/* SYS_IRQS and NR_IRQS are defined in <mach-bf5xx/irq.h> */ 17/* SYS_IRQS and NR_IRQS are defined in <mach-bf5xx/irq.h> */
23#include <mach/irq.h> 18#include <mach/irq.h>
24 19
diff --git a/arch/blackfin/include/asm/irq_handler.h b/arch/blackfin/include/asm/irq_handler.h
index 7d9e2d3bbede..7fbe42307b9a 100644
--- a/arch/blackfin/include/asm/irq_handler.h
+++ b/arch/blackfin/include/asm/irq_handler.h
@@ -1,3 +1,9 @@
1/*
2 * Copyright 2007-2009 Analog Devices Inc.
3 *
4 * Licensed under the GPL-2 or later.
5 */
6
1#ifndef _IRQ_HANDLER_H 7#ifndef _IRQ_HANDLER_H
2#define _IRQ_HANDLER_H 8#define _IRQ_HANDLER_H
3 9
diff --git a/arch/blackfin/include/asm/l1layout.h b/arch/blackfin/include/asm/l1layout.h
index 79dbefaa5bef..c87e68647a2b 100644
--- a/arch/blackfin/include/asm/l1layout.h
+++ b/arch/blackfin/include/asm/l1layout.h
@@ -1,6 +1,9 @@
1/* 1/*
2 * l1layout.h
3 * Defines a layout of L1 scratchpad memory that userspace can rely on. 2 * Defines a layout of L1 scratchpad memory that userspace can rely on.
3 *
4 * Copyright 2006-2008 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2 or later.
4 */ 7 */
5 8
6#ifndef _L1LAYOUT_H_ 9#ifndef _L1LAYOUT_H_
diff --git a/arch/blackfin/include/asm/linkage.h b/arch/blackfin/include/asm/linkage.h
index 5a822bb790f7..f7d6d47a048d 100644
--- a/arch/blackfin/include/asm/linkage.h
+++ b/arch/blackfin/include/asm/linkage.h
@@ -1,3 +1,9 @@
1/*
2 * Copyright 2004-2009 Analog Devices Inc.
3 *
4 * Licensed under the GPL-2 or later.
5 */
6
1#ifndef __ASM_LINKAGE_H 7#ifndef __ASM_LINKAGE_H
2#define __ASM_LINKAGE_H 8#define __ASM_LINKAGE_H
3 9
diff --git a/arch/blackfin/include/asm/mmu.h b/arch/blackfin/include/asm/mmu.h
index dbfd686360e6..26f6b70b11e2 100644
--- a/arch/blackfin/include/asm/mmu.h
+++ b/arch/blackfin/include/asm/mmu.h
@@ -1,8 +1,13 @@
1/*
2 * Copyright 2004-2009 Analog Devices Inc.
3 * 2002 David McCullough <davidm@snapgear.com>
4 *
5 * Licensed under the GPL-2.
6 */
7
1#ifndef __MMU_H 8#ifndef __MMU_H
2#define __MMU_H 9#define __MMU_H
3 10
4/* Copyright (C) 2002, David McCullough <davidm@snapgear.com> */
5
6struct sram_list_struct { 11struct sram_list_struct {
7 struct sram_list_struct *next; 12 struct sram_list_struct *next;
8 void *addr; 13 void *addr;
diff --git a/arch/blackfin/include/asm/mmu_context.h b/arch/blackfin/include/asm/mmu_context.h
index 040410bb07e1..4a3be376ad5b 100644
--- a/arch/blackfin/include/asm/mmu_context.h
+++ b/arch/blackfin/include/asm/mmu_context.h
@@ -1,30 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/mmu_context.h 2 * Copyright 2004-2009 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the GPL-2 or later.
7 * Description:
8 *
9 * Modified:
10 * Copyright 2004-2006 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 5 */
29 6
30#ifndef __BLACKFIN_MMU_CONTEXT_H__ 7#ifndef __BLACKFIN_MMU_CONTEXT_H__
diff --git a/arch/blackfin/include/asm/module.h b/arch/blackfin/include/asm/module.h
index e3128df139d6..9c1cfffddd9b 100644
--- a/arch/blackfin/include/asm/module.h
+++ b/arch/blackfin/include/asm/module.h
@@ -1,3 +1,9 @@
1/*
2 * Copyright 2004-2008 Analog Devices Inc.
3 *
4 * Licensed under the GPL-2 or later.
5 */
6
1#ifndef _ASM_BFIN_MODULE_H 7#ifndef _ASM_BFIN_MODULE_H
2#define _ASM_BFIN_MODULE_H 8#define _ASM_BFIN_MODULE_H
3 9
diff --git a/arch/blackfin/include/asm/mutex.h b/arch/blackfin/include/asm/mutex.h
index 5cc641c50834..f726e3a80ad0 100644
--- a/arch/blackfin/include/asm/mutex.h
+++ b/arch/blackfin/include/asm/mutex.h
@@ -4,6 +4,10 @@
4 * TODO: implement optimized primitives instead, or leave the generic 4 * TODO: implement optimized primitives instead, or leave the generic
5 * implementation in place, or pick the atomic_xchg() based generic 5 * implementation in place, or pick the atomic_xchg() based generic
6 * implementation. (see asm-generic/mutex-xchg.h for details) 6 * implementation. (see asm-generic/mutex-xchg.h for details)
7 *
8 * Copyright 2006-2009 Analog Devices Inc.
9 *
10 * Licensed under the GPL-2 or later.
7 */ 11 */
8 12
9#ifndef _ASM_MUTEX_H 13#ifndef _ASM_MUTEX_H
diff --git a/arch/blackfin/include/asm/nand.h b/arch/blackfin/include/asm/nand.h
index afbaafa793f1..3ae8b569edfc 100644
--- a/arch/blackfin/include/asm/nand.h
+++ b/arch/blackfin/include/asm/nand.h
@@ -1,13 +1,9 @@
1/* linux/include/asm-blackfin/nand.h 1/*
2 *
3 * Copyright (c) 2007 Analog Devices, Inc.
4 * Bryan Wu <bryan.wu@analog.com>
5 *
6 * BF5XX - NAND flash controller platfrom_device info 2 * BF5XX - NAND flash controller platfrom_device info
7 * 3 *
8 * This program is free software; you can redistribute it and/or modify 4 * Copyright 2007-2008 Analog Devices, Inc.
9 * it under the terms of the GNU General Public License version 2 as 5 *
10 * published by the Free Software Foundation. 6 * Licensed under the GPL-2
11 */ 7 */
12 8
13/* struct bf5xx_nand_platform 9/* struct bf5xx_nand_platform
diff --git a/arch/blackfin/include/asm/page.h b/arch/blackfin/include/asm/page.h
index 29dcf75c6112..944a07c6cfd6 100644
--- a/arch/blackfin/include/asm/page.h
+++ b/arch/blackfin/include/asm/page.h
@@ -1,3 +1,9 @@
1/*
2 * Copyright 2004-2009 Analog Devices Inc.
3 *
4 * Licensed under the GPL-2 or later.
5 */
6
1#ifndef _BLACKFIN_PAGE_H 7#ifndef _BLACKFIN_PAGE_H
2#define _BLACKFIN_PAGE_H 8#define _BLACKFIN_PAGE_H
3 9
diff --git a/arch/blackfin/include/asm/page_offset.h b/arch/blackfin/include/asm/page_offset.h
index cbaff24b4b25..d06a89b89d20 100644
--- a/arch/blackfin/include/asm/page_offset.h
+++ b/arch/blackfin/include/asm/page_offset.h
@@ -1,5 +1,10 @@
1 1/*
2/* This handles the memory map.. */ 2 * This handles the memory map
3 *
4 * Copyright 2004-2008 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2 or later.
7 */
3 8
4#ifdef CONFIG_BLACKFIN 9#ifdef CONFIG_BLACKFIN
5#define PAGE_OFFSET_RAW 0x00000000 10#define PAGE_OFFSET_RAW 0x00000000
diff --git a/arch/blackfin/include/asm/pda.h b/arch/blackfin/include/asm/pda.h
index a6f95695731d..d49bb261d9b7 100644
--- a/arch/blackfin/include/asm/pda.h
+++ b/arch/blackfin/include/asm/pda.h
@@ -1,23 +1,8 @@
1/* 1/*
2 * File: arch/blackfin/include/asm/pda.h 2 * Copyright 2007-2009 Analog Devices Inc.
3 * Author: Philippe Gerum <rpm@xenomai.org> 3 * Philippe Gerum <rpm@xenomai.org>
4 * 4 *
5 * Copyright 2007 Analog Devices Inc. 5 * Licensed under the GPL-2 or later.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see the file COPYING, or write
19 * to the Free Software Foundation, Inc.,
20 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 */ 6 */
22 7
23#ifndef _ASM_BLACKFIN_PDA_H 8#ifndef _ASM_BLACKFIN_PDA_H
diff --git a/arch/blackfin/include/asm/pgtable.h b/arch/blackfin/include/asm/pgtable.h
index 783c8f7f8f8c..821c699c2238 100644
--- a/arch/blackfin/include/asm/pgtable.h
+++ b/arch/blackfin/include/asm/pgtable.h
@@ -1,3 +1,9 @@
1/*
2 * Copyright 2004-2009 Analog Devices Inc.
3 *
4 * Licensed under the GPL-2 or later.
5 */
6
1#ifndef _BLACKFIN_PGTABLE_H 7#ifndef _BLACKFIN_PGTABLE_H
2#define _BLACKFIN_PGTABLE_H 8#define _BLACKFIN_PGTABLE_H
3 9
@@ -92,6 +98,12 @@ extern unsigned int kobjsize(const void *objp);
92#define VMALLOC_START 0 98#define VMALLOC_START 0
93#define VMALLOC_END 0xffffffff 99#define VMALLOC_END 0xffffffff
94 100
101/* provide a special get_unmapped_area for framebuffer mmaps of nommu */
102extern unsigned long get_fb_unmapped_area(struct file *filp, unsigned long,
103 unsigned long, unsigned long,
104 unsigned long);
105#define HAVE_ARCH_FB_UNMAPPED_AREA
106
95#include <asm-generic/pgtable.h> 107#include <asm-generic/pgtable.h>
96 108
97#endif /* _BLACKFIN_PGTABLE_H */ 109#endif /* _BLACKFIN_PGTABLE_H */
diff --git a/arch/blackfin/include/asm/poll.h b/arch/blackfin/include/asm/poll.h
index a0556671357b..072d8966c5c3 100644
--- a/arch/blackfin/include/asm/poll.h
+++ b/arch/blackfin/include/asm/poll.h
@@ -1,3 +1,10 @@
1/*
2 * Copyright 2004-2009 Analog Devices Inc.
3 *
4 * Licensed under the GPL-2 or later.
5 *
6 */
7
1#ifndef __BFIN_POLL_H 8#ifndef __BFIN_POLL_H
2#define __BFIN_POLL_H 9#define __BFIN_POLL_H
3 10
diff --git a/arch/blackfin/include/asm/portmux.h b/arch/blackfin/include/asm/portmux.h
index 88eb5c07cc24..edd8ef3a3788 100644
--- a/arch/blackfin/include/asm/portmux.h
+++ b/arch/blackfin/include/asm/portmux.h
@@ -1,6 +1,9 @@
1/* 1/*
2 * Common header file for blackfin family of processors. 2 * Common header file for Blackfin family of processors
3 * 3 *
4 * Copyright 2007-2008 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2 or later.
4 */ 7 */
5 8
6#ifndef _PORTMUX_H_ 9#ifndef _PORTMUX_H_
diff --git a/arch/blackfin/include/asm/posix_types.h b/arch/blackfin/include/asm/posix_types.h
index 80c9d64eb26c..41bc1875c4d7 100644
--- a/arch/blackfin/include/asm/posix_types.h
+++ b/arch/blackfin/include/asm/posix_types.h
@@ -1,3 +1,9 @@
1/*
2 * Copyright 2004-2009 Analog Devices Inc.
3 *
4 * Licensed under the GPL-2 or later.
5 */
6
1#ifndef __ARCH_BFIN_POSIX_TYPES_H 7#ifndef __ARCH_BFIN_POSIX_TYPES_H
2#define __ARCH_BFIN_POSIX_TYPES_H 8#define __ARCH_BFIN_POSIX_TYPES_H
3 9
diff --git a/arch/blackfin/include/asm/processor.h b/arch/blackfin/include/asm/processor.h
index a36ad8dac068..aea880274de7 100644
--- a/arch/blackfin/include/asm/processor.h
+++ b/arch/blackfin/include/asm/processor.h
@@ -1,3 +1,9 @@
1/*
2 * Copyright 2004-2009 Analog Devices Inc.
3 *
4 * Licensed under the GPL-2 or later.
5 */
6
1#ifndef __ASM_BFIN_PROCESSOR_H 7#ifndef __ASM_BFIN_PROCESSOR_H
2#define __ASM_BFIN_PROCESSOR_H 8#define __ASM_BFIN_PROCESSOR_H
3 9
diff --git a/arch/blackfin/include/asm/ptrace.h b/arch/blackfin/include/asm/ptrace.h
index e3f086dc7268..27290c955a7a 100644
--- a/arch/blackfin/include/asm/ptrace.h
+++ b/arch/blackfin/include/asm/ptrace.h
@@ -1,3 +1,9 @@
1/*
2 * Copyright 2004-2008 Analog Devices Inc.
3 *
4 * Licensed under the GPL-2 or later.
5 */
6
1#ifndef _BFIN_PTRACE_H 7#ifndef _BFIN_PTRACE_H
2#define _BFIN_PTRACE_H 8#define _BFIN_PTRACE_H
3 9
diff --git a/arch/blackfin/include/asm/sections.h b/arch/blackfin/include/asm/sections.h
index ae4dae1e370b..1f5381fbb4a7 100644
--- a/arch/blackfin/include/asm/sections.h
+++ b/arch/blackfin/include/asm/sections.h
@@ -1,3 +1,9 @@
1/*
2 * Copyright 2004-2009 Analog Devices Inc.
3 *
4 * Licensed under the GPL-2 or later.
5 */
6
1#ifndef _BLACKFIN_SECTIONS_H 7#ifndef _BLACKFIN_SECTIONS_H
2#define _BLACKFIN_SECTIONS_H 8#define _BLACKFIN_SECTIONS_H
3 9
diff --git a/arch/blackfin/include/asm/segment.h b/arch/blackfin/include/asm/segment.h
index 02cfd09b5a99..f8e1984ffc7e 100644
--- a/arch/blackfin/include/asm/segment.h
+++ b/arch/blackfin/include/asm/segment.h
@@ -1,3 +1,9 @@
1/*
2 * Copyright 2004-2008 Analog Devices Inc.
3 *
4 * Licensed under the GPL-2 or later.
5 */
6
1#ifndef _BFIN_SEGMENT_H 7#ifndef _BFIN_SEGMENT_H
2#define _BFIN_SEGMENT_H 8#define _BFIN_SEGMENT_H
3 9
diff --git a/arch/blackfin/include/asm/sigcontext.h b/arch/blackfin/include/asm/sigcontext.h
index ce00b03c2775..ce4081a4d815 100644
--- a/arch/blackfin/include/asm/sigcontext.h
+++ b/arch/blackfin/include/asm/sigcontext.h
@@ -1,3 +1,9 @@
1/*
2 * Copyright 2004-2008 Analog Devices Inc.
3 *
4 * Licensed under the GPL-2 or later.
5 */
6
1#ifndef _ASM_BLACKFIN_SIGCONTEXT_H 7#ifndef _ASM_BLACKFIN_SIGCONTEXT_H
2#define _ASM_BLACKFIN_SIGCONTEXT_H 8#define _ASM_BLACKFIN_SIGCONTEXT_H
3 9
diff --git a/arch/blackfin/include/asm/siginfo.h b/arch/blackfin/include/asm/siginfo.h
index eca4565cea37..3e81306394e2 100644
--- a/arch/blackfin/include/asm/siginfo.h
+++ b/arch/blackfin/include/asm/siginfo.h
@@ -1,3 +1,9 @@
1/*
2 * Copyright 2004-2008 Analog Devices Inc.
3 *
4 * Licensed under the GPL-2 or later.
5 */
6
1#ifndef _BFIN_SIGINFO_H 7#ifndef _BFIN_SIGINFO_H
2#define _BFIN_SIGINFO_H 8#define _BFIN_SIGINFO_H
3 9
diff --git a/arch/blackfin/include/asm/smp.h b/arch/blackfin/include/asm/smp.h
index 118deeeae7c0..6a0fe94b84a6 100644
--- a/arch/blackfin/include/asm/smp.h
+++ b/arch/blackfin/include/asm/smp.h
@@ -1,23 +1,8 @@
1/* 1/*
2 * File: arch/blackfin/include/asm/smp.h 2 * Copyright 2007-2009 Analog Devices Inc.
3 * Author: Philippe Gerum <rpm@xenomai.org> 3 * Philippe Gerum <rpm@xenomai.org>
4 * 4 *
5 * Copyright 2007 Analog Devices Inc. 5 * Licensed under the GPL-2 or later.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see the file COPYING, or write
19 * to the Free Software Foundation, Inc.,
20 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 */ 6 */
22 7
23#ifndef __ASM_BLACKFIN_SMP_H 8#ifndef __ASM_BLACKFIN_SMP_H
diff --git a/arch/blackfin/include/asm/spinlock.h b/arch/blackfin/include/asm/spinlock.h
index d6ff4b59fcb1..b0c7f0ee4b03 100644
--- a/arch/blackfin/include/asm/spinlock.h
+++ b/arch/blackfin/include/asm/spinlock.h
@@ -1,3 +1,9 @@
1/*
2 * Copyright 2004-2009 Analog Devices Inc.
3 *
4 * Licensed under the GPL-2 or later.
5 */
6
1#ifndef __BFIN_SPINLOCK_H 7#ifndef __BFIN_SPINLOCK_H
2#define __BFIN_SPINLOCK_H 8#define __BFIN_SPINLOCK_H
3 9
diff --git a/arch/blackfin/include/asm/spinlock_types.h b/arch/blackfin/include/asm/spinlock_types.h
index b1e3c4c7b382..be75762c0610 100644
--- a/arch/blackfin/include/asm/spinlock_types.h
+++ b/arch/blackfin/include/asm/spinlock_types.h
@@ -1,3 +1,9 @@
1/*
2 * Copyright 2008 Analog Devices Inc.
3 *
4 * Licensed under the GPL-2 or later.
5 */
6
1#ifndef __ASM_SPINLOCK_TYPES_H 7#ifndef __ASM_SPINLOCK_TYPES_H
2#define __ASM_SPINLOCK_TYPES_H 8#define __ASM_SPINLOCK_TYPES_H
3 9
diff --git a/arch/blackfin/include/asm/stat.h b/arch/blackfin/include/asm/stat.h
index d2b6f11ec231..2e27665c4e91 100644
--- a/arch/blackfin/include/asm/stat.h
+++ b/arch/blackfin/include/asm/stat.h
@@ -1,3 +1,9 @@
1/*
2 * Copyright 2004-2006 Analog Devices Inc.
3 *
4 * Licensed under the GPL-2.
5 */
6
1#ifndef _BFIN_STAT_H 7#ifndef _BFIN_STAT_H
2#define _BFIN_STAT_H 8#define _BFIN_STAT_H
3 9
diff --git a/arch/blackfin/include/asm/string.h b/arch/blackfin/include/asm/string.h
index 321f4d96e4ae..d7f0ccb418c3 100644
--- a/arch/blackfin/include/asm/string.h
+++ b/arch/blackfin/include/asm/string.h
@@ -1,3 +1,9 @@
1/*
2 * Copyright 2004-2008 Analog Devices Inc.
3 *
4 * Licensed under the GPL-2 or later.
5 */
6
1#ifndef _BLACKFIN_STRING_H_ 7#ifndef _BLACKFIN_STRING_H_
2#define _BLACKFIN_STRING_H_ 8#define _BLACKFIN_STRING_H_
3 9
diff --git a/arch/blackfin/include/asm/swab.h b/arch/blackfin/include/asm/swab.h
index d442113de515..89de6507ca2b 100644
--- a/arch/blackfin/include/asm/swab.h
+++ b/arch/blackfin/include/asm/swab.h
@@ -1,3 +1,9 @@
1/*
2 * Copyright 2009 Analog Devices Inc.
3 *
4 * Licensed under the GPL-2 or later.
5 */
6
1#ifndef _BLACKFIN_SWAB_H 7#ifndef _BLACKFIN_SWAB_H
2#define _BLACKFIN_SWAB_H 8#define _BLACKFIN_SWAB_H
3 9
diff --git a/arch/blackfin/include/asm/system.h b/arch/blackfin/include/asm/system.h
index 85e8f16cf8c2..dde19b1d25f5 100644
--- a/arch/blackfin/include/asm/system.h
+++ b/arch/blackfin/include/asm/system.h
@@ -1,34 +1,8 @@
1/* 1/*
2 * File: include/asm/system.h 2 * Copyright 2004-2009 Analog Devices Inc.
3 * Based on: 3 * Tony Kou (tonyko@lineo.ca)
4 * Author: Tony Kou (tonyko@lineo.ca)
5 * Copyright (c) 2002 Arcturus Networks Inc.
6 * (www.arcturusnetworks.com)
7 * Copyright (c) 2003 Metrowerks (www.metrowerks.com)
8 * Copyright (c) 2004 Analog Device Inc.
9 * Created: 25Jan2001 - Tony Kou
10 * Description: system.h include file
11 * 4 *
12 * Modified: 22Sep2006 - Robin Getz 5 * Licensed under the GPL-2 or later
13 * - move include blackfin.h down, so I can get access to
14 * irq functions in other include files.
15 *
16 * Bugs: Enter bugs at http://blackfin.uclinux.org/
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2, or (at your option)
21 * any later version.
22 *
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with this program; see the file COPYING.
30 * If not, write to the Free Software Foundation,
31 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
32 */ 6 */
33 7
34#ifndef _BLACKFIN_SYSTEM_H 8#ifndef _BLACKFIN_SYSTEM_H
diff --git a/arch/blackfin/include/asm/thread_info.h b/arch/blackfin/include/asm/thread_info.h
index 2bbfdd950afc..afb3a8626380 100644
--- a/arch/blackfin/include/asm/thread_info.h
+++ b/arch/blackfin/include/asm/thread_info.h
@@ -1,27 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/thread_info.h 2 * Copyright 2004-2009 Analog Devices Inc.
3 * Based on: include/asm-m68knommu/thread_info.h
4 * Author: LG Soft India
5 * Copyright (C) 2004-2005 Analog Devices Inc.
6 * Created: Tue Sep 21 2004
7 * Description: Blackfin low-level thread information
8 * Modified:
9 * Bugs: Enter bugs at http://blackfin.uclinux.org/
10 * 3 *
11 * This program is free software; you can redistribute it and/or modify 4 * Licensed under the GPL-2 or later.
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2, or (at your option)
14 * any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; see the file COPYING.
23 * If not, write to the Free Software Foundation,
24 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 */ 5 */
26 6
27#ifndef _ASM_THREAD_INFO_H 7#ifndef _ASM_THREAD_INFO_H
diff --git a/arch/blackfin/include/asm/tlb.h b/arch/blackfin/include/asm/tlb.h
index 89a12ee916d8..a74ae08af1a7 100644
--- a/arch/blackfin/include/asm/tlb.h
+++ b/arch/blackfin/include/asm/tlb.h
@@ -1,3 +1,9 @@
1/*
2 * Copyright 2004-2008 Analog Devices Inc.
3 *
4 * Licensed under the GPL-2 or later.
5 */
6
1#ifndef _BLACKFIN_TLB_H 7#ifndef _BLACKFIN_TLB_H
2#define _BLACKFIN_TLB_H 8#define _BLACKFIN_TLB_H
3 9
diff --git a/arch/blackfin/include/asm/trace.h b/arch/blackfin/include/asm/trace.h
index 312b596b9731..609ad3c84189 100644
--- a/arch/blackfin/include/asm/trace.h
+++ b/arch/blackfin/include/asm/trace.h
@@ -1,6 +1,9 @@
1/* 1/*
2 * Common header file for blackfin family of processors. 2 * header file for hardware trace functions
3 * 3 *
4 * Copyright 2007-2008 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2 or later.
4 */ 7 */
5 8
6#ifndef _BLACKFIN_TRACE_ 9#ifndef _BLACKFIN_TRACE_
diff --git a/arch/blackfin/include/asm/traps.h b/arch/blackfin/include/asm/traps.h
index 3cdc454cde23..9fe0da612c09 100644
--- a/arch/blackfin/include/asm/traps.h
+++ b/arch/blackfin/include/asm/traps.h
@@ -1,13 +1,10 @@
1/* 1/*
2 * linux/include/asm/traps.h 2 * Copyright 2004-2009 Analog Devices Inc.
3 * 2001 Lineo, Inc
4 * Tony Kou
5 * 1993 Hamish Macdonald
3 * 6 *
4 * Copyright (C) 1993 Hamish Macdonald 7 * Licensed under the GPL-2
5 *
6 * Lineo, Inc Jul 2001 Tony Kou
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file COPYING in the main directory of this archive
10 * for more details.
11 */ 8 */
12 9
13#ifndef _BFIN_TRAPS_H 10#ifndef _BFIN_TRAPS_H
diff --git a/arch/blackfin/include/asm/uaccess.h b/arch/blackfin/include/asm/uaccess.h
index 2f469a1f80fb..c03b8532aad3 100644
--- a/arch/blackfin/include/asm/uaccess.h
+++ b/arch/blackfin/include/asm/uaccess.h
@@ -1,4 +1,7 @@
1/* Changes made by Lineo Inc. May 2001 1/*
2 * Copyright 2004-2009 Analog Devices Inc.
3 *
4 * Licensed under the GPL-2 or later.
2 * 5 *
3 * Based on: include/asm-m68knommu/uaccess.h 6 * Based on: include/asm-m68knommu/uaccess.h
4 */ 7 */
diff --git a/arch/blackfin/include/asm/unistd.h b/arch/blackfin/include/asm/unistd.h
index 02b1529dad57..779be02a910a 100644
--- a/arch/blackfin/include/asm/unistd.h
+++ b/arch/blackfin/include/asm/unistd.h
@@ -1,3 +1,9 @@
1/*
2 * Copyright 2004-2009 Analog Devices Inc.
3 *
4 * Licensed under the GPL-2 or later.
5 */
6
1#ifndef __ASM_BFIN_UNISTD_H 7#ifndef __ASM_BFIN_UNISTD_H
2#define __ASM_BFIN_UNISTD_H 8#define __ASM_BFIN_UNISTD_H
3/* 9/*
diff --git a/arch/blackfin/kernel/asm-offsets.c b/arch/blackfin/kernel/asm-offsets.c
index f05d1b99b0ef..bd32c09b9349 100644
--- a/arch/blackfin/kernel/asm-offsets.c
+++ b/arch/blackfin/kernel/asm-offsets.c
@@ -1,30 +1,9 @@
1/* 1/*
2 * File: arch/blackfin/kernel/asm-offsets.c 2 * generate definitions needed by assembly language modules
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Copyright 2004-2009 Analog Devices Inc.
7 * Description: generate definitions needed by assembly language modules.
8 * 5 *
9 * Modified: 6 * Licensed under the GPL-2 or later
10 * Copyright 2004-2006 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 7 */
29 8
30#include <linux/stddef.h> 9#include <linux/stddef.h>
diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c
index 384868dedac3..1f170216d2f9 100644
--- a/arch/blackfin/kernel/bfin_dma_5xx.c
+++ b/arch/blackfin/kernel/bfin_dma_5xx.c
@@ -2,6 +2,7 @@
2 * bfin_dma_5xx.c - Blackfin DMA implementation 2 * bfin_dma_5xx.c - Blackfin DMA implementation
3 * 3 *
4 * Copyright 2004-2008 Analog Devices Inc. 4 * Copyright 2004-2008 Analog Devices Inc.
5 *
5 * Licensed under the GPL-2 or later. 6 * Licensed under the GPL-2 or later.
6 */ 7 */
7 8
diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c
index fc4681c0170e..22705eeff34f 100644
--- a/arch/blackfin/kernel/bfin_gpio.c
+++ b/arch/blackfin/kernel/bfin_gpio.c
@@ -1,30 +1,9 @@
1/* 1/*
2 * File: arch/blackfin/kernel/bfin_gpio.c 2 * GPIO Abstraction Layer
3 * Based on:
4 * Author: Michael Hennerich (hennerich@blackfin.uclinux.org)
5 * 3 *
6 * Created: 4 * Copyright 2006-2009 Analog Devices Inc.
7 * Description: GPIO Abstraction Layer
8 * 5 *
9 * Modified: 6 * Licensed under the GPL-2 or later
10 * Copyright 2008 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 7 */
29 8
30#include <linux/delay.h> 9#include <linux/delay.h>
diff --git a/arch/blackfin/kernel/cplb-mpu/cplbinit.c b/arch/blackfin/kernel/cplb-mpu/cplbinit.c
index 36193eed9a1f..f7b9cdce8239 100644
--- a/arch/blackfin/kernel/cplb-mpu/cplbinit.c
+++ b/arch/blackfin/kernel/cplb-mpu/cplbinit.c
@@ -1,25 +1,11 @@
1/* 1/*
2 * Blackfin CPLB initialization 2 * Blackfin CPLB initialization
3 * 3 *
4 * Copyright 2004-2007 Analog Devices Inc. 4 * Copyright 2008-2009 Analog Devices Inc.
5 * 5 *
6 * Bugs: Enter bugs at http://blackfin.uclinux.org/ 6 * Licensed under the GPL-2 or later.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, see the file COPYING, or write
20 * to the Free Software Foundation, Inc.,
21 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 */ 7 */
8
23#include <linux/module.h> 9#include <linux/module.h>
24 10
25#include <asm/blackfin.h> 11#include <asm/blackfin.h>
diff --git a/arch/blackfin/kernel/cplb-mpu/cplbmgr.c b/arch/blackfin/kernel/cplb-mpu/cplbmgr.c
index 8e1e9e9e9632..69e0e530d70f 100644
--- a/arch/blackfin/kernel/cplb-mpu/cplbmgr.c
+++ b/arch/blackfin/kernel/cplb-mpu/cplbmgr.c
@@ -1,22 +1,11 @@
1/* 1/*
2 * Blackfin CPLB exception handling. 2 * Blackfin CPLB exception handling for when MPU in on
3 * Copyright 2004-2007 Analog Devices Inc.
4 * 3 *
5 * This program is free software; you can redistribute it and/or modify 4 * Copyright 2008-2009 Analog Devices Inc.
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 * 5 *
10 * This program is distributed in the hope that it will be useful, 6 * Licensed under the GPL-2 or later.
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, see the file COPYING, or write
17 * to the Free Software Foundation, Inc.,
18 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */ 7 */
8
20#include <linux/module.h> 9#include <linux/module.h>
21#include <linux/mm.h> 10#include <linux/mm.h>
22 11
diff --git a/arch/blackfin/kernel/cplb-nompu/cplbinit.c b/arch/blackfin/kernel/cplb-nompu/cplbinit.c
index 5d8ad503f82a..fd9a2f31e686 100644
--- a/arch/blackfin/kernel/cplb-nompu/cplbinit.c
+++ b/arch/blackfin/kernel/cplb-nompu/cplbinit.c
@@ -1,24 +1,9 @@
1/* 1/*
2 * Blackfin CPLB initialization 2 * Blackfin CPLB initialization
3 * 3 *
4 * Copyright 2004-2007 Analog Devices Inc. 4 * Copyright 2007-2009 Analog Devices Inc.
5 * 5 *
6 * Bugs: Enter bugs at http://blackfin.uclinux.org/ 6 * Licensed under the GPL-2 or later.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, see the file COPYING, or write
20 * to the Free Software Foundation, Inc.,
21 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 */ 7 */
23 8
24#include <linux/module.h> 9#include <linux/module.h>
diff --git a/arch/blackfin/kernel/cplb-nompu/cplbmgr.c b/arch/blackfin/kernel/cplb-nompu/cplbmgr.c
index d9ea46c6e41a..5b88861d6183 100644
--- a/arch/blackfin/kernel/cplb-nompu/cplbmgr.c
+++ b/arch/blackfin/kernel/cplb-nompu/cplbmgr.c
@@ -1,26 +1,14 @@
1/* 1/*
2 * File: arch/blackfin/kernel/cplb-nompu-c/cplbmgr.c
3 * Based on: arch/blackfin/kernel/cplb-mpu/cplbmgr.c 2 * Based on: arch/blackfin/kernel/cplb-mpu/cplbmgr.c
4 * Author: Michael McTernan <mmcternan@airvana.com> 3 * Author: Michael McTernan <mmcternan@airvana.com>
5 * 4 *
6 * Created: 01Nov2008
7 * Description: CPLB miss handler. 5 * Description: CPLB miss handler.
8 * 6 *
9 * Modified: 7 * Modified:
10 * Copyright 2008 Airvana Inc. 8 * Copyright 2008 Airvana Inc.
11 * Copyright 2004-2007 Analog Devices Inc. 9 * Copyright 2008-2009 Analog Devices Inc.
12 * 10 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/ 11 * Licensed under the GPL-2 or later
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 */ 12 */
25 13
26#include <linux/kernel.h> 14#include <linux/kernel.h>
diff --git a/arch/blackfin/kernel/cplbinfo.c b/arch/blackfin/kernel/cplbinfo.c
index 64d78300dd08..0bdaa517a501 100644
--- a/arch/blackfin/kernel/cplbinfo.c
+++ b/arch/blackfin/kernel/cplbinfo.c
@@ -2,6 +2,7 @@
2 * arch/blackfin/kernel/cplbinfo.c - display CPLB status 2 * arch/blackfin/kernel/cplbinfo.c - display CPLB status
3 * 3 *
4 * Copyright 2004-2008 Analog Devices Inc. 4 * Copyright 2004-2008 Analog Devices Inc.
5 *
5 * Licensed under the GPL-2 or later. 6 * Licensed under the GPL-2 or later.
6 */ 7 */
7 8
@@ -111,24 +112,21 @@ static const struct seq_operations cplbinfo_sops = {
111 .show = cplbinfo_show, 112 .show = cplbinfo_show,
112}; 113};
113 114
115#define CPLBINFO_DCPLB_FLAG 0x80000000
116
114static int cplbinfo_open(struct inode *inode, struct file *file) 117static int cplbinfo_open(struct inode *inode, struct file *file)
115{ 118{
116 char buf[256], *path, *p; 119 struct proc_dir_entry *pde = PDE(file->f_path.dentry->d_inode);
120 char cplb_type;
117 unsigned int cpu; 121 unsigned int cpu;
118 char *s_cpu, *s_cplb;
119 int ret; 122 int ret;
120 struct seq_file *m; 123 struct seq_file *m;
121 struct cplbinfo_data *cdata; 124 struct cplbinfo_data *cdata;
122 125
123 path = d_path(&file->f_path, buf, sizeof(buf)); 126 cpu = (unsigned int)pde->data;
124 if (IS_ERR(path)) 127 cplb_type = cpu & CPLBINFO_DCPLB_FLAG ? 'D' : 'I';
125 return PTR_ERR(path); 128 cpu &= ~CPLBINFO_DCPLB_FLAG;
126 s_cpu = strstr(path, "/cpu");
127 s_cplb = strrchr(path, '/');
128 if (!s_cpu || !s_cplb)
129 return -EINVAL;
130 129
131 cpu = simple_strtoul(s_cpu + 4, &p, 10);
132 if (!cpu_online(cpu)) 130 if (!cpu_online(cpu))
133 return -ENODEV; 131 return -ENODEV;
134 132
@@ -139,7 +137,7 @@ static int cplbinfo_open(struct inode *inode, struct file *file)
139 cdata = m->private; 137 cdata = m->private;
140 138
141 cdata->pos = 0; 139 cdata->pos = 0;
142 cdata->cplb_type = toupper(s_cplb[1]); 140 cdata->cplb_type = cplb_type;
143 cplbinfo_seq_init(cdata, cpu); 141 cplbinfo_seq_init(cdata, cpu);
144 142
145 return 0; 143 return 0;
@@ -168,8 +166,10 @@ static int __init cplbinfo_init(void)
168 if (!cpu_dir) 166 if (!cpu_dir)
169 return -ENOMEM; 167 return -ENOMEM;
170 168
171 proc_create("icplb", S_IRUGO, cpu_dir, &cplbinfo_fops); 169 proc_create_data("icplb", S_IRUGO, cpu_dir, &cplbinfo_fops,
172 proc_create("dcplb", S_IRUGO, cpu_dir, &cplbinfo_fops); 170 (void *)cpu);
171 proc_create_data("dcplb", S_IRUGO, cpu_dir, &cplbinfo_fops,
172 (void *)(cpu | CPLBINFO_DCPLB_FLAG));
173 } 173 }
174 174
175 return 0; 175 return 0;
diff --git a/arch/blackfin/kernel/dma-mapping.c b/arch/blackfin/kernel/dma-mapping.c
index 2f62a9f4058a..e74e74d7733f 100644
--- a/arch/blackfin/kernel/dma-mapping.c
+++ b/arch/blackfin/kernel/dma-mapping.c
@@ -1,30 +1,9 @@
1/* 1/*
2 * File: arch/blackfin/kernel/dma-mapping.c 2 * Dynamic DMA mapping support
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Copyright 2005-2009 Analog Devices Inc.
7 * Description: Dynamic DMA mapping support.
8 * 5 *
9 * Modified: 6 * Licensed under the GPL-2 or later
10 * Copyright 2004-2006 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 7 */
29 8
30#include <linux/types.h> 9#include <linux/types.h>
diff --git a/arch/blackfin/kernel/early_printk.c b/arch/blackfin/kernel/early_printk.c
index 931c78b5ea1f..84ed8375113c 100644
--- a/arch/blackfin/kernel/early_printk.c
+++ b/arch/blackfin/kernel/early_printk.c
@@ -1,25 +1,10 @@
1/* 1/*
2 * File: arch/blackfin/kernel/early_printk.c 2 * allow a console to be used for early printk
3 * Based on: arch/x86_64/kernel/early_printk.c 3 * derived from arch/x86/kernel/early_printk.c
4 * Author: Robin Getz <rgetz@blackfin.uclinux.org
5 * 4 *
6 * Created: 14Aug2007 5 * Copyright 2007-2009 Analog Devices Inc.
7 * Description: allow a console to be used for early printk
8 * 6 *
9 * Modified: 7 * Licensed under the GPL-2
10 * Copyright 2004-2007 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 */ 8 */
24 9
25#include <linux/kernel.h> 10#include <linux/kernel.h>
diff --git a/arch/blackfin/kernel/entry.S b/arch/blackfin/kernel/entry.S
index 3f8769b7db54..f27dc2292e1b 100644
--- a/arch/blackfin/kernel/entry.S
+++ b/arch/blackfin/kernel/entry.S
@@ -1,30 +1,7 @@
1/* 1/*
2 * File: arch/blackfin/kernel/entry.S 2 * Copyright 2004-2009 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the GPL-2 or later
7 * Description:
8 *
9 * Modified:
10 * Copyright 2004-2006 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 5 */
29 6
30#include <linux/linkage.h> 7#include <linux/linkage.h>
diff --git a/arch/blackfin/kernel/fixed_code.S b/arch/blackfin/kernel/fixed_code.S
index 0d2d9e0968c8..0565917f23ba 100644
--- a/arch/blackfin/kernel/fixed_code.S
+++ b/arch/blackfin/kernel/fixed_code.S
@@ -6,7 +6,12 @@
6 * These are aligned to 16 bytes, so that we have some space to replace 6 * These are aligned to 16 bytes, so that we have some space to replace
7 * these sequences with something else (e.g. kernel traps if we ever do 7 * these sequences with something else (e.g. kernel traps if we ever do
8 * BF561 SMP). 8 * BF561 SMP).
9 *
10 * Copyright 2007-2008 Analog Devices Inc.
11 *
12 * Licensed under the GPL-2 or later.
9 */ 13 */
14
10#include <linux/linkage.h> 15#include <linux/linkage.h>
11#include <linux/init.h> 16#include <linux/init.h>
12#include <linux/unistd.h> 17#include <linux/unistd.h>
diff --git a/arch/blackfin/kernel/flat.c b/arch/blackfin/kernel/flat.c
index d188b2430536..a88daddbf074 100644
--- a/arch/blackfin/kernel/flat.c
+++ b/arch/blackfin/kernel/flat.c
@@ -1,21 +1,7 @@
1/* 1/*
2 * arch/blackfin/kernel/flat.c 2 * Copyright 2007 Analog Devices Inc.
3 * 3 *
4 * Copyright (C) 2007 Analog Devices, Inc. 4 * Licensed under the GPL-2.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */ 5 */
20 6
21#include <linux/module.h> 7#include <linux/module.h>
diff --git a/arch/blackfin/kernel/init_task.c b/arch/blackfin/kernel/init_task.c
index c26c34de9f3c..118c5b9dedac 100644
--- a/arch/blackfin/kernel/init_task.c
+++ b/arch/blackfin/kernel/init_task.c
@@ -1,30 +1,7 @@
1/* 1/*
2 * File: arch/blackfin/kernel/init_task.c 2 * Copyright 2004-2009 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the GPL-2 or later
7 * Description: This file contains the simple DMA Implementation for Blackfin
8 *
9 * Modified:
10 * Copyright 2004-2006 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 5 */
29 6
30#include <linux/mm.h> 7#include <linux/mm.h>
diff --git a/arch/blackfin/kernel/irqchip.c b/arch/blackfin/kernel/irqchip.c
index 4b5fd36187d9..db9f9c91f11f 100644
--- a/arch/blackfin/kernel/irqchip.c
+++ b/arch/blackfin/kernel/irqchip.c
@@ -1,30 +1,7 @@
1/* 1/*
2 * File: arch/blackfin/kernel/irqchip.c 2 * Copyright 2005-2009 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the GPL-2 or later
7 * Description: This file contains the simple DMA Implementation for Blackfin
8 *
9 * Modified:
10 * Copyright 2004-2006 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 5 */
29 6
30#include <linux/kernel_stat.h> 7#include <linux/kernel_stat.h>
diff --git a/arch/blackfin/kernel/module.c b/arch/blackfin/kernel/module.c
index 67fc7a56c865..a6dfa6b71e63 100644
--- a/arch/blackfin/kernel/module.c
+++ b/arch/blackfin/kernel/module.c
@@ -1,30 +1,7 @@
1/* 1/*
2 * File: arch/blackfin/kernel/module.c 2 * Copyright 2004-2009 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the GPL-2 or later
7 * Description:
8 *
9 * Modified:
10 * Copyright 2004-2006 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 5 */
29 6
30#define pr_fmt(fmt) "module %s: " fmt 7#define pr_fmt(fmt) "module %s: " fmt
diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c
index f5b286189647..430ae39456e8 100644
--- a/arch/blackfin/kernel/process.c
+++ b/arch/blackfin/kernel/process.c
@@ -1,30 +1,9 @@
1/* 1/*
2 * File: arch/blackfin/kernel/process.c 2 * Blackfin architecture-dependent process handling
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Copyright 2004-2009 Analog Devices Inc.
7 * Description: Blackfin architecture-dependent process handling.
8 * 5 *
9 * Modified: 6 * Licensed under the GPL-2 or later
10 * Copyright 2004-2006 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 7 */
29 8
30#include <linux/module.h> 9#include <linux/module.h>
diff --git a/arch/blackfin/kernel/ptrace.c b/arch/blackfin/kernel/ptrace.c
index 30f4828277ad..0982b5d5af10 100644
--- a/arch/blackfin/kernel/ptrace.c
+++ b/arch/blackfin/kernel/ptrace.c
@@ -1,30 +1,8 @@
1/* 1/*
2 * File: arch/blackfin/kernel/ptrace.c 2 * linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
3 * Based on: Taken from linux/kernel/ptrace.c 3 * these modifications are Copyright 2004-2009 Analog Devices Inc.
4 * Author: linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
5 * 4 *
6 * Created: 1/23/92 5 * Licensed under the GPL-2
7 * Description:
8 *
9 * Modified:
10 * Copyright 2004-2006 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 6 */
29 7
30#include <linux/kernel.h> 8#include <linux/kernel.h>
diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c
index 369535b61ed1..c202a44d1416 100644
--- a/arch/blackfin/kernel/setup.c
+++ b/arch/blackfin/kernel/setup.c
@@ -1,9 +1,5 @@
1/* 1/*
2 * arch/blackfin/kernel/setup.c 2 * Copyright 2004-2009 Analog Devices Inc.
3 *
4 * Copyright 2004-2006 Analog Devices Inc.
5 *
6 * Enter bugs at http://blackfin.uclinux.org/
7 * 3 *
8 * Licensed under the GPL-2 or later. 4 * Licensed under the GPL-2 or later.
9 */ 5 */
diff --git a/arch/blackfin/kernel/shadow_console.c b/arch/blackfin/kernel/shadow_console.c
index 8b8c7107a162..557e9fef406a 100644
--- a/arch/blackfin/kernel/shadow_console.c
+++ b/arch/blackfin/kernel/shadow_console.c
@@ -4,8 +4,6 @@
4 * 4 *
5 * Copyright 2009 Analog Devices Inc. 5 * Copyright 2009 Analog Devices Inc.
6 * 6 *
7 * Enter bugs at http://blackfin.uclinux.org/
8 *
9 * Licensed under the GPL-2 or later. 7 * Licensed under the GPL-2 or later.
10 */ 8 */
11 9
diff --git a/arch/blackfin/kernel/signal.c b/arch/blackfin/kernel/signal.c
index dbc3bbf846be..9d90c18fab23 100644
--- a/arch/blackfin/kernel/signal.c
+++ b/arch/blackfin/kernel/signal.c
@@ -1,30 +1,7 @@
1/* 1/*
2 * File: arch/blackfin/kernel/signal.c 2 * Copyright 2004-2009 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the GPL-2 or later
7 * Description:
8 *
9 * Modified:
10 * Copyright 2004-2006 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 5 */
29 6
30#include <linux/signal.h> 7#include <linux/signal.h>
diff --git a/arch/blackfin/kernel/sys_bfin.c b/arch/blackfin/kernel/sys_bfin.c
index 3da60fb13ce4..afcef129d4e8 100644
--- a/arch/blackfin/kernel/sys_bfin.c
+++ b/arch/blackfin/kernel/sys_bfin.c
@@ -1,32 +1,10 @@
1/* 1/*
2 * File: arch/blackfin/kernel/sys_bfin.c 2 * contains various random system calls that have a non-standard
3 * Based on: 3 * calling sequence on the Linux/Blackfin platform.
4 * Author:
5 * 4 *
6 * Created: 5 * Copyright 2004-2009 Analog Devices Inc.
7 * Description: This file contains various random system calls that
8 * have a non-standard calling sequence on the Linux/bfin
9 * platform.
10 * 6 *
11 * Modified: 7 * Licensed under the GPL-2 or later
12 * Copyright 2004-2006 Analog Devices Inc.
13 *
14 * Bugs: Enter bugs at http://blackfin.uclinux.org/
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, see the file COPYING, or write
28 * to the Free Software Foundation, Inc.,
29 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
30 */ 8 */
31 9
32#include <linux/spinlock.h> 10#include <linux/spinlock.h>
@@ -91,3 +69,14 @@ asmlinkage void *sys_dma_memcpy(void *dest, const void *src, size_t len)
91{ 69{
92 return safe_dma_memcpy(dest, src, len); 70 return safe_dma_memcpy(dest, src, len);
93} 71}
72
73#if defined(CONFIG_FB) || defined(CONFIG_FB_MODULE)
74#include <linux/fb.h>
75unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr,
76 unsigned long len, unsigned long pgoff, unsigned long flags)
77{
78 struct fb_info *info = filp->private_data;
79 return (unsigned long)info->screen_base;
80}
81EXPORT_SYMBOL(get_fb_unmapped_area);
82#endif
diff --git a/arch/blackfin/kernel/time-ts.c b/arch/blackfin/kernel/time-ts.c
index f9715764383e..359cfb1815ca 100644
--- a/arch/blackfin/kernel/time-ts.c
+++ b/arch/blackfin/kernel/time-ts.c
@@ -1,13 +1,13 @@
1/* 1/*
2 * linux/arch/kernel/time-ts.c
3 *
4 * Based on arm clockevents implementation and old bfin time tick. 2 * Based on arm clockevents implementation and old bfin time tick.
5 * 3 *
6 * Copyright(C) 2008, GeoTechnologies, Vitja Makarov 4 * Copyright 2008-2009 Analog Devics Inc.
5 * 2008 GeoTechnologies
6 * Vitja Makarov
7 * 7 *
8 * This code is licenced under the GPL version 2. For details see 8 * Licensed under the GPL-2
9 * kernel-base/COPYING.
10 */ 9 */
10
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/profile.h> 12#include <linux/profile.h>
13#include <linux/interrupt.h> 13#include <linux/interrupt.h>
diff --git a/arch/blackfin/kernel/time.c b/arch/blackfin/kernel/time.c
index adb54aa7d7c8..bd3b53da295e 100644
--- a/arch/blackfin/kernel/time.c
+++ b/arch/blackfin/kernel/time.c
@@ -14,6 +14,7 @@
14#include <linux/time.h> 14#include <linux/time.h>
15#include <linux/irq.h> 15#include <linux/irq.h>
16#include <linux/delay.h> 16#include <linux/delay.h>
17#include <linux/sched.h>
17 18
18#include <asm/blackfin.h> 19#include <asm/blackfin.h>
19#include <asm/time.h> 20#include <asm/time.h>
@@ -81,11 +82,11 @@ time_sched_init(irqreturn_t(*timer_routine) (int, void *))
81#endif 82#endif
82} 83}
83 84
85#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
84/* 86/*
85 * Should return useconds since last timer tick 87 * Should return useconds since last timer tick
86 */ 88 */
87#ifndef CONFIG_GENERIC_TIME 89u32 arch_gettimeoffset(void)
88static unsigned long gettimeoffset(void)
89{ 90{
90 unsigned long offset; 91 unsigned long offset;
91 unsigned long clocks_per_jiffy; 92 unsigned long clocks_per_jiffy;
@@ -184,65 +185,6 @@ void __init time_init(void)
184 time_sched_init(timer_interrupt); 185 time_sched_init(timer_interrupt);
185} 186}
186 187
187#ifndef CONFIG_GENERIC_TIME
188void do_gettimeofday(struct timeval *tv)
189{
190 unsigned long flags;
191 unsigned long seq;
192 unsigned long usec, sec;
193
194 do {
195 seq = read_seqbegin_irqsave(&xtime_lock, flags);
196 usec = gettimeoffset();
197 sec = xtime.tv_sec;
198 usec += (xtime.tv_nsec / NSEC_PER_USEC);
199 }
200 while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
201
202 while (usec >= USEC_PER_SEC) {
203 usec -= USEC_PER_SEC;
204 sec++;
205 }
206
207 tv->tv_sec = sec;
208 tv->tv_usec = usec;
209}
210EXPORT_SYMBOL(do_gettimeofday);
211
212int do_settimeofday(struct timespec *tv)
213{
214 time_t wtm_sec, sec = tv->tv_sec;
215 long wtm_nsec, nsec = tv->tv_nsec;
216
217 if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
218 return -EINVAL;
219
220 write_seqlock_irq(&xtime_lock);
221 /*
222 * This is revolting. We need to set the xtime.tv_usec
223 * correctly. However, the value in this location is
224 * is value at the last tick.
225 * Discover what correction gettimeofday
226 * would have done, and then undo it!
227 */
228 nsec -= (gettimeoffset() * NSEC_PER_USEC);
229
230 wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
231 wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
232
233 set_normalized_timespec(&xtime, sec, nsec);
234 set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
235
236 ntp_clear();
237
238 write_sequnlock_irq(&xtime_lock);
239 clock_was_set();
240
241 return 0;
242}
243EXPORT_SYMBOL(do_settimeofday);
244#endif /* !CONFIG_GENERIC_TIME */
245
246/* 188/*
247 * Scheduler clock - returns current time in nanosec units. 189 * Scheduler clock - returns current time in nanosec units.
248 */ 190 */
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c
index 56464cb8edf3..6b7325d634af 100644
--- a/arch/blackfin/kernel/traps.c
+++ b/arch/blackfin/kernel/traps.c
@@ -1,30 +1,7 @@
1/* 1/*
2 * File: arch/blackfin/kernel/traps.c 2 * Copyright 2004-2009 Analog Devices Inc.
3 * Based on:
4 * Author: Hamish Macdonald
5 * 3 *
6 * Created: 4 * Licensed under the GPL-2 or later
7 * Description: uses S/W interrupt 15 for the system calls
8 *
9 * Modified:
10 * Copyright 2004-2006 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 5 */
29 6
30#include <linux/bug.h> 7#include <linux/bug.h>
diff --git a/arch/blackfin/kernel/vmlinux.lds.S b/arch/blackfin/kernel/vmlinux.lds.S
index ffd90fbbc8f9..10e12539000e 100644
--- a/arch/blackfin/kernel/vmlinux.lds.S
+++ b/arch/blackfin/kernel/vmlinux.lds.S
@@ -1,30 +1,7 @@
1/* 1/*
2 * File: arch/blackfin/kernel/vmlinux.lds.S 2 * Copyright 2004-2009 Analog Devices Inc.
3 * Based on: none - original work
4 * Author:
5 * 3 *
6 * Created: Tue Sep 21 2004 4 * Licensed under the GPL-2 or later
7 * Description: Master linker script for blackfin architecture
8 *
9 * Modified:
10 * Copyright 2004-2007 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 5 */
29 6
30#define VMLINUX_SYMBOL(_sym_) _##_sym_ 7#define VMLINUX_SYMBOL(_sym_) _##_sym_
diff --git a/arch/blackfin/lib/ashldi3.c b/arch/blackfin/lib/ashldi3.c
index a8c279e9b192..ab69d8768afc 100644
--- a/arch/blackfin/lib/ashldi3.c
+++ b/arch/blackfin/lib/ashldi3.c
@@ -1,30 +1,7 @@
1/* 1/*
2 * File: arch/blackfin/lib/ashldi3.c 2 * Copyright 2004-2009 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the GPL-2 or later.
7 * Description:
8 *
9 * Modified:
10 * Copyright 2004-2006 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 5 */
29 6
30#include "gcclib.h" 7#include "gcclib.h"
diff --git a/arch/blackfin/lib/ashrdi3.c b/arch/blackfin/lib/ashrdi3.c
index a0d3419329ca..b5b351e82e10 100644
--- a/arch/blackfin/lib/ashrdi3.c
+++ b/arch/blackfin/lib/ashrdi3.c
@@ -1,30 +1,7 @@
1/* 1/*
2 * File: arch/blackfin/lib/ashrdi3.c 2 * Copyright 2004-2009 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the GPL-2 or later.
7 * Description:
8 *
9 * Modified:
10 * Copyright 2004-2006 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 5 */
29 6
30#include "gcclib.h" 7#include "gcclib.h"
diff --git a/arch/blackfin/lib/checksum.c b/arch/blackfin/lib/checksum.c
index cd605e7d8518..c62969dc1bbb 100644
--- a/arch/blackfin/lib/checksum.c
+++ b/arch/blackfin/lib/checksum.c
@@ -1,32 +1,12 @@
1/* 1/*
2 * File: arch/blackfin/lib/checksum.c 2 * Copyright 2004-2009 Analog Devices Inc.
3 * Based on: none - original work
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the GPL-2 or later.
7 * Description: An implementation of the TCP/IP protocol suite for the LINUX
8 * operating system. INET is implemented using the BSD Socket
9 * interface as the means of communication with the user level.
10 * 5 *
11 * Modified: 6 * An implementation of the TCP/IP protocol suite for the LINUX operating
12 * Copyright 2004-2006 Analog Devices Inc. 7 * system. INET is implemented using the BSD Socket interface as the
8 * means of communication with the user level.
13 * 9 *
14 * Bugs: Enter bugs at http://blackfin.uclinux.org/
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, see the file COPYING, or write
28 * to the Free Software Foundation, Inc.,
29 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
30 */ 10 */
31 11
32#include <linux/module.h> 12#include <linux/module.h>
diff --git a/arch/blackfin/lib/divsi3.S b/arch/blackfin/lib/divsi3.S
index 2ac59c70dd94..f89c5a49c47b 100644
--- a/arch/blackfin/lib/divsi3.S
+++ b/arch/blackfin/lib/divsi3.S
@@ -1,10 +1,9 @@
1/* 1/*
2 * File: arch/blackfin/lib/divsi3.S 2 * Copyright 2004-2009 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the ADI BSD license or the GPL-2 (or later)
7 * Description: 16 / 32 bit signed division. 5 *
6 * 16 / 32 bit signed division.
8 * Special cases : 7 * Special cases :
9 * 1) If(numerator == 0) 8 * 1) If(numerator == 0)
10 * return 0 9 * return 0
@@ -22,25 +21,6 @@
22 * R0 - Quotient (o) 21 * R0 - Quotient (o)
23 * Registers Used : R2-R7,P0-P2 22 * Registers Used : R2-R7,P0-P2
24 * 23 *
25 * Modified:
26 * Copyright 2004-2006 Analog Devices Inc.
27 *
28 * Bugs: Enter bugs at http://blackfin.uclinux.org/
29 *
30 * This program is free software; you can redistribute it and/or modify
31 * it under the terms of the GNU General Public License as published by
32 * the Free Software Foundation; either version 2 of the License, or
33 * (at your option) any later version.
34 *
35 * This program is distributed in the hope that it will be useful,
36 * but WITHOUT ANY WARRANTY; without even the implied warranty of
37 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38 * GNU General Public License for more details.
39 *
40 * You should have received a copy of the GNU General Public License
41 * along with this program; if not, see the file COPYING, or write
42 * to the Free Software Foundation, Inc.,
43 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
44 */ 24 */
45 25
46.global ___divsi3; 26.global ___divsi3;
diff --git a/arch/blackfin/lib/gcclib.h b/arch/blackfin/lib/gcclib.h
index 9ccd39a135ee..724f07f14f8d 100644
--- a/arch/blackfin/lib/gcclib.h
+++ b/arch/blackfin/lib/gcclib.h
@@ -1,30 +1,7 @@
1/* 1/*
2 * File: arch/blackfin/lib/gcclib.h 2 * Copyright 2004-2009 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the GPL-2 or later.
7 * Description:
8 *
9 * Modified:
10 * Copyright 2004-2006 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 5 */
29 6
30#define BITS_PER_UNIT 8 7#define BITS_PER_UNIT 8
diff --git a/arch/blackfin/lib/lshrdi3.c b/arch/blackfin/lib/lshrdi3.c
index e57bf6fbdf3f..53f1741047e5 100644
--- a/arch/blackfin/lib/lshrdi3.c
+++ b/arch/blackfin/lib/lshrdi3.c
@@ -1,30 +1,7 @@
1/* 1/*
2 * File: arch/blackfin/lib/lshrdi3.c 2 * Copyright 2004-2009 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the GPL-2 or later.
7 * Description:
8 *
9 * Modified:
10 * Copyright 2004-2006 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 5 */
29 6
30#include "gcclib.h" 7#include "gcclib.h"
diff --git a/arch/blackfin/lib/memchr.S b/arch/blackfin/lib/memchr.S
index 5da428134d32..542e40f8775f 100644
--- a/arch/blackfin/lib/memchr.S
+++ b/arch/blackfin/lib/memchr.S
@@ -1,30 +1,7 @@
1/* 1/*
2 * File: arch/blackfin/lib/memchr.S 2 * Copyright 2005-2009 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the ADI BSD license or the GPL-2 (or later)
7 * Description:
8 *
9 * Modified:
10 * Copyright 2004-2006 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 5 */
29 6
30#include <linux/linkage.h> 7#include <linux/linkage.h>
diff --git a/arch/blackfin/lib/memcmp.S b/arch/blackfin/lib/memcmp.S
index 219fa2877c62..ce5b9f1a8267 100644
--- a/arch/blackfin/lib/memcmp.S
+++ b/arch/blackfin/lib/memcmp.S
@@ -1,30 +1,7 @@
1/* 1/*
2 * File: arch/blackfin/lib/memcmp.S 2 * Copyright 2004-2009 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the ADI BSD license or the GPL-2 (or later)
7 * Description:
8 *
9 * Modified:
10 * Copyright 2004-2006 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 5 */
29 6
30#include <linux/linkage.h> 7#include <linux/linkage.h>
diff --git a/arch/blackfin/lib/memcpy.S b/arch/blackfin/lib/memcpy.S
index e654a18a0754..c31bf22aab19 100644
--- a/arch/blackfin/lib/memcpy.S
+++ b/arch/blackfin/lib/memcpy.S
@@ -1,36 +1,13 @@
1/* 1/*
2 * File: arch/blackfin/lib/memcpy.S 2 * internal version of memcpy(), issued by the compiler to copy blocks of
3 * Based on: 3 * data around. This is really memmove() - it has to be able to deal with
4 * Author: 4 * possible overlaps, because that ambiguity is when the compiler gives up
5 * and calls a function. We have our own, internal version so that we get
6 * something we trust, even if the user has redefined the normal symbol.
5 * 7 *
6 * Created: 8 * Copyright 2004-2009 Analog Devices Inc.
7 * Description: internal version of memcpy(), issued by the compiler
8 * to copy blocks of data around.
9 * This is really memmove() - it has to be able to deal with
10 * possible overlaps, because that ambiguity is when the compiler
11 * gives up and calls a function. We have our own, internal version
12 * so that we get something we trust, even if the user has redefined
13 * the normal symbol.
14 * 9 *
15 * Modified: 10 * Licensed under the ADI BSD license or the GPL-2 (or later)
16 * Copyright 2004-2006 Analog Devices Inc.
17 *
18 * Bugs: Enter bugs at http://blackfin.uclinux.org/
19 *
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2 of the License, or
23 * (at your option) any later version.
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
29 *
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, see the file COPYING, or write
32 * to the Free Software Foundation, Inc.,
33 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
34 */ 11 */
35 12
36#include <linux/linkage.h> 13#include <linux/linkage.h>
diff --git a/arch/blackfin/lib/memmove.S b/arch/blackfin/lib/memmove.S
index 33f8653145b7..80c240acac60 100644
--- a/arch/blackfin/lib/memmove.S
+++ b/arch/blackfin/lib/memmove.S
@@ -1,30 +1,7 @@
1/* 1/*
2 * File: arch/blackfin/lib/memmove.S 2 * Copyright 2005-2009 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the ADI BSD license or the GPL-2 (or later)
7 * Description:
8 *
9 * Modified:
10 * Copyright 2004-2006 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 5 */
29 6
30#include <linux/linkage.h> 7#include <linux/linkage.h>
diff --git a/arch/blackfin/lib/memset.S b/arch/blackfin/lib/memset.S
index 8159136a29ea..c30d99b10969 100644
--- a/arch/blackfin/lib/memset.S
+++ b/arch/blackfin/lib/memset.S
@@ -1,30 +1,7 @@
1/* 1/*
2 * File: arch/blackfin/lib/memset.S 2 * Copyright 2004-2009 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the ADI BSD license or the GPL-2 (or later)
7 * Description:
8 *
9 * Modified:
10 * Copyright 2004-2006 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 5 */
29 6
30#include <linux/linkage.h> 7#include <linux/linkage.h>
diff --git a/arch/blackfin/lib/modsi3.S b/arch/blackfin/lib/modsi3.S
index ca1dd3973b39..8b0c7d4052af 100644
--- a/arch/blackfin/lib/modsi3.S
+++ b/arch/blackfin/lib/modsi3.S
@@ -1,36 +1,12 @@
1/* 1/*
2 * File: arch/blackfin/lib/modsi3.S 2 * This program computes 32 bit signed remainder. It calls div32 function
3 * Based on: 3 * for quotient estimation.
4 * Author: 4 * Registers in: R0, R1 = Numerator/ Denominator
5 * Registers out: R0 = Remainder
5 * 6 *
6 * Created: 7 * Copyright 2004-2009 Analog Devices Inc.
7 * Description: This program computes 32 bit signed remainder. It calls div32 function
8 * for quotient estimation.
9 * 8 *
10 * Registers used : 9 * Licensed under the ADI BSD license or the GPL-2 (or later)
11 * Numerator/ Denominator in R0, R1
12 * R0 - returns remainder.
13 * R2-R7
14 *
15 * Modified:
16 * Copyright 2004-2006 Analog Devices Inc.
17 *
18 * Bugs: Enter bugs at http://blackfin.uclinux.org/
19 *
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2 of the License, or
23 * (at your option) any later version.
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
29 *
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, see the file COPYING, or write
32 * to the Free Software Foundation, Inc.,
33 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
34 */ 10 */
35 11
36.global ___modsi3; 12.global ___modsi3;
diff --git a/arch/blackfin/lib/muldi3.S b/arch/blackfin/lib/muldi3.S
index abde120ee230..953a38a1d1d1 100644
--- a/arch/blackfin/lib/muldi3.S
+++ b/arch/blackfin/lib/muldi3.S
@@ -1,3 +1,9 @@
1/*
2 * Copyright 2008 Analog Devices Inc.
3 *
4 * Licensed under the ADI BSD license or the GPL-2 (or later)
5 */
6
1.align 2 7.align 2
2.global ___muldi3; 8.global ___muldi3;
3.type ___muldi3, STT_FUNC; 9.type ___muldi3, STT_FUNC;
diff --git a/arch/blackfin/lib/outs.S b/arch/blackfin/lib/outs.S
index 4685b7aa0080..250f4d4b9436 100644
--- a/arch/blackfin/lib/outs.S
+++ b/arch/blackfin/lib/outs.S
@@ -1,30 +1,11 @@
1/* 1/*
2 * File: arch/blackfin/lib/outs.S 2 * Implementation of outs{bwl} for BlackFin processors using zero overhead loops.
3 * Based on:
4 * Author: Bas Vermeulen <bas@buyways.nl>
5 * 3 *
6 * Created: Tue Mar 22 15:27:24 CEST 2005 4 * Copyright 2005-2009 Analog Devices Inc.
7 * Description: Implementation of outs{bwl} for BlackFin processors using zero overhead loops. 5 * 2005 BuyWays BV
6 * Bas Vermeulen <bas@buyways.nl>
8 * 7 *
9 * Modified: Copyright (C) 2005 Bas Vermeulen, BuyWays BV <bas@buyways.nl> 8 * Licensed under the GPL-2.
10 * Copyright 2004-2008 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 9 */
29 10
30#include <linux/linkage.h> 11#include <linux/linkage.h>
diff --git a/arch/blackfin/lib/smulsi3_highpart.S b/arch/blackfin/lib/smulsi3_highpart.S
index e383cd3eca5d..99ee8c5de38b 100644
--- a/arch/blackfin/lib/smulsi3_highpart.S
+++ b/arch/blackfin/lib/smulsi3_highpart.S
@@ -1,3 +1,9 @@
1/*
2 * Copyright 2007 Analog Devices Inc.
3 *
4 * Licensed under the ADI BSD license or the GPL-2 (or later)
5 */
6
1.align 2 7.align 2
2.global ___smulsi3_highpart; 8.global ___smulsi3_highpart;
3.type ___smulsi3_highpart, STT_FUNC; 9.type ___smulsi3_highpart, STT_FUNC;
diff --git a/arch/blackfin/lib/udivsi3.S b/arch/blackfin/lib/udivsi3.S
index 58fd96d74766..97e904315ec6 100644
--- a/arch/blackfin/lib/udivsi3.S
+++ b/arch/blackfin/lib/udivsi3.S
@@ -1,30 +1,7 @@
1/* 1/*
2 * File: arch/blackfin/lib/udivsi3.S 2 * Copyright 2004-2009 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the ADI BSD license or the GPL-2 (or later)
7 * Description:
8 *
9 * Modified:
10 * Copyright 2004-2006 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 5 */
29 6
30#include <linux/linkage.h> 7#include <linux/linkage.h>
diff --git a/arch/blackfin/lib/umodsi3.S b/arch/blackfin/lib/umodsi3.S
index 4f2b76ee7626..168eba7c64c8 100644
--- a/arch/blackfin/lib/umodsi3.S
+++ b/arch/blackfin/lib/umodsi3.S
@@ -1,30 +1,9 @@
1/* 1/*
2 * File: arch/blackfin/lib/umodsi3.S 2 * libgcc1 routines for Blackfin 5xx
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Copyright 2004-2009 Analog Devices Inc.
7 * Description: libgcc1 routines for Blackfin 5xx
8 * 5 *
9 * Modified: 6 * Licensed under the ADI BSD license or the GPL-2 (or later)
10 * Copyright 2004-2006 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 7 */
29 8
30#ifdef CONFIG_ARITHMETIC_OPS_L1 9#ifdef CONFIG_ARITHMETIC_OPS_L1
diff --git a/arch/blackfin/lib/umulsi3_highpart.S b/arch/blackfin/lib/umulsi3_highpart.S
index 67b799351e3e..051824a6ed00 100644
--- a/arch/blackfin/lib/umulsi3_highpart.S
+++ b/arch/blackfin/lib/umulsi3_highpart.S
@@ -1,3 +1,9 @@
1/*
2 * Copyright 2007 Analog Devices Inc.
3 *
4 * Licensed under the ADI BSD license or the GPL-2 (or later)
5 */
6
1.align 2 7.align 2
2.global ___umulsi3_highpart; 8.global ___umulsi3_highpart;
3.type ___umulsi3_highpart, STT_FUNC; 9.type ___umulsi3_highpart, STT_FUNC;
diff --git a/arch/blackfin/mach-bf518/boards/ezbrd.c b/arch/blackfin/mach-bf518/boards/ezbrd.c
index 03e4a9941f01..01975c017116 100644
--- a/arch/blackfin/mach-bf518/boards/ezbrd.c
+++ b/arch/blackfin/mach-bf518/boards/ezbrd.c
@@ -1,31 +1,9 @@
1/* 1/*
2 * File: arch/blackfin/mach-bf518/boards/ezbrd.c 2 * Copyright 2004-2009 Analog Devices Inc.
3 * Based on: arch/blackfin/mach-bf527/boards/ezbrd.c 3 * 2005 National ICT Australia (NICTA)
4 * Author: Bryan Wu <cooloney@kernel.org> 4 * Aidan Williams <aidan@nicta.com.au>
5 * 5 *
6 * Created: 6 * Licensed under the GPL-2 or later.
7 * Description:
8 *
9 * Modified:
10 * Copyright 2005 National ICT Australia (NICTA)
11 * Copyright 2004-2008 Analog Devices Inc.
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, see the file COPYING, or write
27 * to the Free Software Foundation, Inc.,
28 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 */ 7 */
30 8
31#include <linux/device.h> 9#include <linux/device.h>
@@ -571,19 +549,6 @@ static struct platform_device bf51x_sdh_device = {
571}; 549};
572#endif 550#endif
573 551
574static struct resource bfin_gpios_resources = {
575 .start = 0,
576 .end = MAX_BLACKFIN_GPIOS - 1,
577 .flags = IORESOURCE_IRQ,
578};
579
580static struct platform_device bfin_gpios_device = {
581 .name = "simple-gpio",
582 .id = -1,
583 .num_resources = 1,
584 .resource = &bfin_gpios_resources,
585};
586
587static const unsigned int cclk_vlev_datasheet[] = 552static const unsigned int cclk_vlev_datasheet[] =
588{ 553{
589 VRPAIR(VLEV_100, 400000000), 554 VRPAIR(VLEV_100, 400000000),
@@ -660,8 +625,6 @@ static struct platform_device *stamp_devices[] __initdata = {
660#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) 625#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
661 &ezbrd_flash_device, 626 &ezbrd_flash_device,
662#endif 627#endif
663
664 &bfin_gpios_device,
665}; 628};
666 629
667static int __init ezbrd_init(void) 630static int __init ezbrd_init(void)
diff --git a/arch/blackfin/mach-bf518/dma.c b/arch/blackfin/mach-bf518/dma.c
index 698e88ca5104..78b43605a0b5 100644
--- a/arch/blackfin/mach-bf518/dma.c
+++ b/arch/blackfin/mach-bf518/dma.c
@@ -1,31 +1,11 @@
1/* 1/*
2 * File: arch/blackfin/mach-bf518/dma.c 2 * the simple DMA Implementation for Blackfin
3 * Based on:
4 * Author: Bryan Wu <cooloney@kernel.org>
5 * 3 *
6 * Created: 4 * Copyright 2008 Analog Devices Inc.
7 * Description: This file contains the simple DMA Implementation for Blackfin
8 * 5 *
9 * Modified: 6 * Licensed under the GPL-2 or later.
10 * Copyright 2004-2008 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 7 */
8
29#include <linux/module.h> 9#include <linux/module.h>
30 10
31#include <asm/blackfin.h> 11#include <asm/blackfin.h>
diff --git a/arch/blackfin/mach-bf518/include/mach/bf518.h b/arch/blackfin/mach-bf518/include/mach/bf518.h
index 78da1a07ee73..856b330ecf0b 100644
--- a/arch/blackfin/mach-bf518/include/mach/bf518.h
+++ b/arch/blackfin/mach-bf518/include/mach/bf518.h
@@ -1,30 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf518/bf518.h 2 * Copyright 2008 Analog Devices Inc.
3 * Based on: include/asm-blackfin/mach-bf527/bf527.h
4 * Author: Michael Hennerich (michael.hennerich@analog.com)
5 * 3 *
6 * Created: 4 * Licensed under the GPL-2 or later.
7 * Description: SYSTEM MMR REGISTER AND MEMORY MAP FOR ADSP-BF518
8 *
9 * Modified:
10 * Copyright 2004-2007 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 5 */
29 6
30#ifndef __MACH_BF518_H__ 7#ifndef __MACH_BF518_H__
diff --git a/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h
index dbade93395eb..970d310021e7 100644
--- a/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h
@@ -1,32 +1,7 @@
1/* 1/*
2 * file: include/asm-blackfin/mach-bf518/bfin_serial_5xx.h 2 * Copyright 2008-2009 Analog Devices Inc.
3 * based on:
4 * author:
5 * 3 *
6 * created: 4 * Licensed under the GPL-2 or later
7 * description:
8 * blackfin serial driver head file
9 * rev:
10 *
11 * modified:
12 *
13 *
14 * bugs: enter bugs at http://blackfin.uclinux.org/
15 *
16 * this program is free software; you can redistribute it and/or modify
17 * it under the terms of the gnu general public license as published by
18 * the free software foundation; either version 2, or (at your option)
19 * any later version.
20 *
21 * this program is distributed in the hope that it will be useful,
22 * but without any warranty; without even the implied warranty of
23 * merchantability or fitness for a particular purpose. see the
24 * gnu general public license for more details.
25 *
26 * you should have received a copy of the gnu general public license
27 * along with this program; see the file copying.
28 * if not, write to the free software foundation,
29 * 59 temple place - suite 330, boston, ma 02111-1307, usa.
30 */ 5 */
31 6
32#include <linux/serial.h> 7#include <linux/serial.h>
diff --git a/arch/blackfin/mach-bf518/include/mach/blackfin.h b/arch/blackfin/mach-bf518/include/mach/blackfin.h
index 83421d393148..6cfb246aebec 100644
--- a/arch/blackfin/mach-bf518/include/mach/blackfin.h
+++ b/arch/blackfin/mach-bf518/include/mach/blackfin.h
@@ -1,32 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf518/blackfin.h 2 * Copyright 2008-2009 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the GPL-2 or later
7 * Description:
8 *
9 * Rev:
10 *
11 * Modified:
12 *
13 *
14 * Bugs: Enter bugs at http://blackfin.uclinux.org/
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2, or (at your option)
19 * any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; see the file COPYING.
28 * If not, write to the Free Software Foundation,
29 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 */ 5 */
31 6
32#ifndef _MACH_BLACKFIN_H_ 7#ifndef _MACH_BLACKFIN_H_
diff --git a/arch/blackfin/mach-bf518/include/mach/cdefBF512.h b/arch/blackfin/mach-bf518/include/mach/cdefBF512.h
index 820c13c4daaa..493020d0a65a 100644
--- a/arch/blackfin/mach-bf518/include/mach/cdefBF512.h
+++ b/arch/blackfin/mach-bf518/include/mach/cdefBF512.h
@@ -1,32 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf518/cdefbf512.h 2 * Copyright 2008-2009 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the ADI BSD license or the GPL-2 (or later)
7 * Description: system mmr register map
8 *
9 * Rev:
10 *
11 * Modified:
12 *
13 *
14 * Bugs: Enter bugs at http://blackfin.uclinux.org/
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2, or (at your option)
19 * any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; see the file COPYING.
28 * If not, write to the Free Software Foundation,
29 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 */ 5 */
31 6
32#ifndef _CDEF_BF512_H 7#ifndef _CDEF_BF512_H
diff --git a/arch/blackfin/mach-bf518/include/mach/cdefBF514.h b/arch/blackfin/mach-bf518/include/mach/cdefBF514.h
index dfe492dfe54e..e1d99911025d 100644
--- a/arch/blackfin/mach-bf518/include/mach/cdefBF514.h
+++ b/arch/blackfin/mach-bf518/include/mach/cdefBF514.h
@@ -1,32 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf518/cdefbf514.h 2 * Copyright 2008-2009 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the GPL-2 or later
7 * Description: system mmr register map
8 *
9 * Rev:
10 *
11 * Modified:
12 *
13 *
14 * Bugs: Enter bugs at http://blackfin.uclinux.org/
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2, or (at your option)
19 * any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; see the file COPYING.
28 * If not, write to the Free Software Foundation,
29 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 */ 5 */
31 6
32#ifndef _CDEF_BF514_H 7#ifndef _CDEF_BF514_H
diff --git a/arch/blackfin/mach-bf518/include/mach/cdefBF516.h b/arch/blackfin/mach-bf518/include/mach/cdefBF516.h
index 14df43d4677a..6b364eda4947 100644
--- a/arch/blackfin/mach-bf518/include/mach/cdefBF516.h
+++ b/arch/blackfin/mach-bf518/include/mach/cdefBF516.h
@@ -1,32 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf518/cdefbf516.h 2 * Copyright 2008-2009 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the GPL-2 or later
7 * Description: system mmr register map
8 *
9 * Rev:
10 *
11 * Modified:
12 *
13 *
14 * Bugs: Enter bugs at http://blackfin.uclinux.org/
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2, or (at your option)
19 * any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; see the file COPYING.
28 * If not, write to the Free Software Foundation,
29 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 */ 5 */
31 6
32#ifndef _CDEF_BF516_H 7#ifndef _CDEF_BF516_H
diff --git a/arch/blackfin/mach-bf518/include/mach/cdefBF518.h b/arch/blackfin/mach-bf518/include/mach/cdefBF518.h
index bafb370cfb3c..929b90650bd4 100644
--- a/arch/blackfin/mach-bf518/include/mach/cdefBF518.h
+++ b/arch/blackfin/mach-bf518/include/mach/cdefBF518.h
@@ -1,32 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf518/cdefbf518.h 2 * Copyright 2008-2009 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the GPL-2 or later
7 * Description: system mmr register map
8 *
9 * Rev:
10 *
11 * Modified:
12 *
13 *
14 * Bugs: Enter bugs at http://blackfin.uclinux.org/
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2, or (at your option)
19 * any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; see the file COPYING.
28 * If not, write to the Free Software Foundation,
29 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 */ 5 */
31 6
32#ifndef _CDEF_BF518_H 7#ifndef _CDEF_BF518_H
@@ -211,6 +186,47 @@
211#define bfin_read_EMAC_TXC_ABORT() bfin_read32(EMAC_TXC_ABORT) 186#define bfin_read_EMAC_TXC_ABORT() bfin_read32(EMAC_TXC_ABORT)
212#define bfin_write_EMAC_TXC_ABORT(val) bfin_write32(EMAC_TXC_ABORT, val) 187#define bfin_write_EMAC_TXC_ABORT(val) bfin_write32(EMAC_TXC_ABORT, val)
213 188
189#define bfin_read_EMAC_PTP_CTL() bfin_read16(EMAC_PTP_CTL)
190#define bfin_write_EMAC_PTP_CTL(val) bfin_write16(EMAC_PTP_CTL, val)
191#define bfin_read_EMAC_PTP_IE() bfin_read16(EMAC_PTP_IE)
192#define bfin_write_EMAC_PTP_IE(val) bfin_write16(EMAC_PTP_IE, val)
193#define bfin_read_EMAC_PTP_ISTAT() bfin_read16(EMAC_PTP_ISTAT)
194#define bfin_write_EMAC_PTP_ISTAT(val) bfin_write16(EMAC_PTP_ISTAT, val)
195#define bfin_read_EMAC_PTP_FOFF() bfin_read32(EMAC_PTP_FOFF)
196#define bfin_write_EMAC_PTP_FOFF(val) bfin_write32(EMAC_PTP_FOFF, val)
197#define bfin_read_EMAC_PTP_FV1() bfin_read32(EMAC_PTP_FV1)
198#define bfin_write_EMAC_PTP_FV1(val) bfin_write32(EMAC_PTP_FV1, val)
199#define bfin_read_EMAC_PTP_FV2() bfin_read32(EMAC_PTP_FV2)
200#define bfin_write_EMAC_PTP_FV2(val) bfin_write32(EMAC_PTP_FV2, val)
201#define bfin_read_EMAC_PTP_FV3() bfin_read32(EMAC_PTP_FV3)
202#define bfin_write_EMAC_PTP_FV3(val) bfin_write32(EMAC_PTP_FV3, val)
203#define bfin_read_EMAC_PTP_ADDEND() bfin_read32(EMAC_PTP_ADDEND)
204#define bfin_write_EMAC_PTP_ADDEND(val) bfin_write32(EMAC_PTP_ADDEND, val)
205#define bfin_read_EMAC_PTP_ACCR() bfin_read32(EMAC_PTP_ACCR)
206#define bfin_write_EMAC_PTP_ACCR(val) bfin_write32(EMAC_PTP_ACCR, val)
207#define bfin_read_EMAC_PTP_OFFSET() bfin_read32(EMAC_PTP_OFFSET)
208#define bfin_write_EMAC_PTP_OFFSET(val) bfin_write32(EMAC_PTP_OFFSET, val)
209#define bfin_read_EMAC_PTP_TIMELO() bfin_read32(EMAC_PTP_TIMELO)
210#define bfin_write_EMAC_PTP_TIMELO(val) bfin_write32(EMAC_PTP_TIMELO, val)
211#define bfin_read_EMAC_PTP_TIMEHI() bfin_read32(EMAC_PTP_TIMEHI)
212#define bfin_write_EMAC_PTP_TIMEHI(val) bfin_write32(EMAC_PTP_TIMEHI, val)
213#define bfin_read_EMAC_PTP_RXSNAPLO() bfin_read32(EMAC_PTP_RXSNAPLO)
214#define bfin_read_EMAC_PTP_RXSNAPHI() bfin_read32(EMAC_PTP_RXSNAPHI)
215#define bfin_read_EMAC_PTP_TXSNAPLO() bfin_read32(EMAC_PTP_TXSNAPLO)
216#define bfin_read_EMAC_PTP_TXSNAPHI() bfin_read32(EMAC_PTP_TXSNAPHI)
217#define bfin_read_EMAC_PTP_ALARMLO() bfin_read32(EMAC_PTP_ALARMLO)
218#define bfin_write_EMAC_PTP_ALARMLO(val) bfin_write32(EMAC_PTP_ALARMLO, val)
219#define bfin_read_EMAC_PTP_ALARMHI() bfin_read32(EMAC_PTP_ALARMHI)
220#define bfin_write_EMAC_PTP_ALARMHI(val) bfin_write32(EMAC_PTP_ALARMHI, val)
221#define bfin_read_EMAC_PTP_ID_OFF() bfin_read16(EMAC_PTP_ID_OFF)
222#define bfin_write_EMAC_PTP_ID_OFF(val) bfin_write16(EMAC_PTP_ID_OFF, val)
223#define bfin_read_EMAC_PTP_ID_SNAP() bfin_read32(EMAC_PTP_ID_SNAP)
224#define bfin_write_EMAC_PTP_ID_SNAP(val) bfin_write32(EMAC_PTP_ID_SNAP, val)
225#define bfin_read_EMAC_PTP_PPS_STARTHI() bfin_read32(EMAC_PTP_PPS_STARTHI)
226#define bfin_write_EMAC_PTP_PPS_STARTHI(val) bfin_write32(EMAC_PTP_PPS_STARTHI, val)
227#define bfin_read_EMAC_PTP_PPS_PERIOD() bfin_read32(EMAC_PTP_PPS_PERIOD)
228#define bfin_write_EMAC_PTP_PPS_PERIOD(val) bfin_write32(EMAC_PTP_PPS_PERIOD, val)
229
214/* Removable Storage Interface Registers */ 230/* Removable Storage Interface Registers */
215 231
216#define bfin_read_RSI_PWR_CTL() bfin_read16(RSI_PWR_CONTROL) 232#define bfin_read_RSI_PWR_CTL() bfin_read16(RSI_PWR_CONTROL)
diff --git a/arch/blackfin/mach-bf518/include/mach/cdefBF51x_base.h b/arch/blackfin/mach-bf518/include/mach/cdefBF51x_base.h
index ee3d4733369c..1d970df7aee9 100644
--- a/arch/blackfin/mach-bf518/include/mach/cdefBF51x_base.h
+++ b/arch/blackfin/mach-bf518/include/mach/cdefBF51x_base.h
@@ -1,31 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf518/cdefBF51x_base.h 2 * Copyright 2008 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the GPL-2 or later
7 * Description:
8 *
9 * Rev:
10 *
11 * Modified:
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2, or (at your option)
18 * any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; see the file COPYING.
27 * If not, write to the Free Software Foundation,
28 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 */ 5 */
30 6
31#ifndef _CDEF_BF52X_H 7#ifndef _CDEF_BF52X_H
diff --git a/arch/blackfin/mach-bf518/include/mach/defBF512.h b/arch/blackfin/mach-bf518/include/mach/defBF512.h
index a96ca90154dd..9b505bb0cb2d 100644
--- a/arch/blackfin/mach-bf518/include/mach/defBF512.h
+++ b/arch/blackfin/mach-bf518/include/mach/defBF512.h
@@ -1,31 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf518/defBF512.h 2 * Copyright 2008 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the ADI BSD license or the GPL-2 (or later)
7 * Description:
8 *
9 * Rev:
10 *
11 * Modified:
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2, or (at your option)
18 * any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; see the file COPYING.
27 * If not, write to the Free Software Foundation,
28 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 */ 5 */
30 6
31#ifndef _DEF_BF512_H 7#ifndef _DEF_BF512_H
diff --git a/arch/blackfin/mach-bf518/include/mach/defBF514.h b/arch/blackfin/mach-bf518/include/mach/defBF514.h
index 56ee5a7c2007..b5adca23a788 100644
--- a/arch/blackfin/mach-bf518/include/mach/defBF514.h
+++ b/arch/blackfin/mach-bf518/include/mach/defBF514.h
@@ -1,31 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf518/defBF514.h 2 * Copyright 2008-2009 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the ADI BSD license or the GPL-2 (or later)
7 * Description:
8 *
9 * Rev:
10 *
11 * Modified:
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2, or (at your option)
18 * any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; see the file COPYING.
27 * If not, write to the Free Software Foundation,
28 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 */ 5 */
30 6
31#ifndef _DEF_BF514_H 7#ifndef _DEF_BF514_H
diff --git a/arch/blackfin/mach-bf518/include/mach/defBF516.h b/arch/blackfin/mach-bf518/include/mach/defBF516.h
index dfc93843517d..7eb18774d727 100644
--- a/arch/blackfin/mach-bf518/include/mach/defBF516.h
+++ b/arch/blackfin/mach-bf518/include/mach/defBF516.h
@@ -1,31 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf518/defBF516.h 2 * Copyright 2008-2009 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the ADI BSD license or the GPL-2 (or later)
7 * Description:
8 *
9 * Rev:
10 *
11 * Modified:
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2, or (at your option)
18 * any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; see the file COPYING.
27 * If not, write to the Free Software Foundation,
28 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 */ 5 */
30 6
31#ifndef _DEF_BF516_H 7#ifndef _DEF_BF516_H
diff --git a/arch/blackfin/mach-bf518/include/mach/defBF518.h b/arch/blackfin/mach-bf518/include/mach/defBF518.h
index 6e982abf4ede..794cf06eb5ba 100644
--- a/arch/blackfin/mach-bf518/include/mach/defBF518.h
+++ b/arch/blackfin/mach-bf518/include/mach/defBF518.h
@@ -1,31 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf518/defBF518.h 2 * Copyright 2008-2009 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the ADI BSD license or the GPL-2 (or later)
7 * Description:
8 *
9 * Rev:
10 *
11 * Modified:
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2, or (at your option)
18 * any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; see the file COPYING.
27 * If not, write to the Free Software Foundation,
28 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 */ 5 */
30 6
31#ifndef _DEF_BF518_H 7#ifndef _DEF_BF518_H
@@ -648,4 +624,32 @@
648 624
649#define RWR 0x1 /* Read Wait Request */ 625#define RWR 0x1 /* Read Wait Request */
650 626
627/* Bit masks for EMAC_PTP_CTL */
628
629#define PTP_EN 0x1 /* Enable the PTP_TSYNC module */
630#define TL 0x2 /* Timestamp lock control */
631#define ASEN 0x10 /* Auxiliary snapshot control */
632#define PPSEN 0x80 /* Pulse-per-second (PPS) control */
633#define CKOEN 0x2000 /* Clock output control */
634
635/* Bit masks for EMAC_PTP_IE */
636
637#define ALIE 0x1 /* Alarm interrupt enable */
638#define RXEIE 0x2 /* Receive event interrupt enable */
639#define RXGIE 0x4 /* Receive general interrupt enable */
640#define TXIE 0x8 /* Transmit interrupt enable */
641#define RXOVE 0x10 /* Receive overrun error interrupt enable */
642#define TXOVE 0x20 /* Transmit overrun error interrupt enable */
643#define ASIE 0x40 /* Auxiliary snapshot interrupt enable */
644
645/* Bit masks for EMAC_PTP_ISTAT */
646
647#define ALS 0x1 /* Alarm status */
648#define RXEL 0x2 /* Receive event interrupt status */
649#define RXGL 0x4 /* Receive general interrupt status */
650#define TXTL 0x8 /* Transmit snapshot status */
651#define RXOV 0x10 /* Receive snapshot overrun status */
652#define TXOV 0x20 /* Transmit snapshot overrun status */
653#define ASL 0x40 /* Auxiliary snapshot interrupt status */
654
651#endif /* _DEF_BF518_H */ 655#endif /* _DEF_BF518_H */
diff --git a/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h b/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h
index 1bec8d1c2a73..e06f4112c695 100644
--- a/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h
+++ b/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h
@@ -1,31 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf518/defBF51x_base.h 2 * Copyright 2008 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the ADI BSD license or the GPL-2 (or later)
7 * Description:
8 *
9 * Rev:
10 *
11 * Modified:
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2, or (at your option)
18 * any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; see the file COPYING.
27 * If not, write to the Free Software Foundation,
28 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 */ 5 */
30 6
31#ifndef _DEF_BF51X_H 7#ifndef _DEF_BF51X_H
diff --git a/arch/blackfin/mach-bf518/include/mach/gpio.h b/arch/blackfin/mach-bf518/include/mach/gpio.h
index 9757683c3948..bbab2d76499c 100644
--- a/arch/blackfin/mach-bf518/include/mach/gpio.h
+++ b/arch/blackfin/mach-bf518/include/mach/gpio.h
@@ -1,7 +1,4 @@
1/* 1/*
2 * File: arch/blackfin/mach-bf518/include/mach/gpio.h
3 * Bugs: Enter bugs at http://blackfin.uclinux.org/
4 *
5 * Copyright (C) 2008 Analog Devices Inc. 2 * Copyright (C) 2008 Analog Devices Inc.
6 * Licensed under the GPL-2 or later. 3 * Licensed under the GPL-2 or later.
7 */ 4 */
diff --git a/arch/blackfin/mach-bf518/include/mach/irq.h b/arch/blackfin/mach-bf518/include/mach/irq.h
index 3ff0f093313d..14e52ec7afa5 100644
--- a/arch/blackfin/mach-bf518/include/mach/irq.h
+++ b/arch/blackfin/mach-bf518/include/mach/irq.h
@@ -1,32 +1,7 @@
1/* 1/*
2 * file: include/asm-blackfin/mach-bf518/irq.h 2 * Copyright 2008 Analog Devices Inc.
3 * based on: include/asm-blackfin/mach-bf527/irq.h
4 * author: Michael Hennerich (michael.hennerich@analog.com)
5 * 3 *
6 * created: 4 * Licensed under the GPL-2 or later
7 * description:
8 * system mmr register map
9 * rev:
10 *
11 * modified:
12 *
13 *
14 * bugs: enter bugs at http://blackfin.uclinux.org/
15 *
16 * this program is free software; you can redistribute it and/or modify
17 * it under the terms of the gnu general public license as published by
18 * the free software foundation; either version 2, or (at your option)
19 * any later version.
20 *
21 * this program is distributed in the hope that it will be useful,
22 * but without any warranty; without even the implied warranty of
23 * merchantability or fitness for a particular purpose. see the
24 * gnu general public license for more details.
25 *
26 * you should have received a copy of the gnu general public license
27 * along with this program; see the file copying.
28 * if not, write to the free software foundation,
29 * 59 temple place - suite 330, boston, ma 02111-1307, usa.
30 */ 5 */
31 6
32#ifndef _BF518_IRQ_H_ 7#ifndef _BF518_IRQ_H_
diff --git a/arch/blackfin/mach-bf518/include/mach/portmux.h b/arch/blackfin/mach-bf518/include/mach/portmux.h
index a0fc77fd3315..e352910f7f99 100644
--- a/arch/blackfin/mach-bf518/include/mach/portmux.h
+++ b/arch/blackfin/mach-bf518/include/mach/portmux.h
@@ -1,3 +1,9 @@
1/*
2 * Copyright 2008-2009 Analog Devices Inc.
3 *
4 * Licensed under the GPL-2 or later
5 */
6
1#ifndef _MACH_PORTMUX_H_ 7#ifndef _MACH_PORTMUX_H_
2#define _MACH_PORTMUX_H_ 8#define _MACH_PORTMUX_H_
3 9
diff --git a/arch/blackfin/mach-bf518/ints-priority.c b/arch/blackfin/mach-bf518/ints-priority.c
index 3151fd5501ca..bb05bef34ec0 100644
--- a/arch/blackfin/mach-bf518/ints-priority.c
+++ b/arch/blackfin/mach-bf518/ints-priority.c
@@ -1,30 +1,9 @@
1/* 1/*
2 * File: arch/blackfin/mach-bf518/ints-priority.c 2 * Set up the interrupt priorities
3 * Based on: arch/blackfin/mach-bf527/ints-priority.c
4 * Author: Bryan Wu <cooloney@kernel.org>
5 * 3 *
6 * Created: 4 * Copyright 2008 Analog Devices Inc.
7 * Description: Set up the interrupt priorities
8 * 5 *
9 * Modified: 6 * Licensed under the GPL-2 or later.
10 * Copyright 2004-2007 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 7 */
29 8
30#include <linux/module.h> 9#include <linux/module.h>
diff --git a/arch/blackfin/mach-bf527/boards/cm_bf527.c b/arch/blackfin/mach-bf527/boards/cm_bf527.c
index 08a3f01c9886..f1996b13a3da 100644
--- a/arch/blackfin/mach-bf527/boards/cm_bf527.c
+++ b/arch/blackfin/mach-bf527/boards/cm_bf527.c
@@ -1,31 +1,10 @@
1/* 1/*
2 * File: arch/blackfin/mach-bf527/boards/cm-bf527.c 2 * Copyright 2004-2009 Analog Devices Inc.
3 * Based on: arch/blackfin/mach-bf537/boards/stamp.c 3 * 2008-2009 Bluetechnix
4 * Author: Aidan Williams <aidan@nicta.com.au> 4 * 2005 National ICT Australia (NICTA)
5 * Aidan Williams <aidan@nicta.com.au>
5 * 6 *
6 * Created: 7 * Licensed under the GPL-2 or later.
7 * Description:
8 *
9 * Modified:
10 * Copyright 2005 National ICT Australia (NICTA)
11 * Copyright 2004-2008 Analog Devices Inc.
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, see the file COPYING, or write
27 * to the Free Software Foundation, Inc.,
28 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 */ 8 */
30 9
31#include <linux/device.h> 10#include <linux/device.h>
@@ -616,12 +595,6 @@ static struct platform_device bfin_spi0_device = {
616}; 595};
617#endif /* spi master and devices */ 596#endif /* spi master and devices */
618 597
619#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE)
620static struct platform_device bfin_fb_adv7393_device = {
621 .name = "bfin-adv7393",
622};
623#endif
624
625#if defined(CONFIG_MTD_GPIO_ADDR) || defined(CONFIG_MTD_GPIO_ADDR_MODULE) 598#if defined(CONFIG_MTD_GPIO_ADDR) || defined(CONFIG_MTD_GPIO_ADDR_MODULE)
626static struct mtd_partition cm_partitions[] = { 599static struct mtd_partition cm_partitions[] = {
627 { 600 {
@@ -786,6 +759,11 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
786 .irq = IRQ_PF8, 759 .irq = IRQ_PF8,
787 }, 760 },
788#endif 761#endif
762#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE)
763 {
764 I2C_BOARD_INFO("bfin-adv7393", 0x2B),
765 },
766#endif
789}; 767};
790 768
791#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) 769#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
@@ -821,19 +799,6 @@ static struct platform_device bfin_device_gpiokeys = {
821}; 799};
822#endif 800#endif
823 801
824static struct resource bfin_gpios_resources = {
825 .start = 0,
826 .end = MAX_BLACKFIN_GPIOS - 1,
827 .flags = IORESOURCE_IRQ,
828};
829
830static struct platform_device bfin_gpios_device = {
831 .name = "simple-gpio",
832 .id = -1,
833 .num_resources = 1,
834 .resource = &bfin_gpios_resources,
835};
836
837static const unsigned int cclk_vlev_datasheet[] = 802static const unsigned int cclk_vlev_datasheet[] =
838{ 803{
839 VRPAIR(VLEV_100, 400000000), 804 VRPAIR(VLEV_100, 400000000),
@@ -909,10 +874,6 @@ static struct platform_device *cmbf527_devices[] __initdata = {
909 &bfin_spi0_device, 874 &bfin_spi0_device,
910#endif 875#endif
911 876
912#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE)
913 &bfin_fb_adv7393_device,
914#endif
915
916#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) 877#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
917 &bfin_uart_device, 878 &bfin_uart_device,
918#endif 879#endif
@@ -942,8 +903,6 @@ static struct platform_device *cmbf527_devices[] __initdata = {
942#if defined(CONFIG_MTD_GPIO_ADDR) || defined(CONFIG_MTD_GPIO_ADDR_MODULE) 903#if defined(CONFIG_MTD_GPIO_ADDR) || defined(CONFIG_MTD_GPIO_ADDR_MODULE)
943 &cm_flash_device, 904 &cm_flash_device,
944#endif 905#endif
945
946 &bfin_gpios_device,
947}; 906};
948 907
949static int __init cm_init(void) 908static int __init cm_init(void)
diff --git a/arch/blackfin/mach-bf527/boards/ezbrd.c b/arch/blackfin/mach-bf527/boards/ezbrd.c
index 68b4c804364c..cad23b15d83c 100644
--- a/arch/blackfin/mach-bf527/boards/ezbrd.c
+++ b/arch/blackfin/mach-bf527/boards/ezbrd.c
@@ -1,31 +1,9 @@
1/* 1/*
2 * File: arch/blackfin/mach-bf527/boards/ezbrd.c 2 * Copyright 2004-2009 Analog Devices Inc.
3 * Based on: arch/blackfin/mach-bf537/boards/stamp.c 3 * 2005 National ICT Australia (NICTA)
4 * Author: Aidan Williams <aidan@nicta.com.au> 4 * Aidan Williams <aidan@nicta.com.au>
5 * 5 *
6 * Created: 6 * Licensed under the GPL-2 or later.
7 * Description:
8 *
9 * Modified:
10 * Copyright 2005 National ICT Australia (NICTA)
11 * Copyright 2004-2008 Analog Devices Inc.
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, see the file COPYING, or write
27 * to the Free Software Foundation, Inc.,
28 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 */ 7 */
30 8
31#include <linux/device.h> 9#include <linux/device.h>
@@ -611,19 +589,6 @@ static struct platform_device bfin_device_gpiokeys = {
611}; 589};
612#endif 590#endif
613 591
614static struct resource bfin_gpios_resources = {
615 .start = 0,
616 .end = MAX_BLACKFIN_GPIOS - 1,
617 .flags = IORESOURCE_IRQ,
618};
619
620static struct platform_device bfin_gpios_device = {
621 .name = "simple-gpio",
622 .id = -1,
623 .num_resources = 1,
624 .resource = &bfin_gpios_resources,
625};
626
627static const unsigned int cclk_vlev_datasheet[] = 592static const unsigned int cclk_vlev_datasheet[] =
628{ 593{
629 VRPAIR(VLEV_100, 400000000), 594 VRPAIR(VLEV_100, 400000000),
@@ -732,8 +697,6 @@ static struct platform_device *stamp_devices[] __initdata = {
732#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) 697#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
733 &ezbrd_flash_device, 698 &ezbrd_flash_device,
734#endif 699#endif
735
736 &bfin_gpios_device,
737}; 700};
738 701
739static int __init ezbrd_init(void) 702static int __init ezbrd_init(void)
diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c
index 2849b09abe99..f09665f74ba0 100644
--- a/arch/blackfin/mach-bf527/boards/ezkit.c
+++ b/arch/blackfin/mach-bf527/boards/ezkit.c
@@ -1,31 +1,9 @@
1/* 1/*
2 * File: arch/blackfin/mach-bf527/boards/ezkit.c 2 * Copyright 2004-2009 Analog Devices Inc.
3 * Based on: arch/blackfin/mach-bf537/boards/stamp.c 3 * 2005 National ICT Australia (NICTA)
4 * Author: Aidan Williams <aidan@nicta.com.au> 4 * Aidan Williams <aidan@nicta.com.au>
5 * 5 *
6 * Created: 6 * Licensed under the GPL-2 or later.
7 * Description:
8 *
9 * Modified:
10 * Copyright 2005 National ICT Australia (NICTA)
11 * Copyright 2004-2008 Analog Devices Inc.
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, see the file COPYING, or write
27 * to the Free Software Foundation, Inc.,
28 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 */ 7 */
30 8
31#include <linux/device.h> 9#include <linux/device.h>
@@ -716,12 +694,6 @@ static struct platform_device bfin_fb_device = {
716}; 694};
717#endif 695#endif
718 696
719#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE)
720static struct platform_device bfin_fb_adv7393_device = {
721 .name = "bfin-adv7393",
722};
723#endif
724
725#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) 697#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
726static struct resource bfin_uart_resources[] = { 698static struct resource bfin_uart_resources[] = {
727#ifdef CONFIG_SERIAL_BFIN_UART0 699#ifdef CONFIG_SERIAL_BFIN_UART0
@@ -837,6 +809,11 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
837 .irq = IRQ_PF8, 809 .irq = IRQ_PF8,
838 }, 810 },
839#endif 811#endif
812#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE)
813 {
814 I2C_BOARD_INFO("bfin-adv7393", 0x2B),
815 },
816#endif
840}; 817};
841 818
842#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) 819#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
@@ -905,19 +882,6 @@ static struct platform_device bfin_rotary_device = {
905}; 882};
906#endif 883#endif
907 884
908static struct resource bfin_gpios_resources = {
909 .start = 0,
910 .end = MAX_BLACKFIN_GPIOS - 1,
911 .flags = IORESOURCE_IRQ,
912};
913
914static struct platform_device bfin_gpios_device = {
915 .name = "simple-gpio",
916 .id = -1,
917 .num_resources = 1,
918 .resource = &bfin_gpios_resources,
919};
920
921static const unsigned int cclk_vlev_datasheet[] = 885static const unsigned int cclk_vlev_datasheet[] =
922{ 886{
923 VRPAIR(VLEV_100, 400000000), 887 VRPAIR(VLEV_100, 400000000),
@@ -1001,10 +965,6 @@ static struct platform_device *stamp_devices[] __initdata = {
1001 &bf52x_t350mcqb_device, 965 &bf52x_t350mcqb_device,
1002#endif 966#endif
1003 967
1004#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE)
1005 &bfin_fb_adv7393_device,
1006#endif
1007
1008#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) 968#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
1009 &bfin_uart_device, 969 &bfin_uart_device,
1010#endif 970#endif
@@ -1038,8 +998,6 @@ static struct platform_device *stamp_devices[] __initdata = {
1038#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) 998#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
1039 &ezkit_flash_device, 999 &ezkit_flash_device,
1040#endif 1000#endif
1041
1042 &bfin_gpios_device,
1043}; 1001};
1044 1002
1045static int __init ezkit_init(void) 1003static int __init ezkit_init(void)
diff --git a/arch/blackfin/mach-bf527/dma.c b/arch/blackfin/mach-bf527/dma.c
index 231877578243..7bc7577d6c4f 100644
--- a/arch/blackfin/mach-bf527/dma.c
+++ b/arch/blackfin/mach-bf527/dma.c
@@ -1,31 +1,11 @@
1/* 1/*
2 * File: arch/blackfin/mach-bf527/dma.c 2 * This file contains the simple DMA Implementation for Blackfin
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Copyright 2007-2008 Analog Devices Inc.
7 * Description: This file contains the simple DMA Implementation for Blackfin
8 * 5 *
9 * Modified: 6 * Licensed under the GPL-2 or later.
10 * Copyright 2004-2007 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 7 */
8
29#include <linux/module.h> 9#include <linux/module.h>
30 10
31#include <asm/blackfin.h> 11#include <asm/blackfin.h>
diff --git a/arch/blackfin/mach-bf527/include/mach/bf527.h b/arch/blackfin/mach-bf527/include/mach/bf527.h
index 3832aab11e9a..ff68c8897087 100644
--- a/arch/blackfin/mach-bf527/include/mach/bf527.h
+++ b/arch/blackfin/mach-bf527/include/mach/bf527.h
@@ -1,30 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf527/bf527.h 2 * Copyright 2007-2009 Analog Devices Inc.
3 * Based on: include/asm-blackfin/mach-bf537/bf537.h
4 * Author: Michael Hennerich (michael.hennerich@analog.com)
5 * 3 *
6 * Created: 4 * Licensed under the GPL-2 or later.
7 * Description: SYSTEM MMR REGISTER AND MEMORY MAP FOR ADSP-BF527
8 *
9 * Modified:
10 * Copyright 2004-2007 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 5 */
29 6
30#ifndef __MACH_BF527_H__ 7#ifndef __MACH_BF527_H__
diff --git a/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h
index ebd6cebc1fbc..c1d55b878b45 100644
--- a/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h
@@ -1,32 +1,7 @@
1/* 1/*
2 * file: include/asm-blackfin/mach-bf527/bfin_serial_5xx.h 2 * Copyright 2007-2009 Analog Devices Inc.
3 * based on:
4 * author:
5 * 3 *
6 * created: 4 * Licensed under the GPL-2 or later
7 * description:
8 * blackfin serial driver head file
9 * rev:
10 *
11 * modified:
12 *
13 *
14 * bugs: enter bugs at http://blackfin.uclinux.org/
15 *
16 * this program is free software; you can redistribute it and/or modify
17 * it under the terms of the gnu general public license as published by
18 * the free software foundation; either version 2, or (at your option)
19 * any later version.
20 *
21 * this program is distributed in the hope that it will be useful,
22 * but without any warranty; without even the implied warranty of
23 * merchantability or fitness for a particular purpose. see the
24 * gnu general public license for more details.
25 *
26 * you should have received a copy of the gnu general public license
27 * along with this program; see the file copying.
28 * if not, write to the free software foundation,
29 * 59 temple place - suite 330, boston, ma 02111-1307, usa.
30 */ 5 */
31 6
32#include <linux/serial.h> 7#include <linux/serial.h>
diff --git a/arch/blackfin/mach-bf527/include/mach/blackfin.h b/arch/blackfin/mach-bf527/include/mach/blackfin.h
index ea9cb0fef8bc..e7d6034f268f 100644
--- a/arch/blackfin/mach-bf527/include/mach/blackfin.h
+++ b/arch/blackfin/mach-bf527/include/mach/blackfin.h
@@ -1,32 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf527/blackfin.h 2 * Copyright 2007-2009 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the GPL-2 or later
7 * Description:
8 *
9 * Rev:
10 *
11 * Modified:
12 *
13 *
14 * Bugs: Enter bugs at http://blackfin.uclinux.org/
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2, or (at your option)
19 * any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; see the file COPYING.
28 * If not, write to the Free Software Foundation,
29 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 */ 5 */
31 6
32#ifndef _MACH_BLACKFIN_H_ 7#ifndef _MACH_BLACKFIN_H_
diff --git a/arch/blackfin/mach-bf527/include/mach/cdefBF522.h b/arch/blackfin/mach-bf527/include/mach/cdefBF522.h
index 663c2bbdfd91..1079af8c7aef 100644
--- a/arch/blackfin/mach-bf527/include/mach/cdefBF522.h
+++ b/arch/blackfin/mach-bf527/include/mach/cdefBF522.h
@@ -1,32 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf527/cdefbf522.h 2 * Copyright 2007-2008 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the GPL-2 or later
7 * Description: system mmr register map
8 *
9 * Rev:
10 *
11 * Modified:
12 *
13 *
14 * Bugs: Enter bugs at http://blackfin.uclinux.org/
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2, or (at your option)
19 * any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; see the file COPYING.
28 * If not, write to the Free Software Foundation,
29 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 */ 5 */
31 6
32#ifndef _CDEF_BF522_H 7#ifndef _CDEF_BF522_H
diff --git a/arch/blackfin/mach-bf527/include/mach/cdefBF525.h b/arch/blackfin/mach-bf527/include/mach/cdefBF525.h
index 00377eb59b75..dc3119e9f663 100644
--- a/arch/blackfin/mach-bf527/include/mach/cdefBF525.h
+++ b/arch/blackfin/mach-bf527/include/mach/cdefBF525.h
@@ -1,32 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf527/cdefbf525.h 2 * Copyright 2007-2008 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the GPL-2 or later
7 * Description: system mmr register map
8 *
9 * Rev:
10 *
11 * Modified:
12 *
13 *
14 * Bugs: Enter bugs at http://blackfin.uclinux.org/
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2, or (at your option)
19 * any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; see the file COPYING.
28 * If not, write to the Free Software Foundation,
29 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 */ 5 */
31 6
32#ifndef _CDEF_BF525_H 7#ifndef _CDEF_BF525_H
diff --git a/arch/blackfin/mach-bf527/include/mach/cdefBF527.h b/arch/blackfin/mach-bf527/include/mach/cdefBF527.h
index fca8db708119..d6579449ee46 100644
--- a/arch/blackfin/mach-bf527/include/mach/cdefBF527.h
+++ b/arch/blackfin/mach-bf527/include/mach/cdefBF527.h
@@ -1,32 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf527/cdefbf527.h 2 * Copyright 2007-2008 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the GPL-2 or later
7 * Description: system mmr register map
8 *
9 * Rev:
10 *
11 * Modified:
12 *
13 *
14 * Bugs: Enter bugs at http://blackfin.uclinux.org/
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2, or (at your option)
19 * any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; see the file COPYING.
28 * If not, write to the Free Software Foundation,
29 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 */ 5 */
31 6
32#ifndef _CDEF_BF527_H 7#ifndef _CDEF_BF527_H
diff --git a/arch/blackfin/mach-bf527/include/mach/cdefBF52x_base.h b/arch/blackfin/mach-bf527/include/mach/cdefBF52x_base.h
index 1fe76d8e0403..7014dde10dd6 100644
--- a/arch/blackfin/mach-bf527/include/mach/cdefBF52x_base.h
+++ b/arch/blackfin/mach-bf527/include/mach/cdefBF52x_base.h
@@ -1,31 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf527/cdefBF52x_base.h 2 * Copyright 2007-2008 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the GPL-2 or later
7 * Description:
8 *
9 * Rev:
10 *
11 * Modified:
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2, or (at your option)
18 * any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; see the file COPYING.
27 * If not, write to the Free Software Foundation,
28 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 */ 5 */
30 6
31#ifndef _CDEF_BF52X_H 7#ifndef _CDEF_BF52X_H
diff --git a/arch/blackfin/mach-bf527/include/mach/defBF522.h b/arch/blackfin/mach-bf527/include/mach/defBF522.h
index 0a8cdcdf0b49..cb139a254810 100644
--- a/arch/blackfin/mach-bf527/include/mach/defBF522.h
+++ b/arch/blackfin/mach-bf527/include/mach/defBF522.h
@@ -1,31 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf527/defBF522.h 2 * Copyright 2007-2008 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the ADI BSD license or the GPL-2 (or later)
7 * Description:
8 *
9 * Rev:
10 *
11 * Modified:
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2, or (at your option)
18 * any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; see the file COPYING.
27 * If not, write to the Free Software Foundation,
28 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 */ 5 */
30 6
31#ifndef _DEF_BF522_H 7#ifndef _DEF_BF522_H
diff --git a/arch/blackfin/mach-bf527/include/mach/defBF525.h b/arch/blackfin/mach-bf527/include/mach/defBF525.h
index 5cd7576fef76..82abefc1ef6c 100644
--- a/arch/blackfin/mach-bf527/include/mach/defBF525.h
+++ b/arch/blackfin/mach-bf527/include/mach/defBF525.h
@@ -1,31 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf527/defBF525.h 2 * Copyright 2007-2008 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the ADI BSD license or the GPL-2 (or later)
7 * Description:
8 *
9 * Rev:
10 *
11 * Modified:
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2, or (at your option)
18 * any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; see the file COPYING.
27 * If not, write to the Free Software Foundation,
28 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 */ 5 */
30 6
31#ifndef _DEF_BF525_H 7#ifndef _DEF_BF525_H
diff --git a/arch/blackfin/mach-bf527/include/mach/defBF527.h b/arch/blackfin/mach-bf527/include/mach/defBF527.h
index f040f364afa3..570a125df025 100644
--- a/arch/blackfin/mach-bf527/include/mach/defBF527.h
+++ b/arch/blackfin/mach-bf527/include/mach/defBF527.h
@@ -1,31 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf527/defBF527.h 2 * Copyright 2007-2008 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the ADI BSD license or the GPL-2 (or later)
7 * Description:
8 *
9 * Rev:
10 *
11 * Modified:
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2, or (at your option)
18 * any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; see the file COPYING.
27 * If not, write to the Free Software Foundation,
28 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 */ 5 */
30 6
31#ifndef _DEF_BF527_H 7#ifndef _DEF_BF527_H
diff --git a/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h b/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h
index 68b55d03fedf..f821700716ee 100644
--- a/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h
+++ b/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h
@@ -1,31 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf527/defBF52x_base.h 2 * Copyright 2007-2008 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the ADI BSD license or the GPL-2 (or later)
7 * Description:
8 *
9 * Rev:
10 *
11 * Modified:
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2, or (at your option)
18 * any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; see the file COPYING.
27 * If not, write to the Free Software Foundation,
28 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 */ 5 */
30 6
31#ifndef _DEF_BF52X_H 7#ifndef _DEF_BF52X_H
diff --git a/arch/blackfin/mach-bf527/include/mach/gpio.h b/arch/blackfin/mach-bf527/include/mach/gpio.h
index 06b6eebf0d49..104bff85290d 100644
--- a/arch/blackfin/mach-bf527/include/mach/gpio.h
+++ b/arch/blackfin/mach-bf527/include/mach/gpio.h
@@ -1,7 +1,4 @@
1/* 1/*
2 * File: arch/blackfin/mach-bf527/include/mach/gpio.h
3 * Bugs: Enter bugs at http://blackfin.uclinux.org/
4 *
5 * Copyright (C) 2008 Analog Devices Inc. 2 * Copyright (C) 2008 Analog Devices Inc.
6 * Licensed under the GPL-2 or later. 3 * Licensed under the GPL-2 or later.
7 */ 4 */
diff --git a/arch/blackfin/mach-bf527/include/mach/irq.h b/arch/blackfin/mach-bf527/include/mach/irq.h
index 8ea660d8151f..aa6579a64a2f 100644
--- a/arch/blackfin/mach-bf527/include/mach/irq.h
+++ b/arch/blackfin/mach-bf527/include/mach/irq.h
@@ -1,32 +1,7 @@
1/* 1/*
2 * file: include/asm-blackfin/mach-bf527/irq.h 2 * Copyright 2007-2008 Analog Devices Inc.
3 * based on: include/asm-blackfin/mach-bf537/irq.h
4 * author: Michael Hennerich (michael.hennerich@analog.com)
5 * 3 *
6 * created: 4 * Licensed under the GPL-2 or later
7 * description:
8 * system mmr register map
9 * rev:
10 *
11 * modified:
12 *
13 *
14 * bugs: enter bugs at http://blackfin.uclinux.org/
15 *
16 * this program is free software; you can redistribute it and/or modify
17 * it under the terms of the gnu general public license as published by
18 * the free software foundation; either version 2, or (at your option)
19 * any later version.
20 *
21 * this program is distributed in the hope that it will be useful,
22 * but without any warranty; without even the implied warranty of
23 * merchantability or fitness for a particular purpose. see the
24 * gnu general public license for more details.
25 *
26 * you should have received a copy of the gnu general public license
27 * along with this program; see the file copying.
28 * if not, write to the free software foundation,
29 * 59 temple place - suite 330, boston, ma 02111-1307, usa.
30 */ 5 */
31 6
32#ifndef _BF527_IRQ_H_ 7#ifndef _BF527_IRQ_H_
diff --git a/arch/blackfin/mach-bf527/include/mach/portmux.h b/arch/blackfin/mach-bf527/include/mach/portmux.h
index 72b1652be4da..d4518b6f4adf 100644
--- a/arch/blackfin/mach-bf527/include/mach/portmux.h
+++ b/arch/blackfin/mach-bf527/include/mach/portmux.h
@@ -1,3 +1,9 @@
1/*
2 * Copyright 2007-2009 Analog Devices Inc.
3 *
4 * Licensed under the GPL-2 or later
5 */
6
1#ifndef _MACH_PORTMUX_H_ 7#ifndef _MACH_PORTMUX_H_
2#define _MACH_PORTMUX_H_ 8#define _MACH_PORTMUX_H_
3 9
diff --git a/arch/blackfin/mach-bf527/ints-priority.c b/arch/blackfin/mach-bf527/ints-priority.c
index f8c8acd73e30..44ca215bf164 100644
--- a/arch/blackfin/mach-bf527/ints-priority.c
+++ b/arch/blackfin/mach-bf527/ints-priority.c
@@ -1,30 +1,9 @@
1/* 1/*
2 * File: arch/blackfin/mach-bf537/ints-priority.c 2 * Set up the interrupt priorities
3 * Based on: arch/blackfin/mach-bf533/ints-priority.c
4 * Author: Michael Hennerich (michael.hennerich@analog.com)
5 * 3 *
6 * Created: 4 * Copyright 2007-2008 Analog Devices Inc.
7 * Description: Set up the interrupt priorities
8 * 5 *
9 * Modified: 6 * Licensed under the GPL-2 or later.
10 * Copyright 2004-2007 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 7 */
29 8
30#include <linux/module.h> 9#include <linux/module.h>
diff --git a/arch/blackfin/mach-bf533/boards/H8606.c b/arch/blackfin/mach-bf533/boards/H8606.c
index 6c2b47fe4fe4..43f43a095a99 100644
--- a/arch/blackfin/mach-bf533/boards/H8606.c
+++ b/arch/blackfin/mach-bf533/boards/H8606.c
@@ -1,32 +1,11 @@
1/* 1/*
2 * File: arch/blackfin/mach-bf533/H8606.c 2 * Copyright 2004-2009 Analog Devices Inc.
3 * Based on: arch/blackfin/mach-bf533/stamp.c 3 * 2007-2008 HV Sistemas S.L.
4 * Author: Javier Herrero <jherrero@hvsistemas.es> 4 * Javier Herrero <jherrero@hvsistemas.es>
5 * 2005 National ICT Australia (NICTA)
6 * Aidan Williams <aidan@nicta.com.au>
5 * 7 *
6 * Created: 2007 8 * Licensed under the GPL-2 or later.
7 * Description: Board Info File for the HV Sistemas H8606 board
8 *
9 * Modified:
10 * Copyright 2005 National ICT Australia (NICTA)
11 * Copyright 2004-2006 Analog Devices Inc
12 * Copyright 2007,2008 HV Sistemas S.L.
13 *
14 * Bugs: Enter bugs at http://blackfin.uclinux.org/
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, see the file COPYING, or write
28 * to the Free Software Foundation, Inc.,
29 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
30 */ 9 */
31 10
32#include <linux/device.h> 11#include <linux/device.h>
diff --git a/arch/blackfin/mach-bf533/boards/blackstamp.c b/arch/blackfin/mach-bf533/boards/blackstamp.c
index 8208d67e2c97..b580884848d4 100644
--- a/arch/blackfin/mach-bf533/boards/blackstamp.c
+++ b/arch/blackfin/mach-bf533/boards/blackstamp.c
@@ -1,16 +1,10 @@
1/* 1/*
2 * File: arch/blackfin/mach-bf533/blackstamp.c 2 * Board Info File for the BlackStamp
3 * Based on: arch/blackfin/mach-bf533/stamp.c
4 * Author: Benjamin Matthews <bmat@lle.rochester.edu>
5 * Aidan Williams <aidan@nicta.com.au>
6 * 3 *
7 * Created: 2008
8 * Description: Board Info File for the BlackStamp
9 *
10 * Copyright 2005 National ICT Australia (NICTA)
11 * Copyright 2004-2008 Analog Devices Inc. 4 * Copyright 2004-2008 Analog Devices Inc.
12 * 5 * 2008 Benjamin Matthews <bmat@lle.rochester.edu>
13 * Enter bugs at http://blackfin.uclinux.org/ 6 * 2005 National ICT Australia (NICTA)
7 * Aidan Williams <aidan@nicta.com.au>
14 * 8 *
15 * More info about the BlackStamp at: 9 * More info about the BlackStamp at:
16 * http://blackfin.uclinux.org/gf/project/blackstamp/ 10 * http://blackfin.uclinux.org/gf/project/blackstamp/
@@ -281,19 +275,6 @@ static struct platform_device bfin_device_gpiokeys = {
281}; 275};
282#endif 276#endif
283 277
284static struct resource bfin_gpios_resources = {
285 .start = 0,
286 .end = MAX_BLACKFIN_GPIOS - 1,
287 .flags = IORESOURCE_IRQ,
288};
289
290static struct platform_device bfin_gpios_device = {
291 .name = "simple-gpio",
292 .id = -1,
293 .num_resources = 1,
294 .resource = &bfin_gpios_resources,
295};
296
297#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) 278#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
298#include <linux/i2c-gpio.h> 279#include <linux/i2c-gpio.h>
299 280
@@ -384,8 +365,6 @@ static struct platform_device *stamp_devices[] __initdata = {
384#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) 365#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
385 &i2c_gpio_device, 366 &i2c_gpio_device,
386#endif 367#endif
387
388 &bfin_gpios_device,
389}; 368};
390 369
391static int __init blackstamp_init(void) 370static int __init blackstamp_init(void)
diff --git a/arch/blackfin/mach-bf533/boards/cm_bf533.c b/arch/blackfin/mach-bf533/boards/cm_bf533.c
index 7443b26c80c5..7fc3b860d4ae 100644
--- a/arch/blackfin/mach-bf533/boards/cm_bf533.c
+++ b/arch/blackfin/mach-bf533/boards/cm_bf533.c
@@ -1,30 +1,10 @@
1/* 1/*
2 * File: arch/blackfin/mach-bf533/boards/cm_bf533.c 2 * Copyright 2004-2009 Analog Devices Inc.
3 * Based on: arch/blackfin/mach-bf533/boards/ezkit.c 3 * 2008-2009 Bluetechnix
4 * Author: Aidan Williams <aidan@nicta.com.au> Copyright 2005 4 * 2005 National ICT Australia (NICTA)
5 * Aidan Williams <aidan@nicta.com.au>
5 * 6 *
6 * Created: 2005 7 * Licensed under the GPL-2 or later.
7 * Description: Board description file
8 *
9 * Modified:
10 * Copyright 2004-2006 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 8 */
29 9
30#include <linux/device.h> 10#include <linux/device.h>
@@ -261,19 +241,6 @@ static struct platform_device smsc911x_device = {
261}; 241};
262#endif 242#endif
263 243
264static struct resource bfin_gpios_resources = {
265 .start = 0,
266 .end = MAX_BLACKFIN_GPIOS - 1,
267 .flags = IORESOURCE_IRQ,
268};
269
270static struct platform_device bfin_gpios_device = {
271 .name = "simple-gpio",
272 .id = -1,
273 .num_resources = 1,
274 .resource = &bfin_gpios_resources,
275};
276
277#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) 244#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
278static struct resource bfin_uart_resources[] = { 245static struct resource bfin_uart_resources[] = {
279 { 246 {
@@ -506,8 +473,6 @@ static struct platform_device *cm_bf533_devices[] __initdata = {
506#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) 473#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
507 &para_flash_device, 474 &para_flash_device,
508#endif 475#endif
509
510 &bfin_gpios_device,
511}; 476};
512 477
513static int __init cm_bf533_init(void) 478static int __init cm_bf533_init(void)
diff --git a/arch/blackfin/mach-bf533/boards/ezkit.c b/arch/blackfin/mach-bf533/boards/ezkit.c
index fd518e383b79..d4689dcc198e 100644
--- a/arch/blackfin/mach-bf533/boards/ezkit.c
+++ b/arch/blackfin/mach-bf533/boards/ezkit.c
@@ -1,31 +1,9 @@
1/* 1/*
2 * File: arch/blackfin/mach-bf533/ezkit.c 2 * Copyright 2004-2009 Analog Devices Inc.
3 * Based on: Original Work 3 * 2005 National ICT Australia (NICTA)
4 * Author: Aidan Williams <aidan@nicta.com.au> 4 * Aidan Williams <aidan@nicta.com.au>
5 * 5 *
6 * Created: 2005 6 * Licensed under the GPL-2 or later.
7 * Description:
8 *
9 * Modified: Robin Getz <rgetz@blackfin.uclinux.org> - Named the boards
10 * Copyright 2005 National ICT Australia (NICTA)
11 * Copyright 2004-2006 Analog Devices Inc.
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, see the file COPYING, or write
27 * to the Free Software Foundation, Inc.,
28 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 */ 7 */
30 8
31#include <linux/device.h> 9#include <linux/device.h>
@@ -33,12 +11,14 @@
33#include <linux/mtd/mtd.h> 11#include <linux/mtd/mtd.h>
34#include <linux/mtd/partitions.h> 12#include <linux/mtd/partitions.h>
35#include <linux/mtd/plat-ram.h> 13#include <linux/mtd/plat-ram.h>
14#include <linux/mtd/physmap.h>
36#include <linux/spi/spi.h> 15#include <linux/spi/spi.h>
37#include <linux/spi/flash.h> 16#include <linux/spi/flash.h>
38#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) 17#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
39#include <linux/usb/isp1362.h> 18#include <linux/usb/isp1362.h>
40#endif 19#endif
41#include <linux/irq.h> 20#include <linux/irq.h>
21#include <linux/i2c.h>
42#include <asm/dma.h> 22#include <asm/dma.h>
43#include <asm/bfin5xx_spi.h> 23#include <asm/bfin5xx_spi.h>
44#include <asm/portmux.h> 24#include <asm/portmux.h>
@@ -56,12 +36,6 @@ static struct platform_device rtc_device = {
56}; 36};
57#endif 37#endif
58 38
59#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE)
60static struct platform_device bfin_fb_adv7393_device = {
61 .name = "bfin-adv7393",
62};
63#endif
64
65/* 39/*
66 * USB-LAN EzExtender board 40 * USB-LAN EzExtender board
67 * Driver needs to know address, irq and flag pin. 41 * Driver needs to know address, irq and flag pin.
@@ -98,54 +72,69 @@ static struct platform_device smc91x_device = {
98}; 72};
99#endif 73#endif
100 74
101#if defined(CONFIG_MTD_PSD4256G) || defined(CONFIG_MTD_PSD4256G_MODULE) 75#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
102static const char *map_probes[] = { 76static struct mtd_partition ezkit_partitions_a[] = {
103 "stm_flash", 77 {
104 NULL, 78 .name = "bootloader(nor a)",
79 .size = 0x40000,
80 .offset = 0,
81 }, {
82 .name = "linux kernel(nor a)",
83 .size = MTDPART_SIZ_FULL,
84 .offset = MTDPART_OFS_APPEND,
85 },
105}; 86};
106 87
107static struct platdata_mtd_ram stm_pri_data_a = { 88static struct physmap_flash_data ezkit_flash_data_a = {
108 .mapname = "Flash A Primary", 89 .width = 2,
109 .map_probes = map_probes, 90 .parts = ezkit_partitions_a,
110 .bankwidth = 2, 91 .nr_parts = ARRAY_SIZE(ezkit_partitions_a),
111}; 92};
112 93
113static struct resource stm_pri_resource_a = { 94static struct resource ezkit_flash_resource_a = {
114 .start = 0x20000000, 95 .start = 0x20000000,
115 .end = 0x200fffff, 96 .end = 0x200fffff,
116 .flags = IORESOURCE_MEM, 97 .flags = IORESOURCE_MEM,
117}; 98};
118 99
119static struct platform_device stm_pri_device_a = { 100static struct platform_device ezkit_flash_device_a = {
120 .name = "mtd-ram", 101 .name = "physmap-flash",
121 .id = 0, 102 .id = 0,
122 .dev = { 103 .dev = {
123 .platform_data = &stm_pri_data_a, 104 .platform_data = &ezkit_flash_data_a,
124 }, 105 },
125 .num_resources = 1, 106 .num_resources = 1,
126 .resource = &stm_pri_resource_a, 107 .resource = &ezkit_flash_resource_a,
108};
109
110static struct mtd_partition ezkit_partitions_b[] = {
111 {
112 .name = "file system(nor b)",
113 .size = MTDPART_SIZ_FULL,
114 .offset = MTDPART_OFS_APPEND,
115 },
127}; 116};
128 117
129static struct platdata_mtd_ram stm_pri_data_b = { 118static struct physmap_flash_data ezkit_flash_data_b = {
130 .mapname = "Flash B Primary", 119 .width = 2,
131 .map_probes = map_probes, 120 .parts = ezkit_partitions_b,
132 .bankwidth = 2, 121 .nr_parts = ARRAY_SIZE(ezkit_partitions_b),
133}; 122};
134 123
135static struct resource stm_pri_resource_b = { 124static struct resource ezkit_flash_resource_b = {
136 .start = 0x20100000, 125 .start = 0x20100000,
137 .end = 0x201fffff, 126 .end = 0x201fffff,
138 .flags = IORESOURCE_MEM, 127 .flags = IORESOURCE_MEM,
139}; 128};
140 129
141static struct platform_device stm_pri_device_b = { 130static struct platform_device ezkit_flash_device_b = {
142 .name = "mtd-ram", 131 .name = "physmap-flash",
143 .id = 4, 132 .id = 4,
144 .dev = { 133 .dev = {
145 .platform_data = &stm_pri_data_b, 134 .platform_data = &ezkit_flash_data_b,
146 }, 135 },
147 .num_resources = 1, 136 .num_resources = 1,
148 .resource = &stm_pri_resource_b, 137 .resource = &ezkit_flash_resource_b,
149}; 138};
150#endif 139#endif
151 140
@@ -400,19 +389,6 @@ static struct platform_device bfin_device_gpiokeys = {
400}; 389};
401#endif 390#endif
402 391
403static struct resource bfin_gpios_resources = {
404 .start = 0,
405 .end = MAX_BLACKFIN_GPIOS - 1,
406 .flags = IORESOURCE_IRQ,
407};
408
409static struct platform_device bfin_gpios_device = {
410 .name = "simple-gpio",
411 .id = -1,
412 .num_resources = 1,
413 .resource = &bfin_gpios_resources,
414};
415
416#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) 392#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
417#include <linux/i2c-gpio.h> 393#include <linux/i2c-gpio.h>
418 394
@@ -460,13 +436,21 @@ static struct platform_device bfin_dpmc = {
460 }, 436 },
461}; 437};
462 438
439static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
440#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE)
441 {
442 I2C_BOARD_INFO("bfin-adv7393", 0x2B),
443 },
444#endif
445};
446
463static struct platform_device *ezkit_devices[] __initdata = { 447static struct platform_device *ezkit_devices[] __initdata = {
464 448
465 &bfin_dpmc, 449 &bfin_dpmc,
466 450
467#if defined(CONFIG_MTD_PSD4256G) || defined(CONFIG_MTD_PSD4256G_MODULE) 451#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
468 &stm_pri_device_a, 452 &ezkit_flash_device_a,
469 &stm_pri_device_b, 453 &ezkit_flash_device_b,
470#endif 454#endif
471 455
472#if defined(CONFIG_MTD_PLATRAM) || defined(CONFIG_MTD_PLATRAM_MODULE) 456#if defined(CONFIG_MTD_PLATRAM) || defined(CONFIG_MTD_PLATRAM_MODULE)
@@ -482,10 +466,6 @@ static struct platform_device *ezkit_devices[] __initdata = {
482 &bfin_spi0_device, 466 &bfin_spi0_device,
483#endif 467#endif
484 468
485#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE)
486 &bfin_fb_adv7393_device,
487#endif
488
489#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) 469#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
490 &rtc_device, 470 &rtc_device,
491#endif 471#endif
@@ -507,8 +487,6 @@ static struct platform_device *ezkit_devices[] __initdata = {
507#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) 487#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
508 &i2c_gpio_device, 488 &i2c_gpio_device,
509#endif 489#endif
510
511 &bfin_gpios_device,
512}; 490};
513 491
514static int __init ezkit_init(void) 492static int __init ezkit_init(void)
@@ -516,6 +494,8 @@ static int __init ezkit_init(void)
516 printk(KERN_INFO "%s(): registering device resources\n", __func__); 494 printk(KERN_INFO "%s(): registering device resources\n", __func__);
517 platform_add_devices(ezkit_devices, ARRAY_SIZE(ezkit_devices)); 495 platform_add_devices(ezkit_devices, ARRAY_SIZE(ezkit_devices));
518 spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); 496 spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info));
497 i2c_register_board_info(0, bfin_i2c_board_info,
498 ARRAY_SIZE(bfin_i2c_board_info));
519 return 0; 499 return 0;
520} 500}
521 501
diff --git a/arch/blackfin/mach-bf533/boards/ip0x.c b/arch/blackfin/mach-bf533/boards/ip0x.c
index f19b63378b12..644be5e5ab6f 100644
--- a/arch/blackfin/mach-bf533/boards/ip0x.c
+++ b/arch/blackfin/mach-bf533/boards/ip0x.c
@@ -1,34 +1,12 @@
1/* 1/*
2 * File: arch/blackfin/mach-bf533/ip0x.c 2 * Copyright 2004-2009 Analog Devices Inc.
3 * Based on: arch/blackfin/mach-bf533/bf1.c 3 * 2007 David Rowe
4 * Based on: arch/blackfin/mach-bf533/stamp.c 4 * 2006 Intratrade Ltd.
5 * Author: Ivan Danov <idanov@gmail.com> 5 * Ivan Danov <idanov@gmail.com>
6 * Modified for IP0X David Rowe 6 * 2005 National ICT Australia (NICTA)
7 * Aidan Williams <aidan@nicta.com.au>
7 * 8 *
8 * Created: 2007 9 * Licensed under the GPL-2 or later.
9 * Description: Board info file for the IP04/IP08 boards, which
10 * are derived from the BlackfinOne V2.0 boards.
11 *
12 * Modified:
13 * COpyright 2007 David Rowe
14 * Copyright 2006 Intratrade Ltd.
15 * Copyright 2005 National ICT Australia (NICTA)
16 * Copyright 2004-2006 Analog Devices Inc.
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
22 *
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, see the file COPYING, or write
30 * to the Free Software Foundation, Inc.,
31 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
32 */ 10 */
33 11
34#include <linux/device.h> 12#include <linux/device.h>
@@ -145,7 +123,6 @@ static struct bfin5xx_spi_chip mmc_spi_chip_info = {
145 .ctl_reg = 0x1000, /* CPOL=0,CPHA=0,Sandisk 1G work */ 123 .ctl_reg = 0x1000, /* CPOL=0,CPHA=0,Sandisk 1G work */
146 .enable_dma = 0, /* if 1 - block!!! */ 124 .enable_dma = 0, /* if 1 - block!!! */
147 .bits_per_word = 8, 125 .bits_per_word = 8,
148 .cs_change_per_word = 0,
149}; 126};
150#endif 127#endif
151 128
diff --git a/arch/blackfin/mach-bf533/boards/stamp.c b/arch/blackfin/mach-bf533/boards/stamp.c
index 729fd7c26336..82f70efd66e7 100644
--- a/arch/blackfin/mach-bf533/boards/stamp.c
+++ b/arch/blackfin/mach-bf533/boards/stamp.c
@@ -1,31 +1,9 @@
1/* 1/*
2 * File: arch/blackfin/mach-bf533/stamp.c 2 * Copyright 2004-2009 Analog Devices Inc.
3 * Based on: arch/blackfin/mach-bf533/ezkit.c 3 * 2005 National ICT Australia (NICTA)
4 * Author: Aidan Williams <aidan@nicta.com.au> 4 * Aidan Williams <aidan@nicta.com.au>
5 * 5 *
6 * Created: 2005 6 * Licensed under the GPL-2 or later.
7 * Description: Board Info File for the BF533-STAMP
8 *
9 * Modified:
10 * Copyright 2005 National ICT Australia (NICTA)
11 * Copyright 2004-2006 Analog Devices Inc.
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, see the file COPYING, or write
27 * to the Free Software Foundation, Inc.,
28 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 */ 7 */
30 8
31#include <linux/device.h> 9#include <linux/device.h>
@@ -95,12 +73,6 @@ static struct platform_device smc91x_device = {
95}; 73};
96#endif 74#endif
97 75
98#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE)
99static struct platform_device bfin_fb_adv7393_device = {
100 .name = "bfin-adv7393",
101};
102#endif
103
104#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE) 76#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
105static struct resource net2272_bfin_resources[] = { 77static struct resource net2272_bfin_resources[] = {
106 { 78 {
@@ -436,19 +408,6 @@ static struct platform_device bfin_device_gpiokeys = {
436}; 408};
437#endif 409#endif
438 410
439static struct resource bfin_gpios_resources = {
440 .start = 0,
441 .end = MAX_BLACKFIN_GPIOS - 1,
442 .flags = IORESOURCE_IRQ,
443};
444
445static struct platform_device bfin_gpios_device = {
446 .name = "simple-gpio",
447 .id = -1,
448 .num_resources = 1,
449 .resource = &bfin_gpios_resources,
450};
451
452#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) 411#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
453#include <linux/i2c-gpio.h> 412#include <linux/i2c-gpio.h>
454 413
@@ -487,6 +446,11 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
487 .irq = 39, 446 .irq = 39,
488 }, 447 },
489#endif 448#endif
449#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE)
450 {
451 I2C_BOARD_INFO("bfin-adv7393", 0x2B),
452 },
453#endif
490}; 454};
491 455
492static const unsigned int cclk_vlev_datasheet[] = 456static const unsigned int cclk_vlev_datasheet[] =
@@ -528,10 +492,6 @@ static struct platform_device *stamp_devices[] __initdata = {
528 &smc91x_device, 492 &smc91x_device,
529#endif 493#endif
530 494
531#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE)
532 &bfin_fb_adv7393_device,
533#endif
534
535#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE) 495#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
536 &net2272_bfin_device, 496 &net2272_bfin_device,
537#endif 497#endif
@@ -563,8 +523,6 @@ static struct platform_device *stamp_devices[] __initdata = {
563 &i2c_gpio_device, 523 &i2c_gpio_device,
564#endif 524#endif
565 525
566 &bfin_gpios_device,
567
568#if defined(CONFIG_MTD_BFIN_ASYNC) || defined(CONFIG_MTD_BFIN_ASYNC_MODULE) 526#if defined(CONFIG_MTD_BFIN_ASYNC) || defined(CONFIG_MTD_BFIN_ASYNC_MODULE)
569 &stamp_flash_device, 527 &stamp_flash_device,
570#endif 528#endif
diff --git a/arch/blackfin/mach-bf533/dma.c b/arch/blackfin/mach-bf533/dma.c
index 7a443c37fb9f..4a14a46a9a68 100644
--- a/arch/blackfin/mach-bf533/dma.c
+++ b/arch/blackfin/mach-bf533/dma.c
@@ -1,31 +1,11 @@
1/* 1/*
2 * File: arch/blackfin/mach-bf533/dma.c 2 * simple DMA Implementation for Blackfin
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Copyright 2007-2009 Analog Devices Inc.
7 * Description: This file contains the simple DMA Implementation for Blackfin
8 * 5 *
9 * Modified: 6 * Licensed under the GPL-2 or later.
10 * Copyright 2004-2006 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 7 */
8
29#include <linux/module.h> 9#include <linux/module.h>
30 10
31#include <asm/blackfin.h> 11#include <asm/blackfin.h>
diff --git a/arch/blackfin/mach-bf533/include/mach/bf533.h b/arch/blackfin/mach-bf533/include/mach/bf533.h
index cf4427cd3f72..e3e05f8f7af9 100644
--- a/arch/blackfin/mach-bf533/include/mach/bf533.h
+++ b/arch/blackfin/mach-bf533/include/mach/bf533.h
@@ -1,30 +1,9 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf533/bf533.h 2 * SYSTEM MMR REGISTER AND MEMORY MAP FOR ADSP-BF561
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Copyright 2005-2008 Analog Devices Inc.
7 * Description: SYSTEM MMR REGISTER AND MEMORY MAP FOR ADSP-BF561
8 * 5 *
9 * Modified: 6 * Licensed under the GPL-2 or later.
10 * Copyright 2004-2006 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 7 */
29 8
30#ifndef __MACH_BF533_H__ 9#ifndef __MACH_BF533_H__
diff --git a/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h
index 6965b4088c44..9e1f3defb6bc 100644
--- a/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h
@@ -1,32 +1,7 @@
1/* 1/*
2 * file: include/asm-blackfin/mach-bf533/bfin_serial_5xx.h 2 * Copyright 2006-2009 Analog Devices Inc.
3 * based on:
4 * author:
5 * 3 *
6 * created: 4 * Licensed under the GPL-2 or later
7 * description:
8 * blackfin serial driver head file
9 * rev:
10 *
11 * modified:
12 *
13 *
14 * bugs: enter bugs at http://blackfin.uclinux.org/
15 *
16 * this program is free software; you can redistribute it and/or modify
17 * it under the terms of the gnu general public license as published by
18 * the free software foundation; either version 2, or (at your option)
19 * any later version.
20 *
21 * this program is distributed in the hope that it will be useful,
22 * but without any warranty; without even the implied warranty of
23 * merchantability or fitness for a particular purpose. see the
24 * gnu general public license for more details.
25 *
26 * you should have received a copy of the gnu general public license
27 * along with this program; see the file copying.
28 * if not, write to the free software foundation,
29 * 59 temple place - suite 330, boston, ma 02111-1307, usa.
30 */ 5 */
31 6
32#include <linux/serial.h> 7#include <linux/serial.h>
diff --git a/arch/blackfin/mach-bf533/include/mach/blackfin.h b/arch/blackfin/mach-bf533/include/mach/blackfin.h
index 499e897a4f4f..f4bd6df5d968 100644
--- a/arch/blackfin/mach-bf533/include/mach/blackfin.h
+++ b/arch/blackfin/mach-bf533/include/mach/blackfin.h
@@ -1,31 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf533/blackfin.h 2 * Copyright 2005-2009 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the GPL-2 or later
7 * Description:
8 *
9 * Rev:
10 *
11 * Modified:
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2, or (at your option)
18 * any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; see the file COPYING.
27 * If not, write to the Free Software Foundation,
28 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 */ 5 */
30 6
31#ifndef _MACH_BLACKFIN_H_ 7#ifndef _MACH_BLACKFIN_H_
diff --git a/arch/blackfin/mach-bf533/include/mach/cdefBF532.h b/arch/blackfin/mach-bf533/include/mach/cdefBF532.h
index bbc3c8386d48..feb2392c43ea 100644
--- a/arch/blackfin/mach-bf533/include/mach/cdefBF532.h
+++ b/arch/blackfin/mach-bf533/include/mach/cdefBF532.h
@@ -1,31 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf533/cdefBF532.h 2 * Copyright 2005-2008 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the GPL-2 or later
7 * Description:
8 *
9 * Rev:
10 *
11 * Modified:
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2, or (at your option)
18 * any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; see the file COPYING.
27 * If not, write to the Free Software Foundation,
28 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 */ 5 */
30 6
31#ifndef _CDEF_BF532_H 7#ifndef _CDEF_BF532_H
diff --git a/arch/blackfin/mach-bf533/include/mach/defBF532.h b/arch/blackfin/mach-bf533/include/mach/defBF532.h
index 7f4633223e6d..02b328eb0e07 100644
--- a/arch/blackfin/mach-bf533/include/mach/defBF532.h
+++ b/arch/blackfin/mach-bf533/include/mach/defBF532.h
@@ -1,48 +1,10 @@
1/************************************************************************
2 *
3 * This file is subject to the terms and conditions of the GNU Public
4 * License. See the file "COPYING" in the main directory of this archive
5 * for more details.
6 *
7 * Non-GPL License also available as part of VisualDSP++
8 * http://www.analog.com/processors/resources/crosscore/visualDspDevSoftware.html
9 *
10 * (c) Copyright 2001-2005 Analog Devices, Inc. All rights reserved
11 *
12 * This file under source code control, please send bugs or changes to:
13 * dsptools.support@analog.com
14 *
15 ************************************************************************/
16/* 1/*
17 * File: include/asm-blackfin/mach-bf533/defBF532.h 2 * System & MMR bit and Address definitions for ADSP-BF532
18 * Based on:
19 * Author:
20 *
21 * Created:
22 * Description:
23 *
24 * Rev:
25 *
26 * Modified:
27 *
28 * Bugs: Enter bugs at http://blackfin.uclinux.org/
29 *
30 * This program is free software; you can redistribute it and/or modify
31 * it under the terms of the GNU General Public License as published by
32 * the Free Software Foundation; either version 2, or (at your option)
33 * any later version.
34 * 3 *
35 * This program is distributed in the hope that it will be useful, 4 * Copyright 2005-2008 Analog Devices Inc.
36 * but WITHOUT ANY WARRANTY; without even the implied warranty of
37 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38 * GNU General Public License for more details.
39 * 5 *
40 * You should have received a copy of the GNU General Public License 6 * Licensed under the ADI BSD license or the GPL-2 (or later)
41 * along with this program; see the file COPYING.
42 * If not, write to the Free Software Foundation,
43 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
44 */ 7 */
45/* SYSTEM & MM REGISTER BIT & ADDRESS DEFINITIONS FOR ADSP-BF532 */
46 8
47#ifndef _DEF_BF532_H 9#ifndef _DEF_BF532_H
48#define _DEF_BF532_H 10#define _DEF_BF532_H
diff --git a/arch/blackfin/mach-bf533/include/mach/gpio.h b/arch/blackfin/mach-bf533/include/mach/gpio.h
index e45c17077aff..2af19d69a7a7 100644
--- a/arch/blackfin/mach-bf533/include/mach/gpio.h
+++ b/arch/blackfin/mach-bf533/include/mach/gpio.h
@@ -1,7 +1,4 @@
1/* 1/*
2 * File: arch/blackfin/mach-bf533/include/mach/gpio.h
3 * Bugs: Enter bugs at http://blackfin.uclinux.org/
4 *
5 * Copyright (C) 2008 Analog Devices Inc. 2 * Copyright (C) 2008 Analog Devices Inc.
6 * Licensed under the GPL-2 or later. 3 * Licensed under the GPL-2 or later.
7 */ 4 */
diff --git a/arch/blackfin/mach-bf533/include/mach/irq.h b/arch/blackfin/mach-bf533/include/mach/irq.h
index db1e346cd1aa..c31498be0bbb 100644
--- a/arch/blackfin/mach-bf533/include/mach/irq.h
+++ b/arch/blackfin/mach-bf533/include/mach/irq.h
@@ -1,31 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf533/defBF532.h 2 * Copyright 2005-2008 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the GPL-2 or later
7 * Description:
8 *
9 * Rev:
10 *
11 * Modified:
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2, or (at your option)
18 * any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; see the file COPYING.
27 * If not, write to the Free Software Foundation,
28 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 */ 5 */
30 6
31#ifndef _BF533_IRQ_H_ 7#ifndef _BF533_IRQ_H_
diff --git a/arch/blackfin/mach-bf533/include/mach/portmux.h b/arch/blackfin/mach-bf533/include/mach/portmux.h
index 2f59ce0b0cb5..075dae1af164 100644
--- a/arch/blackfin/mach-bf533/include/mach/portmux.h
+++ b/arch/blackfin/mach-bf533/include/mach/portmux.h
@@ -1,3 +1,9 @@
1/*
2 * Copyright 2007-2009 Analog Devices Inc.
3 *
4 * Licensed under the GPL-2 or later
5 */
6
1#ifndef _MACH_PORTMUX_H_ 7#ifndef _MACH_PORTMUX_H_
2#define _MACH_PORTMUX_H_ 8#define _MACH_PORTMUX_H_
3 9
diff --git a/arch/blackfin/mach-bf533/ints-priority.c b/arch/blackfin/mach-bf533/ints-priority.c
index f51994b7a2b9..8f714cf8135b 100644
--- a/arch/blackfin/mach-bf533/ints-priority.c
+++ b/arch/blackfin/mach-bf533/ints-priority.c
@@ -1,30 +1,9 @@
1/* 1/*
2 * File: arch/blackfin/mach-bf533/ints-priority.c 2 * Set up the interrupt priorities
3 * Based on:
4 * Author: Michael Hennerich
5 * 3 *
6 * Created: ? 4 * Copyright 2005-2009 Analog Devices Inc.
7 * Description: Set up the interrupt priorities
8 * 5 *
9 * Modified: 6 * Licensed under the GPL-2 or later.
10 * Copyright 2004-2006 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 7 */
29 8
30#include <linux/module.h> 9#include <linux/module.h>
diff --git a/arch/blackfin/mach-bf537/boards/cm_bf537e.c b/arch/blackfin/mach-bf537/boards/cm_bf537e.c
index 87acb7dd2df3..c85f4d770535 100644
--- a/arch/blackfin/mach-bf537/boards/cm_bf537e.c
+++ b/arch/blackfin/mach-bf537/boards/cm_bf537e.c
@@ -1,31 +1,10 @@
1/* 1/*
2 * File: arch/blackfin/mach-bf537/boards/cm_bf537.c 2 * Copyright 2004-2009 Analog Devices Inc.
3 * Based on: arch/blackfin/mach-bf533/boards/ezkit.c 3 * 2008-2009 Bluetechnix
4 * Author: Aidan Williams <aidan@nicta.com.au> 4 * 2005 National ICT Australia (NICTA)
5 * Aidan Williams <aidan@nicta.com.au>
5 * 6 *
6 * Created: 2005 7 * Licensed under the GPL-2 or later.
7 * Description: Board description file
8 *
9 * Modified:
10 * Copyright 2005 National ICT Australia (NICTA)
11 * Copyright 2004-2006 Analog Devices Inc.
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, see the file COPYING, or write
27 * to the Free Software Foundation, Inc.,
28 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 */ 8 */
30 9
31#include <linux/device.h> 10#include <linux/device.h>
@@ -297,19 +276,6 @@ static struct platform_device net2272_bfin_device = {
297}; 276};
298#endif 277#endif
299 278
300static struct resource bfin_gpios_resources = {
301 .start = 0,
302 .end = MAX_BLACKFIN_GPIOS - 1,
303 .flags = IORESOURCE_IRQ,
304};
305
306static struct platform_device bfin_gpios_device = {
307 .name = "simple-gpio",
308 .id = -1,
309 .num_resources = 1,
310 .resource = &bfin_gpios_resources,
311};
312
313#if defined(CONFIG_MTD_GPIO_ADDR) || defined(CONFIG_MTD_GPIO_ADDR_MODULE) 279#if defined(CONFIG_MTD_GPIO_ADDR) || defined(CONFIG_MTD_GPIO_ADDR_MODULE)
314static struct mtd_partition cm_partitions[] = { 280static struct mtd_partition cm_partitions[] = {
315 { 281 {
@@ -699,8 +665,6 @@ static struct platform_device *cm_bf537e_devices[] __initdata = {
699#if defined(CONFIG_MTD_GPIO_ADDR) || defined(CONFIG_MTD_GPIO_ADDR_MODULE) 665#if defined(CONFIG_MTD_GPIO_ADDR) || defined(CONFIG_MTD_GPIO_ADDR_MODULE)
700 &cm_flash_device, 666 &cm_flash_device,
701#endif 667#endif
702
703 &bfin_gpios_device,
704}; 668};
705 669
706static int __init cm_bf537e_init(void) 670static int __init cm_bf537e_init(void)
diff --git a/arch/blackfin/mach-bf537/boards/cm_bf537u.c b/arch/blackfin/mach-bf537/boards/cm_bf537u.c
index 8219dc3d65bd..ea11aa81340d 100644
--- a/arch/blackfin/mach-bf537/boards/cm_bf537u.c
+++ b/arch/blackfin/mach-bf537/boards/cm_bf537u.c
@@ -1,31 +1,10 @@
1/* 1/*
2 * File: arch/blackfin/mach-bf537/boards/cm_bf537u.c 2 * Copyright 2004-2009 Analog Devices Inc.
3 * Based on: arch/blackfin/mach-bf533/boards/ezkit.c 3 * 2008-2009 Bluetechnix
4 * Author: Aidan Williams <aidan@nicta.com.au> 4 * 2005 National ICT Australia (NICTA)
5 * Aidan Williams <aidan@nicta.com.au>
5 * 6 *
6 * Created: 2005 7 * Licensed under the GPL-2 or later.
7 * Description: Board description file
8 *
9 * Modified:
10 * Copyright 2005 National ICT Australia (NICTA)
11 * Copyright 2004-2006 Analog Devices Inc.
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, see the file COPYING, or write
27 * to the Free Software Foundation, Inc.,
28 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 */ 8 */
30 9
31#include <linux/device.h> 10#include <linux/device.h>
@@ -298,19 +277,6 @@ static struct platform_device net2272_bfin_device = {
298}; 277};
299#endif 278#endif
300 279
301static struct resource bfin_gpios_resources = {
302 .start = 0,
303 .end = MAX_BLACKFIN_GPIOS - 1,
304 .flags = IORESOURCE_IRQ,
305};
306
307static struct platform_device bfin_gpios_device = {
308 .name = "simple-gpio",
309 .id = -1,
310 .num_resources = 1,
311 .resource = &bfin_gpios_resources,
312};
313
314#if defined(CONFIG_MTD_GPIO_ADDR) || defined(CONFIG_MTD_GPIO_ADDR_MODULE) 280#if defined(CONFIG_MTD_GPIO_ADDR) || defined(CONFIG_MTD_GPIO_ADDR_MODULE)
315static struct mtd_partition cm_partitions[] = { 281static struct mtd_partition cm_partitions[] = {
316 { 282 {
@@ -605,8 +571,6 @@ static struct platform_device *cm_bf537u_devices[] __initdata = {
605#if defined(CONFIG_MTD_GPIO_ADDR) || defined(CONFIG_MTD_GPIO_ADDR_MODULE) 571#if defined(CONFIG_MTD_GPIO_ADDR) || defined(CONFIG_MTD_GPIO_ADDR_MODULE)
606 &cm_flash_device, 572 &cm_flash_device,
607#endif 573#endif
608
609 &bfin_gpios_device,
610}; 574};
611 575
612static int __init cm_bf537u_init(void) 576static int __init cm_bf537u_init(void)
diff --git a/arch/blackfin/mach-bf537/boards/minotaur.c b/arch/blackfin/mach-bf537/boards/minotaur.c
index 399f81da7b93..0da927252701 100644
--- a/arch/blackfin/mach-bf537/boards/minotaur.c
+++ b/arch/blackfin/mach-bf537/boards/minotaur.c
@@ -1,4 +1,10 @@
1/* 1/*
2 * Copyright 2004-2009 Analog Devices Inc.
3 * 2008-2009 Cambridge Signal Processing
4 * 2005 National ICT Australia (NICTA)
5 * Aidan Williams <aidan@nicta.com.au>
6 *
7 * Licensed under the GPL-2 or later.
2 */ 8 */
3 9
4#include <linux/device.h> 10#include <linux/device.h>
diff --git a/arch/blackfin/mach-bf537/boards/pnav10.c b/arch/blackfin/mach-bf537/boards/pnav10.c
index 10b35b838bac..9ba290466b56 100644
--- a/arch/blackfin/mach-bf537/boards/pnav10.c
+++ b/arch/blackfin/mach-bf537/boards/pnav10.c
@@ -1,31 +1,9 @@
1/* 1/*
2 * File: arch/blackfin/mach-bf537/boards/stamp.c 2 * Copyright 2004-2009 Analog Devices Inc.
3 * Based on: arch/blackfin/mach-bf533/boards/ezkit.c 3 * 2005 National ICT Australia (NICTA)
4 * Author: Aidan Williams <aidan@nicta.com.au> 4 * Aidan Williams <aidan@nicta.com.au>
5 * 5 *
6 * Created: 6 * Licensed under the GPL-2 or later.
7 * Description:
8 *
9 * Modified:
10 * Copyright 2005 National ICT Australia (NICTA)
11 * Copyright 2004-2008 Analog Devices Inc.
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, see the file COPYING, or write
27 * to the Free Software Foundation, Inc.,
28 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 */ 7 */
30 8
31#include <linux/device.h> 9#include <linux/device.h>
@@ -302,7 +280,6 @@ static struct bfin5xx_spi_chip mmc_spi_chip_info = {
302 280
303#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) 281#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
304static struct bfin5xx_spi_chip spi_ad7877_chip_info = { 282static struct bfin5xx_spi_chip spi_ad7877_chip_info = {
305 .cs_change_per_word = 0,
306 .enable_dma = 0, 283 .enable_dma = 0,
307 .bits_per_word = 16, 284 .bits_per_word = 16,
308}; 285};
diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c
index 9db6b40743e0..c46baa5e6d9b 100644
--- a/arch/blackfin/mach-bf537/boards/stamp.c
+++ b/arch/blackfin/mach-bf537/boards/stamp.c
@@ -1,31 +1,9 @@
1/* 1/*
2 * File: arch/blackfin/mach-bf537/boards/stamp.c 2 * Copyright 2004-2009 Analog Devices Inc.
3 * Based on: arch/blackfin/mach-bf533/boards/ezkit.c 3 * 2005 National ICT Australia (NICTA)
4 * Author: Aidan Williams <aidan@nicta.com.au> 4 * Aidan Williams <aidan@nicta.com.au>
5 * 5 *
6 * Created: 6 * Licensed under the GPL-2 or later.
7 * Description:
8 *
9 * Modified:
10 * Copyright 2005 National ICT Australia (NICTA)
11 * Copyright 2004-2006 Analog Devices Inc.
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, see the file COPYING, or write
27 * to the Free Software Foundation, Inc.,
28 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 */ 7 */
30 8
31#include <linux/device.h> 9#include <linux/device.h>
@@ -121,19 +99,6 @@ static struct platform_device bfin_device_gpiokeys = {
121}; 99};
122#endif 100#endif
123 101
124static struct resource bfin_gpios_resources = {
125 .start = 0,
126 .end = MAX_BLACKFIN_GPIOS - 1,
127 .flags = IORESOURCE_IRQ,
128};
129
130static struct platform_device bfin_gpios_device = {
131 .name = "simple-gpio",
132 .id = -1,
133 .num_resources = 1,
134 .resource = &bfin_gpios_resources,
135};
136
137#if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE) 102#if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE)
138static struct resource bfin_pcmcia_cf_resources[] = { 103static struct resource bfin_pcmcia_cf_resources[] = {
139 { 104 {
@@ -1078,12 +1043,6 @@ static struct platform_device bfin_fb_device = {
1078}; 1043};
1079#endif 1044#endif
1080 1045
1081#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE)
1082static struct platform_device bfin_fb_adv7393_device = {
1083 .name = "bfin-adv7393",
1084};
1085#endif
1086
1087#if defined(CONFIG_FB_BFIN_LQ035Q1) || defined(CONFIG_FB_BFIN_LQ035Q1_MODULE) 1046#if defined(CONFIG_FB_BFIN_LQ035Q1) || defined(CONFIG_FB_BFIN_LQ035Q1_MODULE)
1088#include <asm/bfin-lq035q1.h> 1047#include <asm/bfin-lq035q1.h>
1089 1048
@@ -1498,6 +1457,11 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
1498 .platform_data = (void *)&adp5588_gpio_data, 1457 .platform_data = (void *)&adp5588_gpio_data,
1499 }, 1458 },
1500#endif 1459#endif
1460#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE)
1461 {
1462 I2C_BOARD_INFO("bfin-adv7393", 0x2B),
1463 },
1464#endif
1501}; 1465};
1502 1466
1503#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) 1467#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
@@ -1668,10 +1632,6 @@ static struct platform_device *stamp_devices[] __initdata = {
1668 &bfin_lq035q1_device, 1632 &bfin_lq035q1_device,
1669#endif 1633#endif
1670 1634
1671#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE)
1672 &bfin_fb_adv7393_device,
1673#endif
1674
1675#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) 1635#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
1676 &bfin_uart_device, 1636 &bfin_uart_device,
1677#endif 1637#endif
@@ -1702,8 +1662,6 @@ static struct platform_device *stamp_devices[] __initdata = {
1702 &bfin_device_gpiokeys, 1662 &bfin_device_gpiokeys,
1703#endif 1663#endif
1704 1664
1705 &bfin_gpios_device,
1706
1707#if defined(CONFIG_MTD_NAND_PLATFORM) || defined(CONFIG_MTD_NAND_PLATFORM_MODULE) 1665#if defined(CONFIG_MTD_NAND_PLATFORM) || defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
1708 &bfin_async_nand_device, 1666 &bfin_async_nand_device,
1709#endif 1667#endif
diff --git a/arch/blackfin/mach-bf537/boards/tcm_bf537.c b/arch/blackfin/mach-bf537/boards/tcm_bf537.c
index 61353f7bcb9e..57163b65a4f5 100644
--- a/arch/blackfin/mach-bf537/boards/tcm_bf537.c
+++ b/arch/blackfin/mach-bf537/boards/tcm_bf537.c
@@ -1,31 +1,10 @@
1/* 1/*
2 * File: arch/blackfin/mach-bf537/boards/tcm_bf537.c 2 * Copyright 2004-2009 Analog Devices Inc.
3 * Based on: arch/blackfin/mach-bf533/boards/cm_bf537.c 3 * 2008-2009 Bluetechnix
4 * Author: Aidan Williams <aidan@nicta.com.au> 4 * 2005 National ICT Australia (NICTA)
5 * Aidan Williams <aidan@nicta.com.au>
5 * 6 *
6 * Created: 2005 7 * Licensed under the GPL-2 or later.
7 * Description: Board description file
8 *
9 * Modified:
10 * Copyright 2005 National ICT Australia (NICTA)
11 * Copyright 2004-2006 Analog Devices Inc.
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, see the file COPYING, or write
27 * to the Free Software Foundation, Inc.,
28 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 */ 8 */
30 9
31#include <linux/device.h> 10#include <linux/device.h>
@@ -298,19 +277,6 @@ static struct platform_device net2272_bfin_device = {
298}; 277};
299#endif 278#endif
300 279
301static struct resource bfin_gpios_resources = {
302 .start = 0,
303 .end = MAX_BLACKFIN_GPIOS - 1,
304 .flags = IORESOURCE_IRQ,
305};
306
307static struct platform_device bfin_gpios_device = {
308 .name = "simple-gpio",
309 .id = -1,
310 .num_resources = 1,
311 .resource = &bfin_gpios_resources,
312};
313
314#if defined(CONFIG_MTD_GPIO_ADDR) || defined(CONFIG_MTD_GPIO_ADDR_MODULE) 280#if defined(CONFIG_MTD_GPIO_ADDR) || defined(CONFIG_MTD_GPIO_ADDR_MODULE)
315static struct mtd_partition cm_partitions[] = { 281static struct mtd_partition cm_partitions[] = {
316 { 282 {
@@ -607,8 +573,6 @@ static struct platform_device *cm_bf537_devices[] __initdata = {
607#if defined(CONFIG_MTD_GPIO_ADDR) || defined(CONFIG_MTD_GPIO_ADDR_MODULE) 573#if defined(CONFIG_MTD_GPIO_ADDR) || defined(CONFIG_MTD_GPIO_ADDR_MODULE)
608 &cm_flash_device, 574 &cm_flash_device,
609#endif 575#endif
610
611 &bfin_gpios_device,
612}; 576};
613 577
614static int __init tcm_bf537_init(void) 578static int __init tcm_bf537_init(void)
diff --git a/arch/blackfin/mach-bf537/dma.c b/arch/blackfin/mach-bf537/dma.c
index d23fc0edf2b9..5c8c4ed517bb 100644
--- a/arch/blackfin/mach-bf537/dma.c
+++ b/arch/blackfin/mach-bf537/dma.c
@@ -1,31 +1,11 @@
1/* 1/*
2 * File: arch/blackfin/mach-bf537/dma.c 2 * Copyright 2007-2009 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the GPL-2 or later.
7 * Description: This file contains the simple DMA Implementation for Blackfin
8 * 5 *
9 * Modified: 6 * This file contains the simple DMA Implementation for Blackfin
10 * Copyright 2004-2007 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 7 */
8
29#include <linux/module.h> 9#include <linux/module.h>
30 10
31#include <asm/blackfin.h> 11#include <asm/blackfin.h>
diff --git a/arch/blackfin/mach-bf537/include/mach/bf537.h b/arch/blackfin/mach-bf537/include/mach/bf537.h
index f194a848ae8e..17fab4474669 100644
--- a/arch/blackfin/mach-bf537/include/mach/bf537.h
+++ b/arch/blackfin/mach-bf537/include/mach/bf537.h
@@ -1,30 +1,9 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf537/bf537.h 2 * System MMR Register and memory map for ADSP-BF537
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Copyright 2005-2008 Analog Devices Inc.
7 * Description: SYSTEM MMR REGISTER AND MEMORY MAP FOR ADSP-BF537
8 * 5 *
9 * Modified: 6 * Licensed under the GPL-2 or later.
10 * Copyright 2004-2006 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 7 */
29 8
30#ifndef __MACH_BF537_H__ 9#ifndef __MACH_BF537_H__
diff --git a/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h
index e95d54f9af6c..635c91c526a3 100644
--- a/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h
@@ -1,32 +1,7 @@
1/* 1/*
2 * file: include/asm-blackfin/mach-bf537/bfin_serial_5xx.h 2 * Copyright 2006-2009 Analog Devices Inc.
3 * based on:
4 * author:
5 * 3 *
6 * created: 4 * Licensed under the GPL-2 or later
7 * description:
8 * blackfin serial driver header files
9 * rev:
10 *
11 * modified:
12 *
13 *
14 * bugs: enter bugs at http://blackfin.uclinux.org/
15 *
16 * this program is free software; you can redistribute it and/or modify
17 * it under the terms of the gnu general public license as published by
18 * the free software foundation; either version 2, or (at your option)
19 * any later version.
20 *
21 * this program is distributed in the hope that it will be useful,
22 * but without any warranty; without even the implied warranty of
23 * merchantability or fitness for a particular purpose. see the
24 * gnu general public license for more details.
25 *
26 * you should have received a copy of the gnu general public license
27 * along with this program; see the file copying.
28 * if not, write to the free software foundation,
29 * 59 temple place - suite 330, boston, ma 02111-1307, usa.
30 */ 5 */
31 6
32#include <linux/serial.h> 7#include <linux/serial.h>
diff --git a/arch/blackfin/mach-bf537/include/mach/blackfin.h b/arch/blackfin/mach-bf537/include/mach/blackfin.h
index 9ee8834c8f1a..eab006d260c5 100644
--- a/arch/blackfin/mach-bf537/include/mach/blackfin.h
+++ b/arch/blackfin/mach-bf537/include/mach/blackfin.h
@@ -1,32 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf537/blackfin.h 2 * Copyright 2005-2009 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the GPL-2 or later
7 * Description:
8 *
9 * Rev:
10 *
11 * Modified:
12 *
13 *
14 * Bugs: Enter bugs at http://blackfin.uclinux.org/
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2, or (at your option)
19 * any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; see the file COPYING.
28 * If not, write to the Free Software Foundation,
29 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 */ 5 */
31 6
32#ifndef _MACH_BLACKFIN_H_ 7#ifndef _MACH_BLACKFIN_H_
diff --git a/arch/blackfin/mach-bf537/include/mach/cdefBF534.h b/arch/blackfin/mach-bf537/include/mach/cdefBF534.h
index 5f8b5f845be6..91825c9bd226 100644
--- a/arch/blackfin/mach-bf537/include/mach/cdefBF534.h
+++ b/arch/blackfin/mach-bf537/include/mach/cdefBF534.h
@@ -1,32 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf537/cdefbf534.h 2 * Copyright 2005-2008 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the GPL-2 or later
7 * Description: system mmr register map
8 *
9 * Rev:
10 *
11 * Modified:
12 *
13 *
14 * Bugs: Enter bugs at http://blackfin.uclinux.org/
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2, or (at your option)
19 * any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; see the file COPYING.
28 * If not, write to the Free Software Foundation,
29 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 */ 5 */
31 6
32#ifndef _CDEF_BF534_H 7#ifndef _CDEF_BF534_H
diff --git a/arch/blackfin/mach-bf537/include/mach/cdefBF537.h b/arch/blackfin/mach-bf537/include/mach/cdefBF537.h
index b8fc949a991f..9363c3990421 100644
--- a/arch/blackfin/mach-bf537/include/mach/cdefBF537.h
+++ b/arch/blackfin/mach-bf537/include/mach/cdefBF537.h
@@ -1,32 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf537/cdefBF537.h 2 * Copyright 2005-2008 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the GPL-2 or later
7 * Description:
8 * System MMR Register Map
9 * Rev:
10 *
11 * Modified:
12 *
13 *
14 * Bugs: Enter bugs at http://blackfin.uclinux.org/
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2, or (at your option)
19 * any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; see the file COPYING.
28 * If not, write to the Free Software Foundation,
29 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 */ 5 */
31 6
32#ifndef _CDEF_BF537_H 7#ifndef _CDEF_BF537_H
diff --git a/arch/blackfin/mach-bf537/include/mach/defBF534.h b/arch/blackfin/mach-bf537/include/mach/defBF534.h
index a3227f9003ff..cebb14feb1ba 100644
--- a/arch/blackfin/mach-bf537/include/mach/defBF534.h
+++ b/arch/blackfin/mach-bf537/include/mach/defBF534.h
@@ -1,31 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf537/cdefBF537.h 2 * Copyright 2005-2008 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the ADI BSD license or the GPL-2 (or later)
7 * Description:
8 *
9 * Rev:
10 *
11 * Modified:
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2, or (at your option)
18 * any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; see the file COPYING.
27 * If not, write to the Free Software Foundation,
28 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 */ 5 */
30 6
31#ifndef _DEF_BF534_H 7#ifndef _DEF_BF534_H
diff --git a/arch/blackfin/mach-bf537/include/mach/defBF537.h b/arch/blackfin/mach-bf537/include/mach/defBF537.h
index 3d6c83e31b1e..8cb5d5cf0c94 100644
--- a/arch/blackfin/mach-bf537/include/mach/defBF537.h
+++ b/arch/blackfin/mach-bf537/include/mach/defBF537.h
@@ -1,32 +1,7 @@
1/* 1/*
2 * file: include/asm-blackfin/mach-bf537/defbf537.h 2 * Copyright 2005-2008 Analog Devices Inc.
3 * based on:
4 * author:
5 * 3 *
6 * created: 4 * Licensed under the ADI BSD license or the GPL-2 (or later)
7 * description:
8 * system mmr register map
9 * rev:
10 *
11 * modified:
12 *
13 *
14 * bugs: enter bugs at http://blackfin.uclinux.org/
15 *
16 * this program is free software; you can redistribute it and/or modify
17 * it under the terms of the gnu general public license as published by
18 * the free software foundation; either version 2, or (at your option)
19 * any later version.
20 *
21 * this program is distributed in the hope that it will be useful,
22 * but without any warranty; without even the implied warranty of
23 * merchantability or fitness for a particular purpose. see the
24 * gnu general public license for more details.
25 *
26 * you should have received a copy of the gnu general public license
27 * along with this program; see the file copying.
28 * if not, write to the free software foundation,
29 * 59 temple place - suite 330, boston, ma 02111-1307, usa.
30 */ 5 */
31 6
32#ifndef _DEF_BF537_H 7#ifndef _DEF_BF537_H
diff --git a/arch/blackfin/mach-bf537/include/mach/gpio.h b/arch/blackfin/mach-bf537/include/mach/gpio.h
index d77a31e45a30..104bff85290d 100644
--- a/arch/blackfin/mach-bf537/include/mach/gpio.h
+++ b/arch/blackfin/mach-bf537/include/mach/gpio.h
@@ -1,7 +1,4 @@
1/* 1/*
2 * File: arch/blackfin/mach-bf537/include/mach/gpio.h
3 * Bugs: Enter bugs at http://blackfin.uclinux.org/
4 *
5 * Copyright (C) 2008 Analog Devices Inc. 2 * Copyright (C) 2008 Analog Devices Inc.
6 * Licensed under the GPL-2 or later. 3 * Licensed under the GPL-2 or later.
7 */ 4 */
diff --git a/arch/blackfin/mach-bf537/include/mach/irq.h b/arch/blackfin/mach-bf537/include/mach/irq.h
index b2a71d5d4e5f..0defa9457e7f 100644
--- a/arch/blackfin/mach-bf537/include/mach/irq.h
+++ b/arch/blackfin/mach-bf537/include/mach/irq.h
@@ -1,32 +1,7 @@
1/* 1/*
2 * file: include/asm-blackfin/mach-bf537/irq.h 2 * Copyright 2005-2008 Analog Devices Inc.
3 * based on:
4 * author:
5 * 3 *
6 * created: 4 * Licensed under the GPL-2 or later
7 * description:
8 * system mmr register map
9 * rev:
10 *
11 * modified:
12 *
13 *
14 * bugs: enter bugs at http://blackfin.uclinux.org/
15 *
16 * this program is free software; you can redistribute it and/or modify
17 * it under the terms of the gnu general public license as published by
18 * the free software foundation; either version 2, or (at your option)
19 * any later version.
20 *
21 * this program is distributed in the hope that it will be useful,
22 * but without any warranty; without even the implied warranty of
23 * merchantability or fitness for a particular purpose. see the
24 * gnu general public license for more details.
25 *
26 * you should have received a copy of the gnu general public license
27 * along with this program; see the file copying.
28 * if not, write to the free software foundation,
29 * 59 temple place - suite 330, boston, ma 02111-1307, usa.
30 */ 5 */
31 6
32#ifndef _BF537_IRQ_H_ 7#ifndef _BF537_IRQ_H_
diff --git a/arch/blackfin/mach-bf537/include/mach/portmux.h b/arch/blackfin/mach-bf537/include/mach/portmux.h
index 87285e75e903..da9760329e49 100644
--- a/arch/blackfin/mach-bf537/include/mach/portmux.h
+++ b/arch/blackfin/mach-bf537/include/mach/portmux.h
@@ -1,3 +1,9 @@
1/*
2 * Copyright 2007-2009 Analog Devices Inc.
3 *
4 * Licensed under the GPL-2 or later
5 */
6
1#ifndef _MACH_PORTMUX_H_ 7#ifndef _MACH_PORTMUX_H_
2#define _MACH_PORTMUX_H_ 8#define _MACH_PORTMUX_H_
3 9
diff --git a/arch/blackfin/mach-bf537/ints-priority.c b/arch/blackfin/mach-bf537/ints-priority.c
index 51c48087e03b..f6500622b35d 100644
--- a/arch/blackfin/mach-bf537/ints-priority.c
+++ b/arch/blackfin/mach-bf537/ints-priority.c
@@ -1,30 +1,9 @@
1/* 1/*
2 * File: arch/blackfin/mach-bf537/ints-priority.c 2 * Copyright 2005-2009 Analog Devices Inc.
3 * Based on: arch/blackfin/mach-bf533/ints-priority.c
4 * Author: Michael Hennerich
5 * 3 *
6 * Created: 4 * Licensed under the GPL-2 or later.
7 * Description: Set up the interrupt priorities
8 * 5 *
9 * Modified: 6 * Set up the interrupt priorities
10 * Copyright 2004-2006 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 7 */
29 8
30#include <linux/module.h> 9#include <linux/module.h>
diff --git a/arch/blackfin/mach-bf538/boards/ezkit.c b/arch/blackfin/mach-bf538/boards/ezkit.c
index f2ac3b0ebf24..14af5c2088d4 100644
--- a/arch/blackfin/mach-bf538/boards/ezkit.c
+++ b/arch/blackfin/mach-bf538/boards/ezkit.c
@@ -1,31 +1,9 @@
1/* 1/*
2 * File: arch/blackfin/mach-bf538/boards/ezkit.c 2 * Copyright 2004-2009 Analog Devices Inc.
3 * Based on: arch/blackfin/mach-bf537/boards/ezkit.c 3 * 2005 National ICT Australia (NICTA)
4 * Author: Aidan Williams <aidan@nicta.com.au> 4 * Aidan Williams <aidan@nicta.com.au>
5 * 5 *
6 * Created: 6 * Licensed under the GPL-2
7 * Description:
8 *
9 * Modified:
10 * Copyright 2005 National ICT Australia (NICTA)
11 * Copyright 2004-2008 Analog Devices Inc.
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, see the file COPYING, or write
27 * to the Free Software Foundation, Inc.,
28 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 */ 7 */
30 8
31#include <linux/device.h> 9#include <linux/device.h>
@@ -237,7 +215,6 @@ static struct flash_platform_data bfin_spi_flash_data = {
237static struct bfin5xx_spi_chip spi_flash_chip_info = { 215static struct bfin5xx_spi_chip spi_flash_chip_info = {
238 .enable_dma = 0, /* use dma transfer with this chip*/ 216 .enable_dma = 0, /* use dma transfer with this chip*/
239 .bits_per_word = 8, 217 .bits_per_word = 8,
240 .cs_change_per_word = 0,
241}; 218};
242#endif 219#endif
243 220
@@ -506,19 +483,6 @@ static struct platform_device i2c_bfin_twi1_device = {
506#endif 483#endif
507#endif 484#endif
508 485
509static struct resource bfin_gpios_resources = {
510 .start = 0,
511 .end = MAX_BLACKFIN_GPIOS - 1,
512 .flags = IORESOURCE_IRQ,
513};
514
515static struct platform_device bfin_gpios_device = {
516 .name = "simple-gpio",
517 .id = -1,
518 .num_resources = 1,
519 .resource = &bfin_gpios_resources,
520};
521
522#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) 486#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
523#include <linux/gpio_keys.h> 487#include <linux/gpio_keys.h>
524 488
@@ -658,8 +622,6 @@ static struct platform_device *cm_bf538_devices[] __initdata = {
658 &bfin_device_gpiokeys, 622 &bfin_device_gpiokeys,
659#endif 623#endif
660 624
661 &bfin_gpios_device,
662
663#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) 625#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
664 &ezkit_flash_device, 626 &ezkit_flash_device,
665#endif 627#endif
diff --git a/arch/blackfin/mach-bf538/dma.c b/arch/blackfin/mach-bf538/dma.c
index d6837fbf94ea..5dc022589214 100644
--- a/arch/blackfin/mach-bf538/dma.c
+++ b/arch/blackfin/mach-bf538/dma.c
@@ -1,31 +1,11 @@
1/* 1/*
2 * File: arch/blackfin/mach-bf538/dma.c 2 * the simple DMA Implementation for Blackfin
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Copyright 2008 Analog Devices Inc.
7 * Description: This file contains the simple DMA Implementation for Blackfin
8 * 5 *
9 * Modified: 6 * Licensed under the GPL-2 or later.
10 * Copyright 2008 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 7 */
8
29#include <linux/module.h> 9#include <linux/module.h>
30 10
31#include <asm/blackfin.h> 11#include <asm/blackfin.h>
diff --git a/arch/blackfin/mach-bf538/include/mach/bf538.h b/arch/blackfin/mach-bf538/include/mach/bf538.h
index 9c8abb307908..0cf5bf8dab84 100644
--- a/arch/blackfin/mach-bf538/include/mach/bf538.h
+++ b/arch/blackfin/mach-bf538/include/mach/bf538.h
@@ -1,30 +1,9 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf538/bf538.h 2 * SYSTEM MMR REGISTER AND MEMORY MAP FOR ADSP-BF538
3 * Based on: include/asm-blackfin/mach-bf537/bf537.h
4 * Author: Michael Hennerich (michael.hennerich@analog.com)
5 * 3 *
6 * Created: 4 * Copyright 2008 Analog Devices Inc.
7 * Description: SYSTEM MMR REGISTER AND MEMORY MAP FOR ADSP-BF527
8 * 5 *
9 * Modified: 6 * Licensed under the GPL-2 or later.
10 * Copyright 2004-2007 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 7 */
29 8
30#ifndef __MACH_BF538_H__ 9#ifndef __MACH_BF538_H__
diff --git a/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h
index 999f239fe1a6..5c148142f041 100644
--- a/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h
@@ -1,32 +1,7 @@
1/* 1/*
2 * file: include/asm-blackfin/mach-bf538/bfin_serial_5xx.h 2 * Copyright 2008-2009 Analog Devices Inc.
3 * based on:
4 * author:
5 * 3 *
6 * created: 4 * Licensed under the GPL-2 or later.
7 * description:
8 * blackfin serial driver header files
9 * rev:
10 *
11 * modified:
12 *
13 *
14 * bugs: enter bugs at http://blackfin.uclinux.org/
15 *
16 * this program is free software; you can redistribute it and/or modify
17 * it under the terms of the gnu general public license as published by
18 * the free software foundation; either version 2, or (at your option)
19 * any later version.
20 *
21 * this program is distributed in the hope that it will be useful,
22 * but without any warranty; without even the implied warranty of
23 * merchantability or fitness for a particular purpose. see the
24 * gnu general public license for more details.
25 *
26 * you should have received a copy of the gnu general public license
27 * along with this program; see the file copying.
28 * if not, write to the free software foundation,
29 * 59 temple place - suite 330, boston, ma 02111-1307, usa.
30 */ 5 */
31 6
32#include <linux/serial.h> 7#include <linux/serial.h>
diff --git a/arch/blackfin/mach-bf538/include/mach/blackfin.h b/arch/blackfin/mach-bf538/include/mach/blackfin.h
index 5ecee1690957..278e8942eef2 100644
--- a/arch/blackfin/mach-bf538/include/mach/blackfin.h
+++ b/arch/blackfin/mach-bf538/include/mach/blackfin.h
@@ -1,32 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf538/blackfin.h 2 * Copyright 2008-2009 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the GPL-2 or later.
7 * Description:
8 *
9 * Rev:
10 *
11 * Modified:
12 *
13 *
14 * Bugs: Enter bugs at http://blackfin.uclinux.org/
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2, or (at your option)
19 * any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; see the file COPYING.
28 * If not, write to the Free Software Foundation,
29 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 */ 5 */
31 6
32#ifndef _MACH_BLACKFIN_H_ 7#ifndef _MACH_BLACKFIN_H_
diff --git a/arch/blackfin/mach-bf538/include/mach/cdefBF538.h b/arch/blackfin/mach-bf538/include/mach/cdefBF538.h
index 1de67515dc9d..401ebd79d0aa 100644
--- a/arch/blackfin/mach-bf538/include/mach/cdefBF538.h
+++ b/arch/blackfin/mach-bf538/include/mach/cdefBF538.h
@@ -1,31 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf538/cdefBF538.h 2 * Copyright 2008-2009 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the GPL-2 or later.
7 * Description:
8 *
9 * Rev:
10 *
11 * Modified:
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2, or (at your option)
18 * any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; see the file COPYING.
27 * If not, write to the Free Software Foundation,
28 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 */ 5 */
30 6
31#ifndef _CDEF_BF538_H 7#ifndef _CDEF_BF538_H
diff --git a/arch/blackfin/mach-bf538/include/mach/defBF539.h b/arch/blackfin/mach-bf538/include/mach/defBF539.h
index 1c58914a8740..5f6c34dfd08e 100644
--- a/arch/blackfin/mach-bf538/include/mach/defBF539.h
+++ b/arch/blackfin/mach-bf538/include/mach/defBF539.h
@@ -1,47 +1,9 @@
1/************************************************************************
2 *
3 * This file is subject to the terms and conditions of the GNU Public
4 * License. See the file "COPYING" in the main directory of this archive
5 * for more details.
6 *
7 * Non-GPL License also available as part of VisualDSP++
8 * http://www.analog.com/processors/resources/crosscore/visualDspDevSoftware.html
9 *
10 * (c) Copyright 2001-2005 Analog Devices, Inc. All rights reserved
11 *
12 * This file under source code control, please send bugs or changes to:
13 * dsptools.support@analog.com
14 *
15 ************************************************************************/
16/* 1/*
17 * File: include/asm-blackfin/mach-bf538/defBF539.h 2 * Copyright 2008-2009 Analog Devices Inc.
18 * Based on:
19 * Author:
20 *
21 * Created:
22 * Description:
23 * 3 *
24 * Rev: 4 * Licensed under the ADI BSD license or the GPL-2 (or later)
25 *
26 * Modified:
27 *
28 * Bugs: Enter bugs at http://blackfin.uclinux.org/
29 *
30 * This program is free software; you can redistribute it and/or modify
31 * it under the terms of the GNU General Public License as published by
32 * the Free Software Foundation; either version 2, or (at your option)
33 * any later version.
34 *
35 * This program is distributed in the hope that it will be useful,
36 * but WITHOUT ANY WARRANTY; without even the implied warranty of
37 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38 * GNU General Public License for more details.
39 *
40 * You should have received a copy of the GNU General Public License
41 * along with this program; see the file COPYING.
42 * If not, write to the Free Software Foundation,
43 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
44 */ 5 */
6
45/* SYSTEM & MM REGISTER BIT & ADDRESS DEFINITIONS FOR ADSP-BF538/9 */ 7/* SYSTEM & MM REGISTER BIT & ADDRESS DEFINITIONS FOR ADSP-BF538/9 */
46 8
47#ifndef _DEF_BF539_H 9#ifndef _DEF_BF539_H
diff --git a/arch/blackfin/mach-bf538/include/mach/gpio.h b/arch/blackfin/mach-bf538/include/mach/gpio.h
index 30f4f723f7cc..295c78a465c2 100644
--- a/arch/blackfin/mach-bf538/include/mach/gpio.h
+++ b/arch/blackfin/mach-bf538/include/mach/gpio.h
@@ -1,7 +1,4 @@
1/* 1/*
2 * File: arch/blackfin/mach-bf538/include/mach/gpio.h
3 * Bugs: Enter bugs at http://blackfin.uclinux.org/
4 *
5 * Copyright (C) 2008 Analog Devices Inc. 2 * Copyright (C) 2008 Analog Devices Inc.
6 * Licensed under the GPL-2 or later. 3 * Licensed under the GPL-2 or later.
7 */ 4 */
diff --git a/arch/blackfin/mach-bf538/include/mach/irq.h b/arch/blackfin/mach-bf538/include/mach/irq.h
index fdc87fe2c174..a4b7fcbc556b 100644
--- a/arch/blackfin/mach-bf538/include/mach/irq.h
+++ b/arch/blackfin/mach-bf538/include/mach/irq.h
@@ -1,32 +1,7 @@
1/* 1/*
2 * file: include/asm-blackfin/mach-bf538/irq.h 2 * Copyright 2008 Analog Devices Inc.
3 * based on: include/asm-blackfin/mach-bf537/irq.h
4 * author: Michael Hennerich (michael.hennerich@analog.com)
5 * 3 *
6 * created: 4 * Licensed under the GPL-2 or later.
7 * description:
8 * system mmr register map
9 * rev:
10 *
11 * modified:
12 *
13 *
14 * bugs: enter bugs at http://blackfin.uclinux.org/
15 *
16 * this program is free software; you can redistribute it and/or modify
17 * it under the terms of the gnu general public license as published by
18 * the free software foundation; either version 2, or (at your option)
19 * any later version.
20 *
21 * this program is distributed in the hope that it will be useful,
22 * but without any warranty; without even the implied warranty of
23 * merchantability or fitness for a particular purpose. see the
24 * gnu general public license for more details.
25 *
26 * you should have received a copy of the gnu general public license
27 * along with this program; see the file copying.
28 * if not, write to the free software foundation,
29 * 59 temple place - suite 330, boston, ma 02111-1307, usa.
30 */ 5 */
31 6
32#ifndef _BF538_IRQ_H_ 7#ifndef _BF538_IRQ_H_
diff --git a/arch/blackfin/mach-bf538/include/mach/portmux.h b/arch/blackfin/mach-bf538/include/mach/portmux.h
index c8db264e3e4d..6121cf8b5872 100644
--- a/arch/blackfin/mach-bf538/include/mach/portmux.h
+++ b/arch/blackfin/mach-bf538/include/mach/portmux.h
@@ -1,3 +1,9 @@
1/*
2 * Copyright 2008-2009 Analog Devices Inc.
3 *
4 * Licensed under the GPL-2 or later.
5 */
6
1#ifndef _MACH_PORTMUX_H_ 7#ifndef _MACH_PORTMUX_H_
2#define _MACH_PORTMUX_H_ 8#define _MACH_PORTMUX_H_
3 9
diff --git a/arch/blackfin/mach-bf538/ints-priority.c b/arch/blackfin/mach-bf538/ints-priority.c
index 70d17e550e05..1fa793ced347 100644
--- a/arch/blackfin/mach-bf538/ints-priority.c
+++ b/arch/blackfin/mach-bf538/ints-priority.c
@@ -1,30 +1,9 @@
1/* 1/*
2 * File: arch/blackfin/mach-bf538/ints-priority.c 2 * Set up the interrupt priorities
3 * Based on: arch/blackfin/mach-bf533/ints-priority.c
4 * Author: Michael Hennerich
5 * 3 *
6 * Created: 4 * Copyright 2008 Analog Devices Inc.
7 * Description: Set up the interrupt priorities
8 * 5 *
9 * Modified: 6 * Licensed under the GPL-2 or later.
10 * Copyright 2008 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 7 */
29 8
30#include <linux/module.h> 9#include <linux/module.h>
diff --git a/arch/blackfin/mach-bf548/boards/cm_bf548.c b/arch/blackfin/mach-bf548/boards/cm_bf548.c
index e565aae11d72..ccdcd6da2e9f 100644
--- a/arch/blackfin/mach-bf548/boards/cm_bf548.c
+++ b/arch/blackfin/mach-bf548/boards/cm_bf548.c
@@ -1,31 +1,10 @@
1/* 1/*
2 * File: arch/blackfin/mach-bf548/boards/cm_bf548.c 2 * Copyright 2004-2009 Analog Devices Inc.
3 * Based on: arch/blackfin/mach-bf537/boards/ezkit.c 3 * 2008-2009 Bluetechnix
4 * Author: Aidan Williams <aidan@nicta.com.au> 4 * 2005 National ICT Australia (NICTA)
5 * Aidan Williams <aidan@nicta.com.au>
5 * 6 *
6 * Created: 7 * Licensed under the GPL-2 or later.
7 * Description:
8 *
9 * Modified:
10 * Copyright 2005 National ICT Australia (NICTA)
11 * Copyright 2004-2008 Analog Devices Inc.
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, see the file COPYING, or write
27 * to the Free Software Foundation, Inc.,
28 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 */ 8 */
30 9
31#include <linux/device.h> 10#include <linux/device.h>
@@ -380,19 +359,6 @@ static struct platform_device musb_device = {
380}; 359};
381#endif 360#endif
382 361
383static struct resource bfin_gpios_resources = {
384 .start = 0,
385 .end = MAX_BLACKFIN_GPIOS - 1,
386 .flags = IORESOURCE_IRQ,
387};
388
389static struct platform_device bfin_gpios_device = {
390 .name = "simple-gpio",
391 .id = -1,
392 .num_resources = 1,
393 .resource = &bfin_gpios_resources,
394};
395
396#if defined(CONFIG_PATA_BF54X) || defined(CONFIG_PATA_BF54X_MODULE) 362#if defined(CONFIG_PATA_BF54X) || defined(CONFIG_PATA_BF54X_MODULE)
397static struct resource bfin_atapi_resources[] = { 363static struct resource bfin_atapi_resources[] = {
398 { 364 {
@@ -546,13 +512,11 @@ static struct flash_platform_data bfin_spi_flash_data = {
546static struct bfin5xx_spi_chip spi_flash_chip_info = { 512static struct bfin5xx_spi_chip spi_flash_chip_info = {
547 .enable_dma = 0, /* use dma transfer with this chip*/ 513 .enable_dma = 0, /* use dma transfer with this chip*/
548 .bits_per_word = 8, 514 .bits_per_word = 8,
549 .cs_change_per_word = 0,
550}; 515};
551#endif 516#endif
552 517
553#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) 518#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
554static struct bfin5xx_spi_chip spi_ad7877_chip_info = { 519static struct bfin5xx_spi_chip spi_ad7877_chip_info = {
555 .cs_change_per_word = 0,
556 .enable_dma = 0, 520 .enable_dma = 0,
557 .bits_per_word = 16, 521 .bits_per_word = 16,
558}; 522};
@@ -853,8 +817,6 @@ static struct platform_device *cm_bf548_devices[] __initdata = {
853#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) 817#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
854 &para_flash_device, 818 &para_flash_device,
855#endif 819#endif
856
857 &bfin_gpios_device,
858}; 820};
859 821
860static int __init cm_bf548_init(void) 822static int __init cm_bf548_init(void)
diff --git a/arch/blackfin/mach-bf548/boards/ezkit.c b/arch/blackfin/mach-bf548/boards/ezkit.c
index c66f3801274f..1a5286bbb3fa 100644
--- a/arch/blackfin/mach-bf548/boards/ezkit.c
+++ b/arch/blackfin/mach-bf548/boards/ezkit.c
@@ -1,31 +1,9 @@
1/* 1/*
2 * File: arch/blackfin/mach-bf548/boards/ezkit.c 2 * Copyright 2004-2009 Analog Devices Inc.
3 * Based on: arch/blackfin/mach-bf537/boards/ezkit.c 3 * 2005 National ICT Australia (NICTA)
4 * Author: Aidan Williams <aidan@nicta.com.au> 4 * Aidan Williams <aidan@nicta.com.au>
5 * 5 *
6 * Created: 6 * Licensed under the GPL-2 or later.
7 * Description:
8 *
9 * Modified:
10 * Copyright 2005 National ICT Australia (NICTA)
11 * Copyright 2004-2007 Analog Devices Inc.
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, see the file COPYING, or write
27 * to the Free Software Foundation, Inc.,
28 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 */ 7 */
30 8
31#include <linux/device.h> 9#include <linux/device.h>
@@ -208,7 +186,6 @@ static struct platform_device bfin_rotary_device = {
208#endif 186#endif
209 187
210#if defined(CONFIG_INPUT_ADXL34X) || defined(CONFIG_INPUT_ADXL34X_MODULE) 188#if defined(CONFIG_INPUT_ADXL34X) || defined(CONFIG_INPUT_ADXL34X_MODULE)
211#include <linux/input.h>
212#include <linux/spi/adxl34x.h> 189#include <linux/spi/adxl34x.h>
213static const struct adxl34x_platform_data adxl34x_info = { 190static const struct adxl34x_platform_data adxl34x_info = {
214 .x_axis_offset = 0, 191 .x_axis_offset = 0,
@@ -636,7 +613,6 @@ static struct flash_platform_data bfin_spi_flash_data = {
636static struct bfin5xx_spi_chip spi_flash_chip_info = { 613static struct bfin5xx_spi_chip spi_flash_chip_info = {
637 .enable_dma = 0, /* use dma transfer with this chip*/ 614 .enable_dma = 0, /* use dma transfer with this chip*/
638 .bits_per_word = 8, 615 .bits_per_word = 8,
639 .cs_change_per_word = 0,
640}; 616};
641#endif 617#endif
642 618
@@ -650,7 +626,6 @@ static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
650 626
651#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE) 627#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
652static struct bfin5xx_spi_chip spi_ad7877_chip_info = { 628static struct bfin5xx_spi_chip spi_ad7877_chip_info = {
653 .cs_change_per_word = 0,
654 .enable_dma = 0, 629 .enable_dma = 0,
655 .bits_per_word = 16, 630 .bits_per_word = 16,
656}; 631};
@@ -681,7 +656,6 @@ static struct bfin5xx_spi_chip spidev_chip_info = {
681static struct bfin5xx_spi_chip spi_adxl34x_chip_info = { 656static struct bfin5xx_spi_chip spi_adxl34x_chip_info = {
682 .enable_dma = 0, /* use dma transfer with this chip*/ 657 .enable_dma = 0, /* use dma transfer with this chip*/
683 .bits_per_word = 8, 658 .bits_per_word = 8,
684 .cs_change_per_word = 0,
685}; 659};
686#endif 660#endif
687 661
@@ -908,19 +882,6 @@ static struct platform_device bfin_device_gpiokeys = {
908}; 882};
909#endif 883#endif
910 884
911static struct resource bfin_gpios_resources = {
912 .start = 0,
913 .end = MAX_BLACKFIN_GPIOS - 1,
914 .flags = IORESOURCE_IRQ,
915};
916
917static struct platform_device bfin_gpios_device = {
918 .name = "simple-gpio",
919 .id = -1,
920 .num_resources = 1,
921 .resource = &bfin_gpios_resources,
922};
923
924static const unsigned int cclk_vlev_datasheet[] = 885static const unsigned int cclk_vlev_datasheet[] =
925{ 886{
926/* 887/*
@@ -1028,8 +989,6 @@ static struct platform_device *ezkit_devices[] __initdata = {
1028 &bfin_device_gpiokeys, 989 &bfin_device_gpiokeys,
1029#endif 990#endif
1030 991
1031 &bfin_gpios_device,
1032
1033#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) 992#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
1034 &ezkit_flash_device, 993 &ezkit_flash_device,
1035#endif 994#endif
diff --git a/arch/blackfin/mach-bf548/dma.c b/arch/blackfin/mach-bf548/dma.c
index d9239bc05dd4..039a6d9d38f3 100644
--- a/arch/blackfin/mach-bf548/dma.c
+++ b/arch/blackfin/mach-bf548/dma.c
@@ -1,30 +1,9 @@
1/* 1/*
2 * File: arch/blackfin/mach-bf548/dma.c 2 * the simple DMA Implementation for Blackfin
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Copyright 2007-2009 Analog Devices Inc.
7 * Description: This file contains the simple DMA Implementation for Blackfin
8 * 5 *
9 * Modified: 6 * Licensed under the GPL-2 or later.
10 * Copyright 2004-2008 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 7 */
29 8
30#include <linux/module.h> 9#include <linux/module.h>
diff --git a/arch/blackfin/mach-bf548/include/mach/bf548.h b/arch/blackfin/mach-bf548/include/mach/bf548.h
index cd31f72bdd82..7bead5ce0f3b 100644
--- a/arch/blackfin/mach-bf548/include/mach/bf548.h
+++ b/arch/blackfin/mach-bf548/include/mach/bf548.h
@@ -1,30 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf548/bf548.h 2 * Copyright 2007-2009 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the GPL-2 or later.
7 * Description: System MMR register and memory map for ADSP-BF548
8 *
9 * Modified:
10 * Copyright 2004-2007 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 5 */
29 6
30#ifndef __MACH_BF548_H__ 7#ifndef __MACH_BF548_H__
diff --git a/arch/blackfin/mach-bf548/include/mach/bf54x-lq043.h b/arch/blackfin/mach-bf548/include/mach/bf54x-lq043.h
index 9c7ca62a45eb..8821efe57fbc 100644
--- a/arch/blackfin/mach-bf548/include/mach/bf54x-lq043.h
+++ b/arch/blackfin/mach-bf548/include/mach/bf54x-lq043.h
@@ -1,3 +1,9 @@
1/*
2 * Copyright 2007-2008 Analog Devices Inc.
3 *
4 * Licensed under the GPL-2 or later.
5 */
6
1#ifndef BF54X_LQ043_H 7#ifndef BF54X_LQ043_H
2#define BF54X_LQ043_H 8#define BF54X_LQ043_H
3 9
diff --git a/arch/blackfin/mach-bf548/include/mach/bf54x_keys.h b/arch/blackfin/mach-bf548/include/mach/bf54x_keys.h
index 1fb4ec77cc25..49338ae299ab 100644
--- a/arch/blackfin/mach-bf548/include/mach/bf54x_keys.h
+++ b/arch/blackfin/mach-bf548/include/mach/bf54x_keys.h
@@ -1,3 +1,9 @@
1/*
2 * Copyright 2007-2008 Analog Devices Inc.
3 *
4 * Licensed under the GPL-2 or later.
5 */
6
1#ifndef _BFIN_KPAD_H 7#ifndef _BFIN_KPAD_H
2#define _BFIN_KPAD_H 8#define _BFIN_KPAD_H
3 9
diff --git a/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h
index 2d1b5fa3cca0..dd44aa75fe72 100644
--- a/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h
@@ -1,32 +1,7 @@
1/* 1/*
2 * file: include/asm-blackfin/mach-bf548/bfin_serial_5xx.h 2 * Copyright 2007-2009 Analog Devices Inc.
3 * based on:
4 * author:
5 * 3 *
6 * created: 4 * Licensed under the GPL-2 or later.
7 * description:
8 * blackfin serial driver head file
9 * rev:
10 *
11 * modified:
12 *
13 *
14 * bugs: enter bugs at http://blackfin.uclinux.org/
15 *
16 * this program is free software; you can redistribute it and/or modify
17 * it under the terms of the gnu general public license as published by
18 * the free software foundation; either version 2, or (at your option)
19 * any later version.
20 *
21 * this program is distributed in the hope that it will be useful,
22 * but without any warranty; without even the implied warranty of
23 * merchantability or fitness for a particular purpose. see the
24 * gnu general public license for more details.
25 *
26 * you should have received a copy of the gnu general public license
27 * along with this program; see the file copying.
28 * if not, write to the free software foundation,
29 * 59 temple place - suite 330, boston, ma 02111-1307, usa.
30 */ 5 */
31 6
32#include <linux/serial.h> 7#include <linux/serial.h>
diff --git a/arch/blackfin/mach-bf548/include/mach/blackfin.h b/arch/blackfin/mach-bf548/include/mach/blackfin.h
index 318667b2f036..13302b67857a 100644
--- a/arch/blackfin/mach-bf548/include/mach/blackfin.h
+++ b/arch/blackfin/mach-bf548/include/mach/blackfin.h
@@ -1,32 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf548/blackfin.h 2 * Copyright 2007-2009 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the GPL-2 or later.
7 * Description:
8 *
9 * Rev:
10 *
11 * Modified:
12 *
13 *
14 * Bugs: Enter bugs at http://blackfin.uclinux.org/
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2, or (at your option)
19 * any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; see the file COPYING.
28 * If not, write to the Free Software Foundation,
29 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 */ 5 */
31 6
32#ifndef _MACH_BLACKFIN_H_ 7#ifndef _MACH_BLACKFIN_H_
diff --git a/arch/blackfin/mach-bf548/include/mach/cdefBF542.h b/arch/blackfin/mach-bf548/include/mach/cdefBF542.h
index 07aefb9ed79b..42f4a9469549 100644
--- a/arch/blackfin/mach-bf548/include/mach/cdefBF542.h
+++ b/arch/blackfin/mach-bf548/include/mach/cdefBF542.h
@@ -1,31 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf548/cdefBF542.h 2 * Copyright 2007-2008 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the GPL-2 or later.
7 * Description:
8 *
9 * Rev:
10 *
11 * Modified:
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2, or (at your option)
18 * any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; see the file COPYING.
27 * If not, write to the Free Software Foundation,
28 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 */ 5 */
30 6
31#ifndef _CDEF_BF542_H 7#ifndef _CDEF_BF542_H
diff --git a/arch/blackfin/mach-bf548/include/mach/cdefBF544.h b/arch/blackfin/mach-bf548/include/mach/cdefBF544.h
index 431a69278991..2207799575ff 100644
--- a/arch/blackfin/mach-bf548/include/mach/cdefBF544.h
+++ b/arch/blackfin/mach-bf548/include/mach/cdefBF544.h
@@ -1,31 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf548/cdefBF544.h 2 * Copyright 2007-2008 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the GPL-2 or later.
7 * Description:
8 *
9 * Rev:
10 *
11 * Modified:
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2, or (at your option)
18 * any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; see the file COPYING.
27 * If not, write to the Free Software Foundation,
28 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 */ 5 */
30 6
31#ifndef _CDEF_BF544_H 7#ifndef _CDEF_BF544_H
diff --git a/arch/blackfin/mach-bf548/include/mach/cdefBF547.h b/arch/blackfin/mach-bf548/include/mach/cdefBF547.h
index 93376e90dfc5..423421515134 100644
--- a/arch/blackfin/mach-bf548/include/mach/cdefBF547.h
+++ b/arch/blackfin/mach-bf548/include/mach/cdefBF547.h
@@ -1,31 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf548/cdefBF547.h 2 * Copyright 2008 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the GPL-2 or later.
7 * Description:
8 *
9 * Rev:
10 *
11 * Modified:
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2, or (at your option)
18 * any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; see the file COPYING.
27 * If not, write to the Free Software Foundation,
28 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 */ 5 */
30 6
31#ifndef _CDEF_BF548_H 7#ifndef _CDEF_BF548_H
diff --git a/arch/blackfin/mach-bf548/include/mach/cdefBF548.h b/arch/blackfin/mach-bf548/include/mach/cdefBF548.h
index 9cd74384136f..df84180410c4 100644
--- a/arch/blackfin/mach-bf548/include/mach/cdefBF548.h
+++ b/arch/blackfin/mach-bf548/include/mach/cdefBF548.h
@@ -1,31 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf548/cdefBF548.h 2 * Copyright 2007-2008 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the GPL-2 or later.
7 * Description:
8 *
9 * Rev:
10 *
11 * Modified:
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2, or (at your option)
18 * any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; see the file COPYING.
27 * If not, write to the Free Software Foundation,
28 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 */ 5 */
30 6
31#ifndef _CDEF_BF548_H 7#ifndef _CDEF_BF548_H
diff --git a/arch/blackfin/mach-bf548/include/mach/cdefBF549.h b/arch/blackfin/mach-bf548/include/mach/cdefBF549.h
index ead360b69dea..34c84c7fb256 100644
--- a/arch/blackfin/mach-bf548/include/mach/cdefBF549.h
+++ b/arch/blackfin/mach-bf548/include/mach/cdefBF549.h
@@ -1,31 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf549/cdefBF549.h 2 * Copyright 2007-2008 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the GPL-2 or later.
7 * Description:
8 *
9 * Rev:
10 *
11 * Modified:
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2, or (at your option)
18 * any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; see the file COPYING.
27 * If not, write to the Free Software Foundation,
28 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 */ 5 */
30 6
31#ifndef _CDEF_BF549_H 7#ifndef _CDEF_BF549_H
diff --git a/arch/blackfin/mach-bf548/include/mach/cdefBF54x_base.h b/arch/blackfin/mach-bf548/include/mach/cdefBF54x_base.h
index 6e636c418cb0..a2e9d9849eba 100644
--- a/arch/blackfin/mach-bf548/include/mach/cdefBF54x_base.h
+++ b/arch/blackfin/mach-bf548/include/mach/cdefBF54x_base.h
@@ -1,31 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf548/cdefBF54x_base.h 2 * Copyright 2007-2008 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the GPL-2 or later.
7 * Description:
8 *
9 * Rev:
10 *
11 * Modified:
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2, or (at your option)
18 * any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; see the file COPYING.
27 * If not, write to the Free Software Foundation,
28 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 */ 5 */
30 6
31#ifndef _CDEF_BF54X_H 7#ifndef _CDEF_BF54X_H
diff --git a/arch/blackfin/mach-bf548/include/mach/defBF542.h b/arch/blackfin/mach-bf548/include/mach/defBF542.h
index b1316541b8d6..d3bc6d1df547 100644
--- a/arch/blackfin/mach-bf548/include/mach/defBF542.h
+++ b/arch/blackfin/mach-bf548/include/mach/defBF542.h
@@ -1,31 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf548/defBF542.h 2 * Copyright 2007-2008 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the ADI BSD license or the GPL-2 (or later)
7 * Description:
8 *
9 * Rev:
10 *
11 * Modified:
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2, or (at your option)
18 * any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; see the file COPYING.
27 * If not, write to the Free Software Foundation,
28 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 */ 5 */
30 6
31#ifndef _DEF_BF542_H 7#ifndef _DEF_BF542_H
diff --git a/arch/blackfin/mach-bf548/include/mach/defBF544.h b/arch/blackfin/mach-bf548/include/mach/defBF544.h
index c2c785bdc5fc..dd414ae4ba4c 100644
--- a/arch/blackfin/mach-bf548/include/mach/defBF544.h
+++ b/arch/blackfin/mach-bf548/include/mach/defBF544.h
@@ -1,31 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf548/defBF544.h 2 * Copyright 2007-2008 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the ADI BSD license or the GPL-2 (or later)
7 * Description:
8 *
9 * Rev:
10 *
11 * Modified:
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2, or (at your option)
18 * any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; see the file COPYING.
27 * If not, write to the Free Software Foundation,
28 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 */ 5 */
30 6
31#ifndef _DEF_BF544_H 7#ifndef _DEF_BF544_H
diff --git a/arch/blackfin/mach-bf548/include/mach/defBF547.h b/arch/blackfin/mach-bf548/include/mach/defBF547.h
index 661f0d877bd1..5a9dbabe0a68 100644
--- a/arch/blackfin/mach-bf548/include/mach/defBF547.h
+++ b/arch/blackfin/mach-bf548/include/mach/defBF547.h
@@ -1,31 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf548/defBF547.h 2 * Copyright 2008 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the ADI BSD license or the GPL-2 (or later)
7 * Description:
8 *
9 * Rev:
10 *
11 * Modified:
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2, or (at your option)
18 * any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; see the file COPYING.
27 * If not, write to the Free Software Foundation,
28 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 */ 5 */
30 6
31#ifndef _DEF_BF548_H 7#ifndef _DEF_BF548_H
diff --git a/arch/blackfin/mach-bf548/include/mach/defBF548.h b/arch/blackfin/mach-bf548/include/mach/defBF548.h
index 85d4bade911d..82cd593f7391 100644
--- a/arch/blackfin/mach-bf548/include/mach/defBF548.h
+++ b/arch/blackfin/mach-bf548/include/mach/defBF548.h
@@ -1,31 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf548/defBF548.h 2 * Copyright 2007-2008 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the ADI BSD license or the GPL-2 (or later)
7 * Description:
8 *
9 * Rev:
10 *
11 * Modified:
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2, or (at your option)
18 * any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; see the file COPYING.
27 * If not, write to the Free Software Foundation,
28 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 */ 5 */
30 6
31#ifndef _DEF_BF548_H 7#ifndef _DEF_BF548_H
diff --git a/arch/blackfin/mach-bf548/include/mach/defBF549.h b/arch/blackfin/mach-bf548/include/mach/defBF549.h
index 096734541644..6fc6e39ab61b 100644
--- a/arch/blackfin/mach-bf548/include/mach/defBF549.h
+++ b/arch/blackfin/mach-bf548/include/mach/defBF549.h
@@ -1,31 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf548/defBF549.h 2 * Copyright 2007-2008 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the ADI BSD license or the GPL-2 (or later)
7 * Description:
8 *
9 * Rev:
10 *
11 * Modified:
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2, or (at your option)
18 * any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; see the file COPYING.
27 * If not, write to the Free Software Foundation,
28 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 */ 5 */
30 6
31#ifndef _DEF_BF549_H 7#ifndef _DEF_BF549_H
diff --git a/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h b/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h
index e022e896cb18..8590c8c78336 100644
--- a/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h
+++ b/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h
@@ -1,31 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf548/defBF54x_base.h 2 * Copyright 2007-2008 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the ADI BSD license or the GPL-2 (or later)
7 * Description:
8 *
9 * Rev:
10 *
11 * Modified:
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2, or (at your option)
18 * any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; see the file COPYING.
27 * If not, write to the Free Software Foundation,
28 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 */ 5 */
30 6
31#ifndef _DEF_BF54X_H 7#ifndef _DEF_BF54X_H
diff --git a/arch/blackfin/mach-bf548/include/mach/gpio.h b/arch/blackfin/mach-bf548/include/mach/gpio.h
index 3a2051709787..850e39d193e3 100644
--- a/arch/blackfin/mach-bf548/include/mach/gpio.h
+++ b/arch/blackfin/mach-bf548/include/mach/gpio.h
@@ -1,34 +1,8 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf548/gpio.h 2 * Copyright 2007-2009 Analog Devices Inc.
3 * Based on: 3 * Licensed under the GPL-2 or later.
4 * Author: Michael Hennerich (hennerich@blackfin.uclinux.org)
5 *
6 * Created:
7 * Description:
8 *
9 * Modified:
10 * Copyright 2004-2007 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 4 */
29 5
30
31
32#define GPIO_PA0 0 6#define GPIO_PA0 0
33#define GPIO_PA1 1 7#define GPIO_PA1 1
34#define GPIO_PA2 2 8#define GPIO_PA2 2
diff --git a/arch/blackfin/mach-bf548/include/mach/irq.h b/arch/blackfin/mach-bf548/include/mach/irq.h
index f194625f6821..106db05684ae 100644
--- a/arch/blackfin/mach-bf548/include/mach/irq.h
+++ b/arch/blackfin/mach-bf548/include/mach/irq.h
@@ -1,32 +1,7 @@
1/* 1/*
2 * file: include/asm-blackfin/mach-bf548/irq.h 2 * Copyright 2007-2009 Analog Devices Inc.
3 * based on: include/asm-blackfin/mach-bf537/irq.h
4 * author: Roy Huang (roy.huang@analog.com)
5 * 3 *
6 * created: 4 * Licensed under the GPL-2 or later.
7 * description:
8 * system mmr register map
9 * rev:
10 *
11 * modified:
12 *
13 *
14 * bugs: enter bugs at http://blackfin.uclinux.org/
15 *
16 * this program is free software; you can redistribute it and/or modify
17 * it under the terms of the gnu general public license as published by
18 * the free software foundation; either version 2, or (at your option)
19 * any later version.
20 *
21 * this program is distributed in the hope that it will be useful,
22 * but without any warranty; without even the implied warranty of
23 * merchantability or fitness for a particular purpose. see the
24 * gnu general public license for more details.
25 *
26 * you should have received a copy of the gnu general public license
27 * along with this program; see the file copying.
28 * if not, write to the free software foundation,
29 * 59 temple place - suite 330, boston, ma 02111-1307, usa.
30 */ 5 */
31 6
32#ifndef _BF548_IRQ_H_ 7#ifndef _BF548_IRQ_H_
diff --git a/arch/blackfin/mach-bf548/include/mach/portmux.h b/arch/blackfin/mach-bf548/include/mach/portmux.h
index ce372ba0f046..89ad6a886362 100644
--- a/arch/blackfin/mach-bf548/include/mach/portmux.h
+++ b/arch/blackfin/mach-bf548/include/mach/portmux.h
@@ -1,3 +1,9 @@
1/*
2 * Copyright 2007-2009 Analog Devices Inc.
3 *
4 * Licensed under the GPL-2 or later.
5 */
6
1#ifndef _MACH_PORTMUX_H_ 7#ifndef _MACH_PORTMUX_H_
2#define _MACH_PORTMUX_H_ 8#define _MACH_PORTMUX_H_
3 9
diff --git a/arch/blackfin/mach-bf548/ints-priority.c b/arch/blackfin/mach-bf548/ints-priority.c
index 9dd0fa3ac4de..48dd3a4bc4a5 100644
--- a/arch/blackfin/mach-bf548/ints-priority.c
+++ b/arch/blackfin/mach-bf548/ints-priority.c
@@ -1,30 +1,9 @@
1/* 1/*
2 * File: arch/blackfin/mach-bf537/ints-priority.c 2 * Copyright 2007-2008 Analog Devices Inc.
3 * Based on: arch/blackfin/mach-bf533/ints-priority.c
4 * Author: Michael Hennerich
5 * 3 *
6 * Created: 4 * Licensed under the GPL-2 or later.
7 * Description: Set up the interrupt priorities
8 * 5 *
9 * Modified: 6 * Set up the interrupt priorities
10 * Copyright 2004-2006 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 7 */
29 8
30#include <linux/module.h> 9#include <linux/module.h>
diff --git a/arch/blackfin/mach-bf561/atomic.S b/arch/blackfin/mach-bf561/atomic.S
index 9439bc6bd01f..0261a5e751b3 100644
--- a/arch/blackfin/mach-bf561/atomic.S
+++ b/arch/blackfin/mach-bf561/atomic.S
@@ -1,23 +1,8 @@
1/* 1/*
2 * File: arch/blackfin/mach-bf561/atomic.S 2 * Copyright 2007-2008 Analog Devices Inc.
3 * Author: Philippe Gerum <rpm@xenomai.org> 3 * Philippe Gerum <rpm@xenomai.org>
4 * 4 *
5 * Copyright 2007 Analog Devices Inc. 5 * Licensed under the GPL-2 or later.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see the file COPYING, or write
19 * to the Free Software Foundation, Inc.,
20 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 */ 6 */
22 7
23#include <linux/linkage.h> 8#include <linux/linkage.h>
diff --git a/arch/blackfin/mach-bf561/boards/cm_bf561.c b/arch/blackfin/mach-bf561/boards/cm_bf561.c
index 6577ecfcf11e..dfc8d5b77986 100644
--- a/arch/blackfin/mach-bf561/boards/cm_bf561.c
+++ b/arch/blackfin/mach-bf561/boards/cm_bf561.c
@@ -1,30 +1,10 @@
1/* 1/*
2 * File: arch/blackfin/mach-bf533/boards/cm_bf561.c 2 * Copyright 2004-2009 Analog Devices Inc.
3 * Based on: arch/blackfin/mach-bf533/boards/ezkit.c 3 * 2008-2009 Bluetechnix
4 * Author: Aidan Williams <aidan@nicta.com.au> Copyright 2005 4 * 2005 National ICT Australia (NICTA)
5 * Aidan Williams <aidan@nicta.com.au>
5 * 6 *
6 * Created: 2006 7 * Licensed under the GPL-2 or later.
7 * Description: Board description file
8 *
9 * Modified:
10 * Copyright 2004-2006 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 8 */
29 9
30#include <linux/device.h> 10#include <linux/device.h>
@@ -285,19 +265,6 @@ static struct platform_device net2272_bfin_device = {
285}; 265};
286#endif 266#endif
287 267
288static struct resource bfin_gpios_resources = {
289 .start = 0,
290 .end = MAX_BLACKFIN_GPIOS - 1,
291 .flags = IORESOURCE_IRQ,
292};
293
294static struct platform_device bfin_gpios_device = {
295 .name = "simple-gpio",
296 .id = -1,
297 .num_resources = 1,
298 .resource = &bfin_gpios_resources,
299};
300
301#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE) 268#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
302static struct resource isp1362_hcd_resources[] = { 269static struct resource isp1362_hcd_resources[] = {
303 { 270 {
@@ -532,8 +499,6 @@ static struct platform_device *cm_bf561_devices[] __initdata = {
532#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) 499#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
533 &para_flash_device, 500 &para_flash_device,
534#endif 501#endif
535
536 &bfin_gpios_device,
537}; 502};
538 503
539static int __init cm_bf561_init(void) 504static int __init cm_bf561_init(void)
diff --git a/arch/blackfin/mach-bf561/boards/ezkit.c b/arch/blackfin/mach-bf561/boards/ezkit.c
index caed96bb957e..9e2d8cfba546 100644
--- a/arch/blackfin/mach-bf561/boards/ezkit.c
+++ b/arch/blackfin/mach-bf561/boards/ezkit.c
@@ -1,30 +1,9 @@
1/* 1/*
2 * File: arch/blackfin/mach-bf561/ezkit.c 2 * Copyright 2004-2009 Analog Devices Inc.
3 * Based on: 3 * 2005 National ICT Australia (NICTA)
4 * Author: 4 * Aidan Williams <aidan@nicta.com.au>
5 * 5 *
6 * Created: 6 * Licensed under the GPL-2 or later.
7 * Description:
8 *
9 * Modified:
10 * Copyright 2004-2006 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 7 */
29 8
30#include <linux/device.h> 9#include <linux/device.h>
@@ -387,19 +366,6 @@ static struct platform_device bfin_device_gpiokeys = {
387}; 366};
388#endif 367#endif
389 368
390static struct resource bfin_gpios_resources = {
391 .start = 0,
392 .end = MAX_BLACKFIN_GPIOS - 1,
393 .flags = IORESOURCE_IRQ,
394};
395
396static struct platform_device bfin_gpios_device = {
397 .name = "simple-gpio",
398 .id = -1,
399 .num_resources = 1,
400 .resource = &bfin_gpios_resources,
401};
402
403#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE) 369#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
404#include <linux/i2c-gpio.h> 370#include <linux/i2c-gpio.h>
405 371
@@ -493,8 +459,6 @@ static struct platform_device *ezkit_devices[] __initdata = {
493 &isp1362_hcd_device, 459 &isp1362_hcd_device,
494#endif 460#endif
495 461
496 &bfin_gpios_device,
497
498#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE) 462#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
499 &ezkit_flash_device, 463 &ezkit_flash_device,
500#endif 464#endif
diff --git a/arch/blackfin/mach-bf561/boards/tepla.c b/arch/blackfin/mach-bf561/boards/tepla.c
index 6f77dbe952f5..8ba7252455e1 100644
--- a/arch/blackfin/mach-bf561/boards/tepla.c
+++ b/arch/blackfin/mach-bf561/boards/tepla.c
@@ -1,15 +1,13 @@
1/* 1/*
2 * File: arch/blackfin/mach-bf561/tepla.c 2 * Copyright 2004-2007 Analog Devices Inc.
3 * 2005 National ICT Australia (NICTA)
4 * Aidan Williams <aidan@nicta.com.au>
3 * 5 *
4 * Copyright 2004-2007 Analog Devices Inc. 6 * Thanks to Jamey Hicks.
5 * Only SMSC91C1111 was registered, may do more later.
6 * 7 *
7 * Copyright 2005 National ICT Australia (NICTA), Aidan Williams <aidan@nicta.com.au> 8 * Only SMSC91C1111 was registered, may do more later.
8 * Thanks to Jamey Hicks.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * Licensed under the GPL-2
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */ 11 */
14 12
15#include <linux/device.h> 13#include <linux/device.h>
diff --git a/arch/blackfin/mach-bf561/coreb.c b/arch/blackfin/mach-bf561/coreb.c
index 93635a766f9c..1e60a92dd602 100644
--- a/arch/blackfin/mach-bf561/coreb.c
+++ b/arch/blackfin/mach-bf561/coreb.c
@@ -48,7 +48,7 @@ coreb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned l
48 return ret; 48 return ret;
49} 49}
50 50
51static struct file_operations coreb_fops = { 51static const struct file_operations coreb_fops = {
52 .owner = THIS_MODULE, 52 .owner = THIS_MODULE,
53 .ioctl = coreb_ioctl, 53 .ioctl = coreb_ioctl,
54}; 54};
diff --git a/arch/blackfin/mach-bf561/dma.c b/arch/blackfin/mach-bf561/dma.c
index 42b0037afe61..c938c3c7355d 100644
--- a/arch/blackfin/mach-bf561/dma.c
+++ b/arch/blackfin/mach-bf561/dma.c
@@ -1,31 +1,11 @@
1/* 1/*
2 * File: arch/blackfin/mach-bf561/dma.c 2 * the simple DMA Implementation for Blackfin
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Copyright 2007-2008 Analog Devices Inc.
7 * Description: This file contains the simple DMA Implementation for Blackfin
8 * 5 *
9 * Modified: 6 * Licensed under the GPL-2 or later.
10 * Copyright 2004-2007 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 7 */
8
29#include <linux/module.h> 9#include <linux/module.h>
30 10
31#include <asm/blackfin.h> 11#include <asm/blackfin.h>
diff --git a/arch/blackfin/mach-bf561/include/mach/bf561.h b/arch/blackfin/mach-bf561/include/mach/bf561.h
index 9968362a2ee4..9f9a367e6a24 100644
--- a/arch/blackfin/mach-bf561/include/mach/bf561.h
+++ b/arch/blackfin/mach-bf561/include/mach/bf561.h
@@ -1,30 +1,9 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf561/bf561.h 2 * SYSTEM MMR REGISTER AND MEMORY MAP FOR ADSP-BF561
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Copyright 2005-2008 Analog Devices Inc.
7 * Description: SYSTEM MMR REGISTER AND MEMORY MAP FOR ADSP-BF561
8 * 5 *
9 * Modified: 6 * Licensed under the GPL-2 or later.
10 * Copyright 2004-2006 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 7 */
29 8
30#ifndef __MACH_BF561_H__ 9#ifndef __MACH_BF561_H__
diff --git a/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h
index fd5e8878b8c4..e33e158bc16d 100644
--- a/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h
@@ -1,32 +1,7 @@
1/* 1/*
2 * file: include/asm-blackfin/mach-bf561/bfin_serial_5xx.h 2 * Copyright 2006-2009 Analog Devices Inc.
3 * based on:
4 * author:
5 * 3 *
6 * created: 4 * Licensed under the GPL-2 or later.
7 * description:
8 * blackfin serial driver head file
9 * rev:
10 *
11 * modified:
12 *
13 *
14 * bugs: enter bugs at http://blackfin.uclinux.org/
15 *
16 * this program is free software; you can redistribute it and/or modify
17 * it under the terms of the gnu general public license as published by
18 * the free software foundation; either version 2, or (at your option)
19 * any later version.
20 *
21 * this program is distributed in the hope that it will be useful,
22 * but without any warranty; without even the implied warranty of
23 * merchantability or fitness for a particular purpose. see the
24 * gnu general public license for more details.
25 *
26 * you should have received a copy of the gnu general public license
27 * along with this program; see the file copying.
28 * if not, write to the free software foundation,
29 * 59 temple place - suite 330, boston, ma 02111-1307, usa.
30 */ 5 */
31 6
32#include <linux/serial.h> 7#include <linux/serial.h>
diff --git a/arch/blackfin/mach-bf561/include/mach/blackfin.h b/arch/blackfin/mach-bf561/include/mach/blackfin.h
index 8be31358ef88..67d6bdcd3fa8 100644
--- a/arch/blackfin/mach-bf561/include/mach/blackfin.h
+++ b/arch/blackfin/mach-bf561/include/mach/blackfin.h
@@ -1,31 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf561/blackfin.h 2 * Copyright 2005-2009 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the GPL-2 or later.
7 * Description:
8 *
9 * Rev:
10 *
11 * Modified:
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2, or (at your option)
18 * any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; see the file COPYING.
27 * If not, write to the Free Software Foundation,
28 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 */ 5 */
30 6
31#ifndef _MACH_BLACKFIN_H_ 7#ifndef _MACH_BLACKFIN_H_
diff --git a/arch/blackfin/mach-bf561/include/mach/cdefBF561.h b/arch/blackfin/mach-bf561/include/mach/cdefBF561.h
index 9d9858c2be68..81ecdb71c6af 100644
--- a/arch/blackfin/mach-bf561/include/mach/cdefBF561.h
+++ b/arch/blackfin/mach-bf561/include/mach/cdefBF561.h
@@ -1,31 +1,7 @@
1/* 1/*
2 * File: include/asm-blackfin/mach-bf561/cdefBF561.h 2 * Copyright 2005-2009 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the GPL-2 or later.
7 * Description: C POINTERS TO SYSTEM MMR REGISTER AND MEMORY MAP FOR ADSP-BF561
8 *
9 * Rev:
10 *
11 * Modified:
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2, or (at your option)
18 * any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; see the file COPYING.
27 * If not, write to the Free Software Foundation,
28 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 */ 5 */
30 6
31#ifndef _CDEF_BF561_H 7#ifndef _CDEF_BF561_H
diff --git a/arch/blackfin/mach-bf561/include/mach/defBF561.h b/arch/blackfin/mach-bf561/include/mach/defBF561.h
index 5fc0f05026e0..a31e509553fb 100644
--- a/arch/blackfin/mach-bf561/include/mach/defBF561.h
+++ b/arch/blackfin/mach-bf561/include/mach/defBF561.h
@@ -1,32 +1,7 @@
1
2/* 1/*
3 * File: include/asm-blackfin/mach-bf561/defBF561.h 2 * Copyright 2005-2009 Analog Devices Inc.
4 * Based on:
5 * Author:
6 *
7 * Created:
8 * Description:
9 * SYSTEM MMR REGISTER AND MEMORY MAP FOR ADSP-BF561
10 * Rev:
11 *
12 * Modified:
13 *
14 * Bugs: Enter bugs at http://blackfin.uclinux.org/
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2, or (at your option)
19 * any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 * 3 *
26 * You should have received a copy of the GNU General Public License 4 * Licensed under the ADI BSD license or the GPL-2 (or later)
27 * along with this program; see the file COPYING.
28 * If not, write to the Free Software Foundation,
29 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 */ 5 */
31 6
32#ifndef _DEF_BF561_H 7#ifndef _DEF_BF561_H
diff --git a/arch/blackfin/mach-bf561/include/mach/gpio.h b/arch/blackfin/mach-bf561/include/mach/gpio.h
index 7882f79e1ade..a651a8cf805f 100644
--- a/arch/blackfin/mach-bf561/include/mach/gpio.h
+++ b/arch/blackfin/mach-bf561/include/mach/gpio.h
@@ -1,7 +1,4 @@
1/* 1/*
2 * File: arch/blackfin/mach-bf561/include/mach/gpio.h
3 * Bugs: Enter bugs at http://blackfin.uclinux.org/
4 *
5 * Copyright (C) 2008 Analog Devices Inc. 2 * Copyright (C) 2008 Analog Devices Inc.
6 * Licensed under the GPL-2 or later. 3 * Licensed under the GPL-2 or later.
7 */ 4 */
diff --git a/arch/blackfin/mach-bf561/include/mach/irq.h b/arch/blackfin/mach-bf561/include/mach/irq.h
index 6698389c5564..7b208db267bf 100644
--- a/arch/blackfin/mach-bf561/include/mach/irq.h
+++ b/arch/blackfin/mach-bf561/include/mach/irq.h
@@ -1,32 +1,7 @@
1
2/* 1/*
3 * File: include/asm-blackfin/mach-bf561/irq.h 2 * Copyright 2005-2008 Analog Devices Inc.
4 * Based on:
5 * Author:
6 *
7 * Created:
8 * Description:
9 *
10 * Rev:
11 *
12 * Modified:
13 *
14 * Bugs: Enter bugs at http://blackfin.uclinux.org/
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2, or (at your option)
19 * any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 * 3 *
26 * You should have received a copy of the GNU General Public License 4 * Licensed under the GPL-2 or later.
27 * along with this program; see the file COPYING.
28 * If not, write to the Free Software Foundation,
29 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 */ 5 */
31 6
32#ifndef _BF561_IRQ_H_ 7#ifndef _BF561_IRQ_H_
diff --git a/arch/blackfin/mach-bf561/include/mach/portmux.h b/arch/blackfin/mach-bf561/include/mach/portmux.h
index 2e5ad6347dea..3a7b46bbe849 100644
--- a/arch/blackfin/mach-bf561/include/mach/portmux.h
+++ b/arch/blackfin/mach-bf561/include/mach/portmux.h
@@ -1,3 +1,9 @@
1/*
2 * Copyright 2007-2009 Analog Devices Inc.
3 *
4 * Licensed under the GPL-2 or later.
5 */
6
1#ifndef _MACH_PORTMUX_H_ 7#ifndef _MACH_PORTMUX_H_
2#define _MACH_PORTMUX_H_ 8#define _MACH_PORTMUX_H_
3 9
diff --git a/arch/blackfin/mach-bf561/include/mach/smp.h b/arch/blackfin/mach-bf561/include/mach/smp.h
index f9e65ebe81b2..390c7f4ae7b3 100644
--- a/arch/blackfin/mach-bf561/include/mach/smp.h
+++ b/arch/blackfin/mach-bf561/include/mach/smp.h
@@ -1,3 +1,9 @@
1/*
2 * Copyright 2007-2008 Analog Devices Inc.
3 *
4 * Licensed under the GPL-2 or later.
5 */
6
1#ifndef _MACH_BF561_SMP 7#ifndef _MACH_BF561_SMP
2#define _MACH_BF561_SMP 8#define _MACH_BF561_SMP
3 9
diff --git a/arch/blackfin/mach-bf561/ints-priority.c b/arch/blackfin/mach-bf561/ints-priority.c
index 9d2f23344720..b4424172ad9e 100644
--- a/arch/blackfin/mach-bf561/ints-priority.c
+++ b/arch/blackfin/mach-bf561/ints-priority.c
@@ -1,30 +1,9 @@
1/* 1/*
2 * File: arch/blackfin/mach-bf561/ints-priority.c 2 * Set up the interrupt priorities
3 * Based on: arch/blackfin/mach-bf537/ints-priority.c
4 * Author: Michael Hennerich
5 * 3 *
6 * Created: 4 * Copyright 2005-2009 Analog Devices Inc.
7 * Description: Set up the interrupt priorities
8 * 5 *
9 * Modified: 6 * Licensed under the GPL-2 or later.
10 * Copyright 2004-2006 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 7 */
29 8
30#include <linux/module.h> 9#include <linux/module.h>
diff --git a/arch/blackfin/mach-bf561/secondary.S b/arch/blackfin/mach-bf561/secondary.S
index f72a6af20c4f..8e6050369c06 100644
--- a/arch/blackfin/mach-bf561/secondary.S
+++ b/arch/blackfin/mach-bf561/secondary.S
@@ -1,26 +1,10 @@
1/* 1/*
2 * File: arch/blackfin/mach-bf561/secondary.S 2 * BF561 coreB bootstrap file
3 * Based on: arch/blackfin/mach-bf561/head.S
4 * Author: Philippe Gerum <rpm@xenomai.org>
5 * 3 *
6 * Copyright 2007 Analog Devices Inc. 4 * Copyright 2007-2009 Analog Devices Inc.
5 * Philippe Gerum <rpm@xenomai.org>
7 * 6 *
8 * Description: BF561 coreB bootstrap file 7 * Licensed under the GPL-2 or later.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see the file COPYING, or write
22 * to the Free Software Foundation, Inc.,
23 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 */ 8 */
25 9
26#include <linux/linkage.h> 10#include <linux/linkage.h>
diff --git a/arch/blackfin/mach-bf561/smp.c b/arch/blackfin/mach-bf561/smp.c
index 8c10701c251f..510f57641495 100644
--- a/arch/blackfin/mach-bf561/smp.c
+++ b/arch/blackfin/mach-bf561/smp.c
@@ -1,23 +1,8 @@
1/* 1/*
2 * File: arch/blackfin/mach-bf561/smp.c 2 * Copyright 2007-2009 Analog Devices Inc.
3 * Author: Philippe Gerum <rpm@xenomai.org> 3 * Philippe Gerum <rpm@xenomai.org>
4 * 4 *
5 * Copyright 2007 Analog Devices Inc. 5 * Licensed under the GPL-2 or later.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see the file COPYING, or write
19 * to the Free Software Foundation, Inc.,
20 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 */ 6 */
22 7
23#include <linux/init.h> 8#include <linux/init.h>
diff --git a/arch/blackfin/mach-common/arch_checks.c b/arch/blackfin/mach-common/arch_checks.c
index 5998d8632a73..9dbafcdcf479 100644
--- a/arch/blackfin/mach-common/arch_checks.c
+++ b/arch/blackfin/mach-common/arch_checks.c
@@ -1,30 +1,9 @@
1/* 1/*
2 * File: arch/blackfin/mach-common/arch_checks.c 2 * Do some checking to make sure things are OK
3 * Based on:
4 * Author: Robin Getz <rgetz@blackfin.uclinux.org>
5 * 3 *
6 * Created: 25Jul07 4 * Copyright 2007-2009 Analog Devices Inc.
7 * Description: Do some checking to make sure things are OK
8 * 5 *
9 * Modified: 6 * Licensed under the GPL-2 or later.
10 * Copyright 2004-2007 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 7 */
29 8
30#include <asm/fixed_code.h> 9#include <asm/fixed_code.h>
diff --git a/arch/blackfin/mach-common/cache-c.c b/arch/blackfin/mach-common/cache-c.c
index 4ebbd78db3a4..a60a24f5035d 100644
--- a/arch/blackfin/mach-common/cache-c.c
+++ b/arch/blackfin/mach-common/cache-c.c
@@ -3,8 +3,6 @@
3 * 3 *
4 * Copyright 2004-2009 Analog Devices Inc. 4 * Copyright 2004-2009 Analog Devices Inc.
5 * 5 *
6 * Enter bugs at http://blackfin.uclinux.org/
7 *
8 * Licensed under the GPL-2 or later. 6 * Licensed under the GPL-2 or later.
9 */ 7 */
10 8
diff --git a/arch/blackfin/mach-common/cache.S b/arch/blackfin/mach-common/cache.S
index d9666fe6c3d6..ea540318a228 100644
--- a/arch/blackfin/mach-common/cache.S
+++ b/arch/blackfin/mach-common/cache.S
@@ -3,8 +3,6 @@
3 * 3 *
4 * Copyright 2004-2008 Analog Devices Inc. 4 * Copyright 2004-2008 Analog Devices Inc.
5 * 5 *
6 * Enter bugs at http://blackfin.uclinux.org/
7 *
8 * Licensed under the GPL-2 or later. 6 * Licensed under the GPL-2 or later.
9 */ 7 */
10 8
diff --git a/arch/blackfin/mach-common/cpufreq.c b/arch/blackfin/mach-common/cpufreq.c
index 85c658083279..01506504e6d0 100644
--- a/arch/blackfin/mach-common/cpufreq.c
+++ b/arch/blackfin/mach-common/cpufreq.c
@@ -1,30 +1,9 @@
1/* 1/*
2 * File: arch/blackfin/mach-common/cpufreq.c 2 * Blackfin core clock scaling
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Copyright 2008-2009 Analog Devices Inc.
7 * Description: Blackfin core clock scaling
8 * 5 *
9 * Modified: 6 * Licensed under the GPL-2 or later.
10 * Copyright 2004-2008 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 7 */
29 8
30#include <linux/kernel.h> 9#include <linux/kernel.h>
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S
index 1e7cac23e25f..94a0375cbdcf 100644
--- a/arch/blackfin/mach-common/entry.S
+++ b/arch/blackfin/mach-common/entry.S
@@ -1,32 +1,11 @@
1/* 1/*
2 * File: arch/blackfin/mach-common/entry.S 2 * Contains the system-call and fault low-level handling routines.
3 * Based on: 3 * This also contains the timer-interrupt handler, as well as all
4 * Author: Linus Torvalds 4 * interrupts and faults that can result in a task-switch.
5 * 5 *
6 * Created: ? 6 * Copyright 2005-2009 Analog Devices Inc.
7 * Description: contains the system-call and fault low-level handling routines.
8 * This also contains the timer-interrupt handler, as well as all
9 * interrupts and faults that can result in a task-switch.
10 * 7 *
11 * Modified: 8 * Licensed under the GPL-2 or later.
12 * Copyright 2004-2006 Analog Devices Inc.
13 *
14 * Bugs: Enter bugs at http://blackfin.uclinux.org/
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, see the file COPYING, or write
28 * to the Free Software Foundation, Inc.,
29 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
30 */ 9 */
31 10
32/* NOTE: This code handles signal-recognition, which happens every time 11/* NOTE: This code handles signal-recognition, which happens every time
diff --git a/arch/blackfin/mach-common/head.S b/arch/blackfin/mach-common/head.S
index 9c79dfea2a53..cab0a0031eee 100644
--- a/arch/blackfin/mach-common/head.S
+++ b/arch/blackfin/mach-common/head.S
@@ -3,8 +3,6 @@
3 * 3 *
4 * Copyright 2004-2008 Analog Devices Inc. 4 * Copyright 2004-2008 Analog Devices Inc.
5 * 5 *
6 * Enter bugs at http://blackfin.uclinux.org/
7 *
8 * Licensed under the GPL-2 or later. 6 * Licensed under the GPL-2 or later.
9 */ 7 */
10 8
diff --git a/arch/blackfin/mach-common/interrupt.S b/arch/blackfin/mach-common/interrupt.S
index 82d417ef4b5b..8085ff1cce00 100644
--- a/arch/blackfin/mach-common/interrupt.S
+++ b/arch/blackfin/mach-common/interrupt.S
@@ -1,31 +1,11 @@
1/* 1/*
2 * File: arch/blackfin/mach-common/interrupt.S 2 * Interrupt Entries
3 * Based on:
4 * Author: D. Jeff Dionne <jeff@ryeham.ee.ryerson.ca>
5 * Kenneth Albanowski <kjahds@kjahds.com>
6 *
7 * Created: ?
8 * Description: Interrupt Entries
9 *
10 * Modified:
11 * Copyright 2004-2006 Analog Devices Inc.
12 * 3 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/ 4 * Copyright 2005-2009 Analog Devices Inc.
14 * 5 * D. Jeff Dionne <jeff@ryeham.ee.ryerson.ca>
15 * This program is free software; you can redistribute it and/or modify 6 * Kenneth Albanowski <kjahds@kjahds.com>
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 * 7 *
25 * You should have received a copy of the GNU General Public License 8 * Licensed under the GPL-2 or later.
26 * along with this program; if not, see the file COPYING, or write
27 * to the Free Software Foundation, Inc.,
28 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 */ 9 */
30 10
31#include <asm/blackfin.h> 11#include <asm/blackfin.h>
diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c
index 6ffda78aaf9d..660ea1bec54c 100644
--- a/arch/blackfin/mach-common/ints-priority.c
+++ b/arch/blackfin/mach-common/ints-priority.c
@@ -1,33 +1,14 @@
1/* 1/*
2 * File: arch/blackfin/mach-common/ints-priority.c 2 * Set up the interrupt priorities
3 * 3 *
4 * Description: Set up the interrupt priorities 4 * Copyright 2004-2009 Analog Devices Inc.
5 * 2003 Bas Vermeulen <bas@buyways.nl>
6 * 2002 Arcturus Networks Inc. MaTed <mated@sympatico.ca>
7 * 2000-2001 Lineo, Inc. D. Jefff Dionne <jeff@lineo.ca>
8 * 1999 D. Jeff Dionne <jeff@uclinux.org>
9 * 1996 Roman Zippel
5 * 10 *
6 * Modified: 11 * Licensed under the GPL-2
7 * 1996 Roman Zippel
8 * 1999 D. Jeff Dionne <jeff@uclinux.org>
9 * 2000-2001 Lineo, Inc. D. Jefff Dionne <jeff@lineo.ca>
10 * 2002 Arcturus Networks Inc. MaTed <mated@sympatico.ca>
11 * 2003 Metrowerks/Motorola
12 * 2003 Bas Vermeulen <bas@buyways.nl>
13 * Copyright 2004-2008 Analog Devices Inc.
14 *
15 * Bugs: Enter bugs at http://blackfin.uclinux.org/
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, see the file COPYING, or write
29 * to the Free Software Foundation, Inc.,
30 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
31 */ 12 */
32 13
33#include <linux/module.h> 14#include <linux/module.h>
diff --git a/arch/blackfin/mach-common/irqpanic.c b/arch/blackfin/mach-common/irqpanic.c
index 883e3241b17e..c6496249e2bc 100644
--- a/arch/blackfin/mach-common/irqpanic.c
+++ b/arch/blackfin/mach-common/irqpanic.c
@@ -1,30 +1,9 @@
1/* 1/*
2 * File: arch/blackfin/mach-common/irqpanic.c 2 * panic kernel with dump information
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: ? 4 * Copyright 2005-2009 Analog Devices Inc.
7 * Description: panic kernel with dump information
8 * 5 *
9 * Modified: rgetz - added cache checking code 14Feb06 6 * Licensed under the GPL-2 or later.
10 * Copyright 2004-2006 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 7 */
29 8
30#include <linux/module.h> 9#include <linux/module.h>
diff --git a/arch/blackfin/mach-common/pm.c b/arch/blackfin/mach-common/pm.c
index 0e3d4ff9d8b6..8837be4edb4a 100644
--- a/arch/blackfin/mach-common/pm.c
+++ b/arch/blackfin/mach-common/pm.c
@@ -1,35 +1,11 @@
1/* 1/*
2 * File: arch/blackfin/mach-common/pm.c 2 * Blackfin power management
3 * Based on: arm/mach-omap/pm.c
4 * Author: Cliff Brake <cbrake@accelent.com> Copyright (c) 2001
5 * 3 *
6 * Created: 2001 4 * Copyright 2006-2009 Analog Devices Inc.
7 * Description: Blackfin power management
8 * 5 *
9 * Modified: Nicolas Pitre - PXA250 support 6 * Licensed under the GPL-2
10 * Copyright (c) 2002 Monta Vista Software, Inc. 7 * based on arm/mach-omap/pm.c
11 * David Singleton - OMAP1510 8 * Copyright 2001, Cliff Brake <cbrake@accelent.com> and others
12 * Copyright (c) 2002 Monta Vista Software, Inc.
13 * Dirk Behme <dirk.behme@de.bosch.com> - OMAP1510/1610
14 * Copyright 2004
15 * Copyright 2004-2008 Analog Devices Inc.
16 *
17 * Bugs: Enter bugs at http://blackfin.uclinux.org/
18 *
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation; either version 2 of the License, or
22 * (at your option) any later version.
23 *
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
28 *
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, see the file COPYING, or write
31 * to the Free Software Foundation, Inc.,
32 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
33 */ 9 */
34 10
35#include <linux/suspend.h> 11#include <linux/suspend.h>
diff --git a/arch/blackfin/mach-common/smp.c b/arch/blackfin/mach-common/smp.c
index 349ee3f5466a..d98585f3237d 100644
--- a/arch/blackfin/mach-common/smp.c
+++ b/arch/blackfin/mach-common/smp.c
@@ -1,24 +1,10 @@
1/* 1/*
2 * File: arch/blackfin/kernel/smp.c 2 * IPI management based on arch/arm/kernel/smp.c (Copyright 2002 ARM Limited)
3 * Author: Philippe Gerum <rpm@xenomai.org>
4 * IPI management based on arch/arm/kernel/smp.c.
5 * 3 *
6 * Copyright 2007 Analog Devices Inc. 4 * Copyright 2007-2009 Analog Devices Inc.
5 * Philippe Gerum <rpm@xenomai.org>
7 * 6 *
8 * This program is free software; you can redistribute it and/or modify 7 * Licensed under the GPL-2.
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, see the file COPYING, or write
20 * to the Free Software Foundation, Inc.,
21 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 */ 8 */
23 9
24#include <linux/module.h> 10#include <linux/module.h>
diff --git a/arch/blackfin/mm/blackfin_sram.h b/arch/blackfin/mm/blackfin_sram.h
index bc0062884fde..fb0b1599cfb7 100644
--- a/arch/blackfin/mm/blackfin_sram.h
+++ b/arch/blackfin/mm/blackfin_sram.h
@@ -1,30 +1,9 @@
1/* 1/*
2 * File: arch/blackfin/mm/blackfin_sram.h 2 * Local prototypes meant for internal use only
3 * Based on: arch/blackfin/mm/blackfin_sram.c
4 * Author: Mike Frysinger
5 * 3 *
6 * Created: Aug 2006 4 * Copyright 2006-2009 Analog Devices Inc.
7 * Description: Local prototypes meant for internal use only
8 * 5 *
9 * Modified: 6 * Licensed under the GPL-2 or later.
10 * Copyright 2006 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 7 */
29 8
30#ifndef __BLACKFIN_SRAM_H__ 9#ifndef __BLACKFIN_SRAM_H__
diff --git a/arch/blackfin/mm/init.c b/arch/blackfin/mm/init.c
index b88ce7fda548..bb9c98f9cb5b 100644
--- a/arch/blackfin/mm/init.c
+++ b/arch/blackfin/mm/init.c
@@ -1,30 +1,7 @@
1/* 1/*
2 * File: arch/blackfin/mm/init.c 2 * Copyright 2004-2009 Analog Devices Inc.
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Licensed under the GPL-2 or later.
7 * Description:
8 *
9 * Modified:
10 * Copyright 2004-2007 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 5 */
29 6
30#include <linux/swap.h> 7#include <linux/swap.h>
diff --git a/arch/blackfin/mm/isram-driver.c b/arch/blackfin/mm/isram-driver.c
index beb1a608824c..84cdc5a1c139 100644
--- a/arch/blackfin/mm/isram-driver.c
+++ b/arch/blackfin/mm/isram-driver.c
@@ -1,19 +1,9 @@
1/* 1/*
2 * Description: Instruction SRAM accessor functions for the Blackfin 2 * Instruction SRAM accessor functions for the Blackfin
3 * 3 *
4 * Copyright 2008 Analog Devices Inc. 4 * Copyright 2008 Analog Devices Inc.
5 * 5 *
6 * Bugs: Enter bugs at http://blackfin.uclinux.org/ 6 * Licensed under the GPL-2 or later
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, see the file COPYING, or write
15 * to the Free Software Foundation, Inc.,
16 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */ 7 */
18 8
19#define pr_fmt(fmt) "isram: " fmt 9#define pr_fmt(fmt) "isram: " fmt
diff --git a/arch/blackfin/mm/sram-alloc.c b/arch/blackfin/mm/sram-alloc.c
index eb63ab353e5a..f068c11ea98f 100644
--- a/arch/blackfin/mm/sram-alloc.c
+++ b/arch/blackfin/mm/sram-alloc.c
@@ -1,30 +1,9 @@
1/* 1/*
2 * File: arch/blackfin/mm/sram-alloc.c 2 * SRAM allocator for Blackfin on-chip memory
3 * Based on:
4 * Author:
5 * 3 *
6 * Created: 4 * Copyright 2004-2009 Analog Devices Inc.
7 * Description: SRAM allocator for Blackfin L1 and L2 memory
8 * 5 *
9 * Modified: 6 * Licensed under the GPL-2 or later.
10 * Copyright 2004-2008 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */ 7 */
29 8
30#include <linux/module.h> 9#include <linux/module.h>
diff --git a/arch/cris/arch-v10/drivers/sync_serial.c b/arch/cris/arch-v10/drivers/sync_serial.c
index 6cc1a0319a5d..562b9a7feae7 100644
--- a/arch/cris/arch-v10/drivers/sync_serial.c
+++ b/arch/cris/arch-v10/drivers/sync_serial.c
@@ -244,7 +244,7 @@ static unsigned sync_serial_prescale_shadow;
244 244
245#define NUMBER_OF_PORTS 2 245#define NUMBER_OF_PORTS 2
246 246
247static struct file_operations sync_serial_fops = { 247static const struct file_operations sync_serial_fops = {
248 .owner = THIS_MODULE, 248 .owner = THIS_MODULE,
249 .write = sync_serial_write, 249 .write = sync_serial_write,
250 .read = sync_serial_read, 250 .read = sync_serial_read,
diff --git a/arch/cris/arch-v32/drivers/mach-fs/gpio.c b/arch/cris/arch-v32/drivers/mach-fs/gpio.c
index fe1fde893887..d89ab80498ed 100644
--- a/arch/cris/arch-v32/drivers/mach-fs/gpio.c
+++ b/arch/cris/arch-v32/drivers/mach-fs/gpio.c
@@ -855,7 +855,7 @@ gpio_leds_ioctl(unsigned int cmd, unsigned long arg)
855 return 0; 855 return 0;
856} 856}
857 857
858struct file_operations gpio_fops = { 858static const struct file_operations gpio_fops = {
859 .owner = THIS_MODULE, 859 .owner = THIS_MODULE,
860 .poll = gpio_poll, 860 .poll = gpio_poll,
861 .ioctl = gpio_ioctl, 861 .ioctl = gpio_ioctl,
diff --git a/arch/m32r/include/asm/io.h b/arch/m32r/include/asm/io.h
index d06933bd6318..4010f1fc5b65 100644
--- a/arch/m32r/include/asm/io.h
+++ b/arch/m32r/include/asm/io.h
@@ -162,6 +162,13 @@ static inline void _writel(unsigned long l, unsigned long addr)
162#define __raw_writew writew 162#define __raw_writew writew
163#define __raw_writel writel 163#define __raw_writel writel
164 164
165#define ioread8 read
166#define ioread16 readw
167#define ioread32 readl
168#define iowrite8 writeb
169#define iowrite16 writew
170#define iowrite32 writel
171
165#define mmiowb() 172#define mmiowb()
166 173
167#define flush_write_buffers() do { } while (0) /* M32R_FIXME */ 174#define flush_write_buffers() do { } while (0) /* M32R_FIXME */
diff --git a/arch/m32r/kernel/m32r_ksyms.c b/arch/m32r/kernel/m32r_ksyms.c
index 22624b51d4d3..700570747a90 100644
--- a/arch/m32r/kernel/m32r_ksyms.c
+++ b/arch/m32r/kernel/m32r_ksyms.c
@@ -23,12 +23,6 @@ EXPORT_SYMBOL(__ioremap);
23EXPORT_SYMBOL(iounmap); 23EXPORT_SYMBOL(iounmap);
24EXPORT_SYMBOL(kernel_thread); 24EXPORT_SYMBOL(kernel_thread);
25 25
26/* Networking helper routines. */
27/* Delay loops */
28EXPORT_SYMBOL(__udelay);
29EXPORT_SYMBOL(__delay);
30EXPORT_SYMBOL(__const_udelay);
31
32EXPORT_SYMBOL(strncpy_from_user); 26EXPORT_SYMBOL(strncpy_from_user);
33EXPORT_SYMBOL(__strncpy_from_user); 27EXPORT_SYMBOL(__strncpy_from_user);
34EXPORT_SYMBOL(clear_user); 28EXPORT_SYMBOL(clear_user);
diff --git a/arch/m32r/kernel/smp.c b/arch/m32r/kernel/smp.c
index 1b7598e6f6e8..8a88f1f0a3e2 100644
--- a/arch/m32r/kernel/smp.c
+++ b/arch/m32r/kernel/smp.c
@@ -17,6 +17,7 @@
17 17
18#include <linux/irq.h> 18#include <linux/irq.h>
19#include <linux/interrupt.h> 19#include <linux/interrupt.h>
20#include <linux/sched.h>
20#include <linux/spinlock.h> 21#include <linux/spinlock.h>
21#include <linux/mm.h> 22#include <linux/mm.h>
22#include <linux/smp.h> 23#include <linux/smp.h>
diff --git a/arch/m32r/kernel/time.c b/arch/m32r/kernel/time.c
index ba61c4c73202..e7fee0f198d5 100644
--- a/arch/m32r/kernel/time.c
+++ b/arch/m32r/kernel/time.c
@@ -33,6 +33,15 @@
33 33
34#include <asm/hw_irq.h> 34#include <asm/hw_irq.h>
35 35
36#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE)
37/* this needs a better home */
38DEFINE_SPINLOCK(rtc_lock);
39
40#ifdef CONFIG_RTC_DRV_CMOS_MODULE
41EXPORT_SYMBOL(rtc_lock);
42#endif
43#endif /* pc-style 'CMOS' RTC support */
44
36#ifdef CONFIG_SMP 45#ifdef CONFIG_SMP
37extern void smp_local_timer_interrupt(void); 46extern void smp_local_timer_interrupt(void);
38#endif 47#endif
diff --git a/arch/m32r/kernel/traps.c b/arch/m32r/kernel/traps.c
index 03b14e55cd89..fbd109031df3 100644
--- a/arch/m32r/kernel/traps.c
+++ b/arch/m32r/kernel/traps.c
@@ -104,8 +104,8 @@ static void set_eit_vector_entries(void)
104 eit_vector[186] = (unsigned long)smp_call_function_interrupt; 104 eit_vector[186] = (unsigned long)smp_call_function_interrupt;
105 eit_vector[187] = (unsigned long)smp_ipi_timer_interrupt; 105 eit_vector[187] = (unsigned long)smp_ipi_timer_interrupt;
106 eit_vector[188] = (unsigned long)smp_flush_cache_all_interrupt; 106 eit_vector[188] = (unsigned long)smp_flush_cache_all_interrupt;
107 eit_vector[189] = (unsigned long)smp_call_function_single_interrupt; 107 eit_vector[189] = 0; /* CPU_BOOT_IPI */
108 eit_vector[190] = 0; 108 eit_vector[190] = (unsigned long)smp_call_function_single_interrupt;
109 eit_vector[191] = 0; 109 eit_vector[191] = 0;
110#endif 110#endif
111 _flush_cache_copyback_all(); 111 _flush_cache_copyback_all();
diff --git a/arch/m32r/lib/delay.c b/arch/m32r/lib/delay.c
index ced549be80f5..940f4837e42b 100644
--- a/arch/m32r/lib/delay.c
+++ b/arch/m32r/lib/delay.c
@@ -122,4 +122,8 @@ void __ndelay(unsigned long nsecs)
122{ 122{
123 __const_udelay(nsecs * 0x00005); /* 2**32 / 1000000000 (rounded up) */ 123 __const_udelay(nsecs * 0x00005); /* 2**32 / 1000000000 (rounded up) */
124} 124}
125
126EXPORT_SYMBOL(__delay);
127EXPORT_SYMBOL(__const_udelay);
128EXPORT_SYMBOL(__udelay);
125EXPORT_SYMBOL(__ndelay); 129EXPORT_SYMBOL(__ndelay);
diff --git a/arch/m32r/mm/discontig.c b/arch/m32r/mm/discontig.c
index b7a78ad429b7..5d2858f6eede 100644
--- a/arch/m32r/mm/discontig.c
+++ b/arch/m32r/mm/discontig.c
@@ -32,6 +32,9 @@ typedef struct {
32} mem_prof_t; 32} mem_prof_t;
33static mem_prof_t mem_prof[MAX_NUMNODES]; 33static mem_prof_t mem_prof[MAX_NUMNODES];
34 34
35extern unsigned long memory_start;
36extern unsigned long memory_end;
37
35static void __init mem_prof_init(void) 38static void __init mem_prof_init(void)
36{ 39{
37 unsigned long start_pfn, holes, free_pfn; 40 unsigned long start_pfn, holes, free_pfn;
@@ -42,7 +45,7 @@ static void __init mem_prof_init(void)
42 /* Node#0 SDRAM */ 45 /* Node#0 SDRAM */
43 mp = &mem_prof[0]; 46 mp = &mem_prof[0];
44 mp->start_pfn = PFN_UP(CONFIG_MEMORY_START); 47 mp->start_pfn = PFN_UP(CONFIG_MEMORY_START);
45 mp->pages = PFN_DOWN(CONFIG_MEMORY_SIZE); 48 mp->pages = PFN_DOWN(memory_end - memory_start);
46 mp->holes = 0; 49 mp->holes = 0;
47 mp->free_pfn = PFN_UP(__pa(_end)); 50 mp->free_pfn = PFN_UP(__pa(_end));
48 51
diff --git a/arch/m32r/mm/mmu.S b/arch/m32r/mm/mmu.S
index 49a6d16a3d58..e9491a5ae827 100644
--- a/arch/m32r/mm/mmu.S
+++ b/arch/m32r/mm/mmu.S
@@ -150,9 +150,13 @@ ENTRY(tme_handler)
150 150
151 ; pmd = pmd_offset(pgd, address); 151 ; pmd = pmd_offset(pgd, address);
152 ld r3, @r3 ; r3: pmd data 152 ld r3, @r3 ; r3: pmd data
153 ldi r2, #-4096
154 beqz r3, 3f ; pmd_none(*pmd) ? 153 beqz r3, 3f ; pmd_none(*pmd) ?
155 154
155 and3 r2, r3, #0xfff
156 add3 r2, r2, #-355 ; _KERNPG_TABLE(=0x163)
157 bnez r2, 3f ; pmd_bad(*pmd) ?
158 ldi r2, #-4096
159
156 ; pte = pte_offset(pmd, address); 160 ; pte = pte_offset(pmd, address);
157 and r2, r3 ; r2: pte base addr 161 and r2, r3 ; r2: pte base addr
158 srl3 r3, r0, #10 162 srl3 r3, r0, #10
@@ -263,9 +267,9 @@ ENTRY(tme_handler)
263 ld r1, @r3 ; r1: pmd 267 ld r1, @r3 ; r1: pmd
264 beqz r1, 3f ; pmd_none(*pmd) ? 268 beqz r1, 3f ; pmd_none(*pmd) ?
265; 269;
266 and3 r1, r1, #0xeff 270 and3 r1, r1, #0x3ff
267 ldi r4, #611 ; _KERNPG_TABLE(=611) 271 ldi r4, #0x163 ; _KERNPG_TABLE(=0x163)
268 bne r1, r4, 3f ; !pmd_bad(*pmd) ? 272 bne r1, r4, 3f ; pmd_bad(*pmd) ?
269 273
270 .fillinsn 274 .fillinsn
2714: 2754:
diff --git a/arch/m68k/include/asm/hardirq_mm.h b/arch/m68k/include/asm/hardirq_mm.h
index 554f65b6cd3b..394ee946015c 100644
--- a/arch/m68k/include/asm/hardirq_mm.h
+++ b/arch/m68k/include/asm/hardirq_mm.h
@@ -1,8 +1,16 @@
1#ifndef __M68K_HARDIRQ_H 1#ifndef __M68K_HARDIRQ_H
2#define __M68K_HARDIRQ_H 2#define __M68K_HARDIRQ_H
3 3
4#define HARDIRQ_BITS 8 4#include <linux/threads.h>
5#include <linux/cache.h>
6
7/* entry.S is sensitive to the offsets of these fields */
8typedef struct {
9 unsigned int __softirq_pending;
10} ____cacheline_aligned irq_cpustat_t;
5 11
6#include <asm-generic/hardirq.h> 12#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
13
14#define HARDIRQ_BITS 8
7 15
8#endif 16#endif
diff --git a/arch/m68knommu/kernel/asm-offsets.c b/arch/m68knommu/kernel/asm-offsets.c
index 594ee0e657fe..9a8876f715d8 100644
--- a/arch/m68knommu/kernel/asm-offsets.c
+++ b/arch/m68knommu/kernel/asm-offsets.c
@@ -45,25 +45,25 @@ int main(void)
45 DEFINE(THREAD_FPSTATE, offsetof(struct thread_struct, fpstate)); 45 DEFINE(THREAD_FPSTATE, offsetof(struct thread_struct, fpstate));
46 46
47 /* offsets into the pt_regs */ 47 /* offsets into the pt_regs */
48 DEFINE(PT_D0, offsetof(struct pt_regs, d0)); 48 DEFINE(PT_OFF_D0, offsetof(struct pt_regs, d0));
49 DEFINE(PT_ORIG_D0, offsetof(struct pt_regs, orig_d0)); 49 DEFINE(PT_OFF_ORIG_D0, offsetof(struct pt_regs, orig_d0));
50 DEFINE(PT_D1, offsetof(struct pt_regs, d1)); 50 DEFINE(PT_OFF_D1, offsetof(struct pt_regs, d1));
51 DEFINE(PT_D2, offsetof(struct pt_regs, d2)); 51 DEFINE(PT_OFF_D2, offsetof(struct pt_regs, d2));
52 DEFINE(PT_D3, offsetof(struct pt_regs, d3)); 52 DEFINE(PT_OFF_D3, offsetof(struct pt_regs, d3));
53 DEFINE(PT_D4, offsetof(struct pt_regs, d4)); 53 DEFINE(PT_OFF_D4, offsetof(struct pt_regs, d4));
54 DEFINE(PT_D5, offsetof(struct pt_regs, d5)); 54 DEFINE(PT_OFF_D5, offsetof(struct pt_regs, d5));
55 DEFINE(PT_A0, offsetof(struct pt_regs, a0)); 55 DEFINE(PT_OFF_A0, offsetof(struct pt_regs, a0));
56 DEFINE(PT_A1, offsetof(struct pt_regs, a1)); 56 DEFINE(PT_OFF_A1, offsetof(struct pt_regs, a1));
57 DEFINE(PT_A2, offsetof(struct pt_regs, a2)); 57 DEFINE(PT_OFF_A2, offsetof(struct pt_regs, a2));
58 DEFINE(PT_PC, offsetof(struct pt_regs, pc)); 58 DEFINE(PT_OFF_PC, offsetof(struct pt_regs, pc));
59 DEFINE(PT_SR, offsetof(struct pt_regs, sr)); 59 DEFINE(PT_OFF_SR, offsetof(struct pt_regs, sr));
60 60
61#ifdef CONFIG_COLDFIRE 61#ifdef CONFIG_COLDFIRE
62 /* bitfields are a bit difficult */ 62 /* bitfields are a bit difficult */
63 DEFINE(PT_FORMATVEC, offsetof(struct pt_regs, sr) - 2); 63 DEFINE(PT_OFF_FORMATVEC, offsetof(struct pt_regs, sr) - 2);
64#else 64#else
65 /* bitfields are a bit difficult */ 65 /* bitfields are a bit difficult */
66 DEFINE(PT_VECTOR, offsetof(struct pt_regs, pc) + 4); 66 DEFINE(PT_OFF_VECTOR, offsetof(struct pt_regs, pc) + 4);
67#endif 67#endif
68 68
69 /* signal defines */ 69 /* signal defines */
diff --git a/arch/m68knommu/kernel/entry.S b/arch/m68knommu/kernel/entry.S
index f56faa5c9cd9..56043ade3941 100644
--- a/arch/m68knommu/kernel/entry.S
+++ b/arch/m68knommu/kernel/entry.S
@@ -46,7 +46,7 @@
46ENTRY(buserr) 46ENTRY(buserr)
47 SAVE_ALL 47 SAVE_ALL
48 moveq #-1,%d0 48 moveq #-1,%d0
49 movel %d0,%sp@(PT_ORIG_D0) 49 movel %d0,%sp@(PT_OFF_ORIG_D0)
50 movel %sp,%sp@- /* stack frame pointer argument */ 50 movel %sp,%sp@- /* stack frame pointer argument */
51 jsr buserr_c 51 jsr buserr_c
52 addql #4,%sp 52 addql #4,%sp
@@ -55,7 +55,7 @@ ENTRY(buserr)
55ENTRY(trap) 55ENTRY(trap)
56 SAVE_ALL 56 SAVE_ALL
57 moveq #-1,%d0 57 moveq #-1,%d0
58 movel %d0,%sp@(PT_ORIG_D0) 58 movel %d0,%sp@(PT_OFF_ORIG_D0)
59 movel %sp,%sp@- /* stack frame pointer argument */ 59 movel %sp,%sp@- /* stack frame pointer argument */
60 jsr trap_c 60 jsr trap_c
61 addql #4,%sp 61 addql #4,%sp
@@ -67,7 +67,7 @@ ENTRY(trap)
67ENTRY(dbginterrupt) 67ENTRY(dbginterrupt)
68 SAVE_ALL 68 SAVE_ALL
69 moveq #-1,%d0 69 moveq #-1,%d0
70 movel %d0,%sp@(PT_ORIG_D0) 70 movel %d0,%sp@(PT_OFF_ORIG_D0)
71 movel %sp,%sp@- /* stack frame pointer argument */ 71 movel %sp,%sp@- /* stack frame pointer argument */
72 jsr dbginterrupt_c 72 jsr dbginterrupt_c
73 addql #4,%sp 73 addql #4,%sp
diff --git a/arch/m68knommu/mm/init.c b/arch/m68knommu/mm/init.c
index b1703c67a4f1..f3236d0b522d 100644
--- a/arch/m68knommu/mm/init.c
+++ b/arch/m68knommu/mm/init.c
@@ -162,7 +162,7 @@ void free_initrd_mem(unsigned long start, unsigned long end)
162 totalram_pages++; 162 totalram_pages++;
163 pages++; 163 pages++;
164 } 164 }
165 printk (KERN_NOTICE "Freeing initrd memory: %dk freed\n", pages); 165 printk (KERN_NOTICE "Freeing initrd memory: %dk freed\n", pages * (PAGE_SIZE / 1024));
166} 166}
167#endif 167#endif
168 168
diff --git a/arch/m68knommu/platform/5206e/config.c b/arch/m68knommu/platform/5206e/config.c
index 0f41ba82a3b5..942397984c66 100644
--- a/arch/m68knommu/platform/5206e/config.c
+++ b/arch/m68knommu/platform/5206e/config.c
@@ -17,7 +17,6 @@
17#include <asm/mcfsim.h> 17#include <asm/mcfsim.h>
18#include <asm/mcfuart.h> 18#include <asm/mcfuart.h>
19#include <asm/mcfdma.h> 19#include <asm/mcfdma.h>
20#include <asm/mcfuart.h>
21 20
22/***************************************************************************/ 21/***************************************************************************/
23 22
diff --git a/arch/m68knommu/platform/68328/entry.S b/arch/m68knommu/platform/68328/entry.S
index b1aef72f3baf..9d80d2c42866 100644
--- a/arch/m68knommu/platform/68328/entry.S
+++ b/arch/m68knommu/platform/68328/entry.S
@@ -39,17 +39,17 @@
39.globl inthandler7 39.globl inthandler7
40 40
41badsys: 41badsys:
42 movel #-ENOSYS,%sp@(PT_D0) 42 movel #-ENOSYS,%sp@(PT_OFF_D0)
43 jra ret_from_exception 43 jra ret_from_exception
44 44
45do_trace: 45do_trace:
46 movel #-ENOSYS,%sp@(PT_D0) /* needed for strace*/ 46 movel #-ENOSYS,%sp@(PT_OFF_D0) /* needed for strace*/
47 subql #4,%sp 47 subql #4,%sp
48 SAVE_SWITCH_STACK 48 SAVE_SWITCH_STACK
49 jbsr syscall_trace 49 jbsr syscall_trace
50 RESTORE_SWITCH_STACK 50 RESTORE_SWITCH_STACK
51 addql #4,%sp 51 addql #4,%sp
52 movel %sp@(PT_ORIG_D0),%d1 52 movel %sp@(PT_OFF_ORIG_D0),%d1
53 movel #-ENOSYS,%d0 53 movel #-ENOSYS,%d0
54 cmpl #NR_syscalls,%d1 54 cmpl #NR_syscalls,%d1
55 jcc 1f 55 jcc 1f
@@ -57,7 +57,7 @@ do_trace:
57 lea sys_call_table, %a0 57 lea sys_call_table, %a0
58 jbsr %a0@(%d1) 58 jbsr %a0@(%d1)
59 59
601: movel %d0,%sp@(PT_D0) /* save the return value */ 601: movel %d0,%sp@(PT_OFF_D0) /* save the return value */
61 subql #4,%sp /* dummy return address */ 61 subql #4,%sp /* dummy return address */
62 SAVE_SWITCH_STACK 62 SAVE_SWITCH_STACK
63 jbsr syscall_trace 63 jbsr syscall_trace
@@ -75,7 +75,7 @@ ENTRY(system_call)
75 jbsr set_esp0 75 jbsr set_esp0
76 addql #4,%sp 76 addql #4,%sp
77 77
78 movel %sp@(PT_ORIG_D0),%d0 78 movel %sp@(PT_OFF_ORIG_D0),%d0
79 79
80 movel %sp,%d1 /* get thread_info pointer */ 80 movel %sp,%d1 /* get thread_info pointer */
81 andl #-THREAD_SIZE,%d1 81 andl #-THREAD_SIZE,%d1
@@ -88,10 +88,10 @@ ENTRY(system_call)
88 lea sys_call_table,%a0 88 lea sys_call_table,%a0
89 movel %a0@(%d0), %a0 89 movel %a0@(%d0), %a0
90 jbsr %a0@ 90 jbsr %a0@
91 movel %d0,%sp@(PT_D0) /* save the return value*/ 91 movel %d0,%sp@(PT_OFF_D0) /* save the return value*/
92 92
93ret_from_exception: 93ret_from_exception:
94 btst #5,%sp@(PT_SR) /* check if returning to kernel*/ 94 btst #5,%sp@(PT_OFF_SR) /* check if returning to kernel*/
95 jeq Luser_return /* if so, skip resched, signals*/ 95 jeq Luser_return /* if so, skip resched, signals*/
96 96
97Lkernel_return: 97Lkernel_return:
@@ -133,7 +133,7 @@ Lreturn:
133 */ 133 */
134inthandler1: 134inthandler1:
135 SAVE_ALL 135 SAVE_ALL
136 movew %sp@(PT_VECTOR), %d0 136 movew %sp@(PT_OFF_VECTOR), %d0
137 and #0x3ff, %d0 137 and #0x3ff, %d0
138 138
139 movel %sp,%sp@- 139 movel %sp,%sp@-
@@ -144,7 +144,7 @@ inthandler1:
144 144
145inthandler2: 145inthandler2:
146 SAVE_ALL 146 SAVE_ALL
147 movew %sp@(PT_VECTOR), %d0 147 movew %sp@(PT_OFF_VECTOR), %d0
148 and #0x3ff, %d0 148 and #0x3ff, %d0
149 149
150 movel %sp,%sp@- 150 movel %sp,%sp@-
@@ -155,7 +155,7 @@ inthandler2:
155 155
156inthandler3: 156inthandler3:
157 SAVE_ALL 157 SAVE_ALL
158 movew %sp@(PT_VECTOR), %d0 158 movew %sp@(PT_OFF_VECTOR), %d0
159 and #0x3ff, %d0 159 and #0x3ff, %d0
160 160
161 movel %sp,%sp@- 161 movel %sp,%sp@-
@@ -166,7 +166,7 @@ inthandler3:
166 166
167inthandler4: 167inthandler4:
168 SAVE_ALL 168 SAVE_ALL
169 movew %sp@(PT_VECTOR), %d0 169 movew %sp@(PT_OFF_VECTOR), %d0
170 and #0x3ff, %d0 170 and #0x3ff, %d0
171 171
172 movel %sp,%sp@- 172 movel %sp,%sp@-
@@ -177,7 +177,7 @@ inthandler4:
177 177
178inthandler5: 178inthandler5:
179 SAVE_ALL 179 SAVE_ALL
180 movew %sp@(PT_VECTOR), %d0 180 movew %sp@(PT_OFF_VECTOR), %d0
181 and #0x3ff, %d0 181 and #0x3ff, %d0
182 182
183 movel %sp,%sp@- 183 movel %sp,%sp@-
@@ -188,7 +188,7 @@ inthandler5:
188 188
189inthandler6: 189inthandler6:
190 SAVE_ALL 190 SAVE_ALL
191 movew %sp@(PT_VECTOR), %d0 191 movew %sp@(PT_OFF_VECTOR), %d0
192 and #0x3ff, %d0 192 and #0x3ff, %d0
193 193
194 movel %sp,%sp@- 194 movel %sp,%sp@-
@@ -199,7 +199,7 @@ inthandler6:
199 199
200inthandler7: 200inthandler7:
201 SAVE_ALL 201 SAVE_ALL
202 movew %sp@(PT_VECTOR), %d0 202 movew %sp@(PT_OFF_VECTOR), %d0
203 and #0x3ff, %d0 203 and #0x3ff, %d0
204 204
205 movel %sp,%sp@- 205 movel %sp,%sp@-
@@ -210,7 +210,7 @@ inthandler7:
210 210
211inthandler: 211inthandler:
212 SAVE_ALL 212 SAVE_ALL
213 movew %sp@(PT_VECTOR), %d0 213 movew %sp@(PT_OFF_VECTOR), %d0
214 and #0x3ff, %d0 214 and #0x3ff, %d0
215 215
216 movel %sp,%sp@- 216 movel %sp,%sp@-
@@ -224,7 +224,7 @@ ret_from_interrupt:
2242: 2242:
225 RESTORE_ALL 225 RESTORE_ALL
2261: 2261:
227 moveb %sp@(PT_SR), %d0 227 moveb %sp@(PT_OFF_SR), %d0
228 and #7, %d0 228 and #7, %d0
229 jhi 2b 229 jhi 2b
230 230
diff --git a/arch/m68knommu/platform/68360/entry.S b/arch/m68knommu/platform/68360/entry.S
index 55dfefe38642..6d3460a39cac 100644
--- a/arch/m68knommu/platform/68360/entry.S
+++ b/arch/m68knommu/platform/68360/entry.S
@@ -35,17 +35,17 @@
35.globl inthandler 35.globl inthandler
36 36
37badsys: 37badsys:
38 movel #-ENOSYS,%sp@(PT_D0) 38 movel #-ENOSYS,%sp@(PT_OFF_D0)
39 jra ret_from_exception 39 jra ret_from_exception
40 40
41do_trace: 41do_trace:
42 movel #-ENOSYS,%sp@(PT_D0) /* needed for strace*/ 42 movel #-ENOSYS,%sp@(PT_OFF_D0) /* needed for strace*/
43 subql #4,%sp 43 subql #4,%sp
44 SAVE_SWITCH_STACK 44 SAVE_SWITCH_STACK
45 jbsr syscall_trace 45 jbsr syscall_trace
46 RESTORE_SWITCH_STACK 46 RESTORE_SWITCH_STACK
47 addql #4,%sp 47 addql #4,%sp
48 movel %sp@(PT_ORIG_D0),%d1 48 movel %sp@(PT_OFF_ORIG_D0),%d1
49 movel #-ENOSYS,%d0 49 movel #-ENOSYS,%d0
50 cmpl #NR_syscalls,%d1 50 cmpl #NR_syscalls,%d1
51 jcc 1f 51 jcc 1f
@@ -53,7 +53,7 @@ do_trace:
53 lea sys_call_table, %a0 53 lea sys_call_table, %a0
54 jbsr %a0@(%d1) 54 jbsr %a0@(%d1)
55 55
561: movel %d0,%sp@(PT_D0) /* save the return value */ 561: movel %d0,%sp@(PT_OFF_D0) /* save the return value */
57 subql #4,%sp /* dummy return address */ 57 subql #4,%sp /* dummy return address */
58 SAVE_SWITCH_STACK 58 SAVE_SWITCH_STACK
59 jbsr syscall_trace 59 jbsr syscall_trace
@@ -79,10 +79,10 @@ ENTRY(system_call)
79 lea sys_call_table,%a0 79 lea sys_call_table,%a0
80 movel %a0@(%d0), %a0 80 movel %a0@(%d0), %a0
81 jbsr %a0@ 81 jbsr %a0@
82 movel %d0,%sp@(PT_D0) /* save the return value*/ 82 movel %d0,%sp@(PT_OFF_D0) /* save the return value*/
83 83
84ret_from_exception: 84ret_from_exception:
85 btst #5,%sp@(PT_SR) /* check if returning to kernel*/ 85 btst #5,%sp@(PT_OFF_SR) /* check if returning to kernel*/
86 jeq Luser_return /* if so, skip resched, signals*/ 86 jeq Luser_return /* if so, skip resched, signals*/
87 87
88Lkernel_return: 88Lkernel_return:
@@ -124,7 +124,7 @@ Lreturn:
124 */ 124 */
125inthandler: 125inthandler:
126 SAVE_ALL 126 SAVE_ALL
127 movew %sp@(PT_VECTOR), %d0 127 movew %sp@(PT_OFF_VECTOR), %d0
128 and.l #0x3ff, %d0 128 and.l #0x3ff, %d0
129 lsr.l #0x02, %d0 129 lsr.l #0x02, %d0
130 130
@@ -139,7 +139,7 @@ ret_from_interrupt:
1392: 1392:
140 RESTORE_ALL 140 RESTORE_ALL
1411: 1411:
142 moveb %sp@(PT_SR), %d0 142 moveb %sp@(PT_OFF_SR), %d0
143 and #7, %d0 143 and #7, %d0
144 jhi 2b 144 jhi 2b
145 /* check if we need to do software interrupts */ 145 /* check if we need to do software interrupts */
diff --git a/arch/m68knommu/platform/coldfire/entry.S b/arch/m68knommu/platform/coldfire/entry.S
index 3b471c0da24a..dd7d591f70ea 100644
--- a/arch/m68knommu/platform/coldfire/entry.S
+++ b/arch/m68knommu/platform/coldfire/entry.S
@@ -81,11 +81,11 @@ ENTRY(system_call)
81 81
82 movel %d3,%a0 82 movel %d3,%a0
83 jbsr %a0@ 83 jbsr %a0@
84 movel %d0,%sp@(PT_D0) /* save the return value */ 84 movel %d0,%sp@(PT_OFF_D0) /* save the return value */
85 jra ret_from_exception 85 jra ret_from_exception
861: 861:
87 movel #-ENOSYS,%d2 /* strace needs -ENOSYS in PT_D0 */ 87 movel #-ENOSYS,%d2 /* strace needs -ENOSYS in PT_OFF_D0 */
88 movel %d2,PT_D0(%sp) /* on syscall entry */ 88 movel %d2,PT_OFF_D0(%sp) /* on syscall entry */
89 subql #4,%sp 89 subql #4,%sp
90 SAVE_SWITCH_STACK 90 SAVE_SWITCH_STACK
91 jbsr syscall_trace 91 jbsr syscall_trace
@@ -93,7 +93,7 @@ ENTRY(system_call)
93 addql #4,%sp 93 addql #4,%sp
94 movel %d3,%a0 94 movel %d3,%a0
95 jbsr %a0@ 95 jbsr %a0@
96 movel %d0,%sp@(PT_D0) /* save the return value */ 96 movel %d0,%sp@(PT_OFF_D0) /* save the return value */
97 subql #4,%sp /* dummy return address */ 97 subql #4,%sp /* dummy return address */
98 SAVE_SWITCH_STACK 98 SAVE_SWITCH_STACK
99 jbsr syscall_trace 99 jbsr syscall_trace
@@ -104,7 +104,7 @@ ret_from_signal:
104 104
105ret_from_exception: 105ret_from_exception:
106 move #0x2700,%sr /* disable intrs */ 106 move #0x2700,%sr /* disable intrs */
107 btst #5,%sp@(PT_SR) /* check if returning to kernel */ 107 btst #5,%sp@(PT_OFF_SR) /* check if returning to kernel */
108 jeq Luser_return /* if so, skip resched, signals */ 108 jeq Luser_return /* if so, skip resched, signals */
109 109
110#ifdef CONFIG_PREEMPT 110#ifdef CONFIG_PREEMPT
@@ -142,8 +142,8 @@ Luser_return:
142Lreturn: 142Lreturn:
143 move #0x2700,%sr /* disable intrs */ 143 move #0x2700,%sr /* disable intrs */
144 movel sw_usp,%a0 /* get usp */ 144 movel sw_usp,%a0 /* get usp */
145 movel %sp@(PT_PC),%a0@- /* copy exception program counter */ 145 movel %sp@(PT_OFF_PC),%a0@- /* copy exception program counter */
146 movel %sp@(PT_FORMATVEC),%a0@-/* copy exception format/vector/sr */ 146 movel %sp@(PT_OFF_FORMATVEC),%a0@- /* copy exception format/vector/sr */
147 moveml %sp@,%d1-%d5/%a0-%a2 147 moveml %sp@,%d1-%d5/%a0-%a2
148 lea %sp@(32),%sp /* space for 8 regs */ 148 lea %sp@(32),%sp /* space for 8 regs */
149 movel %sp@+,%d0 149 movel %sp@+,%d0
@@ -181,9 +181,9 @@ Lsignal_return:
181ENTRY(inthandler) 181ENTRY(inthandler)
182 SAVE_ALL 182 SAVE_ALL
183 moveq #-1,%d0 183 moveq #-1,%d0
184 movel %d0,%sp@(PT_ORIG_D0) 184 movel %d0,%sp@(PT_OFF_ORIG_D0)
185 185
186 movew %sp@(PT_FORMATVEC),%d0 /* put exception # in d0 */ 186 movew %sp@(PT_OFF_FORMATVEC),%d0 /* put exception # in d0 */
187 andl #0x03fc,%d0 /* mask out vector only */ 187 andl #0x03fc,%d0 /* mask out vector only */
188 188
189 movel %sp,%sp@- /* push regs arg */ 189 movel %sp,%sp@- /* push regs arg */
@@ -203,7 +203,7 @@ ENTRY(inthandler)
203ENTRY(fasthandler) 203ENTRY(fasthandler)
204 SAVE_LOCAL 204 SAVE_LOCAL
205 205
206 movew %sp@(PT_FORMATVEC),%d0 206 movew %sp@(PT_OFF_FORMATVEC),%d0
207 andl #0x03fc,%d0 /* mask out vector only */ 207 andl #0x03fc,%d0 /* mask out vector only */
208 208
209 movel %sp,%sp@- /* push regs arg */ 209 movel %sp,%sp@- /* push regs arg */
diff --git a/arch/microblaze/kernel/entry.S b/arch/microblaze/kernel/entry.S
index acc1f05d1e2c..e3ecb36dd554 100644
--- a/arch/microblaze/kernel/entry.S
+++ b/arch/microblaze/kernel/entry.S
@@ -592,6 +592,8 @@ C_ENTRY(full_exception_trap):
592 nop 592 nop
593 mfs r7, rfsr; /* save FSR */ 593 mfs r7, rfsr; /* save FSR */
594 nop 594 nop
595 mts rfsr, r0; /* Clear sticky fsr */
596 nop
595 la r12, r0, full_exception 597 la r12, r0, full_exception
596 set_vms; 598 set_vms;
597 rtbd r12, 0; 599 rtbd r12, 0;
diff --git a/arch/microblaze/kernel/hw_exception_handler.S b/arch/microblaze/kernel/hw_exception_handler.S
index 6b0288ebccd6..2b86c03aa841 100644
--- a/arch/microblaze/kernel/hw_exception_handler.S
+++ b/arch/microblaze/kernel/hw_exception_handler.S
@@ -384,7 +384,7 @@ handle_other_ex: /* Handle Other exceptions here */
384 addk r8, r17, r0; /* Load exception address */ 384 addk r8, r17, r0; /* Load exception address */
385 bralid r15, full_exception; /* Branch to the handler */ 385 bralid r15, full_exception; /* Branch to the handler */
386 nop; 386 nop;
387 mts r0, rfsr; /* Clear sticky fsr */ 387 mts rfsr, r0; /* Clear sticky fsr */
388 nop 388 nop
389 389
390 /* 390 /*
diff --git a/arch/microblaze/kernel/process.c b/arch/microblaze/kernel/process.c
index 4201c743cc9f..c592d475b3d8 100644
--- a/arch/microblaze/kernel/process.c
+++ b/arch/microblaze/kernel/process.c
@@ -235,7 +235,9 @@ void start_thread(struct pt_regs *regs, unsigned long pc, unsigned long usp)
235 regs->pc = pc; 235 regs->pc = pc;
236 regs->r1 = usp; 236 regs->r1 = usp;
237 regs->pt_mode = 0; 237 regs->pt_mode = 0;
238#ifdef CONFIG_MMU
238 regs->msr |= MSR_UMS; 239 regs->msr |= MSR_UMS;
240#endif
239} 241}
240 242
241#ifdef CONFIG_MMU 243#ifdef CONFIG_MMU
diff --git a/arch/mips/alchemy/common/dbdma.c b/arch/mips/alchemy/common/dbdma.c
index 3ab6d80d150d..19c1c82849ff 100644
--- a/arch/mips/alchemy/common/dbdma.c
+++ b/arch/mips/alchemy/common/dbdma.c
@@ -175,7 +175,7 @@ static dbdev_tab_t dbdev_tab[] = {
175#define DBDEV_TAB_SIZE ARRAY_SIZE(dbdev_tab) 175#define DBDEV_TAB_SIZE ARRAY_SIZE(dbdev_tab)
176 176
177#ifdef CONFIG_PM 177#ifdef CONFIG_PM
178static u32 au1xxx_dbdma_pm_regs[NUM_DBDMA_CHANS + 1][8]; 178static u32 au1xxx_dbdma_pm_regs[NUM_DBDMA_CHANS + 1][6];
179#endif 179#endif
180 180
181 181
@@ -993,14 +993,13 @@ void au1xxx_dbdma_suspend(void)
993 au1xxx_dbdma_pm_regs[0][3] = au_readl(addr + 0x0c); 993 au1xxx_dbdma_pm_regs[0][3] = au_readl(addr + 0x0c);
994 994
995 /* save channel configurations */ 995 /* save channel configurations */
996 for (i = 1, addr = DDMA_CHANNEL_BASE; i < NUM_DBDMA_CHANS; i++) { 996 for (i = 1, addr = DDMA_CHANNEL_BASE; i <= NUM_DBDMA_CHANS; i++) {
997 au1xxx_dbdma_pm_regs[i][0] = au_readl(addr + 0x00); 997 au1xxx_dbdma_pm_regs[i][0] = au_readl(addr + 0x00);
998 au1xxx_dbdma_pm_regs[i][1] = au_readl(addr + 0x04); 998 au1xxx_dbdma_pm_regs[i][1] = au_readl(addr + 0x04);
999 au1xxx_dbdma_pm_regs[i][2] = au_readl(addr + 0x08); 999 au1xxx_dbdma_pm_regs[i][2] = au_readl(addr + 0x08);
1000 au1xxx_dbdma_pm_regs[i][3] = au_readl(addr + 0x0c); 1000 au1xxx_dbdma_pm_regs[i][3] = au_readl(addr + 0x0c);
1001 au1xxx_dbdma_pm_regs[i][4] = au_readl(addr + 0x10); 1001 au1xxx_dbdma_pm_regs[i][4] = au_readl(addr + 0x10);
1002 au1xxx_dbdma_pm_regs[i][5] = au_readl(addr + 0x14); 1002 au1xxx_dbdma_pm_regs[i][5] = au_readl(addr + 0x14);
1003 au1xxx_dbdma_pm_regs[i][6] = au_readl(addr + 0x18);
1004 1003
1005 /* halt channel */ 1004 /* halt channel */
1006 au_writel(au1xxx_dbdma_pm_regs[i][0] & ~1, addr + 0x00); 1005 au_writel(au1xxx_dbdma_pm_regs[i][0] & ~1, addr + 0x00);
@@ -1027,14 +1026,13 @@ void au1xxx_dbdma_resume(void)
1027 au_writel(au1xxx_dbdma_pm_regs[0][3], addr + 0x0c); 1026 au_writel(au1xxx_dbdma_pm_regs[0][3], addr + 0x0c);
1028 1027
1029 /* restore channel configurations */ 1028 /* restore channel configurations */
1030 for (i = 1, addr = DDMA_CHANNEL_BASE; i < NUM_DBDMA_CHANS; i++) { 1029 for (i = 1, addr = DDMA_CHANNEL_BASE; i <= NUM_DBDMA_CHANS; i++) {
1031 au_writel(au1xxx_dbdma_pm_regs[i][0], addr + 0x00); 1030 au_writel(au1xxx_dbdma_pm_regs[i][0], addr + 0x00);
1032 au_writel(au1xxx_dbdma_pm_regs[i][1], addr + 0x04); 1031 au_writel(au1xxx_dbdma_pm_regs[i][1], addr + 0x04);
1033 au_writel(au1xxx_dbdma_pm_regs[i][2], addr + 0x08); 1032 au_writel(au1xxx_dbdma_pm_regs[i][2], addr + 0x08);
1034 au_writel(au1xxx_dbdma_pm_regs[i][3], addr + 0x0c); 1033 au_writel(au1xxx_dbdma_pm_regs[i][3], addr + 0x0c);
1035 au_writel(au1xxx_dbdma_pm_regs[i][4], addr + 0x10); 1034 au_writel(au1xxx_dbdma_pm_regs[i][4], addr + 0x10);
1036 au_writel(au1xxx_dbdma_pm_regs[i][5], addr + 0x14); 1035 au_writel(au1xxx_dbdma_pm_regs[i][5], addr + 0x14);
1037 au_writel(au1xxx_dbdma_pm_regs[i][6], addr + 0x18);
1038 au_sync(); 1036 au_sync();
1039 addr += 0x100; /* next channel base */ 1037 addr += 0x100; /* next channel base */
1040 } 1038 }
diff --git a/arch/mips/basler/excite/excite_iodev.c b/arch/mips/basler/excite/excite_iodev.c
index dfbfd7e2ac08..938b1d0b7652 100644
--- a/arch/mips/basler/excite/excite_iodev.c
+++ b/arch/mips/basler/excite/excite_iodev.c
@@ -112,10 +112,8 @@ static int iodev_open(struct inode *i, struct file *f)
112{ 112{
113 int ret; 113 int ret;
114 114
115 lock_kernel();
116 ret = request_irq(iodev_irq, iodev_irqhdl, IRQF_DISABLED, 115 ret = request_irq(iodev_irq, iodev_irqhdl, IRQF_DISABLED,
117 iodev_name, &miscdev); 116 iodev_name, &miscdev);
118 unlock_kernel();
119 117
120 return ret; 118 return ret;
121} 119}
diff --git a/arch/mips/bcm63xx/Makefile b/arch/mips/bcm63xx/Makefile
index aaa585cf26e3..c146d1ededed 100644
--- a/arch/mips/bcm63xx/Makefile
+++ b/arch/mips/bcm63xx/Makefile
@@ -1,5 +1,5 @@
1obj-y += clk.o cpu.o cs.o gpio.o irq.o prom.o setup.o timer.o \ 1obj-y += clk.o cpu.o cs.o gpio.o irq.o prom.o setup.o timer.o \
2 dev-dsp.o dev-enet.o 2 dev-dsp.o dev-enet.o dev-pcmcia.o dev-uart.o
3obj-$(CONFIG_EARLY_PRINTK) += early_printk.o 3obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
4 4
5obj-y += boards/ 5obj-y += boards/
diff --git a/arch/mips/bcm63xx/boards/board_bcm963xx.c b/arch/mips/bcm63xx/boards/board_bcm963xx.c
index fd77f548207a..78e155d21be6 100644
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -20,10 +20,11 @@
20#include <bcm63xx_cpu.h> 20#include <bcm63xx_cpu.h>
21#include <bcm63xx_regs.h> 21#include <bcm63xx_regs.h>
22#include <bcm63xx_io.h> 22#include <bcm63xx_io.h>
23#include <bcm63xx_board.h>
24#include <bcm63xx_dev_pci.h> 23#include <bcm63xx_dev_pci.h>
25#include <bcm63xx_dev_enet.h> 24#include <bcm63xx_dev_enet.h>
26#include <bcm63xx_dev_dsp.h> 25#include <bcm63xx_dev_dsp.h>
26#include <bcm63xx_dev_pcmcia.h>
27#include <bcm63xx_dev_uart.h>
27#include <board_bcm963xx.h> 28#include <board_bcm963xx.h>
28 29
29#define PFX "board_bcm963xx: " 30#define PFX "board_bcm963xx: "
@@ -793,6 +794,11 @@ int __init board_register_devices(void)
793{ 794{
794 u32 val; 795 u32 val;
795 796
797 bcm63xx_uart_register();
798
799 if (board.has_pccard)
800 bcm63xx_pcmcia_register();
801
796 if (board.has_enet0 && 802 if (board.has_enet0 &&
797 !board_get_mac_address(board.enet0.mac_addr)) 803 !board_get_mac_address(board.enet0.mac_addr))
798 bcm63xx_enet_register(0, &board.enet0); 804 bcm63xx_enet_register(0, &board.enet0);
diff --git a/arch/mips/bcm63xx/dev-pcmcia.c b/arch/mips/bcm63xx/dev-pcmcia.c
new file mode 100644
index 000000000000..de4d917fd54d
--- /dev/null
+++ b/arch/mips/bcm63xx/dev-pcmcia.c
@@ -0,0 +1,144 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
7 */
8
9#include <linux/init.h>
10#include <linux/kernel.h>
11#include <asm/bootinfo.h>
12#include <linux/platform_device.h>
13#include <bcm63xx_cs.h>
14#include <bcm63xx_cpu.h>
15#include <bcm63xx_dev_pcmcia.h>
16#include <bcm63xx_io.h>
17#include <bcm63xx_regs.h>
18
19static struct resource pcmcia_resources[] = {
20 /* pcmcia registers */
21 {
22 /* start & end filled at runtime */
23 .flags = IORESOURCE_MEM,
24 },
25
26 /* pcmcia memory zone resources */
27 {
28 .start = BCM_PCMCIA_COMMON_BASE_PA,
29 .end = BCM_PCMCIA_COMMON_END_PA,
30 .flags = IORESOURCE_MEM,
31 },
32 {
33 .start = BCM_PCMCIA_ATTR_BASE_PA,
34 .end = BCM_PCMCIA_ATTR_END_PA,
35 .flags = IORESOURCE_MEM,
36 },
37 {
38 .start = BCM_PCMCIA_IO_BASE_PA,
39 .end = BCM_PCMCIA_IO_END_PA,
40 .flags = IORESOURCE_MEM,
41 },
42
43 /* PCMCIA irq */
44 {
45 /* start filled at runtime */
46 .flags = IORESOURCE_IRQ,
47 },
48
49 /* declare PCMCIA IO resource also */
50 {
51 .start = BCM_PCMCIA_IO_BASE_PA,
52 .end = BCM_PCMCIA_IO_END_PA,
53 .flags = IORESOURCE_IO,
54 },
55};
56
57static struct bcm63xx_pcmcia_platform_data pd;
58
59static struct platform_device bcm63xx_pcmcia_device = {
60 .name = "bcm63xx_pcmcia",
61 .id = 0,
62 .num_resources = ARRAY_SIZE(pcmcia_resources),
63 .resource = pcmcia_resources,
64 .dev = {
65 .platform_data = &pd,
66 },
67};
68
69static int __init config_pcmcia_cs(unsigned int cs,
70 u32 base, unsigned int size)
71{
72 int ret;
73
74 ret = bcm63xx_set_cs_status(cs, 0);
75 if (!ret)
76 ret = bcm63xx_set_cs_base(cs, base, size);
77 if (!ret)
78 ret = bcm63xx_set_cs_status(cs, 1);
79 return ret;
80}
81
82static const __initdata struct {
83 unsigned int cs;
84 unsigned int base;
85 unsigned int size;
86} pcmcia_cs[3] = {
87 {
88 .cs = MPI_CS_PCMCIA_COMMON,
89 .base = BCM_PCMCIA_COMMON_BASE_PA,
90 .size = BCM_PCMCIA_COMMON_SIZE
91 },
92 {
93 .cs = MPI_CS_PCMCIA_ATTR,
94 .base = BCM_PCMCIA_ATTR_BASE_PA,
95 .size = BCM_PCMCIA_ATTR_SIZE
96 },
97 {
98 .cs = MPI_CS_PCMCIA_IO,
99 .base = BCM_PCMCIA_IO_BASE_PA,
100 .size = BCM_PCMCIA_IO_SIZE
101 },
102};
103
104int __init bcm63xx_pcmcia_register(void)
105{
106 int ret, i;
107
108 if (!BCMCPU_IS_6348() && !BCMCPU_IS_6358())
109 return 0;
110
111 /* use correct pcmcia ready gpio depending on processor */
112 switch (bcm63xx_get_cpu_id()) {
113 case BCM6348_CPU_ID:
114 pd.ready_gpio = 22;
115 break;
116
117 case BCM6358_CPU_ID:
118 pd.ready_gpio = 18;
119 break;
120
121 default:
122 return -ENODEV;
123 }
124
125 pcmcia_resources[0].start = bcm63xx_regset_address(RSET_PCMCIA);
126 pcmcia_resources[0].end = pcmcia_resources[0].start +
127 RSET_PCMCIA_SIZE - 1;
128 pcmcia_resources[4].start = bcm63xx_get_irq_number(IRQ_PCMCIA);
129
130 /* configure pcmcia chip selects */
131 for (i = 0; i < 3; i++) {
132 ret = config_pcmcia_cs(pcmcia_cs[i].cs,
133 pcmcia_cs[i].base,
134 pcmcia_cs[i].size);
135 if (ret)
136 goto out_err;
137 }
138
139 return platform_device_register(&bcm63xx_pcmcia_device);
140
141out_err:
142 printk(KERN_ERR "unable to set pcmcia chip select\n");
143 return ret;
144}
diff --git a/arch/mips/bcm63xx/dev-uart.c b/arch/mips/bcm63xx/dev-uart.c
new file mode 100644
index 000000000000..5f3d89c4a988
--- /dev/null
+++ b/arch/mips/bcm63xx/dev-uart.c
@@ -0,0 +1,41 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
7 */
8
9#include <linux/init.h>
10#include <linux/kernel.h>
11#include <linux/platform_device.h>
12#include <bcm63xx_cpu.h>
13#include <bcm63xx_dev_uart.h>
14
15static struct resource uart_resources[] = {
16 {
17 .start = -1, /* filled at runtime */
18 .end = -1, /* filled at runtime */
19 .flags = IORESOURCE_MEM,
20 },
21 {
22 .start = -1, /* filled at runtime */
23 .flags = IORESOURCE_IRQ,
24 },
25};
26
27static struct platform_device bcm63xx_uart_device = {
28 .name = "bcm63xx_uart",
29 .id = 0,
30 .num_resources = ARRAY_SIZE(uart_resources),
31 .resource = uart_resources,
32};
33
34int __init bcm63xx_uart_register(void)
35{
36 uart_resources[0].start = bcm63xx_regset_address(RSET_UART0);
37 uart_resources[0].end = uart_resources[0].start;
38 uart_resources[0].end += RSET_UART_SIZE - 1;
39 uart_resources[1].start = bcm63xx_get_irq_number(IRQ_UART0);
40 return platform_device_register(&bcm63xx_uart_device);
41}
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_pcmcia.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_pcmcia.h
new file mode 100644
index 000000000000..2beb3969ce3b
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_pcmcia.h
@@ -0,0 +1,13 @@
1#ifndef BCM63XX_DEV_PCMCIA_H_
2#define BCM63XX_DEV_PCMCIA_H_
3
4/*
5 * PCMCIA driver platform data
6 */
7struct bcm63xx_pcmcia_platform_data {
8 unsigned int ready_gpio;
9};
10
11int bcm63xx_pcmcia_register(void);
12
13#endif /* BCM63XX_DEV_PCMCIA_H_ */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_uart.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_uart.h
new file mode 100644
index 000000000000..bf348f573bbc
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_uart.h
@@ -0,0 +1,6 @@
1#ifndef BCM63XX_DEV_UART_H_
2#define BCM63XX_DEV_UART_H_
3
4int bcm63xx_uart_register(void);
5
6#endif /* BCM63XX_DEV_UART_H_ */
diff --git a/arch/mips/include/asm/smp.h b/arch/mips/include/asm/smp.h
index e15f11a09311..af42385245d5 100644
--- a/arch/mips/include/asm/smp.h
+++ b/arch/mips/include/asm/smp.h
@@ -77,7 +77,18 @@ extern void play_dead(void);
77 77
78extern asmlinkage void smp_call_function_interrupt(void); 78extern asmlinkage void smp_call_function_interrupt(void);
79 79
80extern void arch_send_call_function_single_ipi(int cpu); 80static inline void arch_send_call_function_single_ipi(int cpu)
81extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); 81{
82 extern struct plat_smp_ops *mp_ops; /* private */
83
84 mp_ops->send_ipi_mask(&cpumask_of_cpu(cpu), SMP_CALL_FUNCTION);
85}
86
87static inline void arch_send_call_function_ipi_mask(const struct cpumask *mask)
88{
89 extern struct plat_smp_ops *mp_ops; /* private */
90
91 mp_ops->send_ipi_mask(mask, SMP_CALL_FUNCTION);
92}
82 93
83#endif /* __ASM_SMP_H */ 94#endif /* __ASM_SMP_H */
diff --git a/arch/mips/include/asm/unaligned.h b/arch/mips/include/asm/unaligned.h
index 792404948571..42f66c311473 100644
--- a/arch/mips/include/asm/unaligned.h
+++ b/arch/mips/include/asm/unaligned.h
@@ -12,17 +12,17 @@
12#if defined(__MIPSEB__) 12#if defined(__MIPSEB__)
13# include <linux/unaligned/be_struct.h> 13# include <linux/unaligned/be_struct.h>
14# include <linux/unaligned/le_byteshift.h> 14# include <linux/unaligned/le_byteshift.h>
15# include <linux/unaligned/generic.h>
16# define get_unaligned __get_unaligned_be 15# define get_unaligned __get_unaligned_be
17# define put_unaligned __put_unaligned_be 16# define put_unaligned __put_unaligned_be
18#elif defined(__MIPSEL__) 17#elif defined(__MIPSEL__)
19# include <linux/unaligned/le_struct.h> 18# include <linux/unaligned/le_struct.h>
20# include <linux/unaligned/be_byteshift.h> 19# include <linux/unaligned/be_byteshift.h>
21# include <linux/unaligned/generic.h>
22# define get_unaligned __get_unaligned_le 20# define get_unaligned __get_unaligned_le
23# define put_unaligned __put_unaligned_le 21# define put_unaligned __put_unaligned_le
24#else 22#else
25# error "MIPS, but neither __MIPSEB__, nor __MIPSEL__???" 23# error "MIPS, but neither __MIPSEB__, nor __MIPSEL__???"
26#endif 24#endif
27 25
26# include <linux/unaligned/generic.h>
27
28#endif /* _ASM_MIPS_UNALIGNED_H */ 28#endif /* _ASM_MIPS_UNALIGNED_H */
diff --git a/arch/mips/kernel/kspd.c b/arch/mips/kernel/kspd.c
index f2397f00db43..ad4e017ed2f3 100644
--- a/arch/mips/kernel/kspd.c
+++ b/arch/mips/kernel/kspd.c
@@ -172,13 +172,20 @@ static unsigned int translate_open_flags(int flags)
172} 172}
173 173
174 174
175static void sp_setfsuidgid( uid_t uid, gid_t gid) 175static int sp_setfsuidgid(uid_t uid, gid_t gid)
176{ 176{
177 current->cred->fsuid = uid; 177 struct cred *new;
178 current->cred->fsgid = gid;
179 178
180 key_fsuid_changed(current); 179 new = prepare_creds();
181 key_fsgid_changed(current); 180 if (!new)
181 return -ENOMEM;
182
183 new->fsuid = uid;
184 new->fsgid = gid;
185
186 commit_creds(new);
187
188 return 0;
182} 189}
183 190
184/* 191/*
@@ -196,7 +203,7 @@ void sp_work_handle_request(void)
196 mm_segment_t old_fs; 203 mm_segment_t old_fs;
197 struct timeval tv; 204 struct timeval tv;
198 struct timezone tz; 205 struct timezone tz;
199 int cmd; 206 int err, cmd;
200 207
201 char *vcwd; 208 char *vcwd;
202 int size; 209 int size;
@@ -225,8 +232,11 @@ void sp_work_handle_request(void)
225 /* Run the syscall at the privilege of the user who loaded the 232 /* Run the syscall at the privilege of the user who loaded the
226 SP program */ 233 SP program */
227 234
228 if (vpe_getuid(tclimit)) 235 if (vpe_getuid(tclimit)) {
229 sp_setfsuidgid(vpe_getuid(tclimit), vpe_getgid(tclimit)); 236 err = sp_setfsuidgid(vpe_getuid(tclimit), vpe_getgid(tclimit));
237 if (!err)
238 pr_err("Change of creds failed\n");
239 }
230 240
231 switch (sc.cmd) { 241 switch (sc.cmd) {
232 /* needs the flags argument translating from SDE kit to 242 /* needs the flags argument translating from SDE kit to
@@ -283,8 +293,11 @@ void sp_work_handle_request(void)
283 break; 293 break;
284 } /* switch */ 294 } /* switch */
285 295
286 if (vpe_getuid(tclimit)) 296 if (vpe_getuid(tclimit)) {
287 sp_setfsuidgid( 0, 0); 297 err = sp_setfsuidgid(0, 0);
298 if (!err)
299 pr_err("restoring old creds failed\n");
300 }
288 301
289 old_fs = get_fs(); 302 old_fs = get_fs();
290 set_fs(KERNEL_DS); 303 set_fs(KERNEL_DS);
diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c
index a10ebfdc28ae..364f066cb497 100644
--- a/arch/mips/kernel/rtlx.c
+++ b/arch/mips/kernel/rtlx.c
@@ -72,8 +72,9 @@ static void rtlx_dispatch(void)
72*/ 72*/
73static irqreturn_t rtlx_interrupt(int irq, void *dev_id) 73static irqreturn_t rtlx_interrupt(int irq, void *dev_id)
74{ 74{
75 unsigned int vpeflags;
76 unsigned long flags;
75 int i; 77 int i;
76 unsigned int flags, vpeflags;
77 78
78 /* Ought not to be strictly necessary for SMTC builds */ 79 /* Ought not to be strictly necessary for SMTC builds */
79 local_irq_save(flags); 80 local_irq_save(flags);
@@ -392,20 +393,12 @@ out:
392 393
393static int file_open(struct inode *inode, struct file *filp) 394static int file_open(struct inode *inode, struct file *filp)
394{ 395{
395 int minor = iminor(inode); 396 return rtlx_open(iminor(inode), (filp->f_flags & O_NONBLOCK) ? 0 : 1);
396 int err;
397
398 lock_kernel();
399 err = rtlx_open(minor, (filp->f_flags & O_NONBLOCK) ? 0 : 1);
400 unlock_kernel();
401 return err;
402} 397}
403 398
404static int file_release(struct inode *inode, struct file *filp) 399static int file_release(struct inode *inode, struct file *filp)
405{ 400{
406 int minor = iminor(inode); 401 return rtlx_release(iminor(inode));
407
408 return rtlx_release(minor);
409} 402}
410 403
411static unsigned int file_poll(struct file *file, poll_table * wait) 404static unsigned int file_poll(struct file *file, poll_table * wait)
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index 4eb106c6a3ec..e72e6844d134 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -32,7 +32,6 @@
32#include <linux/cpumask.h> 32#include <linux/cpumask.h>
33#include <linux/cpu.h> 33#include <linux/cpu.h>
34#include <linux/err.h> 34#include <linux/err.h>
35#include <linux/smp.h>
36 35
37#include <asm/atomic.h> 36#include <asm/atomic.h>
38#include <asm/cpu.h> 37#include <asm/cpu.h>
@@ -128,19 +127,6 @@ asmlinkage __cpuinit void start_secondary(void)
128 cpu_idle(); 127 cpu_idle();
129} 128}
130 129
131void arch_send_call_function_ipi_mask(const struct cpumask *mask)
132{
133 mp_ops->send_ipi_mask(mask, SMP_CALL_FUNCTION);
134}
135
136/*
137 * We reuse the same vector for the single IPI
138 */
139void arch_send_call_function_single_ipi(int cpu)
140{
141 mp_ops->send_ipi_mask(cpumask_of_cpu(cpu), SMP_CALL_FUNCTION);
142}
143
144/* 130/*
145 * Call into both interrupt handlers, as we share the IPI for them 131 * Call into both interrupt handlers, as we share the IPI for them
146 */ 132 */
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c
index 67153a0dc267..4d181df44a40 100644
--- a/arch/mips/kernel/smtc.c
+++ b/arch/mips/kernel/smtc.c
@@ -1098,9 +1098,8 @@ static void ipi_irq_dispatch(void)
1098 1098
1099static struct irqaction irq_ipi = { 1099static struct irqaction irq_ipi = {
1100 .handler = ipi_interrupt, 1100 .handler = ipi_interrupt,
1101 .flags = IRQF_DISABLED, 1101 .flags = IRQF_DISABLED | IRQF_PERCPU,
1102 .name = "SMTC_IPI", 1102 .name = "SMTC_IPI"
1103 .flags = IRQF_PERCPU
1104}; 1103};
1105 1104
1106static void setup_cross_vpe_interrupts(unsigned int nvpe) 1105static void setup_cross_vpe_interrupts(unsigned int nvpe)
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c
index eb6c4c5b7fbe..03092ab2a296 100644
--- a/arch/mips/kernel/vpe.c
+++ b/arch/mips/kernel/vpe.c
@@ -144,14 +144,15 @@ struct tc {
144}; 144};
145 145
146struct { 146struct {
147 /* Virtual processing elements */ 147 spinlock_t vpe_list_lock;
148 struct list_head vpe_list; 148 struct list_head vpe_list; /* Virtual processing elements */
149 149 spinlock_t tc_list_lock;
150 /* Thread contexts */ 150 struct list_head tc_list; /* Thread contexts */
151 struct list_head tc_list;
152} vpecontrol = { 151} vpecontrol = {
153 .vpe_list = LIST_HEAD_INIT(vpecontrol.vpe_list), 152 .vpe_list_lock = SPIN_LOCK_UNLOCKED,
154 .tc_list = LIST_HEAD_INIT(vpecontrol.tc_list) 153 .vpe_list = LIST_HEAD_INIT(vpecontrol.vpe_list),
154 .tc_list_lock = SPIN_LOCK_UNLOCKED,
155 .tc_list = LIST_HEAD_INIT(vpecontrol.tc_list)
155}; 156};
156 157
157static void release_progmem(void *ptr); 158static void release_progmem(void *ptr);
@@ -159,28 +160,38 @@ static void release_progmem(void *ptr);
159/* get the vpe associated with this minor */ 160/* get the vpe associated with this minor */
160static struct vpe *get_vpe(int minor) 161static struct vpe *get_vpe(int minor)
161{ 162{
162 struct vpe *v; 163 struct vpe *res, *v;
163 164
164 if (!cpu_has_mipsmt) 165 if (!cpu_has_mipsmt)
165 return NULL; 166 return NULL;
166 167
168 res = NULL;
169 spin_lock(&vpecontrol.vpe_list_lock);
167 list_for_each_entry(v, &vpecontrol.vpe_list, list) { 170 list_for_each_entry(v, &vpecontrol.vpe_list, list) {
168 if (v->minor == minor) 171 if (v->minor == minor) {
169 return v; 172 res = v;
173 break;
174 }
170 } 175 }
176 spin_unlock(&vpecontrol.vpe_list_lock);
171 177
172 return NULL; 178 return res;
173} 179}
174 180
175/* get the vpe associated with this minor */ 181/* get the vpe associated with this minor */
176static struct tc *get_tc(int index) 182static struct tc *get_tc(int index)
177{ 183{
178 struct tc *t; 184 struct tc *res, *t;
179 185
186 res = NULL;
187 spin_lock(&vpecontrol.tc_list_lock);
180 list_for_each_entry(t, &vpecontrol.tc_list, list) { 188 list_for_each_entry(t, &vpecontrol.tc_list, list) {
181 if (t->index == index) 189 if (t->index == index) {
182 return t; 190 res = t;
191 break;
192 }
183 } 193 }
194 spin_unlock(&vpecontrol.tc_list_lock);
184 195
185 return NULL; 196 return NULL;
186} 197}
@@ -190,15 +201,17 @@ static struct vpe *alloc_vpe(int minor)
190{ 201{
191 struct vpe *v; 202 struct vpe *v;
192 203
193 if ((v = kzalloc(sizeof(struct vpe), GFP_KERNEL)) == NULL) { 204 if ((v = kzalloc(sizeof(struct vpe), GFP_KERNEL)) == NULL)
194 return NULL; 205 return NULL;
195 }
196 206
197 INIT_LIST_HEAD(&v->tc); 207 INIT_LIST_HEAD(&v->tc);
208 spin_lock(&vpecontrol.vpe_list_lock);
198 list_add_tail(&v->list, &vpecontrol.vpe_list); 209 list_add_tail(&v->list, &vpecontrol.vpe_list);
210 spin_unlock(&vpecontrol.vpe_list_lock);
199 211
200 INIT_LIST_HEAD(&v->notify); 212 INIT_LIST_HEAD(&v->notify);
201 v->minor = minor; 213 v->minor = minor;
214
202 return v; 215 return v;
203} 216}
204 217
@@ -212,7 +225,10 @@ static struct tc *alloc_tc(int index)
212 225
213 INIT_LIST_HEAD(&tc->tc); 226 INIT_LIST_HEAD(&tc->tc);
214 tc->index = index; 227 tc->index = index;
228
229 spin_lock(&vpecontrol.tc_list_lock);
215 list_add_tail(&tc->list, &vpecontrol.tc_list); 230 list_add_tail(&tc->list, &vpecontrol.tc_list);
231 spin_unlock(&vpecontrol.tc_list_lock);
216 232
217out: 233out:
218 return tc; 234 return tc;
@@ -227,7 +243,7 @@ static void release_vpe(struct vpe *v)
227 kfree(v); 243 kfree(v);
228} 244}
229 245
230static void dump_mtregs(void) 246static void __maybe_unused dump_mtregs(void)
231{ 247{
232 unsigned long val; 248 unsigned long val;
233 249
@@ -1048,20 +1064,19 @@ static int vpe_open(struct inode *inode, struct file *filp)
1048 enum vpe_state state; 1064 enum vpe_state state;
1049 struct vpe_notifications *not; 1065 struct vpe_notifications *not;
1050 struct vpe *v; 1066 struct vpe *v;
1051 int ret, err = 0; 1067 int ret;
1052 1068
1053 lock_kernel();
1054 if (minor != iminor(inode)) { 1069 if (minor != iminor(inode)) {
1055 /* assume only 1 device at the moment. */ 1070 /* assume only 1 device at the moment. */
1056 printk(KERN_WARNING "VPE loader: only vpe1 is supported\n"); 1071 pr_warning("VPE loader: only vpe1 is supported\n");
1057 err = -ENODEV; 1072
1058 goto out; 1073 return -ENODEV;
1059 } 1074 }
1060 1075
1061 if ((v = get_vpe(tclimit)) == NULL) { 1076 if ((v = get_vpe(tclimit)) == NULL) {
1062 printk(KERN_WARNING "VPE loader: unable to get vpe\n"); 1077 pr_warning("VPE loader: unable to get vpe\n");
1063 err = -ENODEV; 1078
1064 goto out; 1079 return -ENODEV;
1065 } 1080 }
1066 1081
1067 state = xchg(&v->state, VPE_STATE_INUSE); 1082 state = xchg(&v->state, VPE_STATE_INUSE);
@@ -1101,8 +1116,8 @@ static int vpe_open(struct inode *inode, struct file *filp)
1101 v->shared_ptr = NULL; 1116 v->shared_ptr = NULL;
1102 v->__start = 0; 1117 v->__start = 0;
1103 1118
1104out:
1105 unlock_kernel(); 1119 unlock_kernel();
1120
1106 return 0; 1121 return 0;
1107} 1122}
1108 1123
@@ -1594,14 +1609,14 @@ static void __exit vpe_module_exit(void)
1594{ 1609{
1595 struct vpe *v, *n; 1610 struct vpe *v, *n;
1596 1611
1612 device_del(&vpe_device);
1613 unregister_chrdev(major, module_name);
1614
1615 /* No locking needed here */
1597 list_for_each_entry_safe(v, n, &vpecontrol.vpe_list, list) { 1616 list_for_each_entry_safe(v, n, &vpecontrol.vpe_list, list) {
1598 if (v->state != VPE_STATE_UNUSED) { 1617 if (v->state != VPE_STATE_UNUSED)
1599 release_vpe(v); 1618 release_vpe(v);
1600 }
1601 } 1619 }
1602
1603 device_del(&vpe_device);
1604 unregister_chrdev(major, module_name);
1605} 1620}
1606 1621
1607module_init(vpe_module_init); 1622module_init(vpe_module_init);
diff --git a/arch/mips/mm/sc-mips.c b/arch/mips/mm/sc-mips.c
index b55c2d1b998f..5ab5fa8c1d82 100644
--- a/arch/mips/mm/sc-mips.c
+++ b/arch/mips/mm/sc-mips.c
@@ -32,6 +32,11 @@ static void mips_sc_wback_inv(unsigned long addr, unsigned long size)
32 */ 32 */
33static void mips_sc_inv(unsigned long addr, unsigned long size) 33static void mips_sc_inv(unsigned long addr, unsigned long size)
34{ 34{
35 unsigned long lsize = cpu_scache_line_size();
36 unsigned long almask = ~(lsize - 1);
37
38 cache_op(Hit_Writeback_Inv_SD, addr & almask);
39 cache_op(Hit_Writeback_Inv_SD, (addr + size - 1) & almask);
35 blast_inv_scache_range(addr, addr + size); 40 blast_inv_scache_range(addr, addr + size);
36} 41}
37 42
diff --git a/arch/mips/oprofile/op_model_loongson2.c b/arch/mips/oprofile/op_model_loongson2.c
index 655cb8dec340..deed1d5d4982 100644
--- a/arch/mips/oprofile/op_model_loongson2.c
+++ b/arch/mips/oprofile/op_model_loongson2.c
@@ -44,7 +44,7 @@ static struct loongson2_register_config {
44 unsigned int ctrl; 44 unsigned int ctrl;
45 unsigned long long reset_counter1; 45 unsigned long long reset_counter1;
46 unsigned long long reset_counter2; 46 unsigned long long reset_counter2;
47 int cnt1_enalbed, cnt2_enalbed; 47 int cnt1_enabled, cnt2_enabled;
48} reg; 48} reg;
49 49
50DEFINE_SPINLOCK(sample_lock); 50DEFINE_SPINLOCK(sample_lock);
@@ -81,8 +81,8 @@ static void loongson2_reg_setup(struct op_counter_config *cfg)
81 81
82 reg.ctrl = ctrl; 82 reg.ctrl = ctrl;
83 83
84 reg.cnt1_enalbed = cfg[0].enabled; 84 reg.cnt1_enabled = cfg[0].enabled;
85 reg.cnt2_enalbed = cfg[1].enabled; 85 reg.cnt2_enabled = cfg[1].enabled;
86 86
87} 87}
88 88
@@ -99,7 +99,7 @@ static void loongson2_cpu_setup(void *args)
99static void loongson2_cpu_start(void *args) 99static void loongson2_cpu_start(void *args)
100{ 100{
101 /* Start all counters on current CPU */ 101 /* Start all counters on current CPU */
102 if (reg.cnt1_enalbed || reg.cnt2_enalbed) 102 if (reg.cnt1_enabled || reg.cnt2_enabled)
103 write_c0_perfctrl(reg.ctrl); 103 write_c0_perfctrl(reg.ctrl);
104} 104}
105 105
@@ -125,7 +125,7 @@ static irqreturn_t loongson2_perfcount_handler(int irq, void *dev_id)
125 */ 125 */
126 126
127 /* Check whether the irq belongs to me */ 127 /* Check whether the irq belongs to me */
128 enabled = reg.cnt1_enalbed | reg.cnt2_enalbed; 128 enabled = reg.cnt1_enabled | reg.cnt2_enabled;
129 if (!enabled) 129 if (!enabled)
130 return IRQ_NONE; 130 return IRQ_NONE;
131 131
@@ -136,12 +136,12 @@ static irqreturn_t loongson2_perfcount_handler(int irq, void *dev_id)
136 spin_lock_irqsave(&sample_lock, flags); 136 spin_lock_irqsave(&sample_lock, flags);
137 137
138 if (counter1 & LOONGSON2_PERFCNT_OVERFLOW) { 138 if (counter1 & LOONGSON2_PERFCNT_OVERFLOW) {
139 if (reg.cnt1_enalbed) 139 if (reg.cnt1_enabled)
140 oprofile_add_sample(regs, 0); 140 oprofile_add_sample(regs, 0);
141 counter1 = reg.reset_counter1; 141 counter1 = reg.reset_counter1;
142 } 142 }
143 if (counter2 & LOONGSON2_PERFCNT_OVERFLOW) { 143 if (counter2 & LOONGSON2_PERFCNT_OVERFLOW) {
144 if (reg.cnt2_enalbed) 144 if (reg.cnt2_enabled)
145 oprofile_add_sample(regs, 1); 145 oprofile_add_sample(regs, 1);
146 counter2 = reg.reset_counter2; 146 counter2 = reg.reset_counter2;
147 } 147 }
diff --git a/arch/mips/pci/ops-pmcmsp.c b/arch/mips/pci/ops-pmcmsp.c
index 109c95ca698b..32548b5d68d6 100644
--- a/arch/mips/pci/ops-pmcmsp.c
+++ b/arch/mips/pci/ops-pmcmsp.c
@@ -385,6 +385,7 @@ int msp_pcibios_config_access(unsigned char access_type,
385 unsigned long intr; 385 unsigned long intr;
386 unsigned long value; 386 unsigned long value;
387 static char pciirqflag; 387 static char pciirqflag;
388 int ret;
388#if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL) 389#if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL)
389 unsigned int vpe_status; 390 unsigned int vpe_status;
390#endif 391#endif
@@ -402,11 +403,13 @@ int msp_pcibios_config_access(unsigned char access_type,
402 * allocation assigns an interrupt handler to the interrupt. 403 * allocation assigns an interrupt handler to the interrupt.
403 */ 404 */
404 if (pciirqflag == 0) { 405 if (pciirqflag == 0) {
405 request_irq(MSP_INT_PCI,/* Hardcoded internal MSP7120 wiring */ 406 ret = request_irq(MSP_INT_PCI,/* Hardcoded internal MSP7120 wiring */
406 bpci_interrupt, 407 bpci_interrupt,
407 IRQF_SHARED | IRQF_DISABLED, 408 IRQF_SHARED | IRQF_DISABLED,
408 "PMC MSP PCI Host", 409 "PMC MSP PCI Host",
409 preg); 410 preg);
411 if (ret != 0)
412 return ret;
410 pciirqflag = ~0; 413 pciirqflag = ~0;
411 } 414 }
412 415
diff --git a/arch/mips/sgi-ip27/ip27-smp.c b/arch/mips/sgi-ip27/ip27-smp.c
index 9aa8f2951df6..c6851df9ab74 100644
--- a/arch/mips/sgi-ip27/ip27-smp.c
+++ b/arch/mips/sgi-ip27/ip27-smp.c
@@ -165,7 +165,7 @@ static void ip27_send_ipi_single(int destid, unsigned int action)
165 REMOTE_HUB_SEND_INTR(COMPACT_TO_NASID_NODEID(cpu_to_node(destid)), irq); 165 REMOTE_HUB_SEND_INTR(COMPACT_TO_NASID_NODEID(cpu_to_node(destid)), irq);
166} 166}
167 167
168static void ip27_send_ipi(const struct cpumask *mask, unsigned int action) 168static void ip27_send_ipi_mask(const struct cpumask *mask, unsigned int action)
169{ 169{
170 unsigned int i; 170 unsigned int i;
171 171
diff --git a/arch/mips/sibyte/bcm1480/irq.c b/arch/mips/sibyte/bcm1480/irq.c
index ba59839a021e..4070268aa769 100644
--- a/arch/mips/sibyte/bcm1480/irq.c
+++ b/arch/mips/sibyte/bcm1480/irq.c
@@ -117,10 +117,6 @@ static int bcm1480_set_affinity(unsigned int irq, const struct cpumask *mask)
117 unsigned long flags; 117 unsigned long flags;
118 unsigned int irq_dirty; 118 unsigned int irq_dirty;
119 119
120 if (cpumask_weight(mask) != 1) {
121 printk("attempted to set irq affinity for irq %d to multiple CPUs\n", irq);
122 return -1;
123 }
124 i = cpumask_first(mask); 120 i = cpumask_first(mask);
125 121
126 /* Convert logical CPU to physical CPU */ 122 /* Convert logical CPU to physical CPU */
diff --git a/arch/mips/sibyte/common/sb_tbprof.c b/arch/mips/sibyte/common/sb_tbprof.c
index 637a194e5cd5..15ea778b5e66 100644
--- a/arch/mips/sibyte/common/sb_tbprof.c
+++ b/arch/mips/sibyte/common/sb_tbprof.c
@@ -403,36 +403,31 @@ static int sbprof_zbprof_stop(void)
403static int sbprof_tb_open(struct inode *inode, struct file *filp) 403static int sbprof_tb_open(struct inode *inode, struct file *filp)
404{ 404{
405 int minor; 405 int minor;
406 int err = 0;
407 406
408 lock_kernel();
409 minor = iminor(inode); 407 minor = iminor(inode);
410 if (minor != 0) { 408 if (minor != 0)
411 err = -ENODEV; 409 return -ENODEV;
412 goto out;
413 }
414 410
415 if (xchg(&sbp.open, SB_OPENING) != SB_CLOSED) { 411 if (xchg(&sbp.open, SB_OPENING) != SB_CLOSED)
416 err = -EBUSY; 412 return -EBUSY;
417 goto out;
418 }
419 413
420 memset(&sbp, 0, sizeof(struct sbprof_tb)); 414 memset(&sbp, 0, sizeof(struct sbprof_tb));
421 sbp.sbprof_tbbuf = vmalloc(MAX_TBSAMPLE_BYTES); 415 sbp.sbprof_tbbuf = vmalloc(MAX_TBSAMPLE_BYTES);
422 if (!sbp.sbprof_tbbuf) { 416 if (!sbp.sbprof_tbbuf) {
423 err = -ENOMEM; 417 sbp.open = SB_CLOSED;
424 goto out; 418 wmb();
419 return -ENOMEM;
425 } 420 }
421
426 memset(sbp.sbprof_tbbuf, 0, MAX_TBSAMPLE_BYTES); 422 memset(sbp.sbprof_tbbuf, 0, MAX_TBSAMPLE_BYTES);
427 init_waitqueue_head(&sbp.tb_sync); 423 init_waitqueue_head(&sbp.tb_sync);
428 init_waitqueue_head(&sbp.tb_read); 424 init_waitqueue_head(&sbp.tb_read);
429 mutex_init(&sbp.lock); 425 mutex_init(&sbp.lock);
430 426
431 sbp.open = SB_OPEN; 427 sbp.open = SB_OPEN;
428 wmb();
432 429
433 out: 430 return 0;
434 unlock_kernel();
435 return err;
436} 431}
437 432
438static int sbprof_tb_release(struct inode *inode, struct file *filp) 433static int sbprof_tb_release(struct inode *inode, struct file *filp)
@@ -440,7 +435,7 @@ static int sbprof_tb_release(struct inode *inode, struct file *filp)
440 int minor; 435 int minor;
441 436
442 minor = iminor(inode); 437 minor = iminor(inode);
443 if (minor != 0 || !sbp.open) 438 if (minor != 0 || sbp.open != SB_CLOSED)
444 return -ENODEV; 439 return -ENODEV;
445 440
446 mutex_lock(&sbp.lock); 441 mutex_lock(&sbp.lock);
@@ -449,7 +444,8 @@ static int sbprof_tb_release(struct inode *inode, struct file *filp)
449 sbprof_zbprof_stop(); 444 sbprof_zbprof_stop();
450 445
451 vfree(sbp.sbprof_tbbuf); 446 vfree(sbp.sbprof_tbbuf);
452 sbp.open = 0; 447 sbp.open = SB_CLOSED;
448 wmb();
453 449
454 mutex_unlock(&sbp.lock); 450 mutex_unlock(&sbp.lock);
455 451
@@ -583,7 +579,8 @@ static int __init sbprof_tb_init(void)
583 } 579 }
584 tb_dev = dev; 580 tb_dev = dev;
585 581
586 sbp.open = 0; 582 sbp.open = SB_CLOSED;
583 wmb();
587 tb_period = zbbus_mhz * 10000LL; 584 tb_period = zbbus_mhz * 10000LL;
588 pr_info(DEVNAME ": initialized - tb_period = %lld\n", 585 pr_info(DEVNAME ": initialized - tb_period = %lld\n",
589 (long long) tb_period); 586 (long long) tb_period);
diff --git a/arch/mips/sibyte/swarm/setup.c b/arch/mips/sibyte/swarm/setup.c
index 623ffc933c4c..5277aac96b0f 100644
--- a/arch/mips/sibyte/swarm/setup.c
+++ b/arch/mips/sibyte/swarm/setup.c
@@ -106,7 +106,7 @@ void read_persistent_clock(struct timespec *ts)
106 break; 106 break;
107 } 107 }
108 ts->tv_sec = sec; 108 ts->tv_sec = sec;
109 tv->tv_nsec = 0; 109 ts->tv_nsec = 0;
110} 110}
111 111
112int rtc_mips_set_time(unsigned long sec) 112int rtc_mips_set_time(unsigned long sec)
diff --git a/arch/mn10300/include/asm/uaccess.h b/arch/mn10300/include/asm/uaccess.h
index 8a3a4dd55763..167e10ff06d9 100644
--- a/arch/mn10300/include/asm/uaccess.h
+++ b/arch/mn10300/include/asm/uaccess.h
@@ -129,42 +129,47 @@ extern int fixup_exception(struct pt_regs *regs);
129struct __large_struct { unsigned long buf[100]; }; 129struct __large_struct { unsigned long buf[100]; };
130#define __m(x) (*(struct __large_struct *)(x)) 130#define __m(x) (*(struct __large_struct *)(x))
131 131
132#define __get_user_nocheck(x, ptr, size) \ 132#define __get_user_nocheck(x, ptr, size) \
133({ \ 133({ \
134 __typeof(*(ptr)) __gu_val; \ 134 unsigned long __gu_addr; \
135 unsigned long __gu_addr; \ 135 int __gu_err; \
136 int __gu_err; \ 136 __gu_addr = (unsigned long) (ptr); \
137 __gu_addr = (unsigned long) (ptr); \ 137 switch (size) { \
138 switch (size) { \ 138 case 1: { \
139 case 1: __get_user_asm("bu"); break; \ 139 unsigned char __gu_val; \
140 case 2: __get_user_asm("hu"); break; \ 140 __get_user_asm("bu"); \
141 case 4: __get_user_asm("" ); break; \ 141 (x) = *(__force __typeof__(*(ptr))*) &__gu_val; \
142 default: __get_user_unknown(); break; \ 142 break; \
143 } \ 143 } \
144 x = (__typeof__(*(ptr))) __gu_val; \ 144 case 2: { \
145 __gu_err; \ 145 unsigned short __gu_val; \
146 __get_user_asm("hu"); \
147 (x) = *(__force __typeof__(*(ptr))*) &__gu_val; \
148 break; \
149 } \
150 case 4: { \
151 unsigned int __gu_val; \
152 __get_user_asm(""); \
153 (x) = *(__force __typeof__(*(ptr))*) &__gu_val; \
154 break; \
155 } \
156 default: \
157 __get_user_unknown(); \
158 break; \
159 } \
160 __gu_err; \
146}) 161})
147 162
148#define __get_user_check(x, ptr, size) \ 163#define __get_user_check(x, ptr, size) \
149({ \ 164({ \
150 __typeof__(*(ptr)) __gu_val; \ 165 int _e; \
151 unsigned long __gu_addr; \ 166 if (likely(__access_ok((unsigned long) (ptr), (size)))) \
152 int __gu_err; \ 167 _e = __get_user_nocheck((x), (ptr), (size)); \
153 __gu_addr = (unsigned long) (ptr); \ 168 else { \
154 if (likely(__access_ok(__gu_addr,size))) { \ 169 _e = -EFAULT; \
155 switch (size) { \ 170 (x) = (__typeof__(x))0; \
156 case 1: __get_user_asm("bu"); break; \ 171 } \
157 case 2: __get_user_asm("hu"); break; \ 172 _e; \
158 case 4: __get_user_asm("" ); break; \
159 default: __get_user_unknown(); break; \
160 } \
161 } \
162 else { \
163 __gu_err = -EFAULT; \
164 __gu_val = 0; \
165 } \
166 x = (__typeof__(*(ptr))) __gu_val; \
167 __gu_err; \
168}) 173})
169 174
170#define __get_user_asm(INSN) \ 175#define __get_user_asm(INSN) \
diff --git a/arch/mn10300/unit-asb2303/include/unit/clock.h b/arch/mn10300/unit-asb2303/include/unit/clock.h
index 8b450e920af1..2a0bf79ab968 100644
--- a/arch/mn10300/unit-asb2303/include/unit/clock.h
+++ b/arch/mn10300/unit-asb2303/include/unit/clock.h
@@ -20,9 +20,9 @@ extern unsigned long mn10300_ioclk; /* IOCLK (crystal speed) in HZ */
20extern unsigned long mn10300_iobclk; 20extern unsigned long mn10300_iobclk;
21extern unsigned long mn10300_tsc_per_HZ; 21extern unsigned long mn10300_tsc_per_HZ;
22 22
23#define MN10300_IOCLK ((unsigned long)mn10300_ioclk) 23#define MN10300_IOCLK mn10300_ioclk
24/* If this processors has a another clock, uncomment the below. */ 24/* If this processors has a another clock, uncomment the below. */
25/* #define MN10300_IOBCLK ((unsigned long)mn10300_iobclk) */ 25/* #define MN10300_IOBCLK mn10300_iobclk */
26 26
27#else /* !CONFIG_MN10300_RTC */ 27#else /* !CONFIG_MN10300_RTC */
28 28
@@ -35,7 +35,7 @@ extern unsigned long mn10300_tsc_per_HZ;
35#define MN10300_TSCCLK MN10300_IOCLK 35#define MN10300_TSCCLK MN10300_IOCLK
36 36
37#ifdef CONFIG_MN10300_RTC 37#ifdef CONFIG_MN10300_RTC
38#define MN10300_TSC_PER_HZ ((unsigned long)mn10300_tsc_per_HZ) 38#define MN10300_TSC_PER_HZ mn10300_tsc_per_HZ
39#else /* !CONFIG_MN10300_RTC */ 39#else /* !CONFIG_MN10300_RTC */
40#define MN10300_TSC_PER_HZ (MN10300_TSCCLK/HZ) 40#define MN10300_TSC_PER_HZ (MN10300_TSCCLK/HZ)
41#endif /* !CONFIG_MN10300_RTC */ 41#endif /* !CONFIG_MN10300_RTC */
diff --git a/arch/mn10300/unit-asb2305/include/unit/clock.h b/arch/mn10300/unit-asb2305/include/unit/clock.h
index 7d514841ffda..67be3f2eb18e 100644
--- a/arch/mn10300/unit-asb2305/include/unit/clock.h
+++ b/arch/mn10300/unit-asb2305/include/unit/clock.h
@@ -20,9 +20,9 @@ extern unsigned long mn10300_ioclk; /* IOCLK (crystal speed) in HZ */
20extern unsigned long mn10300_iobclk; 20extern unsigned long mn10300_iobclk;
21extern unsigned long mn10300_tsc_per_HZ; 21extern unsigned long mn10300_tsc_per_HZ;
22 22
23#define MN10300_IOCLK ((unsigned long)mn10300_ioclk) 23#define MN10300_IOCLK mn10300_ioclk
24/* If this processors has a another clock, uncomment the below. */ 24/* If this processors has a another clock, uncomment the below. */
25/* #define MN10300_IOBCLK ((unsigned long)mn10300_iobclk) */ 25/* #define MN10300_IOBCLK mn10300_iobclk */
26 26
27#else /* !CONFIG_MN10300_RTC */ 27#else /* !CONFIG_MN10300_RTC */
28 28
@@ -35,7 +35,7 @@ extern unsigned long mn10300_tsc_per_HZ;
35#define MN10300_TSCCLK MN10300_IOCLK 35#define MN10300_TSCCLK MN10300_IOCLK
36 36
37#ifdef CONFIG_MN10300_RTC 37#ifdef CONFIG_MN10300_RTC
38#define MN10300_TSC_PER_HZ ((unsigned long)mn10300_tsc_per_HZ) 38#define MN10300_TSC_PER_HZ mn10300_tsc_per_HZ
39#else /* !CONFIG_MN10300_RTC */ 39#else /* !CONFIG_MN10300_RTC */
40#define MN10300_TSC_PER_HZ (MN10300_TSCCLK/HZ) 40#define MN10300_TSC_PER_HZ (MN10300_TSCCLK/HZ)
41#endif /* !CONFIG_MN10300_RTC */ 41#endif /* !CONFIG_MN10300_RTC */
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index f388dc68f605..524d9352f17e 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -18,6 +18,7 @@ config PARISC
18 select BUG 18 select BUG
19 select HAVE_PERF_EVENTS 19 select HAVE_PERF_EVENTS
20 select GENERIC_ATOMIC64 if !64BIT 20 select GENERIC_ATOMIC64 if !64BIT
21 select HAVE_ARCH_TRACEHOOK
21 help 22 help
22 The PA-RISC microprocessor is designed by Hewlett-Packard and used 23 The PA-RISC microprocessor is designed by Hewlett-Packard and used
23 in many of their workstations & servers (HP9000 700 and 800 series, 24 in many of their workstations & servers (HP9000 700 and 800 series,
diff --git a/arch/parisc/include/asm/fixmap.h b/arch/parisc/include/asm/fixmap.h
index de3fe3a18229..6fec4d4a1a18 100644
--- a/arch/parisc/include/asm/fixmap.h
+++ b/arch/parisc/include/asm/fixmap.h
@@ -21,9 +21,9 @@
21#define KERNEL_MAP_END (TMPALIAS_MAP_START) 21#define KERNEL_MAP_END (TMPALIAS_MAP_START)
22 22
23#ifndef __ASSEMBLY__ 23#ifndef __ASSEMBLY__
24extern void *vmalloc_start; 24extern void *parisc_vmalloc_start;
25#define PCXL_DMA_MAP_SIZE (8*1024*1024) 25#define PCXL_DMA_MAP_SIZE (8*1024*1024)
26#define VMALLOC_START ((unsigned long)vmalloc_start) 26#define VMALLOC_START ((unsigned long)parisc_vmalloc_start)
27#define VMALLOC_END (KERNEL_MAP_END) 27#define VMALLOC_END (KERNEL_MAP_END)
28#endif /*__ASSEMBLY__*/ 28#endif /*__ASSEMBLY__*/
29 29
diff --git a/arch/parisc/include/asm/hardirq.h b/arch/parisc/include/asm/hardirq.h
index ce93133d5112..0d68184a76cb 100644
--- a/arch/parisc/include/asm/hardirq.h
+++ b/arch/parisc/include/asm/hardirq.h
@@ -1,29 +1,11 @@
1/* hardirq.h: PA-RISC hard IRQ support. 1/* hardirq.h: PA-RISC hard IRQ support.
2 * 2 *
3 * Copyright (C) 2001 Matthew Wilcox <matthew@wil.cx> 3 * Copyright (C) 2001 Matthew Wilcox <matthew@wil.cx>
4 *
5 * The locking is really quite interesting. There's a cpu-local
6 * count of how many interrupts are being handled, and a global
7 * lock. An interrupt can only be serviced if the global lock
8 * is free. You can't be sure no more interrupts are being
9 * serviced until you've acquired the lock and then checked
10 * all the per-cpu interrupt counts are all zero. It's a specialised
11 * br_lock, and that's exactly how Sparc does it. We don't because
12 * it's more locking for us. This way is lock-free in the interrupt path.
13 */ 4 */
14 5
15#ifndef _PARISC_HARDIRQ_H 6#ifndef _PARISC_HARDIRQ_H
16#define _PARISC_HARDIRQ_H 7#define _PARISC_HARDIRQ_H
17 8
18#include <linux/threads.h> 9#include <asm-generic/hardirq.h>
19#include <linux/irq.h>
20
21typedef struct {
22 unsigned long __softirq_pending; /* set_bit is used on this */
23} ____cacheline_aligned irq_cpustat_t;
24
25#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
26
27void ack_bad_irq(unsigned int irq);
28 10
29#endif /* _PARISC_HARDIRQ_H */ 11#endif /* _PARISC_HARDIRQ_H */
diff --git a/arch/parisc/include/asm/ptrace.h b/arch/parisc/include/asm/ptrace.h
index 302f68dc889c..aead40b16dd8 100644
--- a/arch/parisc/include/asm/ptrace.h
+++ b/arch/parisc/include/asm/ptrace.h
@@ -59,8 +59,11 @@ void user_enable_block_step(struct task_struct *task);
59#define user_mode(regs) (((regs)->iaoq[0] & 3) ? 1 : 0) 59#define user_mode(regs) (((regs)->iaoq[0] & 3) ? 1 : 0)
60#define user_space(regs) (((regs)->iasq[1] != 0) ? 1 : 0) 60#define user_space(regs) (((regs)->iasq[1] != 0) ? 1 : 0)
61#define instruction_pointer(regs) ((regs)->iaoq[0] & ~3) 61#define instruction_pointer(regs) ((regs)->iaoq[0] & ~3)
62#define user_stack_pointer(regs) ((regs)->gr[30])
62unsigned long profile_pc(struct pt_regs *); 63unsigned long profile_pc(struct pt_regs *);
63extern void show_regs(struct pt_regs *); 64extern void show_regs(struct pt_regs *);
64#endif 65
66
67#endif /* __KERNEL__ */
65 68
66#endif 69#endif
diff --git a/arch/parisc/include/asm/syscall.h b/arch/parisc/include/asm/syscall.h
new file mode 100644
index 000000000000..8bdfd2c8c39f
--- /dev/null
+++ b/arch/parisc/include/asm/syscall.h
@@ -0,0 +1,40 @@
1/* syscall.h */
2
3#ifndef _ASM_PARISC_SYSCALL_H_
4#define _ASM_PARISC_SYSCALL_H_
5
6#include <linux/err.h>
7#include <asm/ptrace.h>
8
9static inline long syscall_get_nr(struct task_struct *tsk,
10 struct pt_regs *regs)
11{
12 return regs->gr[20];
13}
14
15static inline void syscall_get_arguments(struct task_struct *tsk,
16 struct pt_regs *regs, unsigned int i,
17 unsigned int n, unsigned long *args)
18{
19 BUG_ON(i);
20
21 switch (n) {
22 case 6:
23 args[5] = regs->gr[21];
24 case 5:
25 args[4] = regs->gr[22];
26 case 4:
27 args[3] = regs->gr[23];
28 case 3:
29 args[2] = regs->gr[24];
30 case 2:
31 args[1] = regs->gr[25];
32 case 1:
33 args[0] = regs->gr[26];
34 break;
35 default:
36 BUG();
37 }
38}
39
40#endif /*_ASM_PARISC_SYSCALL_H_*/
diff --git a/arch/parisc/include/asm/thread_info.h b/arch/parisc/include/asm/thread_info.h
index ac775a76bff7..7ecc1039cfed 100644
--- a/arch/parisc/include/asm/thread_info.h
+++ b/arch/parisc/include/asm/thread_info.h
@@ -32,6 +32,11 @@ struct thread_info {
32#define init_thread_info (init_thread_union.thread_info) 32#define init_thread_info (init_thread_union.thread_info)
33#define init_stack (init_thread_union.stack) 33#define init_stack (init_thread_union.stack)
34 34
35/* how to get the thread information struct from C */
36#define current_thread_info() ((struct thread_info *)mfctl(30))
37
38#endif /* !__ASSEMBLY */
39
35/* thread information allocation */ 40/* thread information allocation */
36 41
37#define THREAD_SIZE_ORDER 2 42#define THREAD_SIZE_ORDER 2
@@ -40,11 +45,6 @@ struct thread_info {
40#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) 45#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER)
41#define THREAD_SHIFT (PAGE_SHIFT + THREAD_SIZE_ORDER) 46#define THREAD_SHIFT (PAGE_SHIFT + THREAD_SIZE_ORDER)
42 47
43/* how to get the thread information struct from C */
44#define current_thread_info() ((struct thread_info *)mfctl(30))
45
46#endif /* !__ASSEMBLY */
47
48#define PREEMPT_ACTIVE_BIT 28 48#define PREEMPT_ACTIVE_BIT 28
49#define PREEMPT_ACTIVE (1 << PREEMPT_ACTIVE_BIT) 49#define PREEMPT_ACTIVE (1 << PREEMPT_ACTIVE_BIT)
50 50
@@ -60,6 +60,8 @@ struct thread_info {
60#define TIF_RESTORE_SIGMASK 6 /* restore saved signal mask */ 60#define TIF_RESTORE_SIGMASK 6 /* restore saved signal mask */
61#define TIF_FREEZE 7 /* is freezing for suspend */ 61#define TIF_FREEZE 7 /* is freezing for suspend */
62#define TIF_NOTIFY_RESUME 8 /* callback before returning to user */ 62#define TIF_NOTIFY_RESUME 8 /* callback before returning to user */
63#define TIF_SINGLESTEP 9 /* single stepping? */
64#define TIF_BLOCKSTEP 10 /* branch stepping? */
63 65
64#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) 66#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
65#define _TIF_SIGPENDING (1 << TIF_SIGPENDING) 67#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
@@ -69,6 +71,8 @@ struct thread_info {
69#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) 71#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK)
70#define _TIF_FREEZE (1 << TIF_FREEZE) 72#define _TIF_FREEZE (1 << TIF_FREEZE)
71#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) 73#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
74#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP)
75#define _TIF_BLOCKSTEP (1 << TIF_BLOCKSTEP)
72 76
73#define _TIF_USER_WORK_MASK (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | \ 77#define _TIF_USER_WORK_MASK (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | \
74 _TIF_NEED_RESCHED | _TIF_RESTORE_SIGMASK) 78 _TIF_NEED_RESCHED | _TIF_RESTORE_SIGMASK)
diff --git a/arch/parisc/kernel/asm-offsets.c b/arch/parisc/kernel/asm-offsets.c
index 699cf8ef2118..fcd3c707bf12 100644
--- a/arch/parisc/kernel/asm-offsets.c
+++ b/arch/parisc/kernel/asm-offsets.c
@@ -270,8 +270,8 @@ int main(void)
270 DEFINE(DTLB_OFF_COUNT, offsetof(struct pdc_cache_info, dt_off_count)); 270 DEFINE(DTLB_OFF_COUNT, offsetof(struct pdc_cache_info, dt_off_count));
271 DEFINE(DTLB_LOOP, offsetof(struct pdc_cache_info, dt_loop)); 271 DEFINE(DTLB_LOOP, offsetof(struct pdc_cache_info, dt_loop));
272 BLANK(); 272 BLANK();
273 DEFINE(PA_BLOCKSTEP_BIT, 31-PT_BLOCKSTEP_BIT); 273 DEFINE(TIF_BLOCKSTEP_PA_BIT, 31-TIF_BLOCKSTEP);
274 DEFINE(PA_SINGLESTEP_BIT, 31-PT_SINGLESTEP_BIT); 274 DEFINE(TIF_SINGLESTEP_PA_BIT, 31-TIF_SINGLESTEP);
275 BLANK(); 275 BLANK();
276 DEFINE(ASM_PMD_SHIFT, PMD_SHIFT); 276 DEFINE(ASM_PMD_SHIFT, PMD_SHIFT);
277 DEFINE(ASM_PGDIR_SHIFT, PGDIR_SHIFT); 277 DEFINE(ASM_PGDIR_SHIFT, PGDIR_SHIFT);
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
index 8c4712b74dc1..3a44f7f704fa 100644
--- a/arch/parisc/kernel/entry.S
+++ b/arch/parisc/kernel/entry.S
@@ -2047,12 +2047,13 @@ syscall_do_signal:
2047 b,n syscall_check_sig 2047 b,n syscall_check_sig
2048 2048
2049syscall_restore: 2049syscall_restore:
2050 /* Are we being ptraced? */
2051 LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 2050 LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
2052 2051
2053 ldw TASK_PTRACE(%r1), %r19 2052 /* Are we being ptraced? */
2054 bb,< %r19,31,syscall_restore_rfi 2053 ldw TASK_FLAGS(%r1),%r19
2055 nop 2054 ldi (_TIF_SINGLESTEP|_TIF_BLOCKSTEP),%r2
2055 and,COND(=) %r19,%r2,%r0
2056 b,n syscall_restore_rfi
2056 2057
2057 ldo TASK_PT_FR31(%r1),%r19 /* reload fpregs */ 2058 ldo TASK_PT_FR31(%r1),%r19 /* reload fpregs */
2058 rest_fp %r19 2059 rest_fp %r19
@@ -2113,16 +2114,16 @@ syscall_restore_rfi:
2113 ldi 0x0b,%r20 /* Create new PSW */ 2114 ldi 0x0b,%r20 /* Create new PSW */
2114 depi -1,13,1,%r20 /* C, Q, D, and I bits */ 2115 depi -1,13,1,%r20 /* C, Q, D, and I bits */
2115 2116
2116 /* The values of PA_SINGLESTEP_BIT and PA_BLOCKSTEP_BIT are 2117 /* The values of SINGLESTEP_BIT and BLOCKSTEP_BIT are
2117 * set in include/linux/ptrace.h and converted to PA bitmap 2118 * set in thread_info.h and converted to PA bitmap
2118 * numbers in asm-offsets.c */ 2119 * numbers in asm-offsets.c */
2119 2120
2120 /* if ((%r19.PA_SINGLESTEP_BIT)) { %r20.27=1} */ 2121 /* if ((%r19.SINGLESTEP_BIT)) { %r20.27=1} */
2121 extru,= %r19,PA_SINGLESTEP_BIT,1,%r0 2122 extru,= %r19,TIF_SINGLESTEP_PA_BIT,1,%r0
2122 depi -1,27,1,%r20 /* R bit */ 2123 depi -1,27,1,%r20 /* R bit */
2123 2124
2124 /* if ((%r19.PA_BLOCKSTEP_BIT)) { %r20.7=1} */ 2125 /* if ((%r19.BLOCKSTEP_BIT)) { %r20.7=1} */
2125 extru,= %r19,PA_BLOCKSTEP_BIT,1,%r0 2126 extru,= %r19,TIF_BLOCKSTEP_PA_BIT,1,%r0
2126 depi -1,7,1,%r20 /* T bit */ 2127 depi -1,7,1,%r20 /* T bit */
2127 2128
2128 STREG %r20,TASK_PT_PSW(%r1) 2129 STREG %r20,TASK_PT_PSW(%r1)
diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c
index 330f536a9324..2e7610cb33d5 100644
--- a/arch/parisc/kernel/irq.c
+++ b/arch/parisc/kernel/irq.c
@@ -423,8 +423,3 @@ void __init init_IRQ(void)
423 set_eiem(cpu_eiem); /* EIEM : enable all external intr */ 423 set_eiem(cpu_eiem); /* EIEM : enable all external intr */
424 424
425} 425}
426
427void ack_bad_irq(unsigned int irq)
428{
429 printk(KERN_WARNING "unexpected IRQ %d\n", irq);
430}
diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c
index 61ee0eec4e69..212074653df7 100644
--- a/arch/parisc/kernel/module.c
+++ b/arch/parisc/kernel/module.c
@@ -893,7 +893,7 @@ int module_finalize(const Elf_Ehdr *hdr,
893 * ourselves */ 893 * ourselves */
894 for (i = 1; i < hdr->e_shnum; i++) { 894 for (i = 1; i < hdr->e_shnum; i++) {
895 if(sechdrs[i].sh_type == SHT_SYMTAB 895 if(sechdrs[i].sh_type == SHT_SYMTAB
896 && (sechdrs[i].sh_type & SHF_ALLOC)) { 896 && (sechdrs[i].sh_flags & SHF_ALLOC)) {
897 int strindex = sechdrs[i].sh_link; 897 int strindex = sechdrs[i].sh_link;
898 /* FIXME: AWFUL HACK 898 /* FIXME: AWFUL HACK
899 * The cast is to drop the const from 899 * The cast is to drop the const from
diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c
index 927db3668b6f..c4f49e45129d 100644
--- a/arch/parisc/kernel/ptrace.c
+++ b/arch/parisc/kernel/ptrace.c
@@ -13,6 +13,7 @@
13#include <linux/smp.h> 13#include <linux/smp.h>
14#include <linux/errno.h> 14#include <linux/errno.h>
15#include <linux/ptrace.h> 15#include <linux/ptrace.h>
16#include <linux/tracehook.h>
16#include <linux/user.h> 17#include <linux/user.h>
17#include <linux/personality.h> 18#include <linux/personality.h>
18#include <linux/security.h> 19#include <linux/security.h>
@@ -35,7 +36,8 @@
35 */ 36 */
36void ptrace_disable(struct task_struct *task) 37void ptrace_disable(struct task_struct *task)
37{ 38{
38 task->ptrace &= ~(PT_SINGLESTEP|PT_BLOCKSTEP); 39 clear_tsk_thread_flag(task, TIF_SINGLESTEP);
40 clear_tsk_thread_flag(task, TIF_BLOCKSTEP);
39 41
40 /* make sure the trap bits are not set */ 42 /* make sure the trap bits are not set */
41 pa_psw(task)->r = 0; 43 pa_psw(task)->r = 0;
@@ -55,8 +57,8 @@ void user_disable_single_step(struct task_struct *task)
55 57
56void user_enable_single_step(struct task_struct *task) 58void user_enable_single_step(struct task_struct *task)
57{ 59{
58 task->ptrace &= ~PT_BLOCKSTEP; 60 clear_tsk_thread_flag(task, TIF_BLOCKSTEP);
59 task->ptrace |= PT_SINGLESTEP; 61 set_tsk_thread_flag(task, TIF_SINGLESTEP);
60 62
61 if (pa_psw(task)->n) { 63 if (pa_psw(task)->n) {
62 struct siginfo si; 64 struct siginfo si;
@@ -98,8 +100,8 @@ void user_enable_single_step(struct task_struct *task)
98 100
99void user_enable_block_step(struct task_struct *task) 101void user_enable_block_step(struct task_struct *task)
100{ 102{
101 task->ptrace &= ~PT_SINGLESTEP; 103 clear_tsk_thread_flag(task, TIF_SINGLESTEP);
102 task->ptrace |= PT_BLOCKSTEP; 104 set_tsk_thread_flag(task, TIF_BLOCKSTEP);
103 105
104 /* Enable taken branch trap. */ 106 /* Enable taken branch trap. */
105 pa_psw(task)->r = 0; 107 pa_psw(task)->r = 0;
@@ -263,22 +265,20 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
263} 265}
264#endif 266#endif
265 267
268long do_syscall_trace_enter(struct pt_regs *regs)
269{
270 if (test_thread_flag(TIF_SYSCALL_TRACE) &&
271 tracehook_report_syscall_entry(regs))
272 return -1L;
273
274 return regs->gr[20];
275}
266 276
267void syscall_trace(void) 277void do_syscall_trace_exit(struct pt_regs *regs)
268{ 278{
269 if (!test_thread_flag(TIF_SYSCALL_TRACE)) 279 int stepping = test_thread_flag(TIF_SINGLESTEP) ||
270 return; 280 test_thread_flag(TIF_BLOCKSTEP);
271 if (!(current->ptrace & PT_PTRACED)) 281
272 return; 282 if (stepping || test_thread_flag(TIF_SYSCALL_TRACE))
273 ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) 283 tracehook_report_syscall_exit(regs, stepping);
274 ? 0x80 : 0));
275 /*
276 * this isn't the same as continuing with a signal, but it will do
277 * for normal use. strace only continues with a signal if the
278 * stopping signal is not SIGTRAP. -brl
279 */
280 if (current->exit_code) {
281 send_sig(current->exit_code, current, 1);
282 current->exit_code = 0;
283 }
284} 284}
diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c
index 8eb3c63c407a..e8467e4aa8d1 100644
--- a/arch/parisc/kernel/signal.c
+++ b/arch/parisc/kernel/signal.c
@@ -21,6 +21,7 @@
21#include <linux/errno.h> 21#include <linux/errno.h>
22#include <linux/wait.h> 22#include <linux/wait.h>
23#include <linux/ptrace.h> 23#include <linux/ptrace.h>
24#include <linux/tracehook.h>
24#include <linux/unistd.h> 25#include <linux/unistd.h>
25#include <linux/stddef.h> 26#include <linux/stddef.h>
26#include <linux/compat.h> 27#include <linux/compat.h>
@@ -34,7 +35,6 @@
34#include <asm/asm-offsets.h> 35#include <asm/asm-offsets.h>
35 36
36#ifdef CONFIG_COMPAT 37#ifdef CONFIG_COMPAT
37#include <linux/compat.h>
38#include "signal32.h" 38#include "signal32.h"
39#endif 39#endif
40 40
@@ -468,6 +468,9 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
468 sigaddset(&current->blocked,sig); 468 sigaddset(&current->blocked,sig);
469 recalc_sigpending(); 469 recalc_sigpending();
470 spin_unlock_irq(&current->sighand->siglock); 470 spin_unlock_irq(&current->sighand->siglock);
471
472 tracehook_signal_handler(sig, info, ka, regs, 0);
473
471 return 1; 474 return 1;
472} 475}
473 476
diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S
index 59fc1a43ec3e..f5f96021caa0 100644
--- a/arch/parisc/kernel/syscall.S
+++ b/arch/parisc/kernel/syscall.S
@@ -288,18 +288,23 @@ tracesys:
288 STREG %r18,PT_GR18(%r2) 288 STREG %r18,PT_GR18(%r2)
289 /* Finished saving things for the debugger */ 289 /* Finished saving things for the debugger */
290 290
291 ldil L%syscall_trace,%r1 291 copy %r2,%r26
292 ldil L%do_syscall_trace_enter,%r1
292 ldil L%tracesys_next,%r2 293 ldil L%tracesys_next,%r2
293 be R%syscall_trace(%sr7,%r1) 294 be R%do_syscall_trace_enter(%sr7,%r1)
294 ldo R%tracesys_next(%r2),%r2 295 ldo R%tracesys_next(%r2),%r2
295 296
296tracesys_next: 297tracesys_next:
298 /* do_syscall_trace_enter either returned the syscallno, or -1L,
299 * so we skip restoring the PT_GR20 below, since we pulled it from
300 * task->thread.regs.gr[20] above.
301 */
302 copy %ret0,%r20
297 ldil L%sys_call_table,%r1 303 ldil L%sys_call_table,%r1
298 ldo R%sys_call_table(%r1), %r19 304 ldo R%sys_call_table(%r1), %r19
299 305
300 ldo -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get task ptr */ 306 ldo -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get task ptr */
301 LDREG TI_TASK(%r1), %r1 307 LDREG TI_TASK(%r1), %r1
302 LDREG TASK_PT_GR20(%r1), %r20
303 LDREG TASK_PT_GR26(%r1), %r26 /* Restore the users args */ 308 LDREG TASK_PT_GR26(%r1), %r26 /* Restore the users args */
304 LDREG TASK_PT_GR25(%r1), %r25 309 LDREG TASK_PT_GR25(%r1), %r25
305 LDREG TASK_PT_GR24(%r1), %r24 310 LDREG TASK_PT_GR24(%r1), %r24
@@ -336,7 +341,8 @@ tracesys_exit:
336#ifdef CONFIG_64BIT 341#ifdef CONFIG_64BIT
337 ldo -16(%r30),%r29 /* Reference param save area */ 342 ldo -16(%r30),%r29 /* Reference param save area */
338#endif 343#endif
339 bl syscall_trace, %r2 344 ldo TASK_REGS(%r1),%r26
345 bl do_syscall_trace_exit,%r2
340 STREG %r28,TASK_PT_GR28(%r1) /* save return value now */ 346 STREG %r28,TASK_PT_GR28(%r1) /* save return value now */
341 ldo -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get task ptr */ 347 ldo -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get task ptr */
342 LDREG TI_TASK(%r1), %r1 348 LDREG TI_TASK(%r1), %r1
@@ -353,12 +359,12 @@ tracesys_exit:
353 359
354tracesys_sigexit: 360tracesys_sigexit:
355 ldo -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get task ptr */ 361 ldo -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get task ptr */
356 LDREG 0(%r1), %r1 362 LDREG TI_TASK(%r1), %r1
357#ifdef CONFIG_64BIT 363#ifdef CONFIG_64BIT
358 ldo -16(%r30),%r29 /* Reference param save area */ 364 ldo -16(%r30),%r29 /* Reference param save area */
359#endif 365#endif
360 bl syscall_trace, %r2 366 bl do_syscall_trace_exit,%r2
361 nop 367 ldo TASK_REGS(%r1),%r26
362 368
363 ldil L%syscall_exit_rfi,%r1 369 ldil L%syscall_exit_rfi,%r1
364 be,n R%syscall_exit_rfi(%sr7,%r1) 370 be,n R%syscall_exit_rfi(%sr7,%r1)
diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S
index 775be2791bc2..fda4baa059b5 100644
--- a/arch/parisc/kernel/vmlinux.lds.S
+++ b/arch/parisc/kernel/vmlinux.lds.S
@@ -28,6 +28,7 @@
28#include <asm/cache.h> 28#include <asm/cache.h>
29#include <asm/page.h> 29#include <asm/page.h>
30#include <asm/asm-offsets.h> 30#include <asm/asm-offsets.h>
31#include <asm/thread_info.h>
31 32
32/* ld script to make hppa Linux kernel */ 33/* ld script to make hppa Linux kernel */
33#ifndef CONFIG_64BIT 34#ifndef CONFIG_64BIT
@@ -134,6 +135,15 @@ SECTIONS
134 __init_begin = .; 135 __init_begin = .;
135 INIT_TEXT_SECTION(16384) 136 INIT_TEXT_SECTION(16384)
136 INIT_DATA_SECTION(16) 137 INIT_DATA_SECTION(16)
138 /* we have to discard exit text and such at runtime, not link time */
139 .exit.text :
140 {
141 EXIT_TEXT
142 }
143 .exit.data :
144 {
145 EXIT_DATA
146 }
137 147
138 PERCPU(PAGE_SIZE) 148 PERCPU(PAGE_SIZE)
139 . = ALIGN(PAGE_SIZE); 149 . = ALIGN(PAGE_SIZE);
diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c
index d5aca31fddbb..13b6e3e59b99 100644
--- a/arch/parisc/mm/init.c
+++ b/arch/parisc/mm/init.c
@@ -434,8 +434,8 @@ void mark_rodata_ro(void)
434#define SET_MAP_OFFSET(x) ((void *)(((unsigned long)(x) + VM_MAP_OFFSET) \ 434#define SET_MAP_OFFSET(x) ((void *)(((unsigned long)(x) + VM_MAP_OFFSET) \
435 & ~(VM_MAP_OFFSET-1))) 435 & ~(VM_MAP_OFFSET-1)))
436 436
437void *vmalloc_start __read_mostly; 437void *parisc_vmalloc_start __read_mostly;
438EXPORT_SYMBOL(vmalloc_start); 438EXPORT_SYMBOL(parisc_vmalloc_start);
439 439
440#ifdef CONFIG_PA11 440#ifdef CONFIG_PA11
441unsigned long pcxl_dma_start __read_mostly; 441unsigned long pcxl_dma_start __read_mostly;
@@ -496,13 +496,14 @@ void __init mem_init(void)
496#ifdef CONFIG_PA11 496#ifdef CONFIG_PA11
497 if (hppa_dma_ops == &pcxl_dma_ops) { 497 if (hppa_dma_ops == &pcxl_dma_ops) {
498 pcxl_dma_start = (unsigned long)SET_MAP_OFFSET(MAP_START); 498 pcxl_dma_start = (unsigned long)SET_MAP_OFFSET(MAP_START);
499 vmalloc_start = SET_MAP_OFFSET(pcxl_dma_start + PCXL_DMA_MAP_SIZE); 499 parisc_vmalloc_start = SET_MAP_OFFSET(pcxl_dma_start
500 + PCXL_DMA_MAP_SIZE);
500 } else { 501 } else {
501 pcxl_dma_start = 0; 502 pcxl_dma_start = 0;
502 vmalloc_start = SET_MAP_OFFSET(MAP_START); 503 parisc_vmalloc_start = SET_MAP_OFFSET(MAP_START);
503 } 504 }
504#else 505#else
505 vmalloc_start = SET_MAP_OFFSET(MAP_START); 506 parisc_vmalloc_start = SET_MAP_OFFSET(MAP_START);
506#endif 507#endif
507 508
508 printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init)\n", 509 printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init)\n",
diff --git a/arch/powerpc/include/asm/firmware.h b/arch/powerpc/include/asm/firmware.h
index 3a179827528d..20778a405d7a 100644
--- a/arch/powerpc/include/asm/firmware.h
+++ b/arch/powerpc/include/asm/firmware.h
@@ -37,7 +37,7 @@
37#define FW_FEATURE_VIO ASM_CONST(0x0000000000004000) 37#define FW_FEATURE_VIO ASM_CONST(0x0000000000004000)
38#define FW_FEATURE_RDMA ASM_CONST(0x0000000000008000) 38#define FW_FEATURE_RDMA ASM_CONST(0x0000000000008000)
39#define FW_FEATURE_LLAN ASM_CONST(0x0000000000010000) 39#define FW_FEATURE_LLAN ASM_CONST(0x0000000000010000)
40#define FW_FEATURE_BULK ASM_CONST(0x0000000000020000) 40#define FW_FEATURE_BULK_REMOVE ASM_CONST(0x0000000000020000)
41#define FW_FEATURE_XDABR ASM_CONST(0x0000000000040000) 41#define FW_FEATURE_XDABR ASM_CONST(0x0000000000040000)
42#define FW_FEATURE_MULTITCE ASM_CONST(0x0000000000080000) 42#define FW_FEATURE_MULTITCE ASM_CONST(0x0000000000080000)
43#define FW_FEATURE_SPLPAR ASM_CONST(0x0000000000100000) 43#define FW_FEATURE_SPLPAR ASM_CONST(0x0000000000100000)
@@ -45,8 +45,7 @@
45#define FW_FEATURE_LPAR ASM_CONST(0x0000000000400000) 45#define FW_FEATURE_LPAR ASM_CONST(0x0000000000400000)
46#define FW_FEATURE_PS3_LV1 ASM_CONST(0x0000000000800000) 46#define FW_FEATURE_PS3_LV1 ASM_CONST(0x0000000000800000)
47#define FW_FEATURE_BEAT ASM_CONST(0x0000000001000000) 47#define FW_FEATURE_BEAT ASM_CONST(0x0000000001000000)
48#define FW_FEATURE_BULK_REMOVE ASM_CONST(0x0000000002000000) 48#define FW_FEATURE_CMO ASM_CONST(0x0000000002000000)
49#define FW_FEATURE_CMO ASM_CONST(0x0000000004000000)
50 49
51#ifndef __ASSEMBLY__ 50#ifndef __ASSEMBLY__
52 51
@@ -58,8 +57,9 @@ enum {
58 FW_FEATURE_PERF | FW_FEATURE_DUMP | FW_FEATURE_INTERRUPT | 57 FW_FEATURE_PERF | FW_FEATURE_DUMP | FW_FEATURE_INTERRUPT |
59 FW_FEATURE_MIGRATE | FW_FEATURE_PERFMON | FW_FEATURE_CRQ | 58 FW_FEATURE_MIGRATE | FW_FEATURE_PERFMON | FW_FEATURE_CRQ |
60 FW_FEATURE_VIO | FW_FEATURE_RDMA | FW_FEATURE_LLAN | 59 FW_FEATURE_VIO | FW_FEATURE_RDMA | FW_FEATURE_LLAN |
61 FW_FEATURE_BULK | FW_FEATURE_XDABR | FW_FEATURE_MULTITCE | 60 FW_FEATURE_BULK_REMOVE | FW_FEATURE_XDABR |
62 FW_FEATURE_SPLPAR | FW_FEATURE_LPAR | FW_FEATURE_CMO, 61 FW_FEATURE_MULTITCE | FW_FEATURE_SPLPAR | FW_FEATURE_LPAR |
62 FW_FEATURE_CMO,
63 FW_FEATURE_PSERIES_ALWAYS = 0, 63 FW_FEATURE_PSERIES_ALWAYS = 0,
64 FW_FEATURE_ISERIES_POSSIBLE = FW_FEATURE_ISERIES | FW_FEATURE_LPAR, 64 FW_FEATURE_ISERIES_POSSIBLE = FW_FEATURE_ISERIES | FW_FEATURE_LPAR,
65 FW_FEATURE_ISERIES_ALWAYS = FW_FEATURE_ISERIES | FW_FEATURE_LPAR, 65 FW_FEATURE_ISERIES_ALWAYS = FW_FEATURE_ISERIES | FW_FEATURE_LPAR,
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 0b9c9135922e..03c862b6a9c4 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -711,6 +711,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
711 .cpu_setup = __setup_cpu_750, 711 .cpu_setup = __setup_cpu_750,
712 .machine_check = machine_check_generic, 712 .machine_check = machine_check_generic,
713 .platform = "ppc750", 713 .platform = "ppc750",
714 .oprofile_cpu_type = "ppc/750",
715 .oprofile_type = PPC_OPROFILE_G4,
714 }, 716 },
715 { /* 745/755 */ 717 { /* 745/755 */
716 .pvr_mask = 0xfffff000, 718 .pvr_mask = 0xfffff000,
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 900e0eea0099..f9fd54bfcc84 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -1038,8 +1038,7 @@ _GLOBAL(mod_return_to_handler)
1038 * We are in a module using the module's TOC. 1038 * We are in a module using the module's TOC.
1039 * Switch to our TOC to run inside the core kernel. 1039 * Switch to our TOC to run inside the core kernel.
1040 */ 1040 */
1041 LOAD_REG_IMMEDIATE(r4,ftrace_return_to_handler) 1041 ld r2, PACATOC(r13)
1042 ld r2, 8(r4)
1043 1042
1044 bl .ftrace_return_to_handler 1043 bl .ftrace_return_to_handler
1045 nop 1044 nop
diff --git a/arch/powerpc/kernel/kgdb.c b/arch/powerpc/kernel/kgdb.c
index fe8f71dd0b3f..641c74bb8e27 100644
--- a/arch/powerpc/kernel/kgdb.c
+++ b/arch/powerpc/kernel/kgdb.c
@@ -282,12 +282,6 @@ void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
282{ 282{
283 unsigned long *ptr = gdb_regs; 283 unsigned long *ptr = gdb_regs;
284 int reg; 284 int reg;
285#ifdef CONFIG_SPE
286 union {
287 u32 v32[2];
288 u64 v64;
289 } acc;
290#endif
291 285
292 for (reg = 0; reg < 32; reg++) 286 for (reg = 0; reg < 32; reg++)
293 UNPACK64(regs->gpr[reg], ptr); 287 UNPACK64(regs->gpr[reg], ptr);
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index bb8209e34931..e8dfdbd9327a 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -1190,7 +1190,7 @@ EXPORT_SYMBOL(pcibios_align_resource);
1190 * Reparent resource children of pr that conflict with res 1190 * Reparent resource children of pr that conflict with res
1191 * under res, and make res replace those children. 1191 * under res, and make res replace those children.
1192 */ 1192 */
1193static int __init reparent_resources(struct resource *parent, 1193static int reparent_resources(struct resource *parent,
1194 struct resource *res) 1194 struct resource *res)
1195{ 1195{
1196 struct resource *p, **pp; 1196 struct resource *p, **pp;
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 1168c5f440ab..2ec1eaed19ca 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1016,9 +1016,13 @@ void show_stack(struct task_struct *tsk, unsigned long *stack)
1016#ifdef CONFIG_FUNCTION_GRAPH_TRACER 1016#ifdef CONFIG_FUNCTION_GRAPH_TRACER
1017 int curr_frame = current->curr_ret_stack; 1017 int curr_frame = current->curr_ret_stack;
1018 extern void return_to_handler(void); 1018 extern void return_to_handler(void);
1019 unsigned long addr = (unsigned long)return_to_handler; 1019 unsigned long rth = (unsigned long)return_to_handler;
1020 unsigned long mrth = -1;
1020#ifdef CONFIG_PPC64 1021#ifdef CONFIG_PPC64
1021 addr = *(unsigned long*)addr; 1022 extern void mod_return_to_handler(void);
1023 rth = *(unsigned long *)rth;
1024 mrth = (unsigned long)mod_return_to_handler;
1025 mrth = *(unsigned long *)mrth;
1022#endif 1026#endif
1023#endif 1027#endif
1024 1028
@@ -1044,7 +1048,7 @@ void show_stack(struct task_struct *tsk, unsigned long *stack)
1044 if (!firstframe || ip != lr) { 1048 if (!firstframe || ip != lr) {
1045 printk("["REG"] ["REG"] %pS", sp, ip, (void *)ip); 1049 printk("["REG"] ["REG"] %pS", sp, ip, (void *)ip);
1046#ifdef CONFIG_FUNCTION_GRAPH_TRACER 1050#ifdef CONFIG_FUNCTION_GRAPH_TRACER
1047 if (ip == addr && curr_frame >= 0) { 1051 if ((ip == rth || ip == mrth) && curr_frame >= 0) {
1048 printk(" (%pS)", 1052 printk(" (%pS)",
1049 (void *)current->ret_stack[curr_frame].ret); 1053 (void *)current->ret_stack[curr_frame].ret);
1050 curr_frame--; 1054 curr_frame--;
diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
index f56429362a12..27735a7ac12b 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -236,6 +236,7 @@ SECTIONS
236 READ_MOSTLY_DATA(L1_CACHE_BYTES) 236 READ_MOSTLY_DATA(L1_CACHE_BYTES)
237 } 237 }
238 238
239 . = ALIGN(PAGE_SIZE);
239 .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { 240 .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
240 NOSAVE_DATA 241 NOSAVE_DATA
241 } 242 }
diff --git a/arch/powerpc/kvm/timing.c b/arch/powerpc/kvm/timing.c
index 47ee603f558e..2aa371e30079 100644
--- a/arch/powerpc/kvm/timing.c
+++ b/arch/powerpc/kvm/timing.c
@@ -201,7 +201,7 @@ static int kvmppc_exit_timing_open(struct inode *inode, struct file *file)
201 return single_open(file, kvmppc_exit_timing_show, inode->i_private); 201 return single_open(file, kvmppc_exit_timing_show, inode->i_private);
202} 202}
203 203
204static struct file_operations kvmppc_exit_timing_fops = { 204static const struct file_operations kvmppc_exit_timing_fops = {
205 .owner = THIS_MODULE, 205 .owner = THIS_MODULE,
206 .open = kvmppc_exit_timing_open, 206 .open = kvmppc_exit_timing_open,
207 .read = seq_read, 207 .read = seq_read,
diff --git a/arch/powerpc/mm/slb_low.S b/arch/powerpc/mm/slb_low.S
index bc44dc4b5c67..95ce35581696 100644
--- a/arch/powerpc/mm/slb_low.S
+++ b/arch/powerpc/mm/slb_low.S
@@ -72,19 +72,17 @@ _GLOBAL(slb_miss_kernel_load_vmemmap)
721: 721:
73#endif /* CONFIG_SPARSEMEM_VMEMMAP */ 73#endif /* CONFIG_SPARSEMEM_VMEMMAP */
74 74
75 /* vmalloc/ioremap mapping encoding bits, the "li" instructions below 75 /* vmalloc mapping gets the encoding from the PACA as the mapping
76 * will be patched by the kernel at boot 76 * can be demoted from 64K -> 4K dynamically on some machines
77 */ 77 */
78BEGIN_FTR_SECTION
79 /* check whether this is in vmalloc or ioremap space */
80 clrldi r11,r10,48 78 clrldi r11,r10,48
81 cmpldi r11,(VMALLOC_SIZE >> 28) - 1 79 cmpldi r11,(VMALLOC_SIZE >> 28) - 1
82 bgt 5f 80 bgt 5f
83 lhz r11,PACAVMALLOCSLLP(r13) 81 lhz r11,PACAVMALLOCSLLP(r13)
84 b 6f 82 b 6f
855: 835:
86END_FTR_SECTION_IFCLR(CPU_FTR_CI_LARGE_PAGE) 84 /* IO mapping */
87_GLOBAL(slb_miss_kernel_load_io) 85 _GLOBAL(slb_miss_kernel_load_io)
88 li r11,0 86 li r11,0
896: 876:
90BEGIN_FTR_SECTION 88BEGIN_FTR_SECTION
diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c
index aca5741ddc67..a86c34b3bb84 100644
--- a/arch/powerpc/platforms/cell/axon_msi.c
+++ b/arch/powerpc/platforms/cell/axon_msi.c
@@ -365,7 +365,7 @@ static int axon_msi_probe(struct of_device *device,
365 printk(KERN_ERR 365 printk(KERN_ERR
366 "axon_msi: couldn't parse dcr properties on %s\n", 366 "axon_msi: couldn't parse dcr properties on %s\n",
367 dn->full_name); 367 dn->full_name);
368 goto out; 368 goto out_free_msic;
369 } 369 }
370 370
371 msic->dcr_host = dcr_map(dn, dcr_base, dcr_len); 371 msic->dcr_host = dcr_map(dn, dcr_base, dcr_len);
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index 961309446170..884e8bcec499 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -147,7 +147,7 @@ static int __fops ## _open(struct inode *inode, struct file *file) \
147 __simple_attr_check_format(__fmt, 0ull); \ 147 __simple_attr_check_format(__fmt, 0ull); \
148 return spufs_attr_open(inode, file, __get, __set, __fmt); \ 148 return spufs_attr_open(inode, file, __get, __set, __fmt); \
149} \ 149} \
150static struct file_operations __fops = { \ 150static const struct file_operations __fops = { \
151 .owner = THIS_MODULE, \ 151 .owner = THIS_MODULE, \
152 .open = __fops ## _open, \ 152 .open = __fops ## _open, \
153 .release = spufs_attr_release, \ 153 .release = spufs_attr_release, \
diff --git a/arch/powerpc/platforms/powermac/low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c
index 21226b74c9b2..414ca9849f23 100644
--- a/arch/powerpc/platforms/powermac/low_i2c.c
+++ b/arch/powerpc/platforms/powermac/low_i2c.c
@@ -540,8 +540,11 @@ static struct pmac_i2c_host_kw *__init kw_i2c_host_init(struct device_node *np)
540 /* Make sure IRQ is disabled */ 540 /* Make sure IRQ is disabled */
541 kw_write_reg(reg_ier, 0); 541 kw_write_reg(reg_ier, 0);
542 542
543 /* Request chip interrupt */ 543 /* Request chip interrupt. We set IRQF_TIMER because we don't
544 if (request_irq(host->irq, kw_i2c_irq, 0, "keywest i2c", host)) 544 * want that interrupt disabled between the 2 passes of driver
545 * suspend or we'll have issues running the pfuncs
546 */
547 if (request_irq(host->irq, kw_i2c_irq, IRQF_TIMER, "keywest i2c", host))
545 host->irq = NO_IRQ; 548 host->irq = NO_IRQ;
546 549
547 printk(KERN_INFO "KeyWest i2c @0x%08x irq %d %s\n", 550 printk(KERN_INFO "KeyWest i2c @0x%08x irq %d %s\n",
diff --git a/arch/powerpc/platforms/pseries/dtl.c b/arch/powerpc/platforms/pseries/dtl.c
index ab69925d579b..937a544a236d 100644
--- a/arch/powerpc/platforms/pseries/dtl.c
+++ b/arch/powerpc/platforms/pseries/dtl.c
@@ -209,7 +209,7 @@ static ssize_t dtl_file_read(struct file *filp, char __user *buf, size_t len,
209 return n_read * sizeof(struct dtl_entry); 209 return n_read * sizeof(struct dtl_entry);
210} 210}
211 211
212static struct file_operations dtl_fops = { 212static const struct file_operations dtl_fops = {
213 .open = dtl_file_open, 213 .open = dtl_file_open,
214 .release = dtl_file_release, 214 .release = dtl_file_release,
215 .read = dtl_file_read, 215 .read = dtl_file_read,
diff --git a/arch/powerpc/platforms/pseries/firmware.c b/arch/powerpc/platforms/pseries/firmware.c
index 5a707da3f5c2..0a14d8cd314f 100644
--- a/arch/powerpc/platforms/pseries/firmware.c
+++ b/arch/powerpc/platforms/pseries/firmware.c
@@ -51,11 +51,10 @@ firmware_features_table[FIRMWARE_MAX_FEATURES] = {
51 {FW_FEATURE_VIO, "hcall-vio"}, 51 {FW_FEATURE_VIO, "hcall-vio"},
52 {FW_FEATURE_RDMA, "hcall-rdma"}, 52 {FW_FEATURE_RDMA, "hcall-rdma"},
53 {FW_FEATURE_LLAN, "hcall-lLAN"}, 53 {FW_FEATURE_LLAN, "hcall-lLAN"},
54 {FW_FEATURE_BULK, "hcall-bulk"}, 54 {FW_FEATURE_BULK_REMOVE, "hcall-bulk"},
55 {FW_FEATURE_XDABR, "hcall-xdabr"}, 55 {FW_FEATURE_XDABR, "hcall-xdabr"},
56 {FW_FEATURE_MULTITCE, "hcall-multi-tce"}, 56 {FW_FEATURE_MULTITCE, "hcall-multi-tce"},
57 {FW_FEATURE_SPLPAR, "hcall-splpar"}, 57 {FW_FEATURE_SPLPAR, "hcall-splpar"},
58 {FW_FEATURE_BULK_REMOVE, "hcall-bulk"},
59}; 58};
60 59
61/* Build up the firmware features bitmask using the contents of 60/* Build up the firmware features bitmask using the contents of
diff --git a/arch/s390/hypfs/hypfs_diag.c b/arch/s390/hypfs/hypfs_diag.c
index 704dd396257b..77df726180ba 100644
--- a/arch/s390/hypfs/hypfs_diag.c
+++ b/arch/s390/hypfs/hypfs_diag.c
@@ -438,7 +438,7 @@ static int diag204_probe(void)
438 } 438 }
439 if (diag204((unsigned long)SUBC_STIB6 | 439 if (diag204((unsigned long)SUBC_STIB6 |
440 (unsigned long)INFO_EXT, pages, buf) >= 0) { 440 (unsigned long)INFO_EXT, pages, buf) >= 0) {
441 diag204_store_sc = SUBC_STIB7; 441 diag204_store_sc = SUBC_STIB6;
442 diag204_info_type = INFO_EXT; 442 diag204_info_type = INFO_EXT;
443 goto out; 443 goto out;
444 } 444 }
diff --git a/arch/s390/include/asm/delay.h b/arch/s390/include/asm/delay.h
index a356c958e260..8a096b83f51f 100644
--- a/arch/s390/include/asm/delay.h
+++ b/arch/s390/include/asm/delay.h
@@ -14,10 +14,11 @@
14#ifndef _S390_DELAY_H 14#ifndef _S390_DELAY_H
15#define _S390_DELAY_H 15#define _S390_DELAY_H
16 16
17extern void __udelay(unsigned long usecs); 17extern void __udelay(unsigned long long usecs);
18extern void udelay_simple(unsigned long usecs); 18extern void udelay_simple(unsigned long long usecs);
19extern void __delay(unsigned long loops); 19extern void __delay(unsigned long loops);
20 20
21#define udelay(n) __udelay(n) 21#define udelay(n) __udelay((unsigned long long) (n))
22#define mdelay(n) __udelay((unsigned long long) (n) * 1000)
22 23
23#endif /* defined(_S390_DELAY_H) */ 24#endif /* defined(_S390_DELAY_H) */
diff --git a/arch/s390/include/asm/elf.h b/arch/s390/include/asm/elf.h
index 74d0bbb7d955..e885442c1dfe 100644
--- a/arch/s390/include/asm/elf.h
+++ b/arch/s390/include/asm/elf.h
@@ -92,6 +92,18 @@
92/* Keep this the last entry. */ 92/* Keep this the last entry. */
93#define R_390_NUM 61 93#define R_390_NUM 61
94 94
95/* Bits present in AT_HWCAP. */
96#define HWCAP_S390_ESAN3 1
97#define HWCAP_S390_ZARCH 2
98#define HWCAP_S390_STFLE 4
99#define HWCAP_S390_MSA 8
100#define HWCAP_S390_LDISP 16
101#define HWCAP_S390_EIMM 32
102#define HWCAP_S390_DFP 64
103#define HWCAP_S390_HPAGE 128
104#define HWCAP_S390_ETF3EH 256
105#define HWCAP_S390_HIGH_GPRS 512
106
95/* 107/*
96 * These are used to set parameters in the core dumps. 108 * These are used to set parameters in the core dumps.
97 */ 109 */
diff --git a/arch/s390/include/asm/ptrace.h b/arch/s390/include/asm/ptrace.h
index 539263fc9ab9..95dcf183a28d 100644
--- a/arch/s390/include/asm/ptrace.h
+++ b/arch/s390/include/asm/ptrace.h
@@ -311,6 +311,10 @@ typedef struct
311 __u32 orig_gpr2; 311 __u32 orig_gpr2;
312} s390_compat_regs; 312} s390_compat_regs;
313 313
314typedef struct
315{
316 __u32 gprs_high[NUM_GPRS];
317} s390_compat_regs_high;
314 318
315#ifdef __KERNEL__ 319#ifdef __KERNEL__
316 320
diff --git a/arch/s390/include/asm/ucontext.h b/arch/s390/include/asm/ucontext.h
index d69bec0b03f5..cfb874e66c9a 100644
--- a/arch/s390/include/asm/ucontext.h
+++ b/arch/s390/include/asm/ucontext.h
@@ -9,6 +9,21 @@
9#ifndef _ASM_S390_UCONTEXT_H 9#ifndef _ASM_S390_UCONTEXT_H
10#define _ASM_S390_UCONTEXT_H 10#define _ASM_S390_UCONTEXT_H
11 11
12#define UC_EXTENDED 0x00000001
13
14#ifndef __s390x__
15
16struct ucontext_extended {
17 unsigned long uc_flags;
18 struct ucontext *uc_link;
19 stack_t uc_stack;
20 _sigregs uc_mcontext;
21 unsigned long uc_sigmask[2];
22 unsigned long uc_gprs_high[16];
23};
24
25#endif
26
12struct ucontext { 27struct ucontext {
13 unsigned long uc_flags; 28 unsigned long uc_flags;
14 struct ucontext *uc_link; 29 struct ucontext *uc_link;
diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c
index b537cb0e9b55..eee999853a7c 100644
--- a/arch/s390/kernel/compat_signal.c
+++ b/arch/s390/kernel/compat_signal.c
@@ -39,6 +39,7 @@ typedef struct
39 struct sigcontext32 sc; 39 struct sigcontext32 sc;
40 _sigregs32 sregs; 40 _sigregs32 sregs;
41 int signo; 41 int signo;
42 __u32 gprs_high[NUM_GPRS];
42 __u8 retcode[S390_SYSCALL_SIZE]; 43 __u8 retcode[S390_SYSCALL_SIZE];
43} sigframe32; 44} sigframe32;
44 45
@@ -48,6 +49,7 @@ typedef struct
48 __u8 retcode[S390_SYSCALL_SIZE]; 49 __u8 retcode[S390_SYSCALL_SIZE];
49 compat_siginfo_t info; 50 compat_siginfo_t info;
50 struct ucontext32 uc; 51 struct ucontext32 uc;
52 __u32 gprs_high[NUM_GPRS];
51} rt_sigframe32; 53} rt_sigframe32;
52 54
53int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from) 55int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
@@ -344,6 +346,30 @@ static int restore_sigregs32(struct pt_regs *regs,_sigregs32 __user *sregs)
344 return 0; 346 return 0;
345} 347}
346 348
349static int save_sigregs_gprs_high(struct pt_regs *regs, __u32 __user *uregs)
350{
351 __u32 gprs_high[NUM_GPRS];
352 int i;
353
354 for (i = 0; i < NUM_GPRS; i++)
355 gprs_high[i] = regs->gprs[i] >> 32;
356
357 return __copy_to_user(uregs, &gprs_high, sizeof(gprs_high));
358}
359
360static int restore_sigregs_gprs_high(struct pt_regs *regs, __u32 __user *uregs)
361{
362 __u32 gprs_high[NUM_GPRS];
363 int err, i;
364
365 err = __copy_from_user(&gprs_high, uregs, sizeof(gprs_high));
366 if (err)
367 return err;
368 for (i = 0; i < NUM_GPRS; i++)
369 *(__u32 *)&regs->gprs[i] = gprs_high[i];
370 return 0;
371}
372
347asmlinkage long sys32_sigreturn(void) 373asmlinkage long sys32_sigreturn(void)
348{ 374{
349 struct pt_regs *regs = task_pt_regs(current); 375 struct pt_regs *regs = task_pt_regs(current);
@@ -363,6 +389,8 @@ asmlinkage long sys32_sigreturn(void)
363 389
364 if (restore_sigregs32(regs, &frame->sregs)) 390 if (restore_sigregs32(regs, &frame->sregs))
365 goto badframe; 391 goto badframe;
392 if (restore_sigregs_gprs_high(regs, frame->gprs_high))
393 goto badframe;
366 394
367 return regs->gprs[2]; 395 return regs->gprs[2];
368 396
@@ -394,6 +422,8 @@ asmlinkage long sys32_rt_sigreturn(void)
394 422
395 if (restore_sigregs32(regs, &frame->uc.uc_mcontext)) 423 if (restore_sigregs32(regs, &frame->uc.uc_mcontext))
396 goto badframe; 424 goto badframe;
425 if (restore_sigregs_gprs_high(regs, frame->gprs_high))
426 goto badframe;
397 427
398 err = __get_user(ss_sp, &frame->uc.uc_stack.ss_sp); 428 err = __get_user(ss_sp, &frame->uc.uc_stack.ss_sp);
399 st.ss_sp = compat_ptr(ss_sp); 429 st.ss_sp = compat_ptr(ss_sp);
@@ -474,6 +504,8 @@ static int setup_frame32(int sig, struct k_sigaction *ka,
474 504
475 if (save_sigregs32(regs, &frame->sregs)) 505 if (save_sigregs32(regs, &frame->sregs))
476 goto give_sigsegv; 506 goto give_sigsegv;
507 if (save_sigregs_gprs_high(regs, frame->gprs_high))
508 goto give_sigsegv;
477 if (__put_user((unsigned long) &frame->sregs, &frame->sc.sregs)) 509 if (__put_user((unsigned long) &frame->sregs, &frame->sc.sregs))
478 goto give_sigsegv; 510 goto give_sigsegv;
479 511
@@ -529,13 +561,14 @@ static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info,
529 goto give_sigsegv; 561 goto give_sigsegv;
530 562
531 /* Create the ucontext. */ 563 /* Create the ucontext. */
532 err |= __put_user(0, &frame->uc.uc_flags); 564 err |= __put_user(UC_EXTENDED, &frame->uc.uc_flags);
533 err |= __put_user(0, &frame->uc.uc_link); 565 err |= __put_user(0, &frame->uc.uc_link);
534 err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp); 566 err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
535 err |= __put_user(sas_ss_flags(regs->gprs[15]), 567 err |= __put_user(sas_ss_flags(regs->gprs[15]),
536 &frame->uc.uc_stack.ss_flags); 568 &frame->uc.uc_stack.ss_flags);
537 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); 569 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
538 err |= save_sigregs32(regs, &frame->uc.uc_mcontext); 570 err |= save_sigregs32(regs, &frame->uc.uc_mcontext);
571 err |= save_sigregs_gprs_high(regs, frame->gprs_high);
539 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); 572 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
540 if (err) 573 if (err)
541 goto give_sigsegv; 574 goto give_sigsegv;
diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S
index 682fb69dba21..cbd9901dc0f8 100644
--- a/arch/s390/kernel/compat_wrapper.S
+++ b/arch/s390/kernel/compat_wrapper.S
@@ -409,7 +409,7 @@ sys32_munmap_wrapper:
409 .globl sys32_truncate_wrapper 409 .globl sys32_truncate_wrapper
410sys32_truncate_wrapper: 410sys32_truncate_wrapper:
411 llgtr %r2,%r2 # const char * 411 llgtr %r2,%r2 # const char *
412 llgfr %r3,%r3 # unsigned long 412 lgfr %r3,%r3 # long
413 jg sys_truncate # branch to system call 413 jg sys_truncate # branch to system call
414 414
415 .globl sys32_ftruncate_wrapper 415 .globl sys32_ftruncate_wrapper
diff --git a/arch/s390/kernel/ftrace.c b/arch/s390/kernel/ftrace.c
index 57bdcb1e3cdf..f5fe34dd821b 100644
--- a/arch/s390/kernel/ftrace.c
+++ b/arch/s390/kernel/ftrace.c
@@ -185,9 +185,6 @@ unsigned long prepare_ftrace_return(unsigned long ip, unsigned long parent)
185{ 185{
186 struct ftrace_graph_ent trace; 186 struct ftrace_graph_ent trace;
187 187
188 /* Nmi's are currently unsupported. */
189 if (unlikely(in_nmi()))
190 goto out;
191 if (unlikely(atomic_read(&current->tracing_graph_pause))) 188 if (unlikely(atomic_read(&current->tracing_graph_pause)))
192 goto out; 189 goto out;
193 if (ftrace_push_return_trace(parent, ip, &trace.depth, 0) == -EBUSY) 190 if (ftrace_push_return_trace(parent, ip, &trace.depth, 0) == -EBUSY)
diff --git a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c
index ab2e3ed28abc..639380a0c45c 100644
--- a/arch/s390/kernel/module.c
+++ b/arch/s390/kernel/module.c
@@ -55,6 +55,8 @@ void *module_alloc(unsigned long size)
55/* Free memory returned from module_alloc */ 55/* Free memory returned from module_alloc */
56void module_free(struct module *mod, void *module_region) 56void module_free(struct module *mod, void *module_region)
57{ 57{
58 vfree(mod->arch.syminfo);
59 mod->arch.syminfo = NULL;
58 vfree(module_region); 60 vfree(module_region);
59} 61}
60 62
@@ -402,6 +404,7 @@ int module_finalize(const Elf_Ehdr *hdr,
402 struct module *me) 404 struct module *me)
403{ 405{
404 vfree(me->arch.syminfo); 406 vfree(me->arch.syminfo);
407 me->arch.syminfo = NULL;
405 return module_bug_finalize(hdr, sechdrs, me); 408 return module_bug_finalize(hdr, sechdrs, me);
406} 409}
407 410
diff --git a/arch/s390/kernel/processor.c b/arch/s390/kernel/processor.c
index 802c8ab247f3..0729f36c2fe3 100644
--- a/arch/s390/kernel/processor.c
+++ b/arch/s390/kernel/processor.c
@@ -31,9 +31,9 @@ void __cpuinit print_cpu_info(void)
31 31
32static int show_cpuinfo(struct seq_file *m, void *v) 32static int show_cpuinfo(struct seq_file *m, void *v)
33{ 33{
34 static const char *hwcap_str[9] = { 34 static const char *hwcap_str[10] = {
35 "esan3", "zarch", "stfle", "msa", "ldisp", "eimm", "dfp", 35 "esan3", "zarch", "stfle", "msa", "ldisp", "eimm", "dfp",
36 "edat", "etf3eh" 36 "edat", "etf3eh", "highgprs"
37 }; 37 };
38 struct _lowcore *lc; 38 struct _lowcore *lc;
39 unsigned long n = (unsigned long) v - 1; 39 unsigned long n = (unsigned long) v - 1;
@@ -48,7 +48,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
48 num_online_cpus(), loops_per_jiffy/(500000/HZ), 48 num_online_cpus(), loops_per_jiffy/(500000/HZ),
49 (loops_per_jiffy/(5000/HZ))%100); 49 (loops_per_jiffy/(5000/HZ))%100);
50 seq_puts(m, "features\t: "); 50 seq_puts(m, "features\t: ");
51 for (i = 0; i < 9; i++) 51 for (i = 0; i < 10; i++)
52 if (hwcap_str[i] && (elf_hwcap & (1UL << i))) 52 if (hwcap_str[i] && (elf_hwcap & (1UL << i)))
53 seq_printf(m, "%s ", hwcap_str[i]); 53 seq_printf(m, "%s ", hwcap_str[i]);
54 seq_puts(m, "\n"); 54 seq_puts(m, "\n");
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
index a8738676b26c..653c6a178740 100644
--- a/arch/s390/kernel/ptrace.c
+++ b/arch/s390/kernel/ptrace.c
@@ -57,6 +57,7 @@
57enum s390_regset { 57enum s390_regset {
58 REGSET_GENERAL, 58 REGSET_GENERAL,
59 REGSET_FP, 59 REGSET_FP,
60 REGSET_GENERAL_EXTENDED,
60}; 61};
61 62
62static void 63static void
@@ -879,6 +880,67 @@ static int s390_compat_regs_set(struct task_struct *target,
879 return rc; 880 return rc;
880} 881}
881 882
883static int s390_compat_regs_high_get(struct task_struct *target,
884 const struct user_regset *regset,
885 unsigned int pos, unsigned int count,
886 void *kbuf, void __user *ubuf)
887{
888 compat_ulong_t *gprs_high;
889
890 gprs_high = (compat_ulong_t *)
891 &task_pt_regs(target)->gprs[pos / sizeof(compat_ulong_t)];
892 if (kbuf) {
893 compat_ulong_t *k = kbuf;
894 while (count > 0) {
895 *k++ = *gprs_high;
896 gprs_high += 2;
897 count -= sizeof(*k);
898 }
899 } else {
900 compat_ulong_t __user *u = ubuf;
901 while (count > 0) {
902 if (__put_user(*gprs_high, u++))
903 return -EFAULT;
904 gprs_high += 2;
905 count -= sizeof(*u);
906 }
907 }
908 return 0;
909}
910
911static int s390_compat_regs_high_set(struct task_struct *target,
912 const struct user_regset *regset,
913 unsigned int pos, unsigned int count,
914 const void *kbuf, const void __user *ubuf)
915{
916 compat_ulong_t *gprs_high;
917 int rc = 0;
918
919 gprs_high = (compat_ulong_t *)
920 &task_pt_regs(target)->gprs[pos / sizeof(compat_ulong_t)];
921 if (kbuf) {
922 const compat_ulong_t *k = kbuf;
923 while (count > 0) {
924 *gprs_high = *k++;
925 *gprs_high += 2;
926 count -= sizeof(*k);
927 }
928 } else {
929 const compat_ulong_t __user *u = ubuf;
930 while (count > 0 && !rc) {
931 unsigned long word;
932 rc = __get_user(word, u++);
933 if (rc)
934 break;
935 *gprs_high = word;
936 *gprs_high += 2;
937 count -= sizeof(*u);
938 }
939 }
940
941 return rc;
942}
943
882static const struct user_regset s390_compat_regsets[] = { 944static const struct user_regset s390_compat_regsets[] = {
883 [REGSET_GENERAL] = { 945 [REGSET_GENERAL] = {
884 .core_note_type = NT_PRSTATUS, 946 .core_note_type = NT_PRSTATUS,
@@ -896,6 +958,14 @@ static const struct user_regset s390_compat_regsets[] = {
896 .get = s390_fpregs_get, 958 .get = s390_fpregs_get,
897 .set = s390_fpregs_set, 959 .set = s390_fpregs_set,
898 }, 960 },
961 [REGSET_GENERAL_EXTENDED] = {
962 .core_note_type = NT_PRXSTATUS,
963 .n = sizeof(s390_compat_regs_high) / sizeof(compat_long_t),
964 .size = sizeof(compat_long_t),
965 .align = sizeof(compat_long_t),
966 .get = s390_compat_regs_high_get,
967 .set = s390_compat_regs_high_set,
968 },
899}; 969};
900 970
901static const struct user_regset_view user_s390_compat_view = { 971static const struct user_regset_view user_s390_compat_view = {
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index 9ed13a1ed376..061479ff029f 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -729,7 +729,7 @@ static void __init setup_hwcaps(void)
729 729
730 if ((facility_list & (1UL << (31 - 22))) 730 if ((facility_list & (1UL << (31 - 22)))
731 && (facility_list & (1UL << (31 - 30)))) 731 && (facility_list & (1UL << (31 - 30))))
732 elf_hwcap |= 1UL << 8; 732 elf_hwcap |= HWCAP_S390_ETF3EH;
733 733
734 /* 734 /*
735 * Check for additional facilities with store-facility-list-extended. 735 * Check for additional facilities with store-facility-list-extended.
@@ -748,11 +748,20 @@ static void __init setup_hwcaps(void)
748 __stfle(&facility_list_extended, 1) > 0) { 748 __stfle(&facility_list_extended, 1) > 0) {
749 if ((facility_list_extended & (1ULL << (63 - 42))) 749 if ((facility_list_extended & (1ULL << (63 - 42)))
750 && (facility_list_extended & (1ULL << (63 - 44)))) 750 && (facility_list_extended & (1ULL << (63 - 44))))
751 elf_hwcap |= 1UL << 6; 751 elf_hwcap |= HWCAP_S390_DFP;
752 } 752 }
753 753
754 /*
755 * Huge page support HWCAP_S390_HPAGE is bit 7.
756 */
754 if (MACHINE_HAS_HPAGE) 757 if (MACHINE_HAS_HPAGE)
755 elf_hwcap |= 1UL << 7; 758 elf_hwcap |= HWCAP_S390_HPAGE;
759
760 /*
761 * 64-bit register support for 31-bit processes
762 * HWCAP_S390_HIGH_GPRS is bit 9.
763 */
764 elf_hwcap |= HWCAP_S390_HIGH_GPRS;
756 765
757 switch (S390_lowcore.cpu_id.machine) { 766 switch (S390_lowcore.cpu_id.machine) {
758 case 0x9672: 767 case 0x9672:
diff --git a/arch/s390/kernel/swsusp_asm64.S b/arch/s390/kernel/swsusp_asm64.S
index fe927d0bc20b..7c8653e27db6 100644
--- a/arch/s390/kernel/swsusp_asm64.S
+++ b/arch/s390/kernel/swsusp_asm64.S
@@ -43,7 +43,7 @@ swsusp_arch_suspend:
43 lghi %r1,0x1000 43 lghi %r1,0x1000
44 44
45 /* Save CPU address */ 45 /* Save CPU address */
46 stap __LC_CPU_ADDRESS(%r1) 46 stap __LC_CPU_ADDRESS(%r0)
47 47
48 /* Store registers */ 48 /* Store registers */
49 mvc 0x318(4,%r1),__SF_EMPTY(%r15) /* move prefix to lowcore */ 49 mvc 0x318(4,%r1),__SF_EMPTY(%r15) /* move prefix to lowcore */
@@ -69,8 +69,21 @@ swsusp_arch_suspend:
69 stmg %r0,%r15,0x280(%r1) /* store general registers */ 69 stmg %r0,%r15,0x280(%r1) /* store general registers */
70 70
71 stpt 0x328(%r1) /* store timer */ 71 stpt 0x328(%r1) /* store timer */
72 stck __SF_EMPTY(%r15) /* store clock */
72 stckc 0x330(%r1) /* store clock comparator */ 73 stckc 0x330(%r1) /* store clock comparator */
73 74
75 /* Update cputime accounting before going to sleep */
76 lg %r0,__LC_LAST_UPDATE_TIMER
77 slg %r0,0x328(%r1)
78 alg %r0,__LC_SYSTEM_TIMER
79 stg %r0,__LC_SYSTEM_TIMER
80 mvc __LC_LAST_UPDATE_TIMER(8),0x328(%r1)
81 lg %r0,__LC_LAST_UPDATE_CLOCK
82 slg %r0,__SF_EMPTY(%r15)
83 alg %r0,__LC_STEAL_TIMER
84 stg %r0,__LC_STEAL_TIMER
85 mvc __LC_LAST_UPDATE_CLOCK(8),__SF_EMPTY(%r15)
86
74 /* Activate DAT */ 87 /* Activate DAT */
75 stosm __SF_EMPTY(%r15),0x04 88 stosm __SF_EMPTY(%r15),0x04
76 89
@@ -159,8 +172,7 @@ pgm_check_entry:
159 larl %r1,.Lresume_cpu /* Resume CPU address: r2 */ 172 larl %r1,.Lresume_cpu /* Resume CPU address: r2 */
160 stap 0(%r1) 173 stap 0(%r1)
161 llgh %r2,0(%r1) 174 llgh %r2,0(%r1)
162 lghi %r3,0x1000 175 llgh %r1,__LC_CPU_ADDRESS(%r0) /* Suspend CPU address: r1 */
163 llgh %r1,__LC_CPU_ADDRESS(%r3) /* Suspend CPU address: r1 */
164 cgr %r1,%r2 176 cgr %r1,%r2
165 je restore_registers /* r1 = r2 -> nothing to do */ 177 je restore_registers /* r1 = r2 -> nothing to do */
166 larl %r4,.Lrestart_suspend_psw /* Set new restart PSW */ 178 larl %r4,.Lrestart_suspend_psw /* Set new restart PSW */
@@ -200,8 +212,11 @@ restart_suspend:
200 212
201restore_registers: 213restore_registers:
202 /* Restore registers */ 214 /* Restore registers */
203 lghi %r13,0x1000 /* %r1 = pointer to save arae */ 215 lghi %r13,0x1000 /* %r1 = pointer to save area */
204 216
217 /* Ignore time spent in suspended state. */
218 llgf %r1,0x318(%r13)
219 stck __LC_LAST_UPDATE_CLOCK(%r1)
205 spt 0x328(%r13) /* reprogram timer */ 220 spt 0x328(%r13) /* reprogram timer */
206 //sckc 0x330(%r13) /* set clock comparator */ 221 //sckc 0x330(%r13) /* set clock comparator */
207 222
@@ -229,9 +244,6 @@ restore_registers:
229 /* Load old stack */ 244 /* Load old stack */
230 lg %r15,0x2f8(%r13) 245 lg %r15,0x2f8(%r13)
231 246
232 /* Pointer to save area */
233 lghi %r13,0x1000
234
235 /* Restore prefix register */ 247 /* Restore prefix register */
236 spx 0x318(%r13) 248 spx 0x318(%r13)
237 249
diff --git a/arch/s390/kernel/vdso.c b/arch/s390/kernel/vdso.c
index 45a3e9a7ae21..adfb32aa6d59 100644
--- a/arch/s390/kernel/vdso.c
+++ b/arch/s390/kernel/vdso.c
@@ -247,6 +247,13 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
247 } 247 }
248 248
249 /* 249 /*
250 * Put vDSO base into mm struct. We need to do this before calling
251 * install_special_mapping or the perf counter mmap tracking code
252 * will fail to recognise it as a vDSO (since arch_vma_name fails).
253 */
254 current->mm->context.vdso_base = vdso_base;
255
256 /*
250 * our vma flags don't have VM_WRITE so by default, the process 257 * our vma flags don't have VM_WRITE so by default, the process
251 * isn't allowed to write those pages. 258 * isn't allowed to write those pages.
252 * gdb can break that with ptrace interface, and thus trigger COW 259 * gdb can break that with ptrace interface, and thus trigger COW
@@ -267,14 +274,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
267 VM_ALWAYSDUMP, 274 VM_ALWAYSDUMP,
268 vdso_pagelist); 275 vdso_pagelist);
269 if (rc) 276 if (rc)
270 goto out_up; 277 current->mm->context.vdso_base = 0;
271
272 /* Put vDSO base into mm struct */
273 current->mm->context.vdso_base = vdso_base;
274
275 up_write(&mm->mmap_sem);
276 return 0;
277
278out_up: 278out_up:
279 up_write(&mm->mmap_sem); 279 up_write(&mm->mmap_sem);
280 return rc; 280 return rc;
diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S
index bc15ef93e656..a68ac10213b2 100644
--- a/arch/s390/kernel/vmlinux.lds.S
+++ b/arch/s390/kernel/vmlinux.lds.S
@@ -51,6 +51,7 @@ SECTIONS
51 51
52 . = ALIGN(PAGE_SIZE); 52 . = ALIGN(PAGE_SIZE);
53 _eshared = .; /* End of shareable data */ 53 _eshared = .; /* End of shareable data */
54 _sdata = .; /* Start of data section */
54 55
55 EXCEPTION_TABLE(16) :data 56 EXCEPTION_TABLE(16) :data
56 57
diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h
index ec5eee7c25d8..06cce8285ba0 100644
--- a/arch/s390/kvm/kvm-s390.h
+++ b/arch/s390/kvm/kvm-s390.h
@@ -58,7 +58,7 @@ int kvm_s390_inject_vcpu(struct kvm_vcpu *vcpu,
58int kvm_s390_inject_program_int(struct kvm_vcpu *vcpu, u16 code); 58int kvm_s390_inject_program_int(struct kvm_vcpu *vcpu, u16 code);
59int kvm_s390_inject_sigp_stop(struct kvm_vcpu *vcpu, int action); 59int kvm_s390_inject_sigp_stop(struct kvm_vcpu *vcpu, int action);
60 60
61static inline int kvm_s390_vcpu_get_memsize(struct kvm_vcpu *vcpu) 61static inline long kvm_s390_vcpu_get_memsize(struct kvm_vcpu *vcpu)
62{ 62{
63 return vcpu->arch.sie_block->gmslm 63 return vcpu->arch.sie_block->gmslm
64 - vcpu->arch.sie_block->gmsor 64 - vcpu->arch.sie_block->gmsor
diff --git a/arch/s390/lib/delay.c b/arch/s390/lib/delay.c
index 97c1eca83cc2..752b362bf651 100644
--- a/arch/s390/lib/delay.c
+++ b/arch/s390/lib/delay.c
@@ -25,13 +25,13 @@ void __delay(unsigned long loops)
25 asm volatile("0: brct %0,0b" : : "d" ((loops/2) + 1)); 25 asm volatile("0: brct %0,0b" : : "d" ((loops/2) + 1));
26} 26}
27 27
28static void __udelay_disabled(unsigned long usecs) 28static void __udelay_disabled(unsigned long long usecs)
29{ 29{
30 unsigned long mask, cr0, cr0_saved; 30 unsigned long mask, cr0, cr0_saved;
31 u64 clock_saved; 31 u64 clock_saved;
32 32
33 clock_saved = local_tick_disable(); 33 clock_saved = local_tick_disable();
34 set_clock_comparator(get_clock() + ((u64) usecs << 12)); 34 set_clock_comparator(get_clock() + (usecs << 12));
35 __ctl_store(cr0_saved, 0, 0); 35 __ctl_store(cr0_saved, 0, 0);
36 cr0 = (cr0_saved & 0xffff00e0) | 0x00000800; 36 cr0 = (cr0_saved & 0xffff00e0) | 0x00000800;
37 __ctl_load(cr0 , 0, 0); 37 __ctl_load(cr0 , 0, 0);
@@ -46,20 +46,25 @@ static void __udelay_disabled(unsigned long usecs)
46 set_clock_comparator(S390_lowcore.clock_comparator); 46 set_clock_comparator(S390_lowcore.clock_comparator);
47} 47}
48 48
49static void __udelay_enabled(unsigned long usecs) 49static void __udelay_enabled(unsigned long long usecs)
50{ 50{
51 unsigned long mask; 51 unsigned long mask;
52 u64 end, time; 52 u64 clock_saved;
53 u64 end;
53 54
54 mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_EXT | PSW_MASK_IO; 55 mask = psw_kernel_bits | PSW_MASK_WAIT | PSW_MASK_EXT | PSW_MASK_IO;
55 end = get_clock() + ((u64) usecs << 12); 56 end = get_clock() + (usecs << 12);
56 do { 57 do {
57 time = end < S390_lowcore.clock_comparator ? 58 clock_saved = 0;
58 end : S390_lowcore.clock_comparator; 59 if (end < S390_lowcore.clock_comparator) {
59 set_clock_comparator(time); 60 clock_saved = local_tick_disable();
61 set_clock_comparator(end);
62 }
60 trace_hardirqs_on(); 63 trace_hardirqs_on();
61 __load_psw_mask(mask); 64 __load_psw_mask(mask);
62 local_irq_disable(); 65 local_irq_disable();
66 if (clock_saved)
67 local_tick_enable(clock_saved);
63 } while (get_clock() < end); 68 } while (get_clock() < end);
64 set_clock_comparator(S390_lowcore.clock_comparator); 69 set_clock_comparator(S390_lowcore.clock_comparator);
65} 70}
@@ -67,7 +72,7 @@ static void __udelay_enabled(unsigned long usecs)
67/* 72/*
68 * Waits for 'usecs' microseconds using the TOD clock comparator. 73 * Waits for 'usecs' microseconds using the TOD clock comparator.
69 */ 74 */
70void __udelay(unsigned long usecs) 75void __udelay(unsigned long long usecs)
71{ 76{
72 unsigned long flags; 77 unsigned long flags;
73 78
@@ -101,11 +106,11 @@ EXPORT_SYMBOL(__udelay);
101 * Simple udelay variant. To be used on startup and reboot 106 * Simple udelay variant. To be used on startup and reboot
102 * when the interrupt handler isn't working. 107 * when the interrupt handler isn't working.
103 */ 108 */
104void udelay_simple(unsigned long usecs) 109void udelay_simple(unsigned long long usecs)
105{ 110{
106 u64 end; 111 u64 end;
107 112
108 end = get_clock() + ((u64) usecs << 12); 113 end = get_clock() + (usecs << 12);
109 while (get_clock() < end) 114 while (get_clock() < end)
110 cpu_relax(); 115 cpu_relax();
111} 116}
diff --git a/arch/s390/lib/uaccess_mvcos.c b/arch/s390/lib/uaccess_mvcos.c
index 3f15aaf54855..58da3f461214 100644
--- a/arch/s390/lib/uaccess_mvcos.c
+++ b/arch/s390/lib/uaccess_mvcos.c
@@ -36,7 +36,7 @@ static size_t copy_from_user_mvcos(size_t size, const void __user *ptr, void *x)
36 tmp1 = -4096UL; 36 tmp1 = -4096UL;
37 asm volatile( 37 asm volatile(
38 "0: .insn ss,0xc80000000000,0(%0,%2),0(%1),0\n" 38 "0: .insn ss,0xc80000000000,0(%0,%2),0(%1),0\n"
39 " jz 7f\n" 39 "9: jz 7f\n"
40 "1:"ALR" %0,%3\n" 40 "1:"ALR" %0,%3\n"
41 " "SLR" %1,%3\n" 41 " "SLR" %1,%3\n"
42 " "SLR" %2,%3\n" 42 " "SLR" %2,%3\n"
@@ -47,7 +47,7 @@ static size_t copy_from_user_mvcos(size_t size, const void __user *ptr, void *x)
47 " "CLR" %0,%4\n" /* copy crosses next page boundary? */ 47 " "CLR" %0,%4\n" /* copy crosses next page boundary? */
48 " jnh 4f\n" 48 " jnh 4f\n"
49 "3: .insn ss,0xc80000000000,0(%4,%2),0(%1),0\n" 49 "3: .insn ss,0xc80000000000,0(%4,%2),0(%1),0\n"
50 " "SLR" %0,%4\n" 50 "10:"SLR" %0,%4\n"
51 " "ALR" %2,%4\n" 51 " "ALR" %2,%4\n"
52 "4:"LHI" %4,-1\n" 52 "4:"LHI" %4,-1\n"
53 " "ALR" %4,%0\n" /* copy remaining size, subtract 1 */ 53 " "ALR" %4,%0\n" /* copy remaining size, subtract 1 */
@@ -61,7 +61,7 @@ static size_t copy_from_user_mvcos(size_t size, const void __user *ptr, void *x)
61 " j 8f\n" 61 " j 8f\n"
62 "7:"SLR" %0,%0\n" 62 "7:"SLR" %0,%0\n"
63 "8: \n" 63 "8: \n"
64 EX_TABLE(0b,2b) EX_TABLE(3b,4b) 64 EX_TABLE(0b,2b) EX_TABLE(3b,4b) EX_TABLE(9b,2b) EX_TABLE(10b,4b)
65 : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2) 65 : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2)
66 : "d" (reg0) : "cc", "memory"); 66 : "d" (reg0) : "cc", "memory");
67 return size; 67 return size;
@@ -82,7 +82,7 @@ static size_t copy_to_user_mvcos(size_t size, void __user *ptr, const void *x)
82 tmp1 = -4096UL; 82 tmp1 = -4096UL;
83 asm volatile( 83 asm volatile(
84 "0: .insn ss,0xc80000000000,0(%0,%1),0(%2),0\n" 84 "0: .insn ss,0xc80000000000,0(%0,%1),0(%2),0\n"
85 " jz 4f\n" 85 "6: jz 4f\n"
86 "1:"ALR" %0,%3\n" 86 "1:"ALR" %0,%3\n"
87 " "SLR" %1,%3\n" 87 " "SLR" %1,%3\n"
88 " "SLR" %2,%3\n" 88 " "SLR" %2,%3\n"
@@ -93,11 +93,11 @@ static size_t copy_to_user_mvcos(size_t size, void __user *ptr, const void *x)
93 " "CLR" %0,%4\n" /* copy crosses next page boundary? */ 93 " "CLR" %0,%4\n" /* copy crosses next page boundary? */
94 " jnh 5f\n" 94 " jnh 5f\n"
95 "3: .insn ss,0xc80000000000,0(%4,%1),0(%2),0\n" 95 "3: .insn ss,0xc80000000000,0(%4,%1),0(%2),0\n"
96 " "SLR" %0,%4\n" 96 "7:"SLR" %0,%4\n"
97 " j 5f\n" 97 " j 5f\n"
98 "4:"SLR" %0,%0\n" 98 "4:"SLR" %0,%0\n"
99 "5: \n" 99 "5: \n"
100 EX_TABLE(0b,2b) EX_TABLE(3b,5b) 100 EX_TABLE(0b,2b) EX_TABLE(3b,5b) EX_TABLE(6b,2b) EX_TABLE(7b,5b)
101 : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2) 101 : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2)
102 : "d" (reg0) : "cc", "memory"); 102 : "d" (reg0) : "cc", "memory");
103 return size; 103 return size;
diff --git a/arch/s390/lib/uaccess_std.c b/arch/s390/lib/uaccess_std.c
index d2ffbadb51a7..07deaeee14c8 100644
--- a/arch/s390/lib/uaccess_std.c
+++ b/arch/s390/lib/uaccess_std.c
@@ -36,12 +36,12 @@ size_t copy_from_user_std(size_t size, const void __user *ptr, void *x)
36 tmp1 = -256UL; 36 tmp1 = -256UL;
37 asm volatile( 37 asm volatile(
38 "0: mvcp 0(%0,%2),0(%1),%3\n" 38 "0: mvcp 0(%0,%2),0(%1),%3\n"
39 " jz 8f\n" 39 "10:jz 8f\n"
40 "1:"ALR" %0,%3\n" 40 "1:"ALR" %0,%3\n"
41 " la %1,256(%1)\n" 41 " la %1,256(%1)\n"
42 " la %2,256(%2)\n" 42 " la %2,256(%2)\n"
43 "2: mvcp 0(%0,%2),0(%1),%3\n" 43 "2: mvcp 0(%0,%2),0(%1),%3\n"
44 " jnz 1b\n" 44 "11:jnz 1b\n"
45 " j 8f\n" 45 " j 8f\n"
46 "3: la %4,255(%1)\n" /* %4 = ptr + 255 */ 46 "3: la %4,255(%1)\n" /* %4 = ptr + 255 */
47 " "LHI" %3,-4096\n" 47 " "LHI" %3,-4096\n"
@@ -50,7 +50,7 @@ size_t copy_from_user_std(size_t size, const void __user *ptr, void *x)
50 " "CLR" %0,%4\n" /* copy crosses next page boundary? */ 50 " "CLR" %0,%4\n" /* copy crosses next page boundary? */
51 " jnh 5f\n" 51 " jnh 5f\n"
52 "4: mvcp 0(%4,%2),0(%1),%3\n" 52 "4: mvcp 0(%4,%2),0(%1),%3\n"
53 " "SLR" %0,%4\n" 53 "12:"SLR" %0,%4\n"
54 " "ALR" %2,%4\n" 54 " "ALR" %2,%4\n"
55 "5:"LHI" %4,-1\n" 55 "5:"LHI" %4,-1\n"
56 " "ALR" %4,%0\n" /* copy remaining size, subtract 1 */ 56 " "ALR" %4,%0\n" /* copy remaining size, subtract 1 */
@@ -65,6 +65,7 @@ size_t copy_from_user_std(size_t size, const void __user *ptr, void *x)
65 "8:"SLR" %0,%0\n" 65 "8:"SLR" %0,%0\n"
66 "9: \n" 66 "9: \n"
67 EX_TABLE(0b,3b) EX_TABLE(2b,3b) EX_TABLE(4b,5b) 67 EX_TABLE(0b,3b) EX_TABLE(2b,3b) EX_TABLE(4b,5b)
68 EX_TABLE(10b,3b) EX_TABLE(11b,3b) EX_TABLE(12b,5b)
68 : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2) 69 : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2)
69 : : "cc", "memory"); 70 : : "cc", "memory");
70 return size; 71 return size;
@@ -85,12 +86,12 @@ size_t copy_to_user_std(size_t size, void __user *ptr, const void *x)
85 tmp1 = -256UL; 86 tmp1 = -256UL;
86 asm volatile( 87 asm volatile(
87 "0: mvcs 0(%0,%1),0(%2),%3\n" 88 "0: mvcs 0(%0,%1),0(%2),%3\n"
88 " jz 5f\n" 89 "7: jz 5f\n"
89 "1:"ALR" %0,%3\n" 90 "1:"ALR" %0,%3\n"
90 " la %1,256(%1)\n" 91 " la %1,256(%1)\n"
91 " la %2,256(%2)\n" 92 " la %2,256(%2)\n"
92 "2: mvcs 0(%0,%1),0(%2),%3\n" 93 "2: mvcs 0(%0,%1),0(%2),%3\n"
93 " jnz 1b\n" 94 "8: jnz 1b\n"
94 " j 5f\n" 95 " j 5f\n"
95 "3: la %4,255(%1)\n" /* %4 = ptr + 255 */ 96 "3: la %4,255(%1)\n" /* %4 = ptr + 255 */
96 " "LHI" %3,-4096\n" 97 " "LHI" %3,-4096\n"
@@ -99,11 +100,12 @@ size_t copy_to_user_std(size_t size, void __user *ptr, const void *x)
99 " "CLR" %0,%4\n" /* copy crosses next page boundary? */ 100 " "CLR" %0,%4\n" /* copy crosses next page boundary? */
100 " jnh 6f\n" 101 " jnh 6f\n"
101 "4: mvcs 0(%4,%1),0(%2),%3\n" 102 "4: mvcs 0(%4,%1),0(%2),%3\n"
102 " "SLR" %0,%4\n" 103 "9:"SLR" %0,%4\n"
103 " j 6f\n" 104 " j 6f\n"
104 "5:"SLR" %0,%0\n" 105 "5:"SLR" %0,%0\n"
105 "6: \n" 106 "6: \n"
106 EX_TABLE(0b,3b) EX_TABLE(2b,3b) EX_TABLE(4b,6b) 107 EX_TABLE(0b,3b) EX_TABLE(2b,3b) EX_TABLE(4b,6b)
108 EX_TABLE(7b,3b) EX_TABLE(8b,3b) EX_TABLE(9b,6b)
107 : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2) 109 : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2)
108 : : "cc", "memory"); 110 : : "cc", "memory");
109 return size; 111 return size;
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c
index c60bfb309ce6..2757c5616a07 100644
--- a/arch/s390/mm/pgtable.c
+++ b/arch/s390/mm/pgtable.c
@@ -279,7 +279,10 @@ int s390_enable_sie(void)
279 /* lets check if we are allowed to replace the mm */ 279 /* lets check if we are allowed to replace the mm */
280 task_lock(tsk); 280 task_lock(tsk);
281 if (!tsk->mm || atomic_read(&tsk->mm->mm_users) > 1 || 281 if (!tsk->mm || atomic_read(&tsk->mm->mm_users) > 1 ||
282 tsk->mm != tsk->active_mm || !hlist_empty(&tsk->mm->ioctx_list)) { 282#ifdef CONFIG_AIO
283 !hlist_empty(&tsk->mm->ioctx_list) ||
284#endif
285 tsk->mm != tsk->active_mm) {
283 task_unlock(tsk); 286 task_unlock(tsk);
284 return -EINVAL; 287 return -EINVAL;
285 } 288 }
@@ -295,7 +298,10 @@ int s390_enable_sie(void)
295 /* Now lets check again if something happened */ 298 /* Now lets check again if something happened */
296 task_lock(tsk); 299 task_lock(tsk);
297 if (!tsk->mm || atomic_read(&tsk->mm->mm_users) > 1 || 300 if (!tsk->mm || atomic_read(&tsk->mm->mm_users) > 1 ||
298 tsk->mm != tsk->active_mm || !hlist_empty(&tsk->mm->ioctx_list)) { 301#ifdef CONFIG_AIO
302 !hlist_empty(&tsk->mm->ioctx_list) ||
303#endif
304 tsk->mm != tsk->active_mm) {
299 mmput(mm); 305 mmput(mm);
300 task_unlock(tsk); 306 task_unlock(tsk);
301 return -EINVAL; 307 return -EINVAL;
diff --git a/arch/sh/boards/board-magicpanelr2.c b/arch/sh/boards/board-magicpanelr2.c
index 0a37c8bfc959..99ffc5f1c0dd 100644
--- a/arch/sh/boards/board-magicpanelr2.c
+++ b/arch/sh/boards/board-magicpanelr2.c
@@ -205,8 +205,6 @@ static void __init setup_port_multiplexing(void)
205 205
206static void __init mpr2_setup(char **cmdline_p) 206static void __init mpr2_setup(char **cmdline_p)
207{ 207{
208 __set_io_port_base(0xa0000000);
209
210 /* set Pin Select Register A: 208 /* set Pin Select Register A:
211 * /PCC_CD1, /PCC_CD2, PCC_BVD1, PCC_BVD2, 209 * /PCC_CD1, /PCC_CD2, PCC_BVD1, PCC_BVD2,
212 * /IOIS16, IRQ4, IRQ5, USB1d_SUSPEND 210 * /IOIS16, IRQ4, IRQ5, USB1d_SUSPEND
diff --git a/arch/sh/boards/mach-dreamcast/setup.c b/arch/sh/boards/mach-dreamcast/setup.c
index ebe99227d4e6..a4b7402d6176 100644
--- a/arch/sh/boards/mach-dreamcast/setup.c
+++ b/arch/sh/boards/mach-dreamcast/setup.c
@@ -42,8 +42,6 @@ static void __init dreamcast_setup(char **cmdline_p)
42 /* Acknowledge any previous events */ 42 /* Acknowledge any previous events */
43 /* XXX */ 43 /* XXX */
44 44
45 __set_io_port_base(0xa0000000);
46
47 /* Assign all virtual IRQs to the System ASIC int. handler */ 45 /* Assign all virtual IRQs to the System ASIC int. handler */
48 for (i = HW_EVENT_IRQ_BASE; i < HW_EVENT_IRQ_MAX; i++) 46 for (i = HW_EVENT_IRQ_BASE; i < HW_EVENT_IRQ_MAX; i++)
49 set_irq_chip_and_handler(i, &systemasic_int, 47 set_irq_chip_and_handler(i, &systemasic_int,
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c
index 5f9881e16e2f..3b1ceb46fa54 100644
--- a/arch/sh/boards/mach-ecovec24/setup.c
+++ b/arch/sh/boards/mach-ecovec24/setup.c
@@ -18,6 +18,7 @@
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/usb/r8a66597.h> 19#include <linux/usb/r8a66597.h>
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include <linux/i2c/tsc2007.h>
21#include <linux/input.h> 22#include <linux/input.h>
22#include <video/sh_mobile_lcdc.h> 23#include <video/sh_mobile_lcdc.h>
23#include <media/sh_mobile_ceu.h> 24#include <media/sh_mobile_ceu.h>
@@ -38,6 +39,20 @@
38 * 0x1800_0000 MFI 16bit 39 * 0x1800_0000 MFI 16bit
39 */ 40 */
40 41
42/* SWITCH
43 *------------------------------
44 * DS2[1] = FlashROM write protect ON : write protect
45 * OFF : No write protect
46 * DS2[2] = RMII / TS, SCIF ON : RMII
47 * OFF : TS, SCIF3
48 * DS2[3] = Camera / Video ON : Camera
49 * OFF : NTSC/PAL (IN)
50 * DS2[5] = NTSC_OUT Clock ON : On board OSC
51 * OFF : SH7724 DV_CLK
52 * DS2[6-7] = MMC / SD ON-OFF : SD
53 * OFF-ON : MMC
54 */
55
41/* Heartbeat */ 56/* Heartbeat */
42static unsigned char led_pos[] = { 0, 1, 2, 3 }; 57static unsigned char led_pos[] = { 0, 1, 2, 3 };
43static struct heartbeat_data heartbeat_data = { 58static struct heartbeat_data heartbeat_data = {
@@ -70,7 +85,7 @@ static struct mtd_partition nor_flash_partitions[] = {
70 .name = "boot loader", 85 .name = "boot loader",
71 .offset = 0, 86 .offset = 0,
72 .size = (5 * 1024 * 1024), 87 .size = (5 * 1024 * 1024),
73 .mask_flags = MTD_CAP_ROM, 88 .mask_flags = MTD_WRITEABLE, /* force read-only */
74 }, { 89 }, {
75 .name = "free-area", 90 .name = "free-area",
76 .offset = MTDPART_OFS_APPEND, 91 .offset = MTDPART_OFS_APPEND,
@@ -376,6 +391,43 @@ static struct platform_device keysc_device = {
376 }, 391 },
377}; 392};
378 393
394/* TouchScreen */
395#define IRQ0 32
396static int ts_get_pendown_state(void)
397{
398 int val = 0;
399 gpio_free(GPIO_FN_INTC_IRQ0);
400 gpio_request(GPIO_PTZ0, NULL);
401 gpio_direction_input(GPIO_PTZ0);
402
403 val = gpio_get_value(GPIO_PTZ0);
404
405 gpio_free(GPIO_PTZ0);
406 gpio_request(GPIO_FN_INTC_IRQ0, NULL);
407
408 return val ? 0 : 1;
409}
410
411static int ts_init(void)
412{
413 gpio_request(GPIO_FN_INTC_IRQ0, NULL);
414 return 0;
415}
416
417struct tsc2007_platform_data tsc2007_info = {
418 .model = 2007,
419 .x_plate_ohms = 180,
420 .get_pendown_state = ts_get_pendown_state,
421 .init_platform_hw = ts_init,
422};
423
424static struct i2c_board_info ts_i2c_clients = {
425 I2C_BOARD_INFO("tsc2007", 0x48),
426 .type = "tsc2007",
427 .platform_data = &tsc2007_info,
428 .irq = IRQ0,
429};
430
379static struct platform_device *ecovec_devices[] __initdata = { 431static struct platform_device *ecovec_devices[] __initdata = {
380 &heartbeat_device, 432 &heartbeat_device,
381 &nor_flash_device, 433 &nor_flash_device,
@@ -460,6 +512,11 @@ static void __init sh_eth_init(void)
460#define IODRIVEA 0xA405018A 512#define IODRIVEA 0xA405018A
461static int __init arch_setup(void) 513static int __init arch_setup(void)
462{ 514{
515 /* enable STATUS0, STATUS2 and PDSTATUS */
516 gpio_request(GPIO_FN_STATUS0, NULL);
517 gpio_request(GPIO_FN_STATUS2, NULL);
518 gpio_request(GPIO_FN_PDSTATUS, NULL);
519
463 /* enable SCIFA0 */ 520 /* enable SCIFA0 */
464 gpio_request(GPIO_FN_SCIF0_TXD, NULL); 521 gpio_request(GPIO_FN_SCIF0_TXD, NULL);
465 gpio_request(GPIO_FN_SCIF0_RXD, NULL); 522 gpio_request(GPIO_FN_SCIF0_RXD, NULL);
@@ -590,6 +647,10 @@ static int __init arch_setup(void)
590 */ 647 */
591 gpio_request(GPIO_PTF4, NULL); 648 gpio_request(GPIO_PTF4, NULL);
592 gpio_direction_output(GPIO_PTF4, 1); 649 gpio_direction_output(GPIO_PTF4, 1);
650
651 /* enable TouchScreen */
652 i2c_register_board_info(0, &ts_i2c_clients, 1);
653 set_irq_type(IRQ0, IRQ_TYPE_LEVEL_LOW);
593 } 654 }
594 655
595 /* enable CEU0 */ 656 /* enable CEU0 */
diff --git a/arch/sh/kernel/cpu/sh3/entry.S b/arch/sh/kernel/cpu/sh3/entry.S
index 0151933e5253..bb407ef0b91e 100644
--- a/arch/sh/kernel/cpu/sh3/entry.S
+++ b/arch/sh/kernel/cpu/sh3/entry.S
@@ -152,8 +152,6 @@ call_do_page_fault:
152 mov.l 1f, r0 152 mov.l 1f, r0
153 mov.l @r0, r6 153 mov.l @r0, r6
154 154
155 sti
156
157 mov.l 3f, r0 155 mov.l 3f, r0
158 mov.l 4f, r1 156 mov.l 4f, r1
159 mov r15, r4 157 mov r15, r4
diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S
index 68d9223b145e..3eb84931d2aa 100644
--- a/arch/sh/kernel/entry-common.S
+++ b/arch/sh/kernel/entry-common.S
@@ -121,7 +121,7 @@ noresched:
121ENTRY(resume_userspace) 121ENTRY(resume_userspace)
122 ! r8: current_thread_info 122 ! r8: current_thread_info
123 cli 123 cli
124 TRACE_IRQS_OfF 124 TRACE_IRQS_OFF
125 mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags 125 mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
126 tst #(_TIF_WORK_MASK & 0xff), r0 126 tst #(_TIF_WORK_MASK & 0xff), r0
127 bt/s __restore_all 127 bt/s __restore_all
diff --git a/arch/sh/kernel/ftrace.c b/arch/sh/kernel/ftrace.c
index a3dcc6d5d253..2c48e267256e 100644
--- a/arch/sh/kernel/ftrace.c
+++ b/arch/sh/kernel/ftrace.c
@@ -291,31 +291,48 @@ struct syscall_metadata *syscall_nr_to_meta(int nr)
291 return syscalls_metadata[nr]; 291 return syscalls_metadata[nr];
292} 292}
293 293
294void arch_init_ftrace_syscalls(void) 294int syscall_name_to_nr(char *name)
295{
296 int i;
297
298 if (!syscalls_metadata)
299 return -1;
300 for (i = 0; i < NR_syscalls; i++)
301 if (syscalls_metadata[i])
302 if (!strcmp(syscalls_metadata[i]->name, name))
303 return i;
304 return -1;
305}
306
307void set_syscall_enter_id(int num, int id)
308{
309 syscalls_metadata[num]->enter_id = id;
310}
311
312void set_syscall_exit_id(int num, int id)
313{
314 syscalls_metadata[num]->exit_id = id;
315}
316
317static int __init arch_init_ftrace_syscalls(void)
295{ 318{
296 int i; 319 int i;
297 struct syscall_metadata *meta; 320 struct syscall_metadata *meta;
298 unsigned long **psys_syscall_table = &sys_call_table; 321 unsigned long **psys_syscall_table = &sys_call_table;
299 static atomic_t refs;
300
301 if (atomic_inc_return(&refs) != 1)
302 goto end;
303 322
304 syscalls_metadata = kzalloc(sizeof(*syscalls_metadata) * 323 syscalls_metadata = kzalloc(sizeof(*syscalls_metadata) *
305 FTRACE_SYSCALL_MAX, GFP_KERNEL); 324 FTRACE_SYSCALL_MAX, GFP_KERNEL);
306 if (!syscalls_metadata) { 325 if (!syscalls_metadata) {
307 WARN_ON(1); 326 WARN_ON(1);
308 return; 327 return -ENOMEM;
309 } 328 }
310 329
311 for (i = 0; i < FTRACE_SYSCALL_MAX; i++) { 330 for (i = 0; i < FTRACE_SYSCALL_MAX; i++) {
312 meta = find_syscall_meta(psys_syscall_table[i]); 331 meta = find_syscall_meta(psys_syscall_table[i]);
313 syscalls_metadata[i] = meta; 332 syscalls_metadata[i] = meta;
314 } 333 }
315 return;
316 334
317 /* Paranoid: avoid overflow */ 335 return 0;
318end:
319 atomic_dec(&refs);
320} 336}
337arch_initcall(arch_init_ftrace_syscalls);
321#endif /* CONFIG_FTRACE_SYSCALLS */ 338#endif /* CONFIG_FTRACE_SYSCALLS */
diff --git a/arch/sh/kernel/io_generic.c b/arch/sh/kernel/io_generic.c
index 4ff507239286..b8fa6524760a 100644
--- a/arch/sh/kernel/io_generic.c
+++ b/arch/sh/kernel/io_generic.c
@@ -147,6 +147,9 @@ void generic_outsl(unsigned long port, const void *src, unsigned long count)
147 147
148void __iomem *generic_ioport_map(unsigned long addr, unsigned int size) 148void __iomem *generic_ioport_map(unsigned long addr, unsigned int size)
149{ 149{
150 if (PXSEG(addr) >= P1SEG)
151 return (void __iomem *)addr;
152
150 return (void __iomem *)(addr + generic_io_base); 153 return (void __iomem *)(addr + generic_io_base);
151} 154}
152 155
diff --git a/arch/sh/kernel/machvec.c b/arch/sh/kernel/machvec.c
index 548f6607fd0f..cbce639b108a 100644
--- a/arch/sh/kernel/machvec.c
+++ b/arch/sh/kernel/machvec.c
@@ -14,6 +14,7 @@
14#include <linux/string.h> 14#include <linux/string.h>
15#include <asm/machvec.h> 15#include <asm/machvec.h>
16#include <asm/sections.h> 16#include <asm/sections.h>
17#include <asm/addrspace.h>
17#include <asm/setup.h> 18#include <asm/setup.h>
18#include <asm/io.h> 19#include <asm/io.h>
19#include <asm/irq.h> 20#include <asm/irq.h>
@@ -133,4 +134,6 @@ void __init sh_mv_setup(void)
133 134
134 if (!sh_mv.mv_nr_irqs) 135 if (!sh_mv.mv_nr_irqs)
135 sh_mv.mv_nr_irqs = NR_IRQS; 136 sh_mv.mv_nr_irqs = NR_IRQS;
137
138 __set_io_port_base(P2SEG);
136} 139}
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index f9d44f8e0df6..99b4fb553bf1 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -549,6 +549,8 @@ static int show_cpuinfo(struct seq_file *m, void *v)
549 549
550 if (cpu == 0) 550 if (cpu == 0)
551 seq_printf(m, "machine\t\t: %s\n", get_system_type()); 551 seq_printf(m, "machine\t\t: %s\n", get_system_type());
552 else
553 seq_printf(m, "\n");
552 554
553 seq_printf(m, "processor\t: %d\n", cpu); 555 seq_printf(m, "processor\t: %d\n", cpu);
554 seq_printf(m, "cpu family\t: %s\n", init_utsname()->machine); 556 seq_printf(m, "cpu family\t: %s\n", init_utsname()->machine);
diff --git a/arch/sh/kernel/sh_ksyms_32.c b/arch/sh/kernel/sh_ksyms_32.c
index 8dbe26b17c44..86c270428357 100644
--- a/arch/sh/kernel/sh_ksyms_32.c
+++ b/arch/sh/kernel/sh_ksyms_32.c
@@ -84,6 +84,7 @@ DECLARE_EXPORT(__movstrSI60);
84DECLARE_EXPORT(__movstr_i4_even); 84DECLARE_EXPORT(__movstr_i4_even);
85DECLARE_EXPORT(__movstr_i4_odd); 85DECLARE_EXPORT(__movstr_i4_odd);
86DECLARE_EXPORT(__movstrSI12_i4); 86DECLARE_EXPORT(__movstrSI12_i4);
87DECLARE_EXPORT(__movmem);
87DECLARE_EXPORT(__movmem_i4_even); 88DECLARE_EXPORT(__movmem_i4_even);
88DECLARE_EXPORT(__movmem_i4_odd); 89DECLARE_EXPORT(__movmem_i4_odd);
89DECLARE_EXPORT(__movmemSI12_i4); 90DECLARE_EXPORT(__movmemSI12_i4);
diff --git a/arch/sh/kernel/signal_32.c b/arch/sh/kernel/signal_32.c
index 6729703547a1..3db37425210d 100644
--- a/arch/sh/kernel/signal_32.c
+++ b/arch/sh/kernel/signal_32.c
@@ -145,7 +145,7 @@ static inline int restore_sigcontext_fpu(struct sigcontext __user *sc)
145{ 145{
146 struct task_struct *tsk = current; 146 struct task_struct *tsk = current;
147 147
148 if (!(current_cpu_data.flags & CPU_HAS_FPU)) 148 if (!(boot_cpu_data.flags & CPU_HAS_FPU))
149 return 0; 149 return 0;
150 150
151 set_used_math(); 151 set_used_math();
@@ -158,7 +158,7 @@ static inline int save_sigcontext_fpu(struct sigcontext __user *sc,
158{ 158{
159 struct task_struct *tsk = current; 159 struct task_struct *tsk = current;
160 160
161 if (!(current_cpu_data.flags & CPU_HAS_FPU)) 161 if (!(boot_cpu_data.flags & CPU_HAS_FPU))
162 return 0; 162 return 0;
163 163
164 if (!used_math()) { 164 if (!used_math()) {
@@ -199,7 +199,7 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *r0_p
199#undef COPY 199#undef COPY
200 200
201#ifdef CONFIG_SH_FPU 201#ifdef CONFIG_SH_FPU
202 if (current_cpu_data.flags & CPU_HAS_FPU) { 202 if (boot_cpu_data.flags & CPU_HAS_FPU) {
203 int owned_fp; 203 int owned_fp;
204 struct task_struct *tsk = current; 204 struct task_struct *tsk = current;
205 205
@@ -472,6 +472,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
472 err |= __put_user(OR_R0_R0, &frame->retcode[6]); 472 err |= __put_user(OR_R0_R0, &frame->retcode[6]);
473 err |= __put_user((__NR_rt_sigreturn), &frame->retcode[7]); 473 err |= __put_user((__NR_rt_sigreturn), &frame->retcode[7]);
474 regs->pr = (unsigned long) frame->retcode; 474 regs->pr = (unsigned long) frame->retcode;
475 flush_icache_range(regs->pr, regs->pr + sizeof(frame->retcode));
475 } 476 }
476 477
477 if (err) 478 if (err)
@@ -497,8 +498,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
497 pr_debug("SIG deliver (%s:%d): sp=%p pc=%08lx pr=%08lx\n", 498 pr_debug("SIG deliver (%s:%d): sp=%p pc=%08lx pr=%08lx\n",
498 current->comm, task_pid_nr(current), frame, regs->pc, regs->pr); 499 current->comm, task_pid_nr(current), frame, regs->pc, regs->pr);
499 500
500 flush_icache_range(regs->pr, regs->pr + sizeof(frame->retcode));
501
502 return 0; 501 return 0;
503 502
504give_sigsegv: 503give_sigsegv:
diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c
index 442d8d47a41e..160db1003cfb 100644
--- a/arch/sh/kernel/smp.c
+++ b/arch/sh/kernel/smp.c
@@ -35,6 +35,8 @@ static inline void __init smp_store_cpu_info(unsigned int cpu)
35{ 35{
36 struct sh_cpuinfo *c = cpu_data + cpu; 36 struct sh_cpuinfo *c = cpu_data + cpu;
37 37
38 memcpy(c, &boot_cpu_data, sizeof(struct sh_cpuinfo));
39
38 c->loops_per_jiffy = loops_per_jiffy; 40 c->loops_per_jiffy = loops_per_jiffy;
39} 41}
40 42
diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c
index 69bb1652eccd..7a2ee3a6b8e7 100644
--- a/arch/sh/kernel/traps_32.c
+++ b/arch/sh/kernel/traps_32.c
@@ -25,6 +25,7 @@
25#include <linux/kexec.h> 25#include <linux/kexec.h>
26#include <linux/limits.h> 26#include <linux/limits.h>
27#include <linux/proc_fs.h> 27#include <linux/proc_fs.h>
28#include <linux/sysfs.h>
28#include <asm/system.h> 29#include <asm/system.h>
29#include <asm/uaccess.h> 30#include <asm/uaccess.h>
30#include <asm/fpu.h> 31#include <asm/fpu.h>
@@ -54,8 +55,8 @@ static unsigned long se_multi;
54/* bitfield: 1: warn 2: fixup 4: signal -> combinations 2|4 && 1|2|4 are not 55/* bitfield: 1: warn 2: fixup 4: signal -> combinations 2|4 && 1|2|4 are not
55 valid! */ 56 valid! */
56static int se_usermode = 3; 57static int se_usermode = 3;
57/* 0: no warning 1: print a warning message */ 58/* 0: no warning 1: print a warning message, disabled by default */
58static int se_kernmode_warn = 1; 59static int se_kernmode_warn;
59 60
60#ifdef CONFIG_PROC_FS 61#ifdef CONFIG_PROC_FS
61static const char *se_usermode_action[] = { 62static const char *se_usermode_action[] = {
@@ -159,12 +160,12 @@ void die(const char * str, struct pt_regs * regs, long err)
159 160
160 oops_enter(); 161 oops_enter();
161 162
162 console_verbose();
163 spin_lock_irq(&die_lock); 163 spin_lock_irq(&die_lock);
164 console_verbose();
164 bust_spinlocks(1); 165 bust_spinlocks(1);
165 166
166 printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter); 167 printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
167 168 sysfs_printk_last_file();
168 print_modules(); 169 print_modules();
169 show_regs(regs); 170 show_regs(regs);
170 171
@@ -180,6 +181,7 @@ void die(const char * str, struct pt_regs * regs, long err)
180 bust_spinlocks(0); 181 bust_spinlocks(0);
181 add_taint(TAINT_DIE); 182 add_taint(TAINT_DIE);
182 spin_unlock_irq(&die_lock); 183 spin_unlock_irq(&die_lock);
184 oops_exit();
183 185
184 if (kexec_should_crash(current)) 186 if (kexec_should_crash(current))
185 crash_kexec(regs); 187 crash_kexec(regs);
@@ -190,7 +192,6 @@ void die(const char * str, struct pt_regs * regs, long err)
190 if (panic_on_oops) 192 if (panic_on_oops)
191 panic("Fatal exception"); 193 panic("Fatal exception");
192 194
193 oops_exit();
194 do_exit(SIGSEGV); 195 do_exit(SIGSEGV);
195} 196}
196 197
diff --git a/arch/sh/mm/cache-sh4.c b/arch/sh/mm/cache-sh4.c
index b2453bbef4cd..a98c7d8984fa 100644
--- a/arch/sh/mm/cache-sh4.c
+++ b/arch/sh/mm/cache-sh4.c
@@ -43,7 +43,7 @@ static void (*__flush_dcache_segment_fn)(unsigned long, unsigned long) =
43 * Called from kernel/module.c:sys_init_module and routine for a.out format, 43 * Called from kernel/module.c:sys_init_module and routine for a.out format,
44 * signal handler code and kprobes code 44 * signal handler code and kprobes code
45 */ 45 */
46static void sh4_flush_icache_range(void *args) 46static void __uses_jump_to_uncached sh4_flush_icache_range(void *args)
47{ 47{
48 struct flusher_data *data = args; 48 struct flusher_data *data = args;
49 unsigned long start, end; 49 unsigned long start, end;
diff --git a/arch/sh/mm/cache-sh7705.c b/arch/sh/mm/cache-sh7705.c
index 2cadee2037ac..2601935eb589 100644
--- a/arch/sh/mm/cache-sh7705.c
+++ b/arch/sh/mm/cache-sh7705.c
@@ -78,7 +78,7 @@ static void sh7705_flush_icache_range(void *args)
78/* 78/*
79 * Writeback&Invalidate the D-cache of the page 79 * Writeback&Invalidate the D-cache of the page
80 */ 80 */
81static void __flush_dcache_page(unsigned long phys) 81static void __uses_jump_to_uncached __flush_dcache_page(unsigned long phys)
82{ 82{
83 unsigned long ways, waysize, addrstart; 83 unsigned long ways, waysize, addrstart;
84 unsigned long flags; 84 unsigned long flags;
@@ -144,7 +144,7 @@ static void sh7705_flush_dcache_page(void *arg)
144 __flush_dcache_page(PHYSADDR(page_address(page))); 144 __flush_dcache_page(PHYSADDR(page_address(page)));
145} 145}
146 146
147static void sh7705_flush_cache_all(void *args) 147static void __uses_jump_to_uncached sh7705_flush_cache_all(void *args)
148{ 148{
149 unsigned long flags; 149 unsigned long flags;
150 150
diff --git a/arch/sh/mm/cache.c b/arch/sh/mm/cache.c
index 35c37b7f717a..5e1091be9dc4 100644
--- a/arch/sh/mm/cache.c
+++ b/arch/sh/mm/cache.c
@@ -128,7 +128,7 @@ void __update_cache(struct vm_area_struct *vma,
128 return; 128 return;
129 129
130 page = pfn_to_page(pfn); 130 page = pfn_to_page(pfn);
131 if (pfn_valid(pfn) && page_mapping(page)) { 131 if (pfn_valid(pfn)) {
132 int dirty = test_and_clear_bit(PG_dcache_dirty, &page->flags); 132 int dirty = test_and_clear_bit(PG_dcache_dirty, &page->flags);
133 if (dirty) { 133 if (dirty) {
134 unsigned long addr = (unsigned long)page_address(page); 134 unsigned long addr = (unsigned long)page_address(page);
diff --git a/arch/sh/mm/ioremap_32.c b/arch/sh/mm/ioremap_32.c
index c3250614e3ae..a86eaa9d75a5 100644
--- a/arch/sh/mm/ioremap_32.c
+++ b/arch/sh/mm/ioremap_32.c
@@ -83,7 +83,7 @@ void __iomem *__ioremap(unsigned long phys_addr, unsigned long size,
83 * 83 *
84 * PMB entries are all pre-faulted. 84 * PMB entries are all pre-faulted.
85 */ 85 */
86 if (unlikely(size >= 0x1000000)) { 86 if (unlikely(phys_addr >= P1SEG)) {
87 unsigned long mapped = pmb_remap(addr, phys_addr, size, flags); 87 unsigned long mapped = pmb_remap(addr, phys_addr, size, flags);
88 88
89 if (likely(mapped)) { 89 if (likely(mapped)) {
diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c
index b1a714a92b14..aade31102112 100644
--- a/arch/sh/mm/pmb.c
+++ b/arch/sh/mm/pmb.c
@@ -33,6 +33,8 @@
33 33
34#define NR_PMB_ENTRIES 16 34#define NR_PMB_ENTRIES 16
35 35
36static void __pmb_unmap(struct pmb_entry *);
37
36static struct kmem_cache *pmb_cache; 38static struct kmem_cache *pmb_cache;
37static unsigned long pmb_map; 39static unsigned long pmb_map;
38 40
@@ -218,9 +220,10 @@ static struct {
218long pmb_remap(unsigned long vaddr, unsigned long phys, 220long pmb_remap(unsigned long vaddr, unsigned long phys,
219 unsigned long size, unsigned long flags) 221 unsigned long size, unsigned long flags)
220{ 222{
221 struct pmb_entry *pmbp; 223 struct pmb_entry *pmbp, *pmbe;
222 unsigned long wanted; 224 unsigned long wanted;
223 int pmb_flags, i; 225 int pmb_flags, i;
226 long err;
224 227
225 /* Convert typical pgprot value to the PMB equivalent */ 228 /* Convert typical pgprot value to the PMB equivalent */
226 if (flags & _PAGE_CACHABLE) { 229 if (flags & _PAGE_CACHABLE) {
@@ -236,20 +239,22 @@ long pmb_remap(unsigned long vaddr, unsigned long phys,
236 239
237again: 240again:
238 for (i = 0; i < ARRAY_SIZE(pmb_sizes); i++) { 241 for (i = 0; i < ARRAY_SIZE(pmb_sizes); i++) {
239 struct pmb_entry *pmbe;
240 int ret; 242 int ret;
241 243
242 if (size < pmb_sizes[i].size) 244 if (size < pmb_sizes[i].size)
243 continue; 245 continue;
244 246
245 pmbe = pmb_alloc(vaddr, phys, pmb_flags | pmb_sizes[i].flag); 247 pmbe = pmb_alloc(vaddr, phys, pmb_flags | pmb_sizes[i].flag);
246 if (IS_ERR(pmbe)) 248 if (IS_ERR(pmbe)) {
247 return PTR_ERR(pmbe); 249 err = PTR_ERR(pmbe);
250 goto out;
251 }
248 252
249 ret = set_pmb_entry(pmbe); 253 ret = set_pmb_entry(pmbe);
250 if (ret != 0) { 254 if (ret != 0) {
251 pmb_free(pmbe); 255 pmb_free(pmbe);
252 return -EBUSY; 256 err = -EBUSY;
257 goto out;
253 } 258 }
254 259
255 phys += pmb_sizes[i].size; 260 phys += pmb_sizes[i].size;
@@ -264,12 +269,25 @@ again:
264 pmbp->link = pmbe; 269 pmbp->link = pmbe;
265 270
266 pmbp = pmbe; 271 pmbp = pmbe;
272
273 /*
274 * Instead of trying smaller sizes on every iteration
275 * (even if we succeed in allocating space), try using
276 * pmb_sizes[i].size again.
277 */
278 i--;
267 } 279 }
268 280
269 if (size >= 0x1000000) 281 if (size >= 0x1000000)
270 goto again; 282 goto again;
271 283
272 return wanted - size; 284 return wanted - size;
285
286out:
287 if (pmbp)
288 __pmb_unmap(pmbp);
289
290 return err;
273} 291}
274 292
275void pmb_unmap(unsigned long addr) 293void pmb_unmap(unsigned long addr)
@@ -283,12 +301,19 @@ void pmb_unmap(unsigned long addr)
283 if (unlikely(!pmbe)) 301 if (unlikely(!pmbe))
284 return; 302 return;
285 303
304 __pmb_unmap(pmbe);
305}
306
307static void __pmb_unmap(struct pmb_entry *pmbe)
308{
286 WARN_ON(!test_bit(pmbe->entry, &pmb_map)); 309 WARN_ON(!test_bit(pmbe->entry, &pmb_map));
287 310
288 do { 311 do {
289 struct pmb_entry *pmblink = pmbe; 312 struct pmb_entry *pmblink = pmbe;
290 313
291 clear_pmb_entry(pmbe); 314 if (pmbe->entry != PMB_NO_ENTRY)
315 clear_pmb_entry(pmbe);
316
292 pmbe = pmblink->link; 317 pmbe = pmblink->link;
293 318
294 pmb_free(pmblink); 319 pmb_free(pmblink);
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index ac45aab741a5..05ef5380a687 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -26,6 +26,7 @@ config SPARC
26 select RTC_CLASS 26 select RTC_CLASS
27 select RTC_DRV_M48T59 27 select RTC_DRV_M48T59
28 select HAVE_PERF_EVENTS 28 select HAVE_PERF_EVENTS
29 select PERF_USE_VMALLOC
29 select HAVE_DMA_ATTRS 30 select HAVE_DMA_ATTRS
30 select HAVE_DMA_API_DEBUG 31 select HAVE_DMA_API_DEBUG
31 32
@@ -48,6 +49,7 @@ config SPARC64
48 select RTC_DRV_SUN4V 49 select RTC_DRV_SUN4V
49 select RTC_DRV_STARFIRE 50 select RTC_DRV_STARFIRE
50 select HAVE_PERF_EVENTS 51 select HAVE_PERF_EVENTS
52 select PERF_USE_VMALLOC
51 53
52config ARCH_DEFCONFIG 54config ARCH_DEFCONFIG
53 string 55 string
diff --git a/arch/sparc/include/asm/hardirq_32.h b/arch/sparc/include/asm/hardirq_32.h
index 4f63ed8df551..162007643cdc 100644
--- a/arch/sparc/include/asm/hardirq_32.h
+++ b/arch/sparc/include/asm/hardirq_32.h
@@ -7,17 +7,7 @@
7#ifndef __SPARC_HARDIRQ_H 7#ifndef __SPARC_HARDIRQ_H
8#define __SPARC_HARDIRQ_H 8#define __SPARC_HARDIRQ_H
9 9
10#include <linux/threads.h>
11#include <linux/spinlock.h>
12#include <linux/cache.h>
13
14/* entry.S is sensitive to the offsets of these fields */ /* XXX P3 Is it? */
15typedef struct {
16 unsigned int __softirq_pending;
17} ____cacheline_aligned irq_cpustat_t;
18
19#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
20
21#define HARDIRQ_BITS 8 10#define HARDIRQ_BITS 8
11#include <asm-generic/hardirq.h>
22 12
23#endif /* __SPARC_HARDIRQ_H */ 13#endif /* __SPARC_HARDIRQ_H */
diff --git a/arch/sparc/include/asm/irq_32.h b/arch/sparc/include/asm/irq_32.h
index ea43057d4763..cbf4801deaaf 100644
--- a/arch/sparc/include/asm/irq_32.h
+++ b/arch/sparc/include/asm/irq_32.h
@@ -6,10 +6,10 @@
6#ifndef _SPARC_IRQ_H 6#ifndef _SPARC_IRQ_H
7#define _SPARC_IRQ_H 7#define _SPARC_IRQ_H
8 8
9#include <linux/interrupt.h>
10
11#define NR_IRQS 16 9#define NR_IRQS 16
12 10
11#include <linux/interrupt.h>
12
13#define irq_canonicalize(irq) (irq) 13#define irq_canonicalize(irq) (irq)
14 14
15extern void __init init_IRQ(void); 15extern void __init init_IRQ(void);
diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h
index 0ff92fa22064..f3cb790fa2ae 100644
--- a/arch/sparc/include/asm/pgtable_64.h
+++ b/arch/sparc/include/asm/pgtable_64.h
@@ -41,8 +41,8 @@
41#define LOW_OBP_ADDRESS _AC(0x00000000f0000000,UL) 41#define LOW_OBP_ADDRESS _AC(0x00000000f0000000,UL)
42#define HI_OBP_ADDRESS _AC(0x0000000100000000,UL) 42#define HI_OBP_ADDRESS _AC(0x0000000100000000,UL)
43#define VMALLOC_START _AC(0x0000000100000000,UL) 43#define VMALLOC_START _AC(0x0000000100000000,UL)
44#define VMALLOC_END _AC(0x0000000200000000,UL) 44#define VMALLOC_END _AC(0x0000010000000000,UL)
45#define VMEMMAP_BASE _AC(0x0000000200000000,UL) 45#define VMEMMAP_BASE _AC(0x0000010000000000,UL)
46 46
47#define vmemmap ((struct page *)VMEMMAP_BASE) 47#define vmemmap ((struct page *)VMEMMAP_BASE)
48 48
diff --git a/arch/sparc/kernel/ktlb.S b/arch/sparc/kernel/ktlb.S
index 3ea6e8cde8c5..1d361477d7d6 100644
--- a/arch/sparc/kernel/ktlb.S
+++ b/arch/sparc/kernel/ktlb.S
@@ -280,8 +280,8 @@ kvmap_dtlb_nonlinear:
280 280
281#ifdef CONFIG_SPARSEMEM_VMEMMAP 281#ifdef CONFIG_SPARSEMEM_VMEMMAP
282 /* Do not use the TSB for vmemmap. */ 282 /* Do not use the TSB for vmemmap. */
283 mov (VMEMMAP_BASE >> 24), %g5 283 mov (VMEMMAP_BASE >> 40), %g5
284 sllx %g5, 24, %g5 284 sllx %g5, 40, %g5
285 cmp %g4,%g5 285 cmp %g4,%g5
286 bgeu,pn %xcc, kvmap_vmemmap 286 bgeu,pn %xcc, kvmap_vmemmap
287 nop 287 nop
@@ -293,8 +293,8 @@ kvmap_dtlb_tsbmiss:
293 sethi %hi(MODULES_VADDR), %g5 293 sethi %hi(MODULES_VADDR), %g5
294 cmp %g4, %g5 294 cmp %g4, %g5
295 blu,pn %xcc, kvmap_dtlb_longpath 295 blu,pn %xcc, kvmap_dtlb_longpath
296 mov (VMALLOC_END >> 24), %g5 296 mov (VMALLOC_END >> 40), %g5
297 sllx %g5, 24, %g5 297 sllx %g5, 40, %g5
298 cmp %g4, %g5 298 cmp %g4, %g5
299 bgeu,pn %xcc, kvmap_dtlb_longpath 299 bgeu,pn %xcc, kvmap_dtlb_longpath
300 nop 300 nop
diff --git a/arch/sparc/kernel/ldc.c b/arch/sparc/kernel/ldc.c
index adf5f273868a..cb3c72c45aab 100644
--- a/arch/sparc/kernel/ldc.c
+++ b/arch/sparc/kernel/ldc.c
@@ -1242,13 +1242,13 @@ int ldc_bind(struct ldc_channel *lp, const char *name)
1242 snprintf(lp->tx_irq_name, LDC_IRQ_NAME_MAX, "%s TX", name); 1242 snprintf(lp->tx_irq_name, LDC_IRQ_NAME_MAX, "%s TX", name);
1243 1243
1244 err = request_irq(lp->cfg.rx_irq, ldc_rx, 1244 err = request_irq(lp->cfg.rx_irq, ldc_rx,
1245 IRQF_SAMPLE_RANDOM | IRQF_SHARED, 1245 IRQF_SAMPLE_RANDOM | IRQF_DISABLED | IRQF_SHARED,
1246 lp->rx_irq_name, lp); 1246 lp->rx_irq_name, lp);
1247 if (err) 1247 if (err)
1248 return err; 1248 return err;
1249 1249
1250 err = request_irq(lp->cfg.tx_irq, ldc_tx, 1250 err = request_irq(lp->cfg.tx_irq, ldc_tx,
1251 IRQF_SAMPLE_RANDOM | IRQF_SHARED, 1251 IRQF_SAMPLE_RANDOM | IRQF_DISABLED | IRQF_SHARED,
1252 lp->tx_irq_name, lp); 1252 lp->tx_irq_name, lp);
1253 if (err) { 1253 if (err) {
1254 free_irq(lp->cfg.rx_irq, lp); 1254 free_irq(lp->cfg.rx_irq, lp);
diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c
index 2d6a1b10c81d..fa5936e1c3b9 100644
--- a/arch/sparc/kernel/perf_event.c
+++ b/arch/sparc/kernel/perf_event.c
@@ -56,7 +56,8 @@ struct cpu_hw_events {
56 struct perf_event *events[MAX_HWEVENTS]; 56 struct perf_event *events[MAX_HWEVENTS];
57 unsigned long used_mask[BITS_TO_LONGS(MAX_HWEVENTS)]; 57 unsigned long used_mask[BITS_TO_LONGS(MAX_HWEVENTS)];
58 unsigned long active_mask[BITS_TO_LONGS(MAX_HWEVENTS)]; 58 unsigned long active_mask[BITS_TO_LONGS(MAX_HWEVENTS)];
59 int enabled; 59 u64 pcr;
60 int enabled;
60}; 61};
61DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = { .enabled = 1, }; 62DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = { .enabled = 1, };
62 63
@@ -68,8 +69,30 @@ struct perf_event_map {
68#define PIC_LOWER 0x02 69#define PIC_LOWER 0x02
69}; 70};
70 71
72static unsigned long perf_event_encode(const struct perf_event_map *pmap)
73{
74 return ((unsigned long) pmap->encoding << 16) | pmap->pic_mask;
75}
76
77static void perf_event_decode(unsigned long val, u16 *enc, u8 *msk)
78{
79 *msk = val & 0xff;
80 *enc = val >> 16;
81}
82
83#define C(x) PERF_COUNT_HW_CACHE_##x
84
85#define CACHE_OP_UNSUPPORTED 0xfffe
86#define CACHE_OP_NONSENSE 0xffff
87
88typedef struct perf_event_map cache_map_t
89 [PERF_COUNT_HW_CACHE_MAX]
90 [PERF_COUNT_HW_CACHE_OP_MAX]
91 [PERF_COUNT_HW_CACHE_RESULT_MAX];
92
71struct sparc_pmu { 93struct sparc_pmu {
72 const struct perf_event_map *(*event_map)(int); 94 const struct perf_event_map *(*event_map)(int);
95 const cache_map_t *cache_map;
73 int max_events; 96 int max_events;
74 int upper_shift; 97 int upper_shift;
75 int lower_shift; 98 int lower_shift;
@@ -80,21 +103,109 @@ struct sparc_pmu {
80 int lower_nop; 103 int lower_nop;
81}; 104};
82 105
83static const struct perf_event_map ultra3i_perfmon_event_map[] = { 106static const struct perf_event_map ultra3_perfmon_event_map[] = {
84 [PERF_COUNT_HW_CPU_CYCLES] = { 0x0000, PIC_UPPER | PIC_LOWER }, 107 [PERF_COUNT_HW_CPU_CYCLES] = { 0x0000, PIC_UPPER | PIC_LOWER },
85 [PERF_COUNT_HW_INSTRUCTIONS] = { 0x0001, PIC_UPPER | PIC_LOWER }, 108 [PERF_COUNT_HW_INSTRUCTIONS] = { 0x0001, PIC_UPPER | PIC_LOWER },
86 [PERF_COUNT_HW_CACHE_REFERENCES] = { 0x0009, PIC_LOWER }, 109 [PERF_COUNT_HW_CACHE_REFERENCES] = { 0x0009, PIC_LOWER },
87 [PERF_COUNT_HW_CACHE_MISSES] = { 0x0009, PIC_UPPER }, 110 [PERF_COUNT_HW_CACHE_MISSES] = { 0x0009, PIC_UPPER },
88}; 111};
89 112
90static const struct perf_event_map *ultra3i_event_map(int event_id) 113static const struct perf_event_map *ultra3_event_map(int event_id)
91{ 114{
92 return &ultra3i_perfmon_event_map[event_id]; 115 return &ultra3_perfmon_event_map[event_id];
93} 116}
94 117
95static const struct sparc_pmu ultra3i_pmu = { 118static const cache_map_t ultra3_cache_map = {
96 .event_map = ultra3i_event_map, 119[C(L1D)] = {
97 .max_events = ARRAY_SIZE(ultra3i_perfmon_event_map), 120 [C(OP_READ)] = {
121 [C(RESULT_ACCESS)] = { 0x09, PIC_LOWER, },
122 [C(RESULT_MISS)] = { 0x09, PIC_UPPER, },
123 },
124 [C(OP_WRITE)] = {
125 [C(RESULT_ACCESS)] = { 0x0a, PIC_LOWER },
126 [C(RESULT_MISS)] = { 0x0a, PIC_UPPER },
127 },
128 [C(OP_PREFETCH)] = {
129 [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
130 [C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED },
131 },
132},
133[C(L1I)] = {
134 [C(OP_READ)] = {
135 [C(RESULT_ACCESS)] = { 0x09, PIC_LOWER, },
136 [C(RESULT_MISS)] = { 0x09, PIC_UPPER, },
137 },
138 [ C(OP_WRITE) ] = {
139 [ C(RESULT_ACCESS) ] = { CACHE_OP_NONSENSE },
140 [ C(RESULT_MISS) ] = { CACHE_OP_NONSENSE },
141 },
142 [ C(OP_PREFETCH) ] = {
143 [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
144 [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
145 },
146},
147[C(LL)] = {
148 [C(OP_READ)] = {
149 [C(RESULT_ACCESS)] = { 0x0c, PIC_LOWER, },
150 [C(RESULT_MISS)] = { 0x0c, PIC_UPPER, },
151 },
152 [C(OP_WRITE)] = {
153 [C(RESULT_ACCESS)] = { 0x0c, PIC_LOWER },
154 [C(RESULT_MISS)] = { 0x0c, PIC_UPPER },
155 },
156 [C(OP_PREFETCH)] = {
157 [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
158 [C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED },
159 },
160},
161[C(DTLB)] = {
162 [C(OP_READ)] = {
163 [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
164 [C(RESULT_MISS)] = { 0x12, PIC_UPPER, },
165 },
166 [ C(OP_WRITE) ] = {
167 [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
168 [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
169 },
170 [ C(OP_PREFETCH) ] = {
171 [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
172 [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
173 },
174},
175[C(ITLB)] = {
176 [C(OP_READ)] = {
177 [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
178 [C(RESULT_MISS)] = { 0x11, PIC_UPPER, },
179 },
180 [ C(OP_WRITE) ] = {
181 [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
182 [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
183 },
184 [ C(OP_PREFETCH) ] = {
185 [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
186 [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
187 },
188},
189[C(BPU)] = {
190 [C(OP_READ)] = {
191 [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
192 [C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED },
193 },
194 [ C(OP_WRITE) ] = {
195 [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
196 [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
197 },
198 [ C(OP_PREFETCH) ] = {
199 [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
200 [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
201 },
202},
203};
204
205static const struct sparc_pmu ultra3_pmu = {
206 .event_map = ultra3_event_map,
207 .cache_map = &ultra3_cache_map,
208 .max_events = ARRAY_SIZE(ultra3_perfmon_event_map),
98 .upper_shift = 11, 209 .upper_shift = 11,
99 .lower_shift = 4, 210 .lower_shift = 4,
100 .event_mask = 0x3f, 211 .event_mask = 0x3f,
@@ -102,6 +213,121 @@ static const struct sparc_pmu ultra3i_pmu = {
102 .lower_nop = 0x14, 213 .lower_nop = 0x14,
103}; 214};
104 215
216/* Niagara1 is very limited. The upper PIC is hard-locked to count
217 * only instructions, so it is free running which creates all kinds of
218 * problems. Some hardware designs make one wonder if the creator
219 * even looked at how this stuff gets used by software.
220 */
221static const struct perf_event_map niagara1_perfmon_event_map[] = {
222 [PERF_COUNT_HW_CPU_CYCLES] = { 0x00, PIC_UPPER },
223 [PERF_COUNT_HW_INSTRUCTIONS] = { 0x00, PIC_UPPER },
224 [PERF_COUNT_HW_CACHE_REFERENCES] = { 0, PIC_NONE },
225 [PERF_COUNT_HW_CACHE_MISSES] = { 0x03, PIC_LOWER },
226};
227
228static const struct perf_event_map *niagara1_event_map(int event_id)
229{
230 return &niagara1_perfmon_event_map[event_id];
231}
232
233static const cache_map_t niagara1_cache_map = {
234[C(L1D)] = {
235 [C(OP_READ)] = {
236 [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
237 [C(RESULT_MISS)] = { 0x03, PIC_LOWER, },
238 },
239 [C(OP_WRITE)] = {
240 [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
241 [C(RESULT_MISS)] = { 0x03, PIC_LOWER, },
242 },
243 [C(OP_PREFETCH)] = {
244 [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
245 [C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED },
246 },
247},
248[C(L1I)] = {
249 [C(OP_READ)] = {
250 [C(RESULT_ACCESS)] = { 0x00, PIC_UPPER },
251 [C(RESULT_MISS)] = { 0x02, PIC_LOWER, },
252 },
253 [ C(OP_WRITE) ] = {
254 [ C(RESULT_ACCESS) ] = { CACHE_OP_NONSENSE },
255 [ C(RESULT_MISS) ] = { CACHE_OP_NONSENSE },
256 },
257 [ C(OP_PREFETCH) ] = {
258 [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
259 [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
260 },
261},
262[C(LL)] = {
263 [C(OP_READ)] = {
264 [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
265 [C(RESULT_MISS)] = { 0x07, PIC_LOWER, },
266 },
267 [C(OP_WRITE)] = {
268 [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
269 [C(RESULT_MISS)] = { 0x07, PIC_LOWER, },
270 },
271 [C(OP_PREFETCH)] = {
272 [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
273 [C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED },
274 },
275},
276[C(DTLB)] = {
277 [C(OP_READ)] = {
278 [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
279 [C(RESULT_MISS)] = { 0x05, PIC_LOWER, },
280 },
281 [ C(OP_WRITE) ] = {
282 [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
283 [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
284 },
285 [ C(OP_PREFETCH) ] = {
286 [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
287 [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
288 },
289},
290[C(ITLB)] = {
291 [C(OP_READ)] = {
292 [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
293 [C(RESULT_MISS)] = { 0x04, PIC_LOWER, },
294 },
295 [ C(OP_WRITE) ] = {
296 [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
297 [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
298 },
299 [ C(OP_PREFETCH) ] = {
300 [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
301 [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
302 },
303},
304[C(BPU)] = {
305 [C(OP_READ)] = {
306 [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
307 [C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED },
308 },
309 [ C(OP_WRITE) ] = {
310 [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
311 [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
312 },
313 [ C(OP_PREFETCH) ] = {
314 [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
315 [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
316 },
317},
318};
319
320static const struct sparc_pmu niagara1_pmu = {
321 .event_map = niagara1_event_map,
322 .cache_map = &niagara1_cache_map,
323 .max_events = ARRAY_SIZE(niagara1_perfmon_event_map),
324 .upper_shift = 0,
325 .lower_shift = 4,
326 .event_mask = 0x7,
327 .upper_nop = 0x0,
328 .lower_nop = 0x0,
329};
330
105static const struct perf_event_map niagara2_perfmon_event_map[] = { 331static const struct perf_event_map niagara2_perfmon_event_map[] = {
106 [PERF_COUNT_HW_CPU_CYCLES] = { 0x02ff, PIC_UPPER | PIC_LOWER }, 332 [PERF_COUNT_HW_CPU_CYCLES] = { 0x02ff, PIC_UPPER | PIC_LOWER },
107 [PERF_COUNT_HW_INSTRUCTIONS] = { 0x02ff, PIC_UPPER | PIC_LOWER }, 333 [PERF_COUNT_HW_INSTRUCTIONS] = { 0x02ff, PIC_UPPER | PIC_LOWER },
@@ -116,14 +342,102 @@ static const struct perf_event_map *niagara2_event_map(int event_id)
116 return &niagara2_perfmon_event_map[event_id]; 342 return &niagara2_perfmon_event_map[event_id];
117} 343}
118 344
345static const cache_map_t niagara2_cache_map = {
346[C(L1D)] = {
347 [C(OP_READ)] = {
348 [C(RESULT_ACCESS)] = { 0x0208, PIC_UPPER | PIC_LOWER, },
349 [C(RESULT_MISS)] = { 0x0302, PIC_UPPER | PIC_LOWER, },
350 },
351 [C(OP_WRITE)] = {
352 [C(RESULT_ACCESS)] = { 0x0210, PIC_UPPER | PIC_LOWER, },
353 [C(RESULT_MISS)] = { 0x0302, PIC_UPPER | PIC_LOWER, },
354 },
355 [C(OP_PREFETCH)] = {
356 [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
357 [C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED },
358 },
359},
360[C(L1I)] = {
361 [C(OP_READ)] = {
362 [C(RESULT_ACCESS)] = { 0x02ff, PIC_UPPER | PIC_LOWER, },
363 [C(RESULT_MISS)] = { 0x0301, PIC_UPPER | PIC_LOWER, },
364 },
365 [ C(OP_WRITE) ] = {
366 [ C(RESULT_ACCESS) ] = { CACHE_OP_NONSENSE },
367 [ C(RESULT_MISS) ] = { CACHE_OP_NONSENSE },
368 },
369 [ C(OP_PREFETCH) ] = {
370 [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
371 [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
372 },
373},
374[C(LL)] = {
375 [C(OP_READ)] = {
376 [C(RESULT_ACCESS)] = { 0x0208, PIC_UPPER | PIC_LOWER, },
377 [C(RESULT_MISS)] = { 0x0330, PIC_UPPER | PIC_LOWER, },
378 },
379 [C(OP_WRITE)] = {
380 [C(RESULT_ACCESS)] = { 0x0210, PIC_UPPER | PIC_LOWER, },
381 [C(RESULT_MISS)] = { 0x0320, PIC_UPPER | PIC_LOWER, },
382 },
383 [C(OP_PREFETCH)] = {
384 [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
385 [C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED },
386 },
387},
388[C(DTLB)] = {
389 [C(OP_READ)] = {
390 [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
391 [C(RESULT_MISS)] = { 0x0b08, PIC_UPPER | PIC_LOWER, },
392 },
393 [ C(OP_WRITE) ] = {
394 [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
395 [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
396 },
397 [ C(OP_PREFETCH) ] = {
398 [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
399 [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
400 },
401},
402[C(ITLB)] = {
403 [C(OP_READ)] = {
404 [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
405 [C(RESULT_MISS)] = { 0xb04, PIC_UPPER | PIC_LOWER, },
406 },
407 [ C(OP_WRITE) ] = {
408 [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
409 [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
410 },
411 [ C(OP_PREFETCH) ] = {
412 [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
413 [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
414 },
415},
416[C(BPU)] = {
417 [C(OP_READ)] = {
418 [C(RESULT_ACCESS)] = { CACHE_OP_UNSUPPORTED },
419 [C(RESULT_MISS)] = { CACHE_OP_UNSUPPORTED },
420 },
421 [ C(OP_WRITE) ] = {
422 [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
423 [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
424 },
425 [ C(OP_PREFETCH) ] = {
426 [ C(RESULT_ACCESS) ] = { CACHE_OP_UNSUPPORTED },
427 [ C(RESULT_MISS) ] = { CACHE_OP_UNSUPPORTED },
428 },
429},
430};
431
119static const struct sparc_pmu niagara2_pmu = { 432static const struct sparc_pmu niagara2_pmu = {
120 .event_map = niagara2_event_map, 433 .event_map = niagara2_event_map,
434 .cache_map = &niagara2_cache_map,
121 .max_events = ARRAY_SIZE(niagara2_perfmon_event_map), 435 .max_events = ARRAY_SIZE(niagara2_perfmon_event_map),
122 .upper_shift = 19, 436 .upper_shift = 19,
123 .lower_shift = 6, 437 .lower_shift = 6,
124 .event_mask = 0xfff, 438 .event_mask = 0xfff,
125 .hv_bit = 0x8, 439 .hv_bit = 0x8,
126 .irq_bit = 0x03, 440 .irq_bit = 0x30,
127 .upper_nop = 0x220, 441 .upper_nop = 0x220,
128 .lower_nop = 0x220, 442 .lower_nop = 0x220,
129}; 443};
@@ -151,23 +465,30 @@ static u64 nop_for_index(int idx)
151 sparc_pmu->lower_nop, idx); 465 sparc_pmu->lower_nop, idx);
152} 466}
153 467
154static inline void sparc_pmu_enable_event(struct hw_perf_event *hwc, 468static inline void sparc_pmu_enable_event(struct cpu_hw_events *cpuc, struct hw_perf_event *hwc, int idx)
155 int idx)
156{ 469{
157 u64 val, mask = mask_for_index(idx); 470 u64 val, mask = mask_for_index(idx);
158 471
159 val = pcr_ops->read(); 472 val = cpuc->pcr;
160 pcr_ops->write((val & ~mask) | hwc->config); 473 val &= ~mask;
474 val |= hwc->config;
475 cpuc->pcr = val;
476
477 pcr_ops->write(cpuc->pcr);
161} 478}
162 479
163static inline void sparc_pmu_disable_event(struct hw_perf_event *hwc, 480static inline void sparc_pmu_disable_event(struct cpu_hw_events *cpuc, struct hw_perf_event *hwc, int idx)
164 int idx)
165{ 481{
166 u64 mask = mask_for_index(idx); 482 u64 mask = mask_for_index(idx);
167 u64 nop = nop_for_index(idx); 483 u64 nop = nop_for_index(idx);
168 u64 val = pcr_ops->read(); 484 u64 val;
169 485
170 pcr_ops->write((val & ~mask) | nop); 486 val = cpuc->pcr;
487 val &= ~mask;
488 val |= nop;
489 cpuc->pcr = val;
490
491 pcr_ops->write(cpuc->pcr);
171} 492}
172 493
173void hw_perf_enable(void) 494void hw_perf_enable(void)
@@ -182,7 +503,7 @@ void hw_perf_enable(void)
182 cpuc->enabled = 1; 503 cpuc->enabled = 1;
183 barrier(); 504 barrier();
184 505
185 val = pcr_ops->read(); 506 val = cpuc->pcr;
186 507
187 for (i = 0; i < MAX_HWEVENTS; i++) { 508 for (i = 0; i < MAX_HWEVENTS; i++) {
188 struct perf_event *cp = cpuc->events[i]; 509 struct perf_event *cp = cpuc->events[i];
@@ -194,7 +515,9 @@ void hw_perf_enable(void)
194 val |= hwc->config_base; 515 val |= hwc->config_base;
195 } 516 }
196 517
197 pcr_ops->write(val); 518 cpuc->pcr = val;
519
520 pcr_ops->write(cpuc->pcr);
198} 521}
199 522
200void hw_perf_disable(void) 523void hw_perf_disable(void)
@@ -207,10 +530,12 @@ void hw_perf_disable(void)
207 530
208 cpuc->enabled = 0; 531 cpuc->enabled = 0;
209 532
210 val = pcr_ops->read(); 533 val = cpuc->pcr;
211 val &= ~(PCR_UTRACE | PCR_STRACE | 534 val &= ~(PCR_UTRACE | PCR_STRACE |
212 sparc_pmu->hv_bit | sparc_pmu->irq_bit); 535 sparc_pmu->hv_bit | sparc_pmu->irq_bit);
213 pcr_ops->write(val); 536 cpuc->pcr = val;
537
538 pcr_ops->write(cpuc->pcr);
214} 539}
215 540
216static u32 read_pmc(int idx) 541static u32 read_pmc(int idx)
@@ -242,7 +567,7 @@ static void write_pmc(int idx, u64 val)
242} 567}
243 568
244static int sparc_perf_event_set_period(struct perf_event *event, 569static int sparc_perf_event_set_period(struct perf_event *event,
245 struct hw_perf_event *hwc, int idx) 570 struct hw_perf_event *hwc, int idx)
246{ 571{
247 s64 left = atomic64_read(&hwc->period_left); 572 s64 left = atomic64_read(&hwc->period_left);
248 s64 period = hwc->sample_period; 573 s64 period = hwc->sample_period;
@@ -282,19 +607,19 @@ static int sparc_pmu_enable(struct perf_event *event)
282 if (test_and_set_bit(idx, cpuc->used_mask)) 607 if (test_and_set_bit(idx, cpuc->used_mask))
283 return -EAGAIN; 608 return -EAGAIN;
284 609
285 sparc_pmu_disable_event(hwc, idx); 610 sparc_pmu_disable_event(cpuc, hwc, idx);
286 611
287 cpuc->events[idx] = event; 612 cpuc->events[idx] = event;
288 set_bit(idx, cpuc->active_mask); 613 set_bit(idx, cpuc->active_mask);
289 614
290 sparc_perf_event_set_period(event, hwc, idx); 615 sparc_perf_event_set_period(event, hwc, idx);
291 sparc_pmu_enable_event(hwc, idx); 616 sparc_pmu_enable_event(cpuc, hwc, idx);
292 perf_event_update_userpage(event); 617 perf_event_update_userpage(event);
293 return 0; 618 return 0;
294} 619}
295 620
296static u64 sparc_perf_event_update(struct perf_event *event, 621static u64 sparc_perf_event_update(struct perf_event *event,
297 struct hw_perf_event *hwc, int idx) 622 struct hw_perf_event *hwc, int idx)
298{ 623{
299 int shift = 64 - 32; 624 int shift = 64 - 32;
300 u64 prev_raw_count, new_raw_count; 625 u64 prev_raw_count, new_raw_count;
@@ -324,7 +649,7 @@ static void sparc_pmu_disable(struct perf_event *event)
324 int idx = hwc->idx; 649 int idx = hwc->idx;
325 650
326 clear_bit(idx, cpuc->active_mask); 651 clear_bit(idx, cpuc->active_mask);
327 sparc_pmu_disable_event(hwc, idx); 652 sparc_pmu_disable_event(cpuc, hwc, idx);
328 653
329 barrier(); 654 barrier();
330 655
@@ -338,18 +663,29 @@ static void sparc_pmu_disable(struct perf_event *event)
338static void sparc_pmu_read(struct perf_event *event) 663static void sparc_pmu_read(struct perf_event *event)
339{ 664{
340 struct hw_perf_event *hwc = &event->hw; 665 struct hw_perf_event *hwc = &event->hw;
666
341 sparc_perf_event_update(event, hwc, hwc->idx); 667 sparc_perf_event_update(event, hwc, hwc->idx);
342} 668}
343 669
344static void sparc_pmu_unthrottle(struct perf_event *event) 670static void sparc_pmu_unthrottle(struct perf_event *event)
345{ 671{
672 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
346 struct hw_perf_event *hwc = &event->hw; 673 struct hw_perf_event *hwc = &event->hw;
347 sparc_pmu_enable_event(hwc, hwc->idx); 674
675 sparc_pmu_enable_event(cpuc, hwc, hwc->idx);
348} 676}
349 677
350static atomic_t active_events = ATOMIC_INIT(0); 678static atomic_t active_events = ATOMIC_INIT(0);
351static DEFINE_MUTEX(pmc_grab_mutex); 679static DEFINE_MUTEX(pmc_grab_mutex);
352 680
681static void perf_stop_nmi_watchdog(void *unused)
682{
683 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
684
685 stop_nmi_watchdog(NULL);
686 cpuc->pcr = pcr_ops->read();
687}
688
353void perf_event_grab_pmc(void) 689void perf_event_grab_pmc(void)
354{ 690{
355 if (atomic_inc_not_zero(&active_events)) 691 if (atomic_inc_not_zero(&active_events))
@@ -358,7 +694,7 @@ void perf_event_grab_pmc(void)
358 mutex_lock(&pmc_grab_mutex); 694 mutex_lock(&pmc_grab_mutex);
359 if (atomic_read(&active_events) == 0) { 695 if (atomic_read(&active_events) == 0) {
360 if (atomic_read(&nmi_active) > 0) { 696 if (atomic_read(&nmi_active) > 0) {
361 on_each_cpu(stop_nmi_watchdog, NULL, 1); 697 on_each_cpu(perf_stop_nmi_watchdog, NULL, 1);
362 BUG_ON(atomic_read(&nmi_active) != 0); 698 BUG_ON(atomic_read(&nmi_active) != 0);
363 } 699 }
364 atomic_inc(&active_events); 700 atomic_inc(&active_events);
@@ -375,30 +711,160 @@ void perf_event_release_pmc(void)
375 } 711 }
376} 712}
377 713
714static const struct perf_event_map *sparc_map_cache_event(u64 config)
715{
716 unsigned int cache_type, cache_op, cache_result;
717 const struct perf_event_map *pmap;
718
719 if (!sparc_pmu->cache_map)
720 return ERR_PTR(-ENOENT);
721
722 cache_type = (config >> 0) & 0xff;
723 if (cache_type >= PERF_COUNT_HW_CACHE_MAX)
724 return ERR_PTR(-EINVAL);
725
726 cache_op = (config >> 8) & 0xff;
727 if (cache_op >= PERF_COUNT_HW_CACHE_OP_MAX)
728 return ERR_PTR(-EINVAL);
729
730 cache_result = (config >> 16) & 0xff;
731 if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX)
732 return ERR_PTR(-EINVAL);
733
734 pmap = &((*sparc_pmu->cache_map)[cache_type][cache_op][cache_result]);
735
736 if (pmap->encoding == CACHE_OP_UNSUPPORTED)
737 return ERR_PTR(-ENOENT);
738
739 if (pmap->encoding == CACHE_OP_NONSENSE)
740 return ERR_PTR(-EINVAL);
741
742 return pmap;
743}
744
378static void hw_perf_event_destroy(struct perf_event *event) 745static void hw_perf_event_destroy(struct perf_event *event)
379{ 746{
380 perf_event_release_pmc(); 747 perf_event_release_pmc();
381} 748}
382 749
750/* Make sure all events can be scheduled into the hardware at
751 * the same time. This is simplified by the fact that we only
752 * need to support 2 simultaneous HW events.
753 */
754static int sparc_check_constraints(unsigned long *events, int n_ev)
755{
756 if (n_ev <= perf_max_events) {
757 u8 msk1, msk2;
758 u16 dummy;
759
760 if (n_ev == 1)
761 return 0;
762 BUG_ON(n_ev != 2);
763 perf_event_decode(events[0], &dummy, &msk1);
764 perf_event_decode(events[1], &dummy, &msk2);
765
766 /* If both events can go on any counter, OK. */
767 if (msk1 == (PIC_UPPER | PIC_LOWER) &&
768 msk2 == (PIC_UPPER | PIC_LOWER))
769 return 0;
770
771 /* If one event is limited to a specific counter,
772 * and the other can go on both, OK.
773 */
774 if ((msk1 == PIC_UPPER || msk1 == PIC_LOWER) &&
775 msk2 == (PIC_UPPER | PIC_LOWER))
776 return 0;
777 if ((msk2 == PIC_UPPER || msk2 == PIC_LOWER) &&
778 msk1 == (PIC_UPPER | PIC_LOWER))
779 return 0;
780
781 /* If the events are fixed to different counters, OK. */
782 if ((msk1 == PIC_UPPER && msk2 == PIC_LOWER) ||
783 (msk1 == PIC_LOWER && msk2 == PIC_UPPER))
784 return 0;
785
786 /* Otherwise, there is a conflict. */
787 }
788
789 return -1;
790}
791
792static int check_excludes(struct perf_event **evts, int n_prev, int n_new)
793{
794 int eu = 0, ek = 0, eh = 0;
795 struct perf_event *event;
796 int i, n, first;
797
798 n = n_prev + n_new;
799 if (n <= 1)
800 return 0;
801
802 first = 1;
803 for (i = 0; i < n; i++) {
804 event = evts[i];
805 if (first) {
806 eu = event->attr.exclude_user;
807 ek = event->attr.exclude_kernel;
808 eh = event->attr.exclude_hv;
809 first = 0;
810 } else if (event->attr.exclude_user != eu ||
811 event->attr.exclude_kernel != ek ||
812 event->attr.exclude_hv != eh) {
813 return -EAGAIN;
814 }
815 }
816
817 return 0;
818}
819
820static int collect_events(struct perf_event *group, int max_count,
821 struct perf_event *evts[], unsigned long *events)
822{
823 struct perf_event *event;
824 int n = 0;
825
826 if (!is_software_event(group)) {
827 if (n >= max_count)
828 return -1;
829 evts[n] = group;
830 events[n++] = group->hw.event_base;
831 }
832 list_for_each_entry(event, &group->sibling_list, group_entry) {
833 if (!is_software_event(event) &&
834 event->state != PERF_EVENT_STATE_OFF) {
835 if (n >= max_count)
836 return -1;
837 evts[n] = event;
838 events[n++] = event->hw.event_base;
839 }
840 }
841 return n;
842}
843
383static int __hw_perf_event_init(struct perf_event *event) 844static int __hw_perf_event_init(struct perf_event *event)
384{ 845{
385 struct perf_event_attr *attr = &event->attr; 846 struct perf_event_attr *attr = &event->attr;
847 struct perf_event *evts[MAX_HWEVENTS];
386 struct hw_perf_event *hwc = &event->hw; 848 struct hw_perf_event *hwc = &event->hw;
849 unsigned long events[MAX_HWEVENTS];
387 const struct perf_event_map *pmap; 850 const struct perf_event_map *pmap;
388 u64 enc; 851 u64 enc;
852 int n;
389 853
390 if (atomic_read(&nmi_active) < 0) 854 if (atomic_read(&nmi_active) < 0)
391 return -ENODEV; 855 return -ENODEV;
392 856
393 if (attr->type != PERF_TYPE_HARDWARE) 857 if (attr->type == PERF_TYPE_HARDWARE) {
858 if (attr->config >= sparc_pmu->max_events)
859 return -EINVAL;
860 pmap = sparc_pmu->event_map(attr->config);
861 } else if (attr->type == PERF_TYPE_HW_CACHE) {
862 pmap = sparc_map_cache_event(attr->config);
863 if (IS_ERR(pmap))
864 return PTR_ERR(pmap);
865 } else
394 return -EOPNOTSUPP; 866 return -EOPNOTSUPP;
395 867
396 if (attr->config >= sparc_pmu->max_events)
397 return -EINVAL;
398
399 perf_event_grab_pmc();
400 event->destroy = hw_perf_event_destroy;
401
402 /* We save the enable bits in the config_base. So to 868 /* We save the enable bits in the config_base. So to
403 * turn off sampling just write 'config', and to enable 869 * turn off sampling just write 'config', and to enable
404 * things write 'config | config_base'. 870 * things write 'config | config_base'.
@@ -411,15 +877,39 @@ static int __hw_perf_event_init(struct perf_event *event)
411 if (!attr->exclude_hv) 877 if (!attr->exclude_hv)
412 hwc->config_base |= sparc_pmu->hv_bit; 878 hwc->config_base |= sparc_pmu->hv_bit;
413 879
880 hwc->event_base = perf_event_encode(pmap);
881
882 enc = pmap->encoding;
883
884 n = 0;
885 if (event->group_leader != event) {
886 n = collect_events(event->group_leader,
887 perf_max_events - 1,
888 evts, events);
889 if (n < 0)
890 return -EINVAL;
891 }
892 events[n] = hwc->event_base;
893 evts[n] = event;
894
895 if (check_excludes(evts, n, 1))
896 return -EINVAL;
897
898 if (sparc_check_constraints(events, n + 1))
899 return -EINVAL;
900
901 /* Try to do all error checking before this point, as unwinding
902 * state after grabbing the PMC is difficult.
903 */
904 perf_event_grab_pmc();
905 event->destroy = hw_perf_event_destroy;
906
414 if (!hwc->sample_period) { 907 if (!hwc->sample_period) {
415 hwc->sample_period = MAX_PERIOD; 908 hwc->sample_period = MAX_PERIOD;
416 hwc->last_period = hwc->sample_period; 909 hwc->last_period = hwc->sample_period;
417 atomic64_set(&hwc->period_left, hwc->sample_period); 910 atomic64_set(&hwc->period_left, hwc->sample_period);
418 } 911 }
419 912
420 pmap = sparc_pmu->event_map(attr->config);
421
422 enc = pmap->encoding;
423 if (pmap->pic_mask & PIC_UPPER) { 913 if (pmap->pic_mask & PIC_UPPER) {
424 hwc->idx = PIC_UPPER_INDEX; 914 hwc->idx = PIC_UPPER_INDEX;
425 enc <<= sparc_pmu->upper_shift; 915 enc <<= sparc_pmu->upper_shift;
@@ -472,7 +962,7 @@ void perf_event_print_debug(void)
472} 962}
473 963
474static int __kprobes perf_event_nmi_handler(struct notifier_block *self, 964static int __kprobes perf_event_nmi_handler(struct notifier_block *self,
475 unsigned long cmd, void *__args) 965 unsigned long cmd, void *__args)
476{ 966{
477 struct die_args *args = __args; 967 struct die_args *args = __args;
478 struct perf_sample_data data; 968 struct perf_sample_data data;
@@ -513,7 +1003,7 @@ static int __kprobes perf_event_nmi_handler(struct notifier_block *self,
513 continue; 1003 continue;
514 1004
515 if (perf_event_overflow(event, 1, &data, regs)) 1005 if (perf_event_overflow(event, 1, &data, regs))
516 sparc_pmu_disable_event(hwc, idx); 1006 sparc_pmu_disable_event(cpuc, hwc, idx);
517 } 1007 }
518 1008
519 return NOTIFY_STOP; 1009 return NOTIFY_STOP;
@@ -525,8 +1015,15 @@ static __read_mostly struct notifier_block perf_event_nmi_notifier = {
525 1015
526static bool __init supported_pmu(void) 1016static bool __init supported_pmu(void)
527{ 1017{
528 if (!strcmp(sparc_pmu_type, "ultra3i")) { 1018 if (!strcmp(sparc_pmu_type, "ultra3") ||
529 sparc_pmu = &ultra3i_pmu; 1019 !strcmp(sparc_pmu_type, "ultra3+") ||
1020 !strcmp(sparc_pmu_type, "ultra3i") ||
1021 !strcmp(sparc_pmu_type, "ultra4+")) {
1022 sparc_pmu = &ultra3_pmu;
1023 return true;
1024 }
1025 if (!strcmp(sparc_pmu_type, "niagara")) {
1026 sparc_pmu = &niagara1_pmu;
530 return true; 1027 return true;
531 } 1028 }
532 if (!strcmp(sparc_pmu_type, "niagara2")) { 1029 if (!strcmp(sparc_pmu_type, "niagara2")) {
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
index a70a5e1904d9..1886d37d411b 100644
--- a/arch/sparc/mm/init_64.c
+++ b/arch/sparc/mm/init_64.c
@@ -265,7 +265,7 @@ static void flush_dcache(unsigned long pfn)
265 struct page *page; 265 struct page *page;
266 266
267 page = pfn_to_page(pfn); 267 page = pfn_to_page(pfn);
268 if (page && page_mapping(page)) { 268 if (page) {
269 unsigned long pg_flags; 269 unsigned long pg_flags;
270 270
271 pg_flags = page->flags; 271 pg_flags = page->flags;
diff --git a/arch/sparc/oprofile/init.c b/arch/sparc/oprofile/init.c
index f97cb8b6ee5f..f9024bccff16 100644
--- a/arch/sparc/oprofile/init.c
+++ b/arch/sparc/oprofile/init.c
@@ -11,6 +11,7 @@
11#include <linux/oprofile.h> 11#include <linux/oprofile.h>
12#include <linux/errno.h> 12#include <linux/errno.h>
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/param.h> /* for HZ */
14 15
15#ifdef CONFIG_SPARC64 16#ifdef CONFIG_SPARC64
16#include <linux/notifier.h> 17#include <linux/notifier.h>
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index 14a102e877d6..cf8a97f34518 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -5,6 +5,7 @@
5 5
6#include "linux/irqreturn.h" 6#include "linux/irqreturn.h"
7#include "linux/kd.h" 7#include "linux/kd.h"
8#include "linux/sched.h"
8#include "chan_kern.h" 9#include "chan_kern.h"
9#include "irq_kern.h" 10#include "irq_kern.h"
10#include "irq_user.h" 11#include "irq_user.h"
diff --git a/arch/um/drivers/port_kern.c b/arch/um/drivers/port_kern.c
index 19930081d3d8..4ebc8a34738f 100644
--- a/arch/um/drivers/port_kern.c
+++ b/arch/um/drivers/port_kern.c
@@ -7,6 +7,7 @@
7#include "linux/interrupt.h" 7#include "linux/interrupt.h"
8#include "linux/list.h" 8#include "linux/list.h"
9#include "linux/mutex.h" 9#include "linux/mutex.h"
10#include "linux/workqueue.h"
10#include "asm/atomic.h" 11#include "asm/atomic.h"
11#include "init.h" 12#include "init.h"
12#include "irq_kern.h" 13#include "irq_kern.h"
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
index 454cdb43e351..039270b9b73b 100644
--- a/arch/um/kernel/irq.c
+++ b/arch/um/kernel/irq.c
@@ -10,6 +10,7 @@
10#include "linux/interrupt.h" 10#include "linux/interrupt.h"
11#include "linux/kernel_stat.h" 11#include "linux/kernel_stat.h"
12#include "linux/module.h" 12#include "linux/module.h"
13#include "linux/sched.h"
13#include "linux/seq_file.h" 14#include "linux/seq_file.h"
14#include "as-layout.h" 15#include "as-layout.h"
15#include "kern_util.h" 16#include "kern_util.h"
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 8da93745c087..07e01149e3bf 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -86,10 +86,6 @@ config STACKTRACE_SUPPORT
86config HAVE_LATENCYTOP_SUPPORT 86config HAVE_LATENCYTOP_SUPPORT
87 def_bool y 87 def_bool y
88 88
89config FAST_CMPXCHG_LOCAL
90 bool
91 default y
92
93config MMU 89config MMU
94 def_bool y 90 def_bool y
95 91
@@ -495,7 +491,7 @@ if PARAVIRT_GUEST
495source "arch/x86/xen/Kconfig" 491source "arch/x86/xen/Kconfig"
496 492
497config VMI 493config VMI
498 bool "VMI Guest support" 494 bool "VMI Guest support (DEPRECATED)"
499 select PARAVIRT 495 select PARAVIRT
500 depends on X86_32 496 depends on X86_32
501 ---help--- 497 ---help---
@@ -504,6 +500,15 @@ config VMI
504 at the moment), by linking the kernel to a GPL-ed ROM module 500 at the moment), by linking the kernel to a GPL-ed ROM module
505 provided by the hypervisor. 501 provided by the hypervisor.
506 502
503 As of September 2009, VMware has started a phased retirement
504 of this feature from VMware's products. Please see
505 feature-removal-schedule.txt for details. If you are
506 planning to enable this option, please note that you cannot
507 live migrate a VMI enabled VM to a future VMware product,
508 which doesn't support VMI. So if you expect your kernel to
509 seamlessly migrate to newer VMware products, keep this
510 disabled.
511
507config KVM_CLOCK 512config KVM_CLOCK
508 bool "KVM paravirtualized clock" 513 bool "KVM paravirtualized clock"
509 select PARAVIRT 514 select PARAVIRT
diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
index 527519b8a9f9..f2824fb8c79c 100644
--- a/arch/x86/Kconfig.cpu
+++ b/arch/x86/Kconfig.cpu
@@ -400,7 +400,7 @@ config X86_TSC
400 400
401config X86_CMPXCHG64 401config X86_CMPXCHG64
402 def_bool y 402 def_bool y
403 depends on X86_PAE || X86_64 403 depends on X86_PAE || X86_64 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MATOM
404 404
405# this should be set for all -march=.. options where the compiler 405# this should be set for all -march=.. options where the compiler
406# generates cmov. 406# generates cmov.
@@ -412,6 +412,7 @@ config X86_MINIMUM_CPU_FAMILY
412 int 412 int
413 default "64" if X86_64 413 default "64" if X86_64
414 default "6" if X86_32 && X86_P6_NOP 414 default "6" if X86_32 && X86_P6_NOP
415 default "5" if X86_32 && X86_CMPXCHG64
415 default "4" if X86_32 && (X86_XADD || X86_CMPXCHG || X86_BSWAP || X86_WP_WORKS_OK) 416 default "4" if X86_32 && (X86_XADD || X86_CMPXCHG || X86_BSWAP || X86_WP_WORKS_OK)
416 default "3" 417 default "3"
417 418
diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S
index 74619c4f9fda..1733f9f65e82 100644
--- a/arch/x86/ia32/ia32entry.S
+++ b/arch/x86/ia32/ia32entry.S
@@ -21,8 +21,8 @@
21#define __AUDIT_ARCH_LE 0x40000000 21#define __AUDIT_ARCH_LE 0x40000000
22 22
23#ifndef CONFIG_AUDITSYSCALL 23#ifndef CONFIG_AUDITSYSCALL
24#define sysexit_audit int_ret_from_sys_call 24#define sysexit_audit ia32_ret_from_sys_call
25#define sysretl_audit int_ret_from_sys_call 25#define sysretl_audit ia32_ret_from_sys_call
26#endif 26#endif
27 27
28#define IA32_NR_syscalls ((ia32_syscall_end - ia32_sys_call_table)/8) 28#define IA32_NR_syscalls ((ia32_syscall_end - ia32_sys_call_table)/8)
@@ -39,12 +39,12 @@
39 .endm 39 .endm
40 40
41 /* clobbers %eax */ 41 /* clobbers %eax */
42 .macro CLEAR_RREGS _r9=rax 42 .macro CLEAR_RREGS offset=0, _r9=rax
43 xorl %eax,%eax 43 xorl %eax,%eax
44 movq %rax,R11(%rsp) 44 movq %rax,\offset+R11(%rsp)
45 movq %rax,R10(%rsp) 45 movq %rax,\offset+R10(%rsp)
46 movq %\_r9,R9(%rsp) 46 movq %\_r9,\offset+R9(%rsp)
47 movq %rax,R8(%rsp) 47 movq %rax,\offset+R8(%rsp)
48 .endm 48 .endm
49 49
50 /* 50 /*
@@ -172,6 +172,10 @@ sysexit_from_sys_call:
172 movl RIP-R11(%rsp),%edx /* User %eip */ 172 movl RIP-R11(%rsp),%edx /* User %eip */
173 CFI_REGISTER rip,rdx 173 CFI_REGISTER rip,rdx
174 RESTORE_ARGS 1,24,1,1,1,1 174 RESTORE_ARGS 1,24,1,1,1,1
175 xorq %r8,%r8
176 xorq %r9,%r9
177 xorq %r10,%r10
178 xorq %r11,%r11
175 popfq 179 popfq
176 CFI_ADJUST_CFA_OFFSET -8 180 CFI_ADJUST_CFA_OFFSET -8
177 /*CFI_RESTORE rflags*/ 181 /*CFI_RESTORE rflags*/
@@ -202,7 +206,7 @@ sysexit_from_sys_call:
202 206
203 .macro auditsys_exit exit,ebpsave=RBP 207 .macro auditsys_exit exit,ebpsave=RBP
204 testl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT),TI_flags(%r10) 208 testl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT),TI_flags(%r10)
205 jnz int_ret_from_sys_call 209 jnz ia32_ret_from_sys_call
206 TRACE_IRQS_ON 210 TRACE_IRQS_ON
207 sti 211 sti
208 movl %eax,%esi /* second arg, syscall return value */ 212 movl %eax,%esi /* second arg, syscall return value */
@@ -218,8 +222,9 @@ sysexit_from_sys_call:
218 cli 222 cli
219 TRACE_IRQS_OFF 223 TRACE_IRQS_OFF
220 testl %edi,TI_flags(%r10) 224 testl %edi,TI_flags(%r10)
221 jnz int_with_check 225 jz \exit
222 jmp \exit 226 CLEAR_RREGS -ARGOFFSET
227 jmp int_with_check
223 .endm 228 .endm
224 229
225sysenter_auditsys: 230sysenter_auditsys:
@@ -329,6 +334,9 @@ sysretl_from_sys_call:
329 CFI_REGISTER rip,rcx 334 CFI_REGISTER rip,rcx
330 movl EFLAGS-ARGOFFSET(%rsp),%r11d 335 movl EFLAGS-ARGOFFSET(%rsp),%r11d
331 /*CFI_REGISTER rflags,r11*/ 336 /*CFI_REGISTER rflags,r11*/
337 xorq %r10,%r10
338 xorq %r9,%r9
339 xorq %r8,%r8
332 TRACE_IRQS_ON 340 TRACE_IRQS_ON
333 movl RSP-ARGOFFSET(%rsp),%esp 341 movl RSP-ARGOFFSET(%rsp),%esp
334 CFI_RESTORE rsp 342 CFI_RESTORE rsp
@@ -353,7 +361,7 @@ cstar_tracesys:
353#endif 361#endif
354 xchgl %r9d,%ebp 362 xchgl %r9d,%ebp
355 SAVE_REST 363 SAVE_REST
356 CLEAR_RREGS r9 364 CLEAR_RREGS 0, r9
357 movq $-ENOSYS,RAX(%rsp) /* ptrace can change this for a bad syscall */ 365 movq $-ENOSYS,RAX(%rsp) /* ptrace can change this for a bad syscall */
358 movq %rsp,%rdi /* &pt_regs -> arg1 */ 366 movq %rsp,%rdi /* &pt_regs -> arg1 */
359 call syscall_trace_enter 367 call syscall_trace_enter
@@ -425,6 +433,8 @@ ia32_do_call:
425 call *ia32_sys_call_table(,%rax,8) # xxx: rip relative 433 call *ia32_sys_call_table(,%rax,8) # xxx: rip relative
426ia32_sysret: 434ia32_sysret:
427 movq %rax,RAX-ARGOFFSET(%rsp) 435 movq %rax,RAX-ARGOFFSET(%rsp)
436ia32_ret_from_sys_call:
437 CLEAR_RREGS -ARGOFFSET
428 jmp int_ret_from_sys_call 438 jmp int_ret_from_sys_call
429 439
430ia32_tracesys: 440ia32_tracesys:
@@ -442,8 +452,8 @@ END(ia32_syscall)
442 452
443ia32_badsys: 453ia32_badsys:
444 movq $0,ORIG_RAX-ARGOFFSET(%rsp) 454 movq $0,ORIG_RAX-ARGOFFSET(%rsp)
445 movq $-ENOSYS,RAX-ARGOFFSET(%rsp) 455 movq $-ENOSYS,%rax
446 jmp int_ret_from_sys_call 456 jmp ia32_sysret
447 457
448quiet_ni_syscall: 458quiet_ni_syscall:
449 movq $-ENOSYS,%rax 459 movq $-ENOSYS,%rax
diff --git a/arch/x86/include/asm/checksum_32.h b/arch/x86/include/asm/checksum_32.h
index 7c5ef8b14d92..46fc474fd819 100644
--- a/arch/x86/include/asm/checksum_32.h
+++ b/arch/x86/include/asm/checksum_32.h
@@ -161,7 +161,8 @@ static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
161 "adcl $0, %0 ;\n" 161 "adcl $0, %0 ;\n"
162 : "=&r" (sum) 162 : "=&r" (sum)
163 : "r" (saddr), "r" (daddr), 163 : "r" (saddr), "r" (daddr),
164 "r" (htonl(len)), "r" (htonl(proto)), "0" (sum)); 164 "r" (htonl(len)), "r" (htonl(proto)), "0" (sum)
165 : "memory");
165 166
166 return csum_fold(sum); 167 return csum_fold(sum);
167} 168}
diff --git a/arch/x86/include/asm/cmpxchg_32.h b/arch/x86/include/asm/cmpxchg_32.h
index 82ceb788a981..ee1931be6593 100644
--- a/arch/x86/include/asm/cmpxchg_32.h
+++ b/arch/x86/include/asm/cmpxchg_32.h
@@ -312,19 +312,23 @@ static inline unsigned long cmpxchg_386(volatile void *ptr, unsigned long old,
312 312
313extern unsigned long long cmpxchg_486_u64(volatile void *, u64, u64); 313extern unsigned long long cmpxchg_486_u64(volatile void *, u64, u64);
314 314
315#define cmpxchg64(ptr, o, n) \ 315#define cmpxchg64(ptr, o, n) \
316({ \ 316({ \
317 __typeof__(*(ptr)) __ret; \ 317 __typeof__(*(ptr)) __ret; \
318 if (likely(boot_cpu_data.x86 > 4)) \ 318 __typeof__(*(ptr)) __old = (o); \
319 __ret = (__typeof__(*(ptr)))__cmpxchg64((ptr), \ 319 __typeof__(*(ptr)) __new = (n); \
320 (unsigned long long)(o), \ 320 alternative_io("call cmpxchg8b_emu", \
321 (unsigned long long)(n)); \ 321 "lock; cmpxchg8b (%%esi)" , \
322 else \ 322 X86_FEATURE_CX8, \
323 __ret = (__typeof__(*(ptr)))cmpxchg_486_u64((ptr), \ 323 "=A" (__ret), \
324 (unsigned long long)(o), \ 324 "S" ((ptr)), "0" (__old), \
325 (unsigned long long)(n)); \ 325 "b" ((unsigned int)__new), \
326 __ret; \ 326 "c" ((unsigned int)(__new>>32)) \
327}) 327 : "memory"); \
328 __ret; })
329
330
331
328#define cmpxchg64_local(ptr, o, n) \ 332#define cmpxchg64_local(ptr, o, n) \
329({ \ 333({ \
330 __typeof__(*(ptr)) __ret; \ 334 __typeof__(*(ptr)) __ret; \
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 3be000435fad..d83892226f73 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -796,6 +796,7 @@ asmlinkage void kvm_handle_fault_on_reboot(void);
796#define KVM_ARCH_WANT_MMU_NOTIFIER 796#define KVM_ARCH_WANT_MMU_NOTIFIER
797int kvm_unmap_hva(struct kvm *kvm, unsigned long hva); 797int kvm_unmap_hva(struct kvm *kvm, unsigned long hva);
798int kvm_age_hva(struct kvm *kvm, unsigned long hva); 798int kvm_age_hva(struct kvm *kvm, unsigned long hva);
799void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte);
799int cpuid_maxphyaddr(struct kvm_vcpu *vcpu); 800int cpuid_maxphyaddr(struct kvm_vcpu *vcpu);
800int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu); 801int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu);
801int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu); 802int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu);
diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h
index b608a64c5814..f1363b72364f 100644
--- a/arch/x86/include/asm/mce.h
+++ b/arch/x86/include/asm/mce.h
@@ -133,6 +133,8 @@ static inline void winchip_mcheck_init(struct cpuinfo_x86 *c) {}
133static inline void enable_p5_mce(void) {} 133static inline void enable_p5_mce(void) {}
134#endif 134#endif
135 135
136extern void (*x86_mce_decode_callback)(struct mce *m);
137
136void mce_setup(struct mce *m); 138void mce_setup(struct mce *m);
137void mce_log(struct mce *m); 139void mce_log(struct mce *m);
138DECLARE_PER_CPU(struct sys_device, mce_dev); 140DECLARE_PER_CPU(struct sys_device, mce_dev);
diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h
index 8aebcc41041d..efb38994859c 100644
--- a/arch/x86/include/asm/paravirt.h
+++ b/arch/x86/include/asm/paravirt.h
@@ -840,42 +840,22 @@ static __always_inline void __raw_spin_unlock(struct raw_spinlock *lock)
840 840
841static inline unsigned long __raw_local_save_flags(void) 841static inline unsigned long __raw_local_save_flags(void)
842{ 842{
843 unsigned long f; 843 return PVOP_CALLEE0(unsigned long, pv_irq_ops.save_fl);
844
845 asm volatile(paravirt_alt(PARAVIRT_CALL)
846 : "=a"(f)
847 : paravirt_type(pv_irq_ops.save_fl),
848 paravirt_clobber(CLBR_EAX)
849 : "memory", "cc");
850 return f;
851} 844}
852 845
853static inline void raw_local_irq_restore(unsigned long f) 846static inline void raw_local_irq_restore(unsigned long f)
854{ 847{
855 asm volatile(paravirt_alt(PARAVIRT_CALL) 848 PVOP_VCALLEE1(pv_irq_ops.restore_fl, f);
856 : "=a"(f)
857 : PV_FLAGS_ARG(f),
858 paravirt_type(pv_irq_ops.restore_fl),
859 paravirt_clobber(CLBR_EAX)
860 : "memory", "cc");
861} 849}
862 850
863static inline void raw_local_irq_disable(void) 851static inline void raw_local_irq_disable(void)
864{ 852{
865 asm volatile(paravirt_alt(PARAVIRT_CALL) 853 PVOP_VCALLEE0(pv_irq_ops.irq_disable);
866 :
867 : paravirt_type(pv_irq_ops.irq_disable),
868 paravirt_clobber(CLBR_EAX)
869 : "memory", "eax", "cc");
870} 854}
871 855
872static inline void raw_local_irq_enable(void) 856static inline void raw_local_irq_enable(void)
873{ 857{
874 asm volatile(paravirt_alt(PARAVIRT_CALL) 858 PVOP_VCALLEE0(pv_irq_ops.irq_enable);
875 :
876 : paravirt_type(pv_irq_ops.irq_enable),
877 paravirt_clobber(CLBR_EAX)
878 : "memory", "eax", "cc");
879} 859}
880 860
881static inline unsigned long __raw_local_irq_save(void) 861static inline unsigned long __raw_local_irq_save(void)
diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h
index dd0f5b32489d..9357473c8da0 100644
--- a/arch/x86/include/asm/paravirt_types.h
+++ b/arch/x86/include/asm/paravirt_types.h
@@ -494,10 +494,11 @@ int paravirt_disable_iospace(void);
494#define EXTRA_CLOBBERS 494#define EXTRA_CLOBBERS
495#define VEXTRA_CLOBBERS 495#define VEXTRA_CLOBBERS
496#else /* CONFIG_X86_64 */ 496#else /* CONFIG_X86_64 */
497/* [re]ax isn't an arg, but the return val */
497#define PVOP_VCALL_ARGS \ 498#define PVOP_VCALL_ARGS \
498 unsigned long __edi = __edi, __esi = __esi, \ 499 unsigned long __edi = __edi, __esi = __esi, \
499 __edx = __edx, __ecx = __ecx 500 __edx = __edx, __ecx = __ecx, __eax = __eax
500#define PVOP_CALL_ARGS PVOP_VCALL_ARGS, __eax 501#define PVOP_CALL_ARGS PVOP_VCALL_ARGS
501 502
502#define PVOP_CALL_ARG1(x) "D" ((unsigned long)(x)) 503#define PVOP_CALL_ARG1(x) "D" ((unsigned long)(x))
503#define PVOP_CALL_ARG2(x) "S" ((unsigned long)(x)) 504#define PVOP_CALL_ARG2(x) "S" ((unsigned long)(x))
@@ -509,6 +510,7 @@ int paravirt_disable_iospace(void);
509 "=c" (__ecx) 510 "=c" (__ecx)
510#define PVOP_CALL_CLOBBERS PVOP_VCALL_CLOBBERS, "=a" (__eax) 511#define PVOP_CALL_CLOBBERS PVOP_VCALL_CLOBBERS, "=a" (__eax)
511 512
513/* void functions are still allowed [re]ax for scratch */
512#define PVOP_VCALLEE_CLOBBERS "=a" (__eax) 514#define PVOP_VCALLEE_CLOBBERS "=a" (__eax)
513#define PVOP_CALLEE_CLOBBERS PVOP_VCALLEE_CLOBBERS 515#define PVOP_CALLEE_CLOBBERS PVOP_VCALLEE_CLOBBERS
514 516
@@ -583,8 +585,8 @@ int paravirt_disable_iospace(void);
583 VEXTRA_CLOBBERS, \ 585 VEXTRA_CLOBBERS, \
584 pre, post, ##__VA_ARGS__) 586 pre, post, ##__VA_ARGS__)
585 587
586#define __PVOP_VCALLEESAVE(rettype, op, pre, post, ...) \ 588#define __PVOP_VCALLEESAVE(op, pre, post, ...) \
587 ____PVOP_CALL(rettype, op.func, CLBR_RET_REG, \ 589 ____PVOP_VCALL(op.func, CLBR_RET_REG, \
588 PVOP_VCALLEE_CLOBBERS, , \ 590 PVOP_VCALLEE_CLOBBERS, , \
589 pre, post, ##__VA_ARGS__) 591 pre, post, ##__VA_ARGS__)
590 592
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
index 183c3457d2f4..b1598a9436d0 100644
--- a/arch/x86/kernel/cpu/mcheck/mce.c
+++ b/arch/x86/kernel/cpu/mcheck/mce.c
@@ -85,6 +85,18 @@ static DECLARE_WAIT_QUEUE_HEAD(mce_wait);
85static DEFINE_PER_CPU(struct mce, mces_seen); 85static DEFINE_PER_CPU(struct mce, mces_seen);
86static int cpu_missing; 86static int cpu_missing;
87 87
88static void default_decode_mce(struct mce *m)
89{
90 pr_emerg("No human readable MCE decoding support on this CPU type.\n");
91 pr_emerg("Run the message through 'mcelog --ascii' to decode.\n");
92}
93
94/*
95 * CPU/chipset specific EDAC code can register a callback here to print
96 * MCE errors in a human-readable form:
97 */
98void (*x86_mce_decode_callback)(struct mce *m) = default_decode_mce;
99EXPORT_SYMBOL(x86_mce_decode_callback);
88 100
89/* MCA banks polled by the period polling timer for corrected events */ 101/* MCA banks polled by the period polling timer for corrected events */
90DEFINE_PER_CPU(mce_banks_t, mce_poll_banks) = { 102DEFINE_PER_CPU(mce_banks_t, mce_poll_banks) = {
@@ -165,46 +177,46 @@ void mce_log(struct mce *mce)
165 set_bit(0, &mce_need_notify); 177 set_bit(0, &mce_need_notify);
166} 178}
167 179
168void __weak decode_mce(struct mce *m)
169{
170 return;
171}
172
173static void print_mce(struct mce *m) 180static void print_mce(struct mce *m)
174{ 181{
175 printk(KERN_EMERG 182 pr_emerg("CPU %d: Machine Check Exception: %16Lx Bank %d: %016Lx\n",
176 "CPU %d: Machine Check Exception: %16Lx Bank %d: %016Lx\n",
177 m->extcpu, m->mcgstatus, m->bank, m->status); 183 m->extcpu, m->mcgstatus, m->bank, m->status);
184
178 if (m->ip) { 185 if (m->ip) {
179 printk(KERN_EMERG "RIP%s %02x:<%016Lx> ", 186 pr_emerg("RIP%s %02x:<%016Lx> ",
180 !(m->mcgstatus & MCG_STATUS_EIPV) ? " !INEXACT!" : "", 187 !(m->mcgstatus & MCG_STATUS_EIPV) ? " !INEXACT!" : "",
181 m->cs, m->ip); 188 m->cs, m->ip);
189
182 if (m->cs == __KERNEL_CS) 190 if (m->cs == __KERNEL_CS)
183 print_symbol("{%s}", m->ip); 191 print_symbol("{%s}", m->ip);
184 printk(KERN_CONT "\n"); 192 pr_cont("\n");
185 } 193 }
186 printk(KERN_EMERG "TSC %llx ", m->tsc); 194
195 pr_emerg("TSC %llx ", m->tsc);
187 if (m->addr) 196 if (m->addr)
188 printk(KERN_CONT "ADDR %llx ", m->addr); 197 pr_cont("ADDR %llx ", m->addr);
189 if (m->misc) 198 if (m->misc)
190 printk(KERN_CONT "MISC %llx ", m->misc); 199 pr_cont("MISC %llx ", m->misc);
191 printk(KERN_CONT "\n"); 200
192 printk(KERN_EMERG "PROCESSOR %u:%x TIME %llu SOCKET %u APIC %x\n", 201 pr_cont("\n");
193 m->cpuvendor, m->cpuid, m->time, m->socketid, 202 pr_emerg("PROCESSOR %u:%x TIME %llu SOCKET %u APIC %x\n",
194 m->apicid); 203 m->cpuvendor, m->cpuid, m->time, m->socketid, m->apicid);
195 204
196 decode_mce(m); 205 /*
206 * Print out human-readable details about the MCE error,
207 * (if the CPU has an implementation for that):
208 */
209 x86_mce_decode_callback(m);
197} 210}
198 211
199static void print_mce_head(void) 212static void print_mce_head(void)
200{ 213{
201 printk(KERN_EMERG "\nHARDWARE ERROR\n"); 214 pr_emerg("\nHARDWARE ERROR\n");
202} 215}
203 216
204static void print_mce_tail(void) 217static void print_mce_tail(void)
205{ 218{
206 printk(KERN_EMERG "This is not a software problem!\n" 219 pr_emerg("This is not a software problem!\n");
207 "Run through mcelog --ascii to decode and contact your hardware vendor\n");
208} 220}
209 221
210#define PANIC_TIMEOUT 5 /* 5 seconds */ 222#define PANIC_TIMEOUT 5 /* 5 seconds */
@@ -218,6 +230,7 @@ static atomic_t mce_fake_paniced;
218static void wait_for_panic(void) 230static void wait_for_panic(void)
219{ 231{
220 long timeout = PANIC_TIMEOUT*USEC_PER_SEC; 232 long timeout = PANIC_TIMEOUT*USEC_PER_SEC;
233
221 preempt_disable(); 234 preempt_disable();
222 local_irq_enable(); 235 local_irq_enable();
223 while (timeout-- > 0) 236 while (timeout-- > 0)
@@ -285,6 +298,7 @@ static void mce_panic(char *msg, struct mce *final, char *exp)
285static int msr_to_offset(u32 msr) 298static int msr_to_offset(u32 msr)
286{ 299{
287 unsigned bank = __get_cpu_var(injectm.bank); 300 unsigned bank = __get_cpu_var(injectm.bank);
301
288 if (msr == rip_msr) 302 if (msr == rip_msr)
289 return offsetof(struct mce, ip); 303 return offsetof(struct mce, ip);
290 if (msr == MSR_IA32_MCx_STATUS(bank)) 304 if (msr == MSR_IA32_MCx_STATUS(bank))
diff --git a/arch/x86/kernel/cpu/mcheck/mce_intel.c b/arch/x86/kernel/cpu/mcheck/mce_intel.c
index 889f665fe93d..7c785634af2b 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_intel.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_intel.c
@@ -8,6 +8,7 @@
8#include <linux/init.h> 8#include <linux/init.h>
9#include <linux/interrupt.h> 9#include <linux/interrupt.h>
10#include <linux/percpu.h> 10#include <linux/percpu.h>
11#include <linux/sched.h>
11#include <asm/apic.h> 12#include <asm/apic.h>
12#include <asm/processor.h> 13#include <asm/processor.h>
13#include <asm/msr.h> 14#include <asm/msr.h>
diff --git a/arch/x86/kernel/cpu/mtrr/if.c b/arch/x86/kernel/cpu/mtrr/if.c
index f04e72527604..3c1b12d461d1 100644
--- a/arch/x86/kernel/cpu/mtrr/if.c
+++ b/arch/x86/kernel/cpu/mtrr/if.c
@@ -96,17 +96,24 @@ mtrr_write(struct file *file, const char __user *buf, size_t len, loff_t * ppos)
96 unsigned long long base, size; 96 unsigned long long base, size;
97 char *ptr; 97 char *ptr;
98 char line[LINE_SIZE]; 98 char line[LINE_SIZE];
99 int length;
99 size_t linelen; 100 size_t linelen;
100 101
101 if (!capable(CAP_SYS_ADMIN)) 102 if (!capable(CAP_SYS_ADMIN))
102 return -EPERM; 103 return -EPERM;
103 if (!len)
104 return -EINVAL;
105 104
106 memset(line, 0, LINE_SIZE); 105 memset(line, 0, LINE_SIZE);
107 if (len > LINE_SIZE) 106
108 len = LINE_SIZE; 107 length = len;
109 if (copy_from_user(line, buf, len - 1)) 108 length--;
109
110 if (length > LINE_SIZE - 1)
111 length = LINE_SIZE - 1;
112
113 if (length < 0)
114 return -EINVAL;
115
116 if (copy_from_user(line, buf, length))
110 return -EFAULT; 117 return -EFAULT;
111 118
112 linelen = strlen(line); 119 linelen = strlen(line);
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index 85419bb7d4ab..d17d482a04f4 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -1378,8 +1378,8 @@ static unsigned long ram_alignment(resource_size_t pos)
1378 if (mb < 16) 1378 if (mb < 16)
1379 return 1024*1024; 1379 return 1024*1024;
1380 1380
1381 /* To 32MB for anything above that */ 1381 /* To 64MB for anything above that */
1382 return 32*1024*1024; 1382 return 64*1024*1024;
1383} 1383}
1384 1384
1385#define MAX_RESOURCE_SIZE ((resource_size_t)-1) 1385#define MAX_RESOURCE_SIZE ((resource_size_t)-1)
diff --git a/arch/x86/kernel/early_printk.c b/arch/x86/kernel/early_printk.c
index 41fd965c80c6..b9c830c12b4a 100644
--- a/arch/x86/kernel/early_printk.c
+++ b/arch/x86/kernel/early_printk.c
@@ -206,8 +206,11 @@ static int __init setup_early_printk(char *buf)
206 206
207 while (*buf != '\0') { 207 while (*buf != '\0') {
208 if (!strncmp(buf, "serial", 6)) { 208 if (!strncmp(buf, "serial", 6)) {
209 early_serial_init(buf + 6); 209 buf += 6;
210 early_serial_init(buf);
210 early_console_register(&early_serial_console, keep); 211 early_console_register(&early_serial_console, keep);
212 if (!strncmp(buf, ",ttyS", 5))
213 buf += 5;
211 } 214 }
212 if (!strncmp(buf, "ttyS", 4)) { 215 if (!strncmp(buf, "ttyS", 4)) {
213 early_serial_init(buf + 4); 216 early_serial_init(buf + 4);
diff --git a/arch/x86/kernel/i386_ksyms_32.c b/arch/x86/kernel/i386_ksyms_32.c
index 43cec6bdda63..9c3bd4a2050e 100644
--- a/arch/x86/kernel/i386_ksyms_32.c
+++ b/arch/x86/kernel/i386_ksyms_32.c
@@ -10,6 +10,16 @@
10EXPORT_SYMBOL(mcount); 10EXPORT_SYMBOL(mcount);
11#endif 11#endif
12 12
13/*
14 * Note, this is a prototype to get at the symbol for
15 * the export, but dont use it from C code, it is used
16 * by assembly code and is not using C calling convention!
17 */
18#ifndef CONFIG_X86_CMPXCHG64
19extern void cmpxchg8b_emu(void);
20EXPORT_SYMBOL(cmpxchg8b_emu);
21#endif
22
13/* Networking helper routines. */ 23/* Networking helper routines. */
14EXPORT_SYMBOL(csum_partial_copy_generic); 24EXPORT_SYMBOL(csum_partial_copy_generic);
15 25
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index 74656d1d4e30..04bbd5278568 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -63,10 +63,10 @@ static int show_other_interrupts(struct seq_file *p, int prec)
63 for_each_online_cpu(j) 63 for_each_online_cpu(j)
64 seq_printf(p, "%10u ", irq_stats(j)->irq_spurious_count); 64 seq_printf(p, "%10u ", irq_stats(j)->irq_spurious_count);
65 seq_printf(p, " Spurious interrupts\n"); 65 seq_printf(p, " Spurious interrupts\n");
66 seq_printf(p, "%*s: ", prec, "CNT"); 66 seq_printf(p, "%*s: ", prec, "PMI");
67 for_each_online_cpu(j) 67 for_each_online_cpu(j)
68 seq_printf(p, "%10u ", irq_stats(j)->apic_perf_irqs); 68 seq_printf(p, "%10u ", irq_stats(j)->apic_perf_irqs);
69 seq_printf(p, " Performance counter interrupts\n"); 69 seq_printf(p, " Performance monitoring interrupts\n");
70 seq_printf(p, "%*s: ", prec, "PND"); 70 seq_printf(p, "%*s: ", prec, "PND");
71 for_each_online_cpu(j) 71 for_each_online_cpu(j)
72 seq_printf(p, "%10u ", irq_stats(j)->apic_pending_irqs); 72 seq_printf(p, "%10u ", irq_stats(j)->apic_pending_irqs);
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c
index 64b838eac18c..b2a71dca5642 100644
--- a/arch/x86/kernel/pci-dma.c
+++ b/arch/x86/kernel/pci-dma.c
@@ -35,7 +35,7 @@ int iommu_detected __read_mostly = 0;
35 35
36/* 36/*
37 * This variable becomes 1 if iommu=pt is passed on the kernel command line. 37 * This variable becomes 1 if iommu=pt is passed on the kernel command line.
38 * If this variable is 1, IOMMU implementations do no DMA ranslation for 38 * If this variable is 1, IOMMU implementations do no DMA translation for
39 * devices and allow every device to access to whole physical memory. This is 39 * devices and allow every device to access to whole physical memory. This is
40 * useful if a user want to use an IOMMU only for KVM device assignment to 40 * useful if a user want to use an IOMMU only for KVM device assignment to
41 * guests and not for driver dma translation. 41 * guests and not for driver dma translation.
@@ -311,7 +311,7 @@ void pci_iommu_shutdown(void)
311 amd_iommu_shutdown(); 311 amd_iommu_shutdown();
312} 312}
313/* Must execute after PCI subsystem */ 313/* Must execute after PCI subsystem */
314fs_initcall(pci_iommu_init); 314rootfs_initcall(pci_iommu_init);
315 315
316#ifdef CONFIG_PCI 316#ifdef CONFIG_PCI
317/* Many VIA bridges seem to corrupt data for DAC. Disable it here */ 317/* Many VIA bridges seem to corrupt data for DAC. Disable it here */
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c
index 98a827ee9ed7..a7f1b64f86e0 100644
--- a/arch/x86/kernel/pci-gart_64.c
+++ b/arch/x86/kernel/pci-gart_64.c
@@ -16,6 +16,7 @@
16#include <linux/agp_backend.h> 16#include <linux/agp_backend.h>
17#include <linux/init.h> 17#include <linux/init.h>
18#include <linux/mm.h> 18#include <linux/mm.h>
19#include <linux/sched.h>
19#include <linux/string.h> 20#include <linux/string.h>
20#include <linux/spinlock.h> 21#include <linux/spinlock.h>
21#include <linux/pci.h> 22#include <linux/pci.h>
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
index 27349f92a6d7..a1a3cdda06e1 100644
--- a/arch/x86/kernel/reboot.c
+++ b/arch/x86/kernel/reboot.c
@@ -4,6 +4,7 @@
4#include <linux/pm.h> 4#include <linux/pm.h>
5#include <linux/efi.h> 5#include <linux/efi.h>
6#include <linux/dmi.h> 6#include <linux/dmi.h>
7#include <linux/sched.h>
7#include <linux/tboot.h> 8#include <linux/tboot.h>
8#include <acpi/reboot.h> 9#include <acpi/reboot.h>
9#include <asm/io.h> 10#include <asm/io.h>
diff --git a/arch/x86/kernel/time.c b/arch/x86/kernel/time.c
index dcb00d278512..be2573448ed9 100644
--- a/arch/x86/kernel/time.c
+++ b/arch/x86/kernel/time.c
@@ -38,7 +38,8 @@ unsigned long profile_pc(struct pt_regs *regs)
38#ifdef CONFIG_FRAME_POINTER 38#ifdef CONFIG_FRAME_POINTER
39 return *(unsigned long *)(regs->bp + sizeof(long)); 39 return *(unsigned long *)(regs->bp + sizeof(long));
40#else 40#else
41 unsigned long *sp = (unsigned long *)regs->sp; 41 unsigned long *sp =
42 (unsigned long *)kernel_stack_pointer(regs);
42 /* 43 /*
43 * Return address is either directly at stack pointer 44 * Return address is either directly at stack pointer
44 * or above a saved flags. Eflags has bits 22-31 zero, 45 * or above a saved flags. Eflags has bits 22-31 zero,
diff --git a/arch/x86/kernel/trampoline.c b/arch/x86/kernel/trampoline.c
index 699f7eeb896a..cd022121cab6 100644
--- a/arch/x86/kernel/trampoline.c
+++ b/arch/x86/kernel/trampoline.c
@@ -3,8 +3,16 @@
3#include <asm/trampoline.h> 3#include <asm/trampoline.h>
4#include <asm/e820.h> 4#include <asm/e820.h>
5 5
6#if defined(CONFIG_X86_64) && defined(CONFIG_ACPI_SLEEP)
7#define __trampinit
8#define __trampinitdata
9#else
10#define __trampinit __cpuinit
11#define __trampinitdata __cpuinitdata
12#endif
13
6/* ready for x86_64 and x86 */ 14/* ready for x86_64 and x86 */
7unsigned char *__cpuinitdata trampoline_base = __va(TRAMPOLINE_BASE); 15unsigned char *__trampinitdata trampoline_base = __va(TRAMPOLINE_BASE);
8 16
9void __init reserve_trampoline_memory(void) 17void __init reserve_trampoline_memory(void)
10{ 18{
@@ -26,7 +34,7 @@ void __init reserve_trampoline_memory(void)
26 * bootstrap into the page concerned. The caller 34 * bootstrap into the page concerned. The caller
27 * has made sure it's suitably aligned. 35 * has made sure it's suitably aligned.
28 */ 36 */
29unsigned long __cpuinit setup_trampoline(void) 37unsigned long __trampinit setup_trampoline(void)
30{ 38{
31 memcpy(trampoline_base, trampoline_data, TRAMPOLINE_SIZE); 39 memcpy(trampoline_base, trampoline_data, TRAMPOLINE_SIZE);
32 return virt_to_phys(trampoline_base); 40 return virt_to_phys(trampoline_base);
diff --git a/arch/x86/kernel/trampoline_64.S b/arch/x86/kernel/trampoline_64.S
index 596d54c660a5..3af2dff58b21 100644
--- a/arch/x86/kernel/trampoline_64.S
+++ b/arch/x86/kernel/trampoline_64.S
@@ -32,8 +32,12 @@
32#include <asm/segment.h> 32#include <asm/segment.h>
33#include <asm/processor-flags.h> 33#include <asm/processor-flags.h>
34 34
35#ifdef CONFIG_ACPI_SLEEP
36.section .rodata, "a", @progbits
37#else
35/* We can free up the trampoline after bootup if cpu hotplug is not supported. */ 38/* We can free up the trampoline after bootup if cpu hotplug is not supported. */
36__CPUINITRODATA 39__CPUINITRODATA
40#endif
37.code16 41.code16
38 42
39ENTRY(trampoline_data) 43ENTRY(trampoline_data)
diff --git a/arch/x86/kernel/vmi_32.c b/arch/x86/kernel/vmi_32.c
index 31e6f6cfe53e..d430e4c30193 100644
--- a/arch/x86/kernel/vmi_32.c
+++ b/arch/x86/kernel/vmi_32.c
@@ -648,7 +648,7 @@ static inline int __init activate_vmi(void)
648 648
649 pv_info.paravirt_enabled = 1; 649 pv_info.paravirt_enabled = 1;
650 pv_info.kernel_rpl = kernel_cs & SEGMENT_RPL_MASK; 650 pv_info.kernel_rpl = kernel_cs & SEGMENT_RPL_MASK;
651 pv_info.name = "vmi"; 651 pv_info.name = "vmi [deprecated]";
652 652
653 pv_init_ops.patch = vmi_patch; 653 pv_init_ops.patch = vmi_patch;
654 654
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index 1ae5ceba7eb2..7024224f0fc8 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -664,7 +664,7 @@ static void start_apic_timer(struct kvm_lapic *apic)
664{ 664{
665 ktime_t now = apic->lapic_timer.timer.base->get_time(); 665 ktime_t now = apic->lapic_timer.timer.base->get_time();
666 666
667 apic->lapic_timer.period = apic_get_reg(apic, APIC_TMICT) * 667 apic->lapic_timer.period = (u64)apic_get_reg(apic, APIC_TMICT) *
668 APIC_BUS_CYCLE_NS * apic->divide_count; 668 APIC_BUS_CYCLE_NS * apic->divide_count;
669 atomic_set(&apic->lapic_timer.pending, 0); 669 atomic_set(&apic->lapic_timer.pending, 0);
670 670
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index eca41ae9f453..685a4ffac8e6 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -156,6 +156,8 @@ module_param(oos_shadow, bool, 0644);
156#define CREATE_TRACE_POINTS 156#define CREATE_TRACE_POINTS
157#include "mmutrace.h" 157#include "mmutrace.h"
158 158
159#define SPTE_HOST_WRITEABLE (1ULL << PT_FIRST_AVAIL_BITS_SHIFT)
160
159#define SHADOW_PT_INDEX(addr, level) PT64_INDEX(addr, level) 161#define SHADOW_PT_INDEX(addr, level) PT64_INDEX(addr, level)
160 162
161struct kvm_rmap_desc { 163struct kvm_rmap_desc {
@@ -634,9 +636,7 @@ static void rmap_remove(struct kvm *kvm, u64 *spte)
634 if (*spte & shadow_accessed_mask) 636 if (*spte & shadow_accessed_mask)
635 kvm_set_pfn_accessed(pfn); 637 kvm_set_pfn_accessed(pfn);
636 if (is_writeble_pte(*spte)) 638 if (is_writeble_pte(*spte))
637 kvm_release_pfn_dirty(pfn); 639 kvm_set_pfn_dirty(pfn);
638 else
639 kvm_release_pfn_clean(pfn);
640 rmapp = gfn_to_rmap(kvm, sp->gfns[spte - sp->spt], sp->role.level); 640 rmapp = gfn_to_rmap(kvm, sp->gfns[spte - sp->spt], sp->role.level);
641 if (!*rmapp) { 641 if (!*rmapp) {
642 printk(KERN_ERR "rmap_remove: %p %llx 0->BUG\n", spte, *spte); 642 printk(KERN_ERR "rmap_remove: %p %llx 0->BUG\n", spte, *spte);
@@ -748,7 +748,7 @@ static int rmap_write_protect(struct kvm *kvm, u64 gfn)
748 return write_protected; 748 return write_protected;
749} 749}
750 750
751static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp) 751static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp, u64 data)
752{ 752{
753 u64 *spte; 753 u64 *spte;
754 int need_tlb_flush = 0; 754 int need_tlb_flush = 0;
@@ -763,8 +763,45 @@ static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp)
763 return need_tlb_flush; 763 return need_tlb_flush;
764} 764}
765 765
766static int kvm_handle_hva(struct kvm *kvm, unsigned long hva, 766static int kvm_set_pte_rmapp(struct kvm *kvm, unsigned long *rmapp, u64 data)
767 int (*handler)(struct kvm *kvm, unsigned long *rmapp)) 767{
768 int need_flush = 0;
769 u64 *spte, new_spte;
770 pte_t *ptep = (pte_t *)data;
771 pfn_t new_pfn;
772
773 WARN_ON(pte_huge(*ptep));
774 new_pfn = pte_pfn(*ptep);
775 spte = rmap_next(kvm, rmapp, NULL);
776 while (spte) {
777 BUG_ON(!is_shadow_present_pte(*spte));
778 rmap_printk("kvm_set_pte_rmapp: spte %p %llx\n", spte, *spte);
779 need_flush = 1;
780 if (pte_write(*ptep)) {
781 rmap_remove(kvm, spte);
782 __set_spte(spte, shadow_trap_nonpresent_pte);
783 spte = rmap_next(kvm, rmapp, NULL);
784 } else {
785 new_spte = *spte &~ (PT64_BASE_ADDR_MASK);
786 new_spte |= (u64)new_pfn << PAGE_SHIFT;
787
788 new_spte &= ~PT_WRITABLE_MASK;
789 new_spte &= ~SPTE_HOST_WRITEABLE;
790 if (is_writeble_pte(*spte))
791 kvm_set_pfn_dirty(spte_to_pfn(*spte));
792 __set_spte(spte, new_spte);
793 spte = rmap_next(kvm, rmapp, spte);
794 }
795 }
796 if (need_flush)
797 kvm_flush_remote_tlbs(kvm);
798
799 return 0;
800}
801
802static int kvm_handle_hva(struct kvm *kvm, unsigned long hva, u64 data,
803 int (*handler)(struct kvm *kvm, unsigned long *rmapp,
804 u64 data))
768{ 805{
769 int i, j; 806 int i, j;
770 int retval = 0; 807 int retval = 0;
@@ -786,13 +823,15 @@ static int kvm_handle_hva(struct kvm *kvm, unsigned long hva,
786 if (hva >= start && hva < end) { 823 if (hva >= start && hva < end) {
787 gfn_t gfn_offset = (hva - start) >> PAGE_SHIFT; 824 gfn_t gfn_offset = (hva - start) >> PAGE_SHIFT;
788 825
789 retval |= handler(kvm, &memslot->rmap[gfn_offset]); 826 retval |= handler(kvm, &memslot->rmap[gfn_offset],
827 data);
790 828
791 for (j = 0; j < KVM_NR_PAGE_SIZES - 1; ++j) { 829 for (j = 0; j < KVM_NR_PAGE_SIZES - 1; ++j) {
792 int idx = gfn_offset; 830 int idx = gfn_offset;
793 idx /= KVM_PAGES_PER_HPAGE(PT_DIRECTORY_LEVEL + j); 831 idx /= KVM_PAGES_PER_HPAGE(PT_DIRECTORY_LEVEL + j);
794 retval |= handler(kvm, 832 retval |= handler(kvm,
795 &memslot->lpage_info[j][idx].rmap_pde); 833 &memslot->lpage_info[j][idx].rmap_pde,
834 data);
796 } 835 }
797 } 836 }
798 } 837 }
@@ -802,10 +841,15 @@ static int kvm_handle_hva(struct kvm *kvm, unsigned long hva,
802 841
803int kvm_unmap_hva(struct kvm *kvm, unsigned long hva) 842int kvm_unmap_hva(struct kvm *kvm, unsigned long hva)
804{ 843{
805 return kvm_handle_hva(kvm, hva, kvm_unmap_rmapp); 844 return kvm_handle_hva(kvm, hva, 0, kvm_unmap_rmapp);
806} 845}
807 846
808static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp) 847void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte)
848{
849 kvm_handle_hva(kvm, hva, (u64)&pte, kvm_set_pte_rmapp);
850}
851
852static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp, u64 data)
809{ 853{
810 u64 *spte; 854 u64 *spte;
811 int young = 0; 855 int young = 0;
@@ -841,13 +885,13 @@ static void rmap_recycle(struct kvm_vcpu *vcpu, u64 *spte, gfn_t gfn)
841 gfn = unalias_gfn(vcpu->kvm, gfn); 885 gfn = unalias_gfn(vcpu->kvm, gfn);
842 rmapp = gfn_to_rmap(vcpu->kvm, gfn, sp->role.level); 886 rmapp = gfn_to_rmap(vcpu->kvm, gfn, sp->role.level);
843 887
844 kvm_unmap_rmapp(vcpu->kvm, rmapp); 888 kvm_unmap_rmapp(vcpu->kvm, rmapp, 0);
845 kvm_flush_remote_tlbs(vcpu->kvm); 889 kvm_flush_remote_tlbs(vcpu->kvm);
846} 890}
847 891
848int kvm_age_hva(struct kvm *kvm, unsigned long hva) 892int kvm_age_hva(struct kvm *kvm, unsigned long hva)
849{ 893{
850 return kvm_handle_hva(kvm, hva, kvm_age_rmapp); 894 return kvm_handle_hva(kvm, hva, 0, kvm_age_rmapp);
851} 895}
852 896
853#ifdef MMU_DEBUG 897#ifdef MMU_DEBUG
@@ -1756,7 +1800,7 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
1756 unsigned pte_access, int user_fault, 1800 unsigned pte_access, int user_fault,
1757 int write_fault, int dirty, int level, 1801 int write_fault, int dirty, int level,
1758 gfn_t gfn, pfn_t pfn, bool speculative, 1802 gfn_t gfn, pfn_t pfn, bool speculative,
1759 bool can_unsync) 1803 bool can_unsync, bool reset_host_protection)
1760{ 1804{
1761 u64 spte; 1805 u64 spte;
1762 int ret = 0; 1806 int ret = 0;
@@ -1783,6 +1827,9 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
1783 spte |= kvm_x86_ops->get_mt_mask(vcpu, gfn, 1827 spte |= kvm_x86_ops->get_mt_mask(vcpu, gfn,
1784 kvm_is_mmio_pfn(pfn)); 1828 kvm_is_mmio_pfn(pfn));
1785 1829
1830 if (reset_host_protection)
1831 spte |= SPTE_HOST_WRITEABLE;
1832
1786 spte |= (u64)pfn << PAGE_SHIFT; 1833 spte |= (u64)pfn << PAGE_SHIFT;
1787 1834
1788 if ((pte_access & ACC_WRITE_MASK) 1835 if ((pte_access & ACC_WRITE_MASK)
@@ -1828,7 +1875,8 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
1828 unsigned pt_access, unsigned pte_access, 1875 unsigned pt_access, unsigned pte_access,
1829 int user_fault, int write_fault, int dirty, 1876 int user_fault, int write_fault, int dirty,
1830 int *ptwrite, int level, gfn_t gfn, 1877 int *ptwrite, int level, gfn_t gfn,
1831 pfn_t pfn, bool speculative) 1878 pfn_t pfn, bool speculative,
1879 bool reset_host_protection)
1832{ 1880{
1833 int was_rmapped = 0; 1881 int was_rmapped = 0;
1834 int was_writeble = is_writeble_pte(*sptep); 1882 int was_writeble = is_writeble_pte(*sptep);
@@ -1860,7 +1908,8 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
1860 } 1908 }
1861 1909
1862 if (set_spte(vcpu, sptep, pte_access, user_fault, write_fault, 1910 if (set_spte(vcpu, sptep, pte_access, user_fault, write_fault,
1863 dirty, level, gfn, pfn, speculative, true)) { 1911 dirty, level, gfn, pfn, speculative, true,
1912 reset_host_protection)) {
1864 if (write_fault) 1913 if (write_fault)
1865 *ptwrite = 1; 1914 *ptwrite = 1;
1866 kvm_x86_ops->tlb_flush(vcpu); 1915 kvm_x86_ops->tlb_flush(vcpu);
@@ -1877,8 +1926,7 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
1877 page_header_update_slot(vcpu->kvm, sptep, gfn); 1926 page_header_update_slot(vcpu->kvm, sptep, gfn);
1878 if (!was_rmapped) { 1927 if (!was_rmapped) {
1879 rmap_count = rmap_add(vcpu, sptep, gfn); 1928 rmap_count = rmap_add(vcpu, sptep, gfn);
1880 if (!is_rmap_spte(*sptep)) 1929 kvm_release_pfn_clean(pfn);
1881 kvm_release_pfn_clean(pfn);
1882 if (rmap_count > RMAP_RECYCLE_THRESHOLD) 1930 if (rmap_count > RMAP_RECYCLE_THRESHOLD)
1883 rmap_recycle(vcpu, sptep, gfn); 1931 rmap_recycle(vcpu, sptep, gfn);
1884 } else { 1932 } else {
@@ -1909,7 +1957,7 @@ static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write,
1909 if (iterator.level == level) { 1957 if (iterator.level == level) {
1910 mmu_set_spte(vcpu, iterator.sptep, ACC_ALL, ACC_ALL, 1958 mmu_set_spte(vcpu, iterator.sptep, ACC_ALL, ACC_ALL,
1911 0, write, 1, &pt_write, 1959 0, write, 1, &pt_write,
1912 level, gfn, pfn, false); 1960 level, gfn, pfn, false, true);
1913 ++vcpu->stat.pf_fixed; 1961 ++vcpu->stat.pf_fixed;
1914 break; 1962 break;
1915 } 1963 }
diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h
index d2fec9c12d22..72558f8ff3f5 100644
--- a/arch/x86/kvm/paging_tmpl.h
+++ b/arch/x86/kvm/paging_tmpl.h
@@ -273,9 +273,13 @@ static void FNAME(update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *page,
273 if (mmu_notifier_retry(vcpu, vcpu->arch.update_pte.mmu_seq)) 273 if (mmu_notifier_retry(vcpu, vcpu->arch.update_pte.mmu_seq))
274 return; 274 return;
275 kvm_get_pfn(pfn); 275 kvm_get_pfn(pfn);
276 /*
277 * we call mmu_set_spte() with reset_host_protection = true beacuse that
278 * vcpu->arch.update_pte.pfn was fetched from get_user_pages(write = 1).
279 */
276 mmu_set_spte(vcpu, spte, page->role.access, pte_access, 0, 0, 280 mmu_set_spte(vcpu, spte, page->role.access, pte_access, 0, 0,
277 gpte & PT_DIRTY_MASK, NULL, PT_PAGE_TABLE_LEVEL, 281 gpte & PT_DIRTY_MASK, NULL, PT_PAGE_TABLE_LEVEL,
278 gpte_to_gfn(gpte), pfn, true); 282 gpte_to_gfn(gpte), pfn, true, true);
279} 283}
280 284
281/* 285/*
@@ -308,7 +312,7 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
308 user_fault, write_fault, 312 user_fault, write_fault,
309 gw->ptes[gw->level-1] & PT_DIRTY_MASK, 313 gw->ptes[gw->level-1] & PT_DIRTY_MASK,
310 ptwrite, level, 314 ptwrite, level,
311 gw->gfn, pfn, false); 315 gw->gfn, pfn, false, true);
312 break; 316 break;
313 } 317 }
314 318
@@ -558,6 +562,7 @@ static void FNAME(prefetch_page)(struct kvm_vcpu *vcpu,
558static int FNAME(sync_page)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp) 562static int FNAME(sync_page)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp)
559{ 563{
560 int i, offset, nr_present; 564 int i, offset, nr_present;
565 bool reset_host_protection;
561 566
562 offset = nr_present = 0; 567 offset = nr_present = 0;
563 568
@@ -595,9 +600,16 @@ static int FNAME(sync_page)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp)
595 600
596 nr_present++; 601 nr_present++;
597 pte_access = sp->role.access & FNAME(gpte_access)(vcpu, gpte); 602 pte_access = sp->role.access & FNAME(gpte_access)(vcpu, gpte);
603 if (!(sp->spt[i] & SPTE_HOST_WRITEABLE)) {
604 pte_access &= ~ACC_WRITE_MASK;
605 reset_host_protection = 0;
606 } else {
607 reset_host_protection = 1;
608 }
598 set_spte(vcpu, &sp->spt[i], pte_access, 0, 0, 609 set_spte(vcpu, &sp->spt[i], pte_access, 0, 0,
599 is_dirty_gpte(gpte), PT_PAGE_TABLE_LEVEL, gfn, 610 is_dirty_gpte(gpte), PT_PAGE_TABLE_LEVEL, gfn,
600 spte_to_pfn(sp->spt[i]), true, false); 611 spte_to_pfn(sp->spt[i]), true, false,
612 reset_host_protection);
601 } 613 }
602 614
603 return !nr_present; 615 return !nr_present;
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 944cc9c04b3c..c17404add91f 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -767,6 +767,8 @@ static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
767 rdtscll(tsc_this); 767 rdtscll(tsc_this);
768 delta = vcpu->arch.host_tsc - tsc_this; 768 delta = vcpu->arch.host_tsc - tsc_this;
769 svm->vmcb->control.tsc_offset += delta; 769 svm->vmcb->control.tsc_offset += delta;
770 if (is_nested(svm))
771 svm->nested.hsave->control.tsc_offset += delta;
770 vcpu->cpu = cpu; 772 vcpu->cpu = cpu;
771 kvm_migrate_timers(vcpu); 773 kvm_migrate_timers(vcpu);
772 svm->asid_generation = 0; 774 svm->asid_generation = 0;
@@ -2057,10 +2059,14 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data)
2057 2059
2058 switch (ecx) { 2060 switch (ecx) {
2059 case MSR_IA32_TSC: { 2061 case MSR_IA32_TSC: {
2060 u64 tsc; 2062 u64 tsc_offset;
2063
2064 if (is_nested(svm))
2065 tsc_offset = svm->nested.hsave->control.tsc_offset;
2066 else
2067 tsc_offset = svm->vmcb->control.tsc_offset;
2061 2068
2062 rdtscll(tsc); 2069 *data = tsc_offset + native_read_tsc();
2063 *data = svm->vmcb->control.tsc_offset + tsc;
2064 break; 2070 break;
2065 } 2071 }
2066 case MSR_K6_STAR: 2072 case MSR_K6_STAR:
@@ -2146,10 +2152,17 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data)
2146 2152
2147 switch (ecx) { 2153 switch (ecx) {
2148 case MSR_IA32_TSC: { 2154 case MSR_IA32_TSC: {
2149 u64 tsc; 2155 u64 tsc_offset = data - native_read_tsc();
2156 u64 g_tsc_offset = 0;
2157
2158 if (is_nested(svm)) {
2159 g_tsc_offset = svm->vmcb->control.tsc_offset -
2160 svm->nested.hsave->control.tsc_offset;
2161 svm->nested.hsave->control.tsc_offset = tsc_offset;
2162 }
2163
2164 svm->vmcb->control.tsc_offset = tsc_offset + g_tsc_offset;
2150 2165
2151 rdtscll(tsc);
2152 svm->vmcb->control.tsc_offset = data - tsc;
2153 break; 2166 break;
2154 } 2167 }
2155 case MSR_K6_STAR: 2168 case MSR_K6_STAR:
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index f3812014bd0b..ed53b42caba1 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -709,7 +709,7 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
709 if (vcpu->cpu != cpu) { 709 if (vcpu->cpu != cpu) {
710 vcpu_clear(vmx); 710 vcpu_clear(vmx);
711 kvm_migrate_timers(vcpu); 711 kvm_migrate_timers(vcpu);
712 vpid_sync_vcpu_all(vmx); 712 set_bit(KVM_REQ_TLB_FLUSH, &vcpu->requests);
713 local_irq_disable(); 713 local_irq_disable();
714 list_add(&vmx->local_vcpus_link, 714 list_add(&vmx->local_vcpus_link,
715 &per_cpu(vcpus_on_cpu, cpu)); 715 &per_cpu(vcpus_on_cpu, cpu));
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index be451ee44249..9b9695322f56 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1591,6 +1591,8 @@ static int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid,
1591 1591
1592 if (cpuid->nent < 1) 1592 if (cpuid->nent < 1)
1593 goto out; 1593 goto out;
1594 if (cpuid->nent > KVM_MAX_CPUID_ENTRIES)
1595 cpuid->nent = KVM_MAX_CPUID_ENTRIES;
1594 r = -ENOMEM; 1596 r = -ENOMEM;
1595 cpuid_entries = vmalloc(sizeof(struct kvm_cpuid_entry2) * cpuid->nent); 1597 cpuid_entries = vmalloc(sizeof(struct kvm_cpuid_entry2) * cpuid->nent);
1596 if (!cpuid_entries) 1598 if (!cpuid_entries)
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
index 9e609206fac9..85f5db95c60f 100644
--- a/arch/x86/lib/Makefile
+++ b/arch/x86/lib/Makefile
@@ -16,7 +16,9 @@ ifeq ($(CONFIG_X86_32),y)
16 lib-y += checksum_32.o 16 lib-y += checksum_32.o
17 lib-y += strstr_32.o 17 lib-y += strstr_32.o
18 lib-y += semaphore_32.o string_32.o 18 lib-y += semaphore_32.o string_32.o
19 19ifneq ($(CONFIG_X86_CMPXCHG64),y)
20 lib-y += cmpxchg8b_emu.o
21endif
20 lib-$(CONFIG_X86_USE_3DNOW) += mmx_32.o 22 lib-$(CONFIG_X86_USE_3DNOW) += mmx_32.o
21else 23else
22 obj-y += io_64.o iomap_copy_64.o 24 obj-y += io_64.o iomap_copy_64.o
diff --git a/arch/x86/lib/cmpxchg8b_emu.S b/arch/x86/lib/cmpxchg8b_emu.S
new file mode 100644
index 000000000000..828cb710dec2
--- /dev/null
+++ b/arch/x86/lib/cmpxchg8b_emu.S
@@ -0,0 +1,57 @@
1/*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; version 2
5 * of the License.
6 *
7 */
8
9#include <linux/linkage.h>
10#include <asm/alternative-asm.h>
11#include <asm/frame.h>
12#include <asm/dwarf2.h>
13
14
15.text
16
17/*
18 * Inputs:
19 * %esi : memory location to compare
20 * %eax : low 32 bits of old value
21 * %edx : high 32 bits of old value
22 * %ebx : low 32 bits of new value
23 * %ecx : high 32 bits of new value
24 */
25ENTRY(cmpxchg8b_emu)
26CFI_STARTPROC
27
28#
29# Emulate 'cmpxchg8b (%esi)' on UP except we don't
30# set the whole ZF thing (caller will just compare
31# eax:edx with the expected value)
32#
33cmpxchg8b_emu:
34 pushfl
35 cli
36
37 cmpl (%esi), %eax
38 jne not_same
39 cmpl 4(%esi), %edx
40 jne half_same
41
42 movl %ebx, (%esi)
43 movl %ecx, 4(%esi)
44
45 popfl
46 ret
47
48 not_same:
49 movl (%esi), %eax
50 half_same:
51 movl 4(%esi), %edx
52
53 popfl
54 ret
55
56CFI_ENDPROC
57ENDPROC(cmpxchg8b_emu)
diff --git a/arch/x86/xen/debugfs.c b/arch/x86/xen/debugfs.c
index b53225d2cac3..e133ce25e290 100644
--- a/arch/x86/xen/debugfs.c
+++ b/arch/x86/xen/debugfs.c
@@ -100,7 +100,7 @@ static int xen_array_release(struct inode *inode, struct file *file)
100 return 0; 100 return 0;
101} 101}
102 102
103static struct file_operations u32_array_fops = { 103static const struct file_operations u32_array_fops = {
104 .owner = THIS_MODULE, 104 .owner = THIS_MODULE,
105 .open = u32_array_open, 105 .open = u32_array_open,
106 .release= xen_array_release, 106 .release= xen_array_release,
diff --git a/arch/xtensa/kernel/time.c b/arch/xtensa/kernel/time.c
index 19085ff0484a..19f7df30937f 100644
--- a/arch/xtensa/kernel/time.c
+++ b/arch/xtensa/kernel/time.c
@@ -13,6 +13,7 @@
13 */ 13 */
14 14
15#include <linux/errno.h> 15#include <linux/errno.h>
16#include <linux/sched.h>
16#include <linux/time.h> 17#include <linux/time.h>
17#include <linux/clocksource.h> 18#include <linux/clocksource.h>
18#include <linux/interrupt.h> 19#include <linux/interrupt.h>
diff --git a/block/blk-barrier.c b/block/blk-barrier.c
index 6593ab39cfe9..8873b9b439ff 100644
--- a/block/blk-barrier.c
+++ b/block/blk-barrier.c
@@ -350,6 +350,7 @@ static void blkdev_discard_end_io(struct bio *bio, int err)
350 350
351 if (bio->bi_private) 351 if (bio->bi_private)
352 complete(bio->bi_private); 352 complete(bio->bi_private);
353 __free_page(bio_page(bio));
353 354
354 bio_put(bio); 355 bio_put(bio);
355} 356}
@@ -372,30 +373,50 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
372 struct request_queue *q = bdev_get_queue(bdev); 373 struct request_queue *q = bdev_get_queue(bdev);
373 int type = flags & DISCARD_FL_BARRIER ? 374 int type = flags & DISCARD_FL_BARRIER ?
374 DISCARD_BARRIER : DISCARD_NOBARRIER; 375 DISCARD_BARRIER : DISCARD_NOBARRIER;
376 struct bio *bio;
377 struct page *page;
375 int ret = 0; 378 int ret = 0;
376 379
377 if (!q) 380 if (!q)
378 return -ENXIO; 381 return -ENXIO;
379 382
380 if (!q->prepare_discard_fn) 383 if (!blk_queue_discard(q))
381 return -EOPNOTSUPP; 384 return -EOPNOTSUPP;
382 385
383 while (nr_sects && !ret) { 386 while (nr_sects && !ret) {
384 struct bio *bio = bio_alloc(gfp_mask, 0); 387 unsigned int sector_size = q->limits.logical_block_size;
385 if (!bio) 388 unsigned int max_discard_sectors =
386 return -ENOMEM; 389 min(q->limits.max_discard_sectors, UINT_MAX >> 9);
387 390
391 bio = bio_alloc(gfp_mask, 1);
392 if (!bio)
393 goto out;
394 bio->bi_sector = sector;
388 bio->bi_end_io = blkdev_discard_end_io; 395 bio->bi_end_io = blkdev_discard_end_io;
389 bio->bi_bdev = bdev; 396 bio->bi_bdev = bdev;
390 if (flags & DISCARD_FL_WAIT) 397 if (flags & DISCARD_FL_WAIT)
391 bio->bi_private = &wait; 398 bio->bi_private = &wait;
392 399
393 bio->bi_sector = sector; 400 /*
401 * Add a zeroed one-sector payload as that's what
402 * our current implementations need. If we'll ever need
403 * more the interface will need revisiting.
404 */
405 page = alloc_page(GFP_KERNEL | __GFP_ZERO);
406 if (!page)
407 goto out_free_bio;
408 if (bio_add_pc_page(q, bio, page, sector_size, 0) < sector_size)
409 goto out_free_page;
394 410
395 if (nr_sects > queue_max_hw_sectors(q)) { 411 /*
396 bio->bi_size = queue_max_hw_sectors(q) << 9; 412 * And override the bio size - the way discard works we
397 nr_sects -= queue_max_hw_sectors(q); 413 * touch many more blocks on disk than the actual payload
398 sector += queue_max_hw_sectors(q); 414 * length.
415 */
416 if (nr_sects > max_discard_sectors) {
417 bio->bi_size = max_discard_sectors << 9;
418 nr_sects -= max_discard_sectors;
419 sector += max_discard_sectors;
399 } else { 420 } else {
400 bio->bi_size = nr_sects << 9; 421 bio->bi_size = nr_sects << 9;
401 nr_sects = 0; 422 nr_sects = 0;
@@ -414,5 +435,11 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
414 bio_put(bio); 435 bio_put(bio);
415 } 436 }
416 return ret; 437 return ret;
438out_free_page:
439 __free_page(page);
440out_free_bio:
441 bio_put(bio);
442out:
443 return -ENOMEM;
417} 444}
418EXPORT_SYMBOL(blkdev_issue_discard); 445EXPORT_SYMBOL(blkdev_issue_discard);
diff --git a/block/blk-core.c b/block/blk-core.c
index 8135228e4b29..ac0fa10f8fa5 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -34,6 +34,7 @@
34#include "blk.h" 34#include "blk.h"
35 35
36EXPORT_TRACEPOINT_SYMBOL_GPL(block_remap); 36EXPORT_TRACEPOINT_SYMBOL_GPL(block_remap);
37EXPORT_TRACEPOINT_SYMBOL_GPL(block_rq_remap);
37EXPORT_TRACEPOINT_SYMBOL_GPL(block_bio_complete); 38EXPORT_TRACEPOINT_SYMBOL_GPL(block_bio_complete);
38 39
39static int __make_request(struct request_queue *q, struct bio *bio); 40static int __make_request(struct request_queue *q, struct bio *bio);
@@ -1029,7 +1030,7 @@ static void part_round_stats_single(int cpu, struct hd_struct *part,
1029 if (now == part->stamp) 1030 if (now == part->stamp)
1030 return; 1031 return;
1031 1032
1032 if (part->in_flight) { 1033 if (part_in_flight(part)) {
1033 __part_stat_add(cpu, part, time_in_queue, 1034 __part_stat_add(cpu, part, time_in_queue,
1034 part_in_flight(part) * (now - part->stamp)); 1035 part_in_flight(part) * (now - part->stamp));
1035 __part_stat_add(cpu, part, io_ticks, (now - part->stamp)); 1036 __part_stat_add(cpu, part, io_ticks, (now - part->stamp));
@@ -1124,7 +1125,6 @@ void init_request_from_bio(struct request *req, struct bio *bio)
1124 req->cmd_flags |= REQ_DISCARD; 1125 req->cmd_flags |= REQ_DISCARD;
1125 if (bio_rw_flagged(bio, BIO_RW_BARRIER)) 1126 if (bio_rw_flagged(bio, BIO_RW_BARRIER))
1126 req->cmd_flags |= REQ_SOFTBARRIER; 1127 req->cmd_flags |= REQ_SOFTBARRIER;
1127 req->q->prepare_discard_fn(req->q, req);
1128 } else if (unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER))) 1128 } else if (unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER)))
1129 req->cmd_flags |= REQ_HARDBARRIER; 1129 req->cmd_flags |= REQ_HARDBARRIER;
1130 1130
@@ -1437,7 +1437,8 @@ static inline void __generic_make_request(struct bio *bio)
1437 goto end_io; 1437 goto end_io;
1438 } 1438 }
1439 1439
1440 if (unlikely(nr_sectors > queue_max_hw_sectors(q))) { 1440 if (unlikely(!bio_rw_flagged(bio, BIO_RW_DISCARD) &&
1441 nr_sectors > queue_max_hw_sectors(q))) {
1441 printk(KERN_ERR "bio too big device %s (%u > %u)\n", 1442 printk(KERN_ERR "bio too big device %s (%u > %u)\n",
1442 bdevname(bio->bi_bdev, b), 1443 bdevname(bio->bi_bdev, b),
1443 bio_sectors(bio), 1444 bio_sectors(bio),
@@ -1470,7 +1471,7 @@ static inline void __generic_make_request(struct bio *bio)
1470 goto end_io; 1471 goto end_io;
1471 1472
1472 if (bio_rw_flagged(bio, BIO_RW_DISCARD) && 1473 if (bio_rw_flagged(bio, BIO_RW_DISCARD) &&
1473 !q->prepare_discard_fn) { 1474 !blk_queue_discard(q)) {
1474 err = -EOPNOTSUPP; 1475 err = -EOPNOTSUPP;
1475 goto end_io; 1476 goto end_io;
1476 } 1477 }
diff --git a/block/blk-settings.c b/block/blk-settings.c
index 83413ff83739..66d4aa8799b7 100644
--- a/block/blk-settings.c
+++ b/block/blk-settings.c
@@ -34,23 +34,6 @@ void blk_queue_prep_rq(struct request_queue *q, prep_rq_fn *pfn)
34EXPORT_SYMBOL(blk_queue_prep_rq); 34EXPORT_SYMBOL(blk_queue_prep_rq);
35 35
36/** 36/**
37 * blk_queue_set_discard - set a discard_sectors function for queue
38 * @q: queue
39 * @dfn: prepare_discard function
40 *
41 * It's possible for a queue to register a discard callback which is used
42 * to transform a discard request into the appropriate type for the
43 * hardware. If none is registered, then discard requests are failed
44 * with %EOPNOTSUPP.
45 *
46 */
47void blk_queue_set_discard(struct request_queue *q, prepare_discard_fn *dfn)
48{
49 q->prepare_discard_fn = dfn;
50}
51EXPORT_SYMBOL(blk_queue_set_discard);
52
53/**
54 * blk_queue_merge_bvec - set a merge_bvec function for queue 37 * blk_queue_merge_bvec - set a merge_bvec function for queue
55 * @q: queue 38 * @q: queue
56 * @mbfn: merge_bvec_fn 39 * @mbfn: merge_bvec_fn
@@ -111,7 +94,9 @@ void blk_set_default_limits(struct queue_limits *lim)
111 lim->max_hw_segments = MAX_HW_SEGMENTS; 94 lim->max_hw_segments = MAX_HW_SEGMENTS;
112 lim->seg_boundary_mask = BLK_SEG_BOUNDARY_MASK; 95 lim->seg_boundary_mask = BLK_SEG_BOUNDARY_MASK;
113 lim->max_segment_size = MAX_SEGMENT_SIZE; 96 lim->max_segment_size = MAX_SEGMENT_SIZE;
114 lim->max_sectors = lim->max_hw_sectors = SAFE_MAX_SECTORS; 97 lim->max_sectors = BLK_DEF_MAX_SECTORS;
98 lim->max_hw_sectors = INT_MAX;
99 lim->max_discard_sectors = SAFE_MAX_SECTORS;
115 lim->logical_block_size = lim->physical_block_size = lim->io_min = 512; 100 lim->logical_block_size = lim->physical_block_size = lim->io_min = 512;
116 lim->bounce_pfn = (unsigned long)(BLK_BOUNCE_ANY >> PAGE_SHIFT); 101 lim->bounce_pfn = (unsigned long)(BLK_BOUNCE_ANY >> PAGE_SHIFT);
117 lim->alignment_offset = 0; 102 lim->alignment_offset = 0;
@@ -164,6 +149,7 @@ void blk_queue_make_request(struct request_queue *q, make_request_fn *mfn)
164 q->unplug_timer.data = (unsigned long)q; 149 q->unplug_timer.data = (unsigned long)q;
165 150
166 blk_set_default_limits(&q->limits); 151 blk_set_default_limits(&q->limits);
152 blk_queue_max_sectors(q, SAFE_MAX_SECTORS);
167 153
168 /* 154 /*
169 * If the caller didn't supply a lock, fall back to our embedded 155 * If the caller didn't supply a lock, fall back to our embedded
@@ -254,6 +240,18 @@ void blk_queue_max_hw_sectors(struct request_queue *q, unsigned int max_sectors)
254EXPORT_SYMBOL(blk_queue_max_hw_sectors); 240EXPORT_SYMBOL(blk_queue_max_hw_sectors);
255 241
256/** 242/**
243 * blk_queue_max_discard_sectors - set max sectors for a single discard
244 * @q: the request queue for the device
245 * @max_discard_sectors: maximum number of sectors to discard
246 **/
247void blk_queue_max_discard_sectors(struct request_queue *q,
248 unsigned int max_discard_sectors)
249{
250 q->limits.max_discard_sectors = max_discard_sectors;
251}
252EXPORT_SYMBOL(blk_queue_max_discard_sectors);
253
254/**
257 * blk_queue_max_phys_segments - set max phys segments for a request for this queue 255 * blk_queue_max_phys_segments - set max phys segments for a request for this queue
258 * @q: the request queue for the device 256 * @q: the request queue for the device
259 * @max_segments: max number of segments 257 * @max_segments: max number of segments
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index b78c9c3e2670..8a6d81afb284 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -452,6 +452,7 @@ int blk_register_queue(struct gendisk *disk)
452 if (ret) { 452 if (ret) {
453 kobject_uevent(&q->kobj, KOBJ_REMOVE); 453 kobject_uevent(&q->kobj, KOBJ_REMOVE);
454 kobject_del(&q->kobj); 454 kobject_del(&q->kobj);
455 blk_trace_remove_sysfs(disk_to_dev(disk));
455 return ret; 456 return ret;
456 } 457 }
457 458
@@ -465,11 +466,11 @@ void blk_unregister_queue(struct gendisk *disk)
465 if (WARN_ON(!q)) 466 if (WARN_ON(!q))
466 return; 467 return;
467 468
468 if (q->request_fn) { 469 if (q->request_fn)
469 elv_unregister_queue(q); 470 elv_unregister_queue(q);
470 471
471 kobject_uevent(&q->kobj, KOBJ_REMOVE); 472 kobject_uevent(&q->kobj, KOBJ_REMOVE);
472 kobject_del(&q->kobj); 473 kobject_del(&q->kobj);
473 kobject_put(&disk_to_dev(disk)->kobj); 474 blk_trace_remove_sysfs(disk_to_dev(disk));
474 } 475 kobject_put(&disk_to_dev(disk)->kobj);
475} 476}
diff --git a/block/blk-tag.c b/block/blk-tag.c
index 2e5cfeb59333..6b0f52c20964 100644
--- a/block/blk-tag.c
+++ b/block/blk-tag.c
@@ -359,7 +359,7 @@ int blk_queue_start_tag(struct request_queue *q, struct request *rq)
359 max_depth -= 2; 359 max_depth -= 2;
360 if (!max_depth) 360 if (!max_depth)
361 max_depth = 1; 361 max_depth = 1;
362 if (q->in_flight[0] > max_depth) 362 if (q->in_flight[BLK_RW_ASYNC] > max_depth)
363 return 1; 363 return 1;
364 } 364 }
365 365
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index 1ca813b16e78..069a61017c02 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -173,6 +173,7 @@ struct cfq_data {
173 unsigned int cfq_slice[2]; 173 unsigned int cfq_slice[2];
174 unsigned int cfq_slice_async_rq; 174 unsigned int cfq_slice_async_rq;
175 unsigned int cfq_slice_idle; 175 unsigned int cfq_slice_idle;
176 unsigned int cfq_latency;
176 177
177 struct list_head cic_list; 178 struct list_head cic_list;
178 179
@@ -180,6 +181,8 @@ struct cfq_data {
180 * Fallback dummy cfqq for extreme OOM conditions 181 * Fallback dummy cfqq for extreme OOM conditions
181 */ 182 */
182 struct cfq_queue oom_cfqq; 183 struct cfq_queue oom_cfqq;
184
185 unsigned long last_end_sync_rq;
183}; 186};
184 187
185enum cfqq_state_flags { 188enum cfqq_state_flags {
@@ -227,7 +230,7 @@ CFQ_CFQQ_FNS(coop);
227 blk_add_trace_msg((cfqd)->queue, "cfq " fmt, ##args) 230 blk_add_trace_msg((cfqd)->queue, "cfq " fmt, ##args)
228 231
229static void cfq_dispatch_insert(struct request_queue *, struct request *); 232static void cfq_dispatch_insert(struct request_queue *, struct request *);
230static struct cfq_queue *cfq_get_queue(struct cfq_data *, int, 233static struct cfq_queue *cfq_get_queue(struct cfq_data *, bool,
231 struct io_context *, gfp_t); 234 struct io_context *, gfp_t);
232static struct cfq_io_context *cfq_cic_lookup(struct cfq_data *, 235static struct cfq_io_context *cfq_cic_lookup(struct cfq_data *,
233 struct io_context *); 236 struct io_context *);
@@ -238,27 +241,24 @@ static inline int rq_in_driver(struct cfq_data *cfqd)
238} 241}
239 242
240static inline struct cfq_queue *cic_to_cfqq(struct cfq_io_context *cic, 243static inline struct cfq_queue *cic_to_cfqq(struct cfq_io_context *cic,
241 int is_sync) 244 bool is_sync)
242{ 245{
243 return cic->cfqq[!!is_sync]; 246 return cic->cfqq[is_sync];
244} 247}
245 248
246static inline void cic_set_cfqq(struct cfq_io_context *cic, 249static inline void cic_set_cfqq(struct cfq_io_context *cic,
247 struct cfq_queue *cfqq, int is_sync) 250 struct cfq_queue *cfqq, bool is_sync)
248{ 251{
249 cic->cfqq[!!is_sync] = cfqq; 252 cic->cfqq[is_sync] = cfqq;
250} 253}
251 254
252/* 255/*
253 * We regard a request as SYNC, if it's either a read or has the SYNC bit 256 * We regard a request as SYNC, if it's either a read or has the SYNC bit
254 * set (in which case it could also be direct WRITE). 257 * set (in which case it could also be direct WRITE).
255 */ 258 */
256static inline int cfq_bio_sync(struct bio *bio) 259static inline bool cfq_bio_sync(struct bio *bio)
257{ 260{
258 if (bio_data_dir(bio) == READ || bio_rw_flagged(bio, BIO_RW_SYNCIO)) 261 return bio_data_dir(bio) == READ || bio_rw_flagged(bio, BIO_RW_SYNCIO);
259 return 1;
260
261 return 0;
262} 262}
263 263
264/* 264/*
@@ -285,7 +285,7 @@ static int cfq_queue_empty(struct request_queue *q)
285 * if a queue is marked sync and has sync io queued. A sync queue with async 285 * if a queue is marked sync and has sync io queued. A sync queue with async
286 * io only, should not get full sync slice length. 286 * io only, should not get full sync slice length.
287 */ 287 */
288static inline int cfq_prio_slice(struct cfq_data *cfqd, int sync, 288static inline int cfq_prio_slice(struct cfq_data *cfqd, bool sync,
289 unsigned short prio) 289 unsigned short prio)
290{ 290{
291 const int base_slice = cfqd->cfq_slice[sync]; 291 const int base_slice = cfqd->cfq_slice[sync];
@@ -313,7 +313,7 @@ cfq_set_prio_slice(struct cfq_data *cfqd, struct cfq_queue *cfqq)
313 * isn't valid until the first request from the dispatch is activated 313 * isn't valid until the first request from the dispatch is activated
314 * and the slice time set. 314 * and the slice time set.
315 */ 315 */
316static inline int cfq_slice_used(struct cfq_queue *cfqq) 316static inline bool cfq_slice_used(struct cfq_queue *cfqq)
317{ 317{
318 if (cfq_cfqq_slice_new(cfqq)) 318 if (cfq_cfqq_slice_new(cfqq))
319 return 0; 319 return 0;
@@ -488,7 +488,7 @@ static unsigned long cfq_slice_offset(struct cfq_data *cfqd,
488 * we will service the queues. 488 * we will service the queues.
489 */ 489 */
490static void cfq_service_tree_add(struct cfq_data *cfqd, struct cfq_queue *cfqq, 490static void cfq_service_tree_add(struct cfq_data *cfqd, struct cfq_queue *cfqq,
491 int add_front) 491 bool add_front)
492{ 492{
493 struct rb_node **p, *parent; 493 struct rb_node **p, *parent;
494 struct cfq_queue *__cfqq; 494 struct cfq_queue *__cfqq;
@@ -504,11 +504,20 @@ static void cfq_service_tree_add(struct cfq_data *cfqd, struct cfq_queue *cfqq,
504 } else 504 } else
505 rb_key += jiffies; 505 rb_key += jiffies;
506 } else if (!add_front) { 506 } else if (!add_front) {
507 /*
508 * Get our rb key offset. Subtract any residual slice
509 * value carried from last service. A negative resid
510 * count indicates slice overrun, and this should position
511 * the next service time further away in the tree.
512 */
507 rb_key = cfq_slice_offset(cfqd, cfqq) + jiffies; 513 rb_key = cfq_slice_offset(cfqd, cfqq) + jiffies;
508 rb_key += cfqq->slice_resid; 514 rb_key -= cfqq->slice_resid;
509 cfqq->slice_resid = 0; 515 cfqq->slice_resid = 0;
510 } else 516 } else {
511 rb_key = 0; 517 rb_key = -HZ;
518 __cfqq = cfq_rb_first(&cfqd->service_tree);
519 rb_key += __cfqq ? __cfqq->rb_key : jiffies;
520 }
512 521
513 if (!RB_EMPTY_NODE(&cfqq->rb_node)) { 522 if (!RB_EMPTY_NODE(&cfqq->rb_node)) {
514 /* 523 /*
@@ -542,7 +551,7 @@ static void cfq_service_tree_add(struct cfq_data *cfqd, struct cfq_queue *cfqq,
542 n = &(*p)->rb_left; 551 n = &(*p)->rb_left;
543 else if (cfq_class_idle(cfqq) > cfq_class_idle(__cfqq)) 552 else if (cfq_class_idle(cfqq) > cfq_class_idle(__cfqq))
544 n = &(*p)->rb_right; 553 n = &(*p)->rb_right;
545 else if (rb_key < __cfqq->rb_key) 554 else if (time_before(rb_key, __cfqq->rb_key))
546 n = &(*p)->rb_left; 555 n = &(*p)->rb_left;
547 else 556 else
548 n = &(*p)->rb_right; 557 n = &(*p)->rb_right;
@@ -822,8 +831,10 @@ cfq_merged_requests(struct request_queue *q, struct request *rq,
822 * reposition in fifo if next is older than rq 831 * reposition in fifo if next is older than rq
823 */ 832 */
824 if (!list_empty(&rq->queuelist) && !list_empty(&next->queuelist) && 833 if (!list_empty(&rq->queuelist) && !list_empty(&next->queuelist) &&
825 time_before(next->start_time, rq->start_time)) 834 time_before(rq_fifo_time(next), rq_fifo_time(rq))) {
826 list_move(&rq->queuelist, &next->queuelist); 835 list_move(&rq->queuelist, &next->queuelist);
836 rq_set_fifo_time(rq, rq_fifo_time(next));
837 }
827 838
828 cfq_remove_request(next); 839 cfq_remove_request(next);
829} 840}
@@ -839,7 +850,7 @@ static int cfq_allow_merge(struct request_queue *q, struct request *rq,
839 * Disallow merge of a sync bio into an async request. 850 * Disallow merge of a sync bio into an async request.
840 */ 851 */
841 if (cfq_bio_sync(bio) && !rq_is_sync(rq)) 852 if (cfq_bio_sync(bio) && !rq_is_sync(rq))
842 return 0; 853 return false;
843 854
844 /* 855 /*
845 * Lookup the cfqq that this bio will be queued with. Allow 856 * Lookup the cfqq that this bio will be queued with. Allow
@@ -847,13 +858,10 @@ static int cfq_allow_merge(struct request_queue *q, struct request *rq,
847 */ 858 */
848 cic = cfq_cic_lookup(cfqd, current->io_context); 859 cic = cfq_cic_lookup(cfqd, current->io_context);
849 if (!cic) 860 if (!cic)
850 return 0; 861 return false;
851 862
852 cfqq = cic_to_cfqq(cic, cfq_bio_sync(bio)); 863 cfqq = cic_to_cfqq(cic, cfq_bio_sync(bio));
853 if (cfqq == RQ_CFQQ(rq)) 864 return cfqq == RQ_CFQQ(rq);
854 return 1;
855
856 return 0;
857} 865}
858 866
859static void __cfq_set_active_queue(struct cfq_data *cfqd, 867static void __cfq_set_active_queue(struct cfq_data *cfqd,
@@ -881,7 +889,7 @@ static void __cfq_set_active_queue(struct cfq_data *cfqd,
881 */ 889 */
882static void 890static void
883__cfq_slice_expired(struct cfq_data *cfqd, struct cfq_queue *cfqq, 891__cfq_slice_expired(struct cfq_data *cfqd, struct cfq_queue *cfqq,
884 int timed_out) 892 bool timed_out)
885{ 893{
886 cfq_log_cfqq(cfqd, cfqq, "slice expired t=%d", timed_out); 894 cfq_log_cfqq(cfqd, cfqq, "slice expired t=%d", timed_out);
887 895
@@ -909,7 +917,7 @@ __cfq_slice_expired(struct cfq_data *cfqd, struct cfq_queue *cfqq,
909 } 917 }
910} 918}
911 919
912static inline void cfq_slice_expired(struct cfq_data *cfqd, int timed_out) 920static inline void cfq_slice_expired(struct cfq_data *cfqd, bool timed_out)
913{ 921{
914 struct cfq_queue *cfqq = cfqd->active_queue; 922 struct cfq_queue *cfqq = cfqd->active_queue;
915 923
@@ -1021,7 +1029,7 @@ static struct cfq_queue *cfqq_close(struct cfq_data *cfqd,
1021 */ 1029 */
1022static struct cfq_queue *cfq_close_cooperator(struct cfq_data *cfqd, 1030static struct cfq_queue *cfq_close_cooperator(struct cfq_data *cfqd,
1023 struct cfq_queue *cur_cfqq, 1031 struct cfq_queue *cur_cfqq,
1024 int probe) 1032 bool probe)
1025{ 1033{
1026 struct cfq_queue *cfqq; 1034 struct cfq_queue *cfqq;
1027 1035
@@ -1085,6 +1093,15 @@ static void cfq_arm_slice_timer(struct cfq_data *cfqd)
1085 if (!cic || !atomic_read(&cic->ioc->nr_tasks)) 1093 if (!cic || !atomic_read(&cic->ioc->nr_tasks))
1086 return; 1094 return;
1087 1095
1096 /*
1097 * If our average think time is larger than the remaining time
1098 * slice, then don't idle. This avoids overrunning the allotted
1099 * time slice.
1100 */
1101 if (sample_valid(cic->ttime_samples) &&
1102 (cfqq->slice_end - jiffies < cic->ttime_mean))
1103 return;
1104
1088 cfq_mark_cfqq_wait_request(cfqq); 1105 cfq_mark_cfqq_wait_request(cfqq);
1089 1106
1090 /* 1107 /*
@@ -1124,9 +1141,7 @@ static void cfq_dispatch_insert(struct request_queue *q, struct request *rq)
1124 */ 1141 */
1125static struct request *cfq_check_fifo(struct cfq_queue *cfqq) 1142static struct request *cfq_check_fifo(struct cfq_queue *cfqq)
1126{ 1143{
1127 struct cfq_data *cfqd = cfqq->cfqd; 1144 struct request *rq = NULL;
1128 struct request *rq;
1129 int fifo;
1130 1145
1131 if (cfq_cfqq_fifo_expire(cfqq)) 1146 if (cfq_cfqq_fifo_expire(cfqq))
1132 return NULL; 1147 return NULL;
@@ -1136,13 +1151,11 @@ static struct request *cfq_check_fifo(struct cfq_queue *cfqq)
1136 if (list_empty(&cfqq->fifo)) 1151 if (list_empty(&cfqq->fifo))
1137 return NULL; 1152 return NULL;
1138 1153
1139 fifo = cfq_cfqq_sync(cfqq);
1140 rq = rq_entry_fifo(cfqq->fifo.next); 1154 rq = rq_entry_fifo(cfqq->fifo.next);
1141 1155 if (time_before(jiffies, rq_fifo_time(rq)))
1142 if (time_before(jiffies, rq->start_time + cfqd->cfq_fifo_expire[fifo]))
1143 rq = NULL; 1156 rq = NULL;
1144 1157
1145 cfq_log_cfqq(cfqd, cfqq, "fifo=%p", rq); 1158 cfq_log_cfqq(cfqq->cfqd, cfqq, "fifo=%p", rq);
1146 return rq; 1159 return rq;
1147} 1160}
1148 1161
@@ -1243,16 +1256,83 @@ static int cfq_forced_dispatch(struct cfq_data *cfqd)
1243 return dispatched; 1256 return dispatched;
1244} 1257}
1245 1258
1259static bool cfq_may_dispatch(struct cfq_data *cfqd, struct cfq_queue *cfqq)
1260{
1261 unsigned int max_dispatch;
1262
1263 /*
1264 * Drain async requests before we start sync IO
1265 */
1266 if (cfq_cfqq_idle_window(cfqq) && cfqd->rq_in_driver[BLK_RW_ASYNC])
1267 return false;
1268
1269 /*
1270 * If this is an async queue and we have sync IO in flight, let it wait
1271 */
1272 if (cfqd->sync_flight && !cfq_cfqq_sync(cfqq))
1273 return false;
1274
1275 max_dispatch = cfqd->cfq_quantum;
1276 if (cfq_class_idle(cfqq))
1277 max_dispatch = 1;
1278
1279 /*
1280 * Does this cfqq already have too much IO in flight?
1281 */
1282 if (cfqq->dispatched >= max_dispatch) {
1283 /*
1284 * idle queue must always only have a single IO in flight
1285 */
1286 if (cfq_class_idle(cfqq))
1287 return false;
1288
1289 /*
1290 * We have other queues, don't allow more IO from this one
1291 */
1292 if (cfqd->busy_queues > 1)
1293 return false;
1294
1295 /*
1296 * Sole queue user, allow bigger slice
1297 */
1298 max_dispatch *= 4;
1299 }
1300
1301 /*
1302 * Async queues must wait a bit before being allowed dispatch.
1303 * We also ramp up the dispatch depth gradually for async IO,
1304 * based on the last sync IO we serviced
1305 */
1306 if (!cfq_cfqq_sync(cfqq) && cfqd->cfq_latency) {
1307 unsigned long last_sync = jiffies - cfqd->last_end_sync_rq;
1308 unsigned int depth;
1309
1310 depth = last_sync / cfqd->cfq_slice[1];
1311 if (!depth && !cfqq->dispatched)
1312 depth = 1;
1313 if (depth < max_dispatch)
1314 max_dispatch = depth;
1315 }
1316
1317 /*
1318 * If we're below the current max, allow a dispatch
1319 */
1320 return cfqq->dispatched < max_dispatch;
1321}
1322
1246/* 1323/*
1247 * Dispatch a request from cfqq, moving them to the request queue 1324 * Dispatch a request from cfqq, moving them to the request queue
1248 * dispatch list. 1325 * dispatch list.
1249 */ 1326 */
1250static void cfq_dispatch_request(struct cfq_data *cfqd, struct cfq_queue *cfqq) 1327static bool cfq_dispatch_request(struct cfq_data *cfqd, struct cfq_queue *cfqq)
1251{ 1328{
1252 struct request *rq; 1329 struct request *rq;
1253 1330
1254 BUG_ON(RB_EMPTY_ROOT(&cfqq->sort_list)); 1331 BUG_ON(RB_EMPTY_ROOT(&cfqq->sort_list));
1255 1332
1333 if (!cfq_may_dispatch(cfqd, cfqq))
1334 return false;
1335
1256 /* 1336 /*
1257 * follow expired path, else get first next available 1337 * follow expired path, else get first next available
1258 */ 1338 */
@@ -1271,6 +1351,8 @@ static void cfq_dispatch_request(struct cfq_data *cfqd, struct cfq_queue *cfqq)
1271 atomic_long_inc(&cic->ioc->refcount); 1351 atomic_long_inc(&cic->ioc->refcount);
1272 cfqd->active_cic = cic; 1352 cfqd->active_cic = cic;
1273 } 1353 }
1354
1355 return true;
1274} 1356}
1275 1357
1276/* 1358/*
@@ -1281,7 +1363,6 @@ static int cfq_dispatch_requests(struct request_queue *q, int force)
1281{ 1363{
1282 struct cfq_data *cfqd = q->elevator->elevator_data; 1364 struct cfq_data *cfqd = q->elevator->elevator_data;
1283 struct cfq_queue *cfqq; 1365 struct cfq_queue *cfqq;
1284 unsigned int max_dispatch;
1285 1366
1286 if (!cfqd->busy_queues) 1367 if (!cfqd->busy_queues)
1287 return 0; 1368 return 0;
@@ -1294,48 +1375,11 @@ static int cfq_dispatch_requests(struct request_queue *q, int force)
1294 return 0; 1375 return 0;
1295 1376
1296 /* 1377 /*
1297 * Drain async requests before we start sync IO 1378 * Dispatch a request from this cfqq, if it is allowed
1298 */ 1379 */
1299 if (cfq_cfqq_idle_window(cfqq) && cfqd->rq_in_driver[BLK_RW_ASYNC]) 1380 if (!cfq_dispatch_request(cfqd, cfqq))
1300 return 0; 1381 return 0;
1301 1382
1302 /*
1303 * If this is an async queue and we have sync IO in flight, let it wait
1304 */
1305 if (cfqd->sync_flight && !cfq_cfqq_sync(cfqq))
1306 return 0;
1307
1308 max_dispatch = cfqd->cfq_quantum;
1309 if (cfq_class_idle(cfqq))
1310 max_dispatch = 1;
1311
1312 /*
1313 * Does this cfqq already have too much IO in flight?
1314 */
1315 if (cfqq->dispatched >= max_dispatch) {
1316 /*
1317 * idle queue must always only have a single IO in flight
1318 */
1319 if (cfq_class_idle(cfqq))
1320 return 0;
1321
1322 /*
1323 * We have other queues, don't allow more IO from this one
1324 */
1325 if (cfqd->busy_queues > 1)
1326 return 0;
1327
1328 /*
1329 * we are the only queue, allow up to 4 times of 'quantum'
1330 */
1331 if (cfqq->dispatched >= 4 * max_dispatch)
1332 return 0;
1333 }
1334
1335 /*
1336 * Dispatch a request from this cfqq
1337 */
1338 cfq_dispatch_request(cfqd, cfqq);
1339 cfqq->slice_dispatch++; 1383 cfqq->slice_dispatch++;
1340 cfq_clear_cfqq_must_dispatch(cfqq); 1384 cfq_clear_cfqq_must_dispatch(cfqq);
1341 1385
@@ -1635,7 +1679,7 @@ static void cfq_ioc_set_ioprio(struct io_context *ioc)
1635} 1679}
1636 1680
1637static void cfq_init_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq, 1681static void cfq_init_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq,
1638 pid_t pid, int is_sync) 1682 pid_t pid, bool is_sync)
1639{ 1683{
1640 RB_CLEAR_NODE(&cfqq->rb_node); 1684 RB_CLEAR_NODE(&cfqq->rb_node);
1641 RB_CLEAR_NODE(&cfqq->p_node); 1685 RB_CLEAR_NODE(&cfqq->p_node);
@@ -1655,7 +1699,7 @@ static void cfq_init_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq,
1655} 1699}
1656 1700
1657static struct cfq_queue * 1701static struct cfq_queue *
1658cfq_find_alloc_queue(struct cfq_data *cfqd, int is_sync, 1702cfq_find_alloc_queue(struct cfq_data *cfqd, bool is_sync,
1659 struct io_context *ioc, gfp_t gfp_mask) 1703 struct io_context *ioc, gfp_t gfp_mask)
1660{ 1704{
1661 struct cfq_queue *cfqq, *new_cfqq = NULL; 1705 struct cfq_queue *cfqq, *new_cfqq = NULL;
@@ -1719,7 +1763,7 @@ cfq_async_queue_prio(struct cfq_data *cfqd, int ioprio_class, int ioprio)
1719} 1763}
1720 1764
1721static struct cfq_queue * 1765static struct cfq_queue *
1722cfq_get_queue(struct cfq_data *cfqd, int is_sync, struct io_context *ioc, 1766cfq_get_queue(struct cfq_data *cfqd, bool is_sync, struct io_context *ioc,
1723 gfp_t gfp_mask) 1767 gfp_t gfp_mask)
1724{ 1768{
1725 const int ioprio = task_ioprio(ioc); 1769 const int ioprio = task_ioprio(ioc);
@@ -1951,10 +1995,13 @@ cfq_update_idle_window(struct cfq_data *cfqd, struct cfq_queue *cfqq,
1951 enable_idle = old_idle = cfq_cfqq_idle_window(cfqq); 1995 enable_idle = old_idle = cfq_cfqq_idle_window(cfqq);
1952 1996
1953 if (!atomic_read(&cic->ioc->nr_tasks) || !cfqd->cfq_slice_idle || 1997 if (!atomic_read(&cic->ioc->nr_tasks) || !cfqd->cfq_slice_idle ||
1954 (cfqd->hw_tag && CIC_SEEKY(cic))) 1998 (!cfqd->cfq_latency && cfqd->hw_tag && CIC_SEEKY(cic)))
1955 enable_idle = 0; 1999 enable_idle = 0;
1956 else if (sample_valid(cic->ttime_samples)) { 2000 else if (sample_valid(cic->ttime_samples)) {
1957 if (cic->ttime_mean > cfqd->cfq_slice_idle) 2001 unsigned int slice_idle = cfqd->cfq_slice_idle;
2002 if (sample_valid(cic->seek_samples) && CIC_SEEKY(cic))
2003 slice_idle = msecs_to_jiffies(CFQ_MIN_TT);
2004 if (cic->ttime_mean > slice_idle)
1958 enable_idle = 0; 2005 enable_idle = 0;
1959 else 2006 else
1960 enable_idle = 1; 2007 enable_idle = 1;
@@ -1973,7 +2020,7 @@ cfq_update_idle_window(struct cfq_data *cfqd, struct cfq_queue *cfqq,
1973 * Check if new_cfqq should preempt the currently active queue. Return 0 for 2020 * Check if new_cfqq should preempt the currently active queue. Return 0 for
1974 * no or if we aren't sure, a 1 will cause a preempt. 2021 * no or if we aren't sure, a 1 will cause a preempt.
1975 */ 2022 */
1976static int 2023static bool
1977cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq, 2024cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq,
1978 struct request *rq) 2025 struct request *rq)
1979{ 2026{
@@ -1981,48 +2028,48 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq,
1981 2028
1982 cfqq = cfqd->active_queue; 2029 cfqq = cfqd->active_queue;
1983 if (!cfqq) 2030 if (!cfqq)
1984 return 0; 2031 return false;
1985 2032
1986 if (cfq_slice_used(cfqq)) 2033 if (cfq_slice_used(cfqq))
1987 return 1; 2034 return true;
1988 2035
1989 if (cfq_class_idle(new_cfqq)) 2036 if (cfq_class_idle(new_cfqq))
1990 return 0; 2037 return false;
1991 2038
1992 if (cfq_class_idle(cfqq)) 2039 if (cfq_class_idle(cfqq))
1993 return 1; 2040 return true;
1994 2041
1995 /* 2042 /*
1996 * if the new request is sync, but the currently running queue is 2043 * if the new request is sync, but the currently running queue is
1997 * not, let the sync request have priority. 2044 * not, let the sync request have priority.
1998 */ 2045 */
1999 if (rq_is_sync(rq) && !cfq_cfqq_sync(cfqq)) 2046 if (rq_is_sync(rq) && !cfq_cfqq_sync(cfqq))
2000 return 1; 2047 return true;
2001 2048
2002 /* 2049 /*
2003 * So both queues are sync. Let the new request get disk time if 2050 * So both queues are sync. Let the new request get disk time if
2004 * it's a metadata request and the current queue is doing regular IO. 2051 * it's a metadata request and the current queue is doing regular IO.
2005 */ 2052 */
2006 if (rq_is_meta(rq) && !cfqq->meta_pending) 2053 if (rq_is_meta(rq) && !cfqq->meta_pending)
2007 return 1; 2054 return false;
2008 2055
2009 /* 2056 /*
2010 * Allow an RT request to pre-empt an ongoing non-RT cfqq timeslice. 2057 * Allow an RT request to pre-empt an ongoing non-RT cfqq timeslice.
2011 */ 2058 */
2012 if (cfq_class_rt(new_cfqq) && !cfq_class_rt(cfqq)) 2059 if (cfq_class_rt(new_cfqq) && !cfq_class_rt(cfqq))
2013 return 1; 2060 return true;
2014 2061
2015 if (!cfqd->active_cic || !cfq_cfqq_wait_request(cfqq)) 2062 if (!cfqd->active_cic || !cfq_cfqq_wait_request(cfqq))
2016 return 0; 2063 return false;
2017 2064
2018 /* 2065 /*
2019 * if this request is as-good as one we would expect from the 2066 * if this request is as-good as one we would expect from the
2020 * current cfqq, let it preempt 2067 * current cfqq, let it preempt
2021 */ 2068 */
2022 if (cfq_rq_close(cfqd, rq)) 2069 if (cfq_rq_close(cfqd, rq))
2023 return 1; 2070 return true;
2024 2071
2025 return 0; 2072 return false;
2026} 2073}
2027 2074
2028/* 2075/*
@@ -2107,6 +2154,7 @@ static void cfq_insert_request(struct request_queue *q, struct request *rq)
2107 2154
2108 cfq_add_rq_rb(rq); 2155 cfq_add_rq_rb(rq);
2109 2156
2157 rq_set_fifo_time(rq, jiffies + cfqd->cfq_fifo_expire[rq_is_sync(rq)]);
2110 list_add_tail(&rq->queuelist, &cfqq->fifo); 2158 list_add_tail(&rq->queuelist, &cfqq->fifo);
2111 2159
2112 cfq_rq_enqueued(cfqd, cfqq, rq); 2160 cfq_rq_enqueued(cfqd, cfqq, rq);
@@ -2157,8 +2205,10 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq)
2157 if (cfq_cfqq_sync(cfqq)) 2205 if (cfq_cfqq_sync(cfqq))
2158 cfqd->sync_flight--; 2206 cfqd->sync_flight--;
2159 2207
2160 if (sync) 2208 if (sync) {
2161 RQ_CIC(rq)->last_end_request = now; 2209 RQ_CIC(rq)->last_end_request = now;
2210 cfqd->last_end_sync_rq = now;
2211 }
2162 2212
2163 /* 2213 /*
2164 * If this is the active queue, check if it needs to be expired, 2214 * If this is the active queue, check if it needs to be expired,
@@ -2284,7 +2334,7 @@ cfq_set_request(struct request_queue *q, struct request *rq, gfp_t gfp_mask)
2284 struct cfq_data *cfqd = q->elevator->elevator_data; 2334 struct cfq_data *cfqd = q->elevator->elevator_data;
2285 struct cfq_io_context *cic; 2335 struct cfq_io_context *cic;
2286 const int rw = rq_data_dir(rq); 2336 const int rw = rq_data_dir(rq);
2287 const int is_sync = rq_is_sync(rq); 2337 const bool is_sync = rq_is_sync(rq);
2288 struct cfq_queue *cfqq; 2338 struct cfq_queue *cfqq;
2289 unsigned long flags; 2339 unsigned long flags;
2290 2340
@@ -2480,8 +2530,9 @@ static void *cfq_init_queue(struct request_queue *q)
2480 cfqd->cfq_slice[1] = cfq_slice_sync; 2530 cfqd->cfq_slice[1] = cfq_slice_sync;
2481 cfqd->cfq_slice_async_rq = cfq_slice_async_rq; 2531 cfqd->cfq_slice_async_rq = cfq_slice_async_rq;
2482 cfqd->cfq_slice_idle = cfq_slice_idle; 2532 cfqd->cfq_slice_idle = cfq_slice_idle;
2533 cfqd->cfq_latency = 1;
2483 cfqd->hw_tag = 1; 2534 cfqd->hw_tag = 1;
2484 2535 cfqd->last_end_sync_rq = jiffies;
2485 return cfqd; 2536 return cfqd;
2486} 2537}
2487 2538
@@ -2549,6 +2600,7 @@ SHOW_FUNCTION(cfq_slice_idle_show, cfqd->cfq_slice_idle, 1);
2549SHOW_FUNCTION(cfq_slice_sync_show, cfqd->cfq_slice[1], 1); 2600SHOW_FUNCTION(cfq_slice_sync_show, cfqd->cfq_slice[1], 1);
2550SHOW_FUNCTION(cfq_slice_async_show, cfqd->cfq_slice[0], 1); 2601SHOW_FUNCTION(cfq_slice_async_show, cfqd->cfq_slice[0], 1);
2551SHOW_FUNCTION(cfq_slice_async_rq_show, cfqd->cfq_slice_async_rq, 0); 2602SHOW_FUNCTION(cfq_slice_async_rq_show, cfqd->cfq_slice_async_rq, 0);
2603SHOW_FUNCTION(cfq_low_latency_show, cfqd->cfq_latency, 0);
2552#undef SHOW_FUNCTION 2604#undef SHOW_FUNCTION
2553 2605
2554#define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX, __CONV) \ 2606#define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX, __CONV) \
@@ -2580,6 +2632,7 @@ STORE_FUNCTION(cfq_slice_sync_store, &cfqd->cfq_slice[1], 1, UINT_MAX, 1);
2580STORE_FUNCTION(cfq_slice_async_store, &cfqd->cfq_slice[0], 1, UINT_MAX, 1); 2632STORE_FUNCTION(cfq_slice_async_store, &cfqd->cfq_slice[0], 1, UINT_MAX, 1);
2581STORE_FUNCTION(cfq_slice_async_rq_store, &cfqd->cfq_slice_async_rq, 1, 2633STORE_FUNCTION(cfq_slice_async_rq_store, &cfqd->cfq_slice_async_rq, 1,
2582 UINT_MAX, 0); 2634 UINT_MAX, 0);
2635STORE_FUNCTION(cfq_low_latency_store, &cfqd->cfq_latency, 0, 1, 0);
2583#undef STORE_FUNCTION 2636#undef STORE_FUNCTION
2584 2637
2585#define CFQ_ATTR(name) \ 2638#define CFQ_ATTR(name) \
@@ -2595,6 +2648,7 @@ static struct elv_fs_entry cfq_attrs[] = {
2595 CFQ_ATTR(slice_async), 2648 CFQ_ATTR(slice_async),
2596 CFQ_ATTR(slice_async_rq), 2649 CFQ_ATTR(slice_async_rq),
2597 CFQ_ATTR(slice_idle), 2650 CFQ_ATTR(slice_idle),
2651 CFQ_ATTR(low_latency),
2598 __ATTR_NULL 2652 __ATTR_NULL
2599}; 2653};
2600 2654
diff --git a/block/compat_ioctl.c b/block/compat_ioctl.c
index 7865a34e0faa..9bd086c1a4d5 100644
--- a/block/compat_ioctl.c
+++ b/block/compat_ioctl.c
@@ -21,6 +21,11 @@ static int compat_put_int(unsigned long arg, int val)
21 return put_user(val, (compat_int_t __user *)compat_ptr(arg)); 21 return put_user(val, (compat_int_t __user *)compat_ptr(arg));
22} 22}
23 23
24static int compat_put_uint(unsigned long arg, unsigned int val)
25{
26 return put_user(val, (compat_uint_t __user *)compat_ptr(arg));
27}
28
24static int compat_put_long(unsigned long arg, long val) 29static int compat_put_long(unsigned long arg, long val)
25{ 30{
26 return put_user(val, (compat_long_t __user *)compat_ptr(arg)); 31 return put_user(val, (compat_long_t __user *)compat_ptr(arg));
@@ -734,6 +739,14 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
734 switch (cmd) { 739 switch (cmd) {
735 case HDIO_GETGEO: 740 case HDIO_GETGEO:
736 return compat_hdio_getgeo(disk, bdev, compat_ptr(arg)); 741 return compat_hdio_getgeo(disk, bdev, compat_ptr(arg));
742 case BLKPBSZGET:
743 return compat_put_uint(arg, bdev_physical_block_size(bdev));
744 case BLKIOMIN:
745 return compat_put_uint(arg, bdev_io_min(bdev));
746 case BLKIOOPT:
747 return compat_put_uint(arg, bdev_io_opt(bdev));
748 case BLKALIGNOFF:
749 return compat_put_int(arg, bdev_alignment_offset(bdev));
737 case BLKFLSBUF: 750 case BLKFLSBUF:
738 case BLKROSET: 751 case BLKROSET:
739 case BLKDISCARD: 752 case BLKDISCARD:
diff --git a/block/elevator.c b/block/elevator.c
index 1975b619c86d..a847046c6e53 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -1059,9 +1059,7 @@ ssize_t elv_iosched_store(struct request_queue *q, const char *name,
1059 return count; 1059 return count;
1060 1060
1061 strlcpy(elevator_name, name, sizeof(elevator_name)); 1061 strlcpy(elevator_name, name, sizeof(elevator_name));
1062 strstrip(elevator_name); 1062 e = elevator_get(strstrip(elevator_name));
1063
1064 e = elevator_get(elevator_name);
1065 if (!e) { 1063 if (!e) {
1066 printk(KERN_ERR "elevator: type %s not found\n", elevator_name); 1064 printk(KERN_ERR "elevator: type %s not found\n", elevator_name);
1067 return -EINVAL; 1065 return -EINVAL;
diff --git a/block/ioctl.c b/block/ioctl.c
index d3e6b5827a34..1f4d1de12b09 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -138,6 +138,11 @@ static int put_int(unsigned long arg, int val)
138 return put_user(val, (int __user *)arg); 138 return put_user(val, (int __user *)arg);
139} 139}
140 140
141static int put_uint(unsigned long arg, unsigned int val)
142{
143 return put_user(val, (unsigned int __user *)arg);
144}
145
141static int put_long(unsigned long arg, long val) 146static int put_long(unsigned long arg, long val)
142{ 147{
143 return put_user(val, (long __user *)arg); 148 return put_user(val, (long __user *)arg);
@@ -263,10 +268,18 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
263 return put_long(arg, (bdi->ra_pages * PAGE_CACHE_SIZE) / 512); 268 return put_long(arg, (bdi->ra_pages * PAGE_CACHE_SIZE) / 512);
264 case BLKROGET: 269 case BLKROGET:
265 return put_int(arg, bdev_read_only(bdev) != 0); 270 return put_int(arg, bdev_read_only(bdev) != 0);
266 case BLKBSZGET: /* get the logical block size (cf. BLKSSZGET) */ 271 case BLKBSZGET: /* get block device soft block size (cf. BLKSSZGET) */
267 return put_int(arg, block_size(bdev)); 272 return put_int(arg, block_size(bdev));
268 case BLKSSZGET: /* get block device hardware sector size */ 273 case BLKSSZGET: /* get block device logical block size */
269 return put_int(arg, bdev_logical_block_size(bdev)); 274 return put_int(arg, bdev_logical_block_size(bdev));
275 case BLKPBSZGET: /* get block device physical block size */
276 return put_uint(arg, bdev_physical_block_size(bdev));
277 case BLKIOMIN:
278 return put_uint(arg, bdev_io_min(bdev));
279 case BLKIOOPT:
280 return put_uint(arg, bdev_io_opt(bdev));
281 case BLKALIGNOFF:
282 return put_int(arg, bdev_alignment_offset(bdev));
270 case BLKSECTGET: 283 case BLKSECTGET:
271 return put_ushort(arg, queue_max_sectors(bdev_get_queue(bdev))); 284 return put_ushort(arg, queue_max_sectors(bdev_get_queue(bdev)));
272 case BLKRASET: 285 case BLKRASET:
diff --git a/crypto/aead.c b/crypto/aead.c
index d9aa733db164..0a55da70845e 100644
--- a/crypto/aead.c
+++ b/crypto/aead.c
@@ -18,6 +18,7 @@
18#include <linux/kernel.h> 18#include <linux/kernel.h>
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/rtnetlink.h> 20#include <linux/rtnetlink.h>
21#include <linux/sched.h>
21#include <linux/slab.h> 22#include <linux/slab.h>
22#include <linux/seq_file.h> 23#include <linux/seq_file.h>
23 24
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index dd8729d674e5..93d2c7971df6 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -211,6 +211,18 @@ config ACPI_HOTPLUG_CPU
211 select ACPI_CONTAINER 211 select ACPI_CONTAINER
212 default y 212 default y
213 213
214config ACPI_PROCESSOR_AGGREGATOR
215 tristate "Processor Aggregator"
216 depends on ACPI_PROCESSOR
217 depends on EXPERIMENTAL
218 depends on X86
219 help
220 ACPI 4.0 defines processor Aggregator, which enables OS to perform
221 specific processor configuration and control that applies to all
222 processors in the platform. Currently only logical processor idling
223 is defined, which is to reduce power consumption. This driver
224 supports the new device.
225
214config ACPI_THERMAL 226config ACPI_THERMAL
215 tristate "Thermal Zone" 227 tristate "Thermal Zone"
216 depends on ACPI_PROCESSOR 228 depends on ACPI_PROCESSOR
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 82cd49dc603b..7702118509a0 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -62,3 +62,5 @@ obj-$(CONFIG_ACPI_POWER_METER) += power_meter.o
62processor-y := processor_core.o processor_throttling.o 62processor-y := processor_core.o processor_throttling.o
63processor-y += processor_idle.o processor_thermal.o 63processor-y += processor_idle.o processor_thermal.o
64processor-$(CONFIG_CPU_FREQ) += processor_perflib.o 64processor-$(CONFIG_CPU_FREQ) += processor_perflib.o
65
66obj-$(CONFIG_ACPI_PROCESSOR_AGGREGATOR) += acpi_pad.o
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index 98b9690b0159..b6ed60b57b0d 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -245,6 +245,7 @@ static void acpi_ac_notify(struct acpi_device *device, u32 event)
245 acpi_bus_generate_netlink_event(device->pnp.device_class, 245 acpi_bus_generate_netlink_event(device->pnp.device_class,
246 dev_name(&device->dev), event, 246 dev_name(&device->dev), event,
247 (u32) ac->state); 247 (u32) ac->state);
248 acpi_notifier_call_chain(device, event, (u32) ac->state);
248#ifdef CONFIG_ACPI_SYSFS_POWER 249#ifdef CONFIG_ACPI_SYSFS_POWER
249 kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE); 250 kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE);
250#endif 251#endif
diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c
new file mode 100644
index 000000000000..0d2cdb86158b
--- /dev/null
+++ b/drivers/acpi/acpi_pad.c
@@ -0,0 +1,514 @@
1/*
2 * acpi_pad.c ACPI Processor Aggregator Driver
3 *
4 * Copyright (c) 2009, Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 */
20
21#include <linux/kernel.h>
22#include <linux/cpumask.h>
23#include <linux/module.h>
24#include <linux/init.h>
25#include <linux/types.h>
26#include <linux/kthread.h>
27#include <linux/freezer.h>
28#include <linux/cpu.h>
29#include <linux/clockchips.h>
30#include <acpi/acpi_bus.h>
31#include <acpi/acpi_drivers.h>
32
33#define ACPI_PROCESSOR_AGGREGATOR_CLASS "processor_aggregator"
34#define ACPI_PROCESSOR_AGGREGATOR_DEVICE_NAME "Processor Aggregator"
35#define ACPI_PROCESSOR_AGGREGATOR_NOTIFY 0x80
36static DEFINE_MUTEX(isolated_cpus_lock);
37
38#define MWAIT_SUBSTATE_MASK (0xf)
39#define MWAIT_CSTATE_MASK (0xf)
40#define MWAIT_SUBSTATE_SIZE (4)
41#define CPUID_MWAIT_LEAF (5)
42#define CPUID5_ECX_EXTENSIONS_SUPPORTED (0x1)
43#define CPUID5_ECX_INTERRUPT_BREAK (0x2)
44static unsigned long power_saving_mwait_eax;
45static void power_saving_mwait_init(void)
46{
47 unsigned int eax, ebx, ecx, edx;
48 unsigned int highest_cstate = 0;
49 unsigned int highest_subcstate = 0;
50 int i;
51
52 if (!boot_cpu_has(X86_FEATURE_MWAIT))
53 return;
54 if (boot_cpu_data.cpuid_level < CPUID_MWAIT_LEAF)
55 return;
56
57 cpuid(CPUID_MWAIT_LEAF, &eax, &ebx, &ecx, &edx);
58
59 if (!(ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED) ||
60 !(ecx & CPUID5_ECX_INTERRUPT_BREAK))
61 return;
62
63 edx >>= MWAIT_SUBSTATE_SIZE;
64 for (i = 0; i < 7 && edx; i++, edx >>= MWAIT_SUBSTATE_SIZE) {
65 if (edx & MWAIT_SUBSTATE_MASK) {
66 highest_cstate = i;
67 highest_subcstate = edx & MWAIT_SUBSTATE_MASK;
68 }
69 }
70 power_saving_mwait_eax = (highest_cstate << MWAIT_SUBSTATE_SIZE) |
71 (highest_subcstate - 1);
72
73 for_each_online_cpu(i)
74 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ON, &i);
75
76#if defined(CONFIG_GENERIC_TIME) && defined(CONFIG_X86)
77 switch (boot_cpu_data.x86_vendor) {
78 case X86_VENDOR_AMD:
79 case X86_VENDOR_INTEL:
80 /*
81 * AMD Fam10h TSC will tick in all
82 * C/P/S0/S1 states when this bit is set.
83 */
84 if (boot_cpu_has(X86_FEATURE_NONSTOP_TSC))
85 return;
86
87 /*FALL THROUGH*/
88 default:
89 /* TSC could halt in idle, so notify users */
90 mark_tsc_unstable("TSC halts in idle");
91 }
92#endif
93}
94
95static unsigned long cpu_weight[NR_CPUS];
96static int tsk_in_cpu[NR_CPUS] = {[0 ... NR_CPUS-1] = -1};
97static DECLARE_BITMAP(pad_busy_cpus_bits, NR_CPUS);
98static void round_robin_cpu(unsigned int tsk_index)
99{
100 struct cpumask *pad_busy_cpus = to_cpumask(pad_busy_cpus_bits);
101 cpumask_var_t tmp;
102 int cpu;
103 unsigned long min_weight = -1, preferred_cpu;
104
105 if (!alloc_cpumask_var(&tmp, GFP_KERNEL))
106 return;
107
108 mutex_lock(&isolated_cpus_lock);
109 cpumask_clear(tmp);
110 for_each_cpu(cpu, pad_busy_cpus)
111 cpumask_or(tmp, tmp, topology_thread_cpumask(cpu));
112 cpumask_andnot(tmp, cpu_online_mask, tmp);
113 /* avoid HT sibilings if possible */
114 if (cpumask_empty(tmp))
115 cpumask_andnot(tmp, cpu_online_mask, pad_busy_cpus);
116 if (cpumask_empty(tmp)) {
117 mutex_unlock(&isolated_cpus_lock);
118 return;
119 }
120 for_each_cpu(cpu, tmp) {
121 if (cpu_weight[cpu] < min_weight) {
122 min_weight = cpu_weight[cpu];
123 preferred_cpu = cpu;
124 }
125 }
126
127 if (tsk_in_cpu[tsk_index] != -1)
128 cpumask_clear_cpu(tsk_in_cpu[tsk_index], pad_busy_cpus);
129 tsk_in_cpu[tsk_index] = preferred_cpu;
130 cpumask_set_cpu(preferred_cpu, pad_busy_cpus);
131 cpu_weight[preferred_cpu]++;
132 mutex_unlock(&isolated_cpus_lock);
133
134 set_cpus_allowed_ptr(current, cpumask_of(preferred_cpu));
135}
136
137static void exit_round_robin(unsigned int tsk_index)
138{
139 struct cpumask *pad_busy_cpus = to_cpumask(pad_busy_cpus_bits);
140 cpumask_clear_cpu(tsk_in_cpu[tsk_index], pad_busy_cpus);
141 tsk_in_cpu[tsk_index] = -1;
142}
143
144static unsigned int idle_pct = 5; /* percentage */
145static unsigned int round_robin_time = 10; /* second */
146static int power_saving_thread(void *data)
147{
148 struct sched_param param = {.sched_priority = 1};
149 int do_sleep;
150 unsigned int tsk_index = (unsigned long)data;
151 u64 last_jiffies = 0;
152
153 sched_setscheduler(current, SCHED_RR, &param);
154
155 while (!kthread_should_stop()) {
156 int cpu;
157 u64 expire_time;
158
159 try_to_freeze();
160
161 /* round robin to cpus */
162 if (last_jiffies + round_robin_time * HZ < jiffies) {
163 last_jiffies = jiffies;
164 round_robin_cpu(tsk_index);
165 }
166
167 do_sleep = 0;
168
169 current_thread_info()->status &= ~TS_POLLING;
170 /*
171 * TS_POLLING-cleared state must be visible before we test
172 * NEED_RESCHED:
173 */
174 smp_mb();
175
176 expire_time = jiffies + HZ * (100 - idle_pct) / 100;
177
178 while (!need_resched()) {
179 local_irq_disable();
180 cpu = smp_processor_id();
181 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER,
182 &cpu);
183 stop_critical_timings();
184
185 __monitor((void *)&current_thread_info()->flags, 0, 0);
186 smp_mb();
187 if (!need_resched())
188 __mwait(power_saving_mwait_eax, 1);
189
190 start_critical_timings();
191 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT,
192 &cpu);
193 local_irq_enable();
194
195 if (jiffies > expire_time) {
196 do_sleep = 1;
197 break;
198 }
199 }
200
201 current_thread_info()->status |= TS_POLLING;
202
203 /*
204 * current sched_rt has threshold for rt task running time.
205 * When a rt task uses 95% CPU time, the rt thread will be
206 * scheduled out for 5% CPU time to not starve other tasks. But
207 * the mechanism only works when all CPUs have RT task running,
208 * as if one CPU hasn't RT task, RT task from other CPUs will
209 * borrow CPU time from this CPU and cause RT task use > 95%
210 * CPU time. To make 'avoid staration' work, takes a nap here.
211 */
212 if (do_sleep)
213 schedule_timeout_killable(HZ * idle_pct / 100);
214 }
215
216 exit_round_robin(tsk_index);
217 return 0;
218}
219
220static struct task_struct *ps_tsks[NR_CPUS];
221static unsigned int ps_tsk_num;
222static int create_power_saving_task(void)
223{
224 ps_tsks[ps_tsk_num] = kthread_run(power_saving_thread,
225 (void *)(unsigned long)ps_tsk_num,
226 "power_saving/%d", ps_tsk_num);
227 if (ps_tsks[ps_tsk_num]) {
228 ps_tsk_num++;
229 return 0;
230 }
231 return -EINVAL;
232}
233
234static void destroy_power_saving_task(void)
235{
236 if (ps_tsk_num > 0) {
237 ps_tsk_num--;
238 kthread_stop(ps_tsks[ps_tsk_num]);
239 }
240}
241
242static void set_power_saving_task_num(unsigned int num)
243{
244 if (num > ps_tsk_num) {
245 while (ps_tsk_num < num) {
246 if (create_power_saving_task())
247 return;
248 }
249 } else if (num < ps_tsk_num) {
250 while (ps_tsk_num > num)
251 destroy_power_saving_task();
252 }
253}
254
255static int acpi_pad_idle_cpus(unsigned int num_cpus)
256{
257 get_online_cpus();
258
259 num_cpus = min_t(unsigned int, num_cpus, num_online_cpus());
260 set_power_saving_task_num(num_cpus);
261
262 put_online_cpus();
263 return 0;
264}
265
266static uint32_t acpi_pad_idle_cpus_num(void)
267{
268 return ps_tsk_num;
269}
270
271static ssize_t acpi_pad_rrtime_store(struct device *dev,
272 struct device_attribute *attr, const char *buf, size_t count)
273{
274 unsigned long num;
275 if (strict_strtoul(buf, 0, &num))
276 return -EINVAL;
277 if (num < 1 || num >= 100)
278 return -EINVAL;
279 mutex_lock(&isolated_cpus_lock);
280 round_robin_time = num;
281 mutex_unlock(&isolated_cpus_lock);
282 return count;
283}
284
285static ssize_t acpi_pad_rrtime_show(struct device *dev,
286 struct device_attribute *attr, char *buf)
287{
288 return scnprintf(buf, PAGE_SIZE, "%d", round_robin_time);
289}
290static DEVICE_ATTR(rrtime, S_IRUGO|S_IWUSR,
291 acpi_pad_rrtime_show,
292 acpi_pad_rrtime_store);
293
294static ssize_t acpi_pad_idlepct_store(struct device *dev,
295 struct device_attribute *attr, const char *buf, size_t count)
296{
297 unsigned long num;
298 if (strict_strtoul(buf, 0, &num))
299 return -EINVAL;
300 if (num < 1 || num >= 100)
301 return -EINVAL;
302 mutex_lock(&isolated_cpus_lock);
303 idle_pct = num;
304 mutex_unlock(&isolated_cpus_lock);
305 return count;
306}
307
308static ssize_t acpi_pad_idlepct_show(struct device *dev,
309 struct device_attribute *attr, char *buf)
310{
311 return scnprintf(buf, PAGE_SIZE, "%d", idle_pct);
312}
313static DEVICE_ATTR(idlepct, S_IRUGO|S_IWUSR,
314 acpi_pad_idlepct_show,
315 acpi_pad_idlepct_store);
316
317static ssize_t acpi_pad_idlecpus_store(struct device *dev,
318 struct device_attribute *attr, const char *buf, size_t count)
319{
320 unsigned long num;
321 if (strict_strtoul(buf, 0, &num))
322 return -EINVAL;
323 mutex_lock(&isolated_cpus_lock);
324 acpi_pad_idle_cpus(num);
325 mutex_unlock(&isolated_cpus_lock);
326 return count;
327}
328
329static ssize_t acpi_pad_idlecpus_show(struct device *dev,
330 struct device_attribute *attr, char *buf)
331{
332 return cpumask_scnprintf(buf, PAGE_SIZE,
333 to_cpumask(pad_busy_cpus_bits));
334}
335static DEVICE_ATTR(idlecpus, S_IRUGO|S_IWUSR,
336 acpi_pad_idlecpus_show,
337 acpi_pad_idlecpus_store);
338
339static int acpi_pad_add_sysfs(struct acpi_device *device)
340{
341 int result;
342
343 result = device_create_file(&device->dev, &dev_attr_idlecpus);
344 if (result)
345 return -ENODEV;
346 result = device_create_file(&device->dev, &dev_attr_idlepct);
347 if (result) {
348 device_remove_file(&device->dev, &dev_attr_idlecpus);
349 return -ENODEV;
350 }
351 result = device_create_file(&device->dev, &dev_attr_rrtime);
352 if (result) {
353 device_remove_file(&device->dev, &dev_attr_idlecpus);
354 device_remove_file(&device->dev, &dev_attr_idlepct);
355 return -ENODEV;
356 }
357 return 0;
358}
359
360static void acpi_pad_remove_sysfs(struct acpi_device *device)
361{
362 device_remove_file(&device->dev, &dev_attr_idlecpus);
363 device_remove_file(&device->dev, &dev_attr_idlepct);
364 device_remove_file(&device->dev, &dev_attr_rrtime);
365}
366
367/* Query firmware how many CPUs should be idle */
368static int acpi_pad_pur(acpi_handle handle, int *num_cpus)
369{
370 struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
371 acpi_status status;
372 union acpi_object *package;
373 int rev, num, ret = -EINVAL;
374
375 status = acpi_evaluate_object(handle, "_PUR", NULL, &buffer);
376 if (ACPI_FAILURE(status))
377 return -EINVAL;
378 package = buffer.pointer;
379 if (package->type != ACPI_TYPE_PACKAGE || package->package.count != 2)
380 goto out;
381 rev = package->package.elements[0].integer.value;
382 num = package->package.elements[1].integer.value;
383 if (rev != 1)
384 goto out;
385 *num_cpus = num;
386 ret = 0;
387out:
388 kfree(buffer.pointer);
389 return ret;
390}
391
392/* Notify firmware how many CPUs are idle */
393static void acpi_pad_ost(acpi_handle handle, int stat,
394 uint32_t idle_cpus)
395{
396 union acpi_object params[3] = {
397 {.type = ACPI_TYPE_INTEGER,},
398 {.type = ACPI_TYPE_INTEGER,},
399 {.type = ACPI_TYPE_BUFFER,},
400 };
401 struct acpi_object_list arg_list = {3, params};
402
403 params[0].integer.value = ACPI_PROCESSOR_AGGREGATOR_NOTIFY;
404 params[1].integer.value = stat;
405 params[2].buffer.length = 4;
406 params[2].buffer.pointer = (void *)&idle_cpus;
407 acpi_evaluate_object(handle, "_OST", &arg_list, NULL);
408}
409
410static void acpi_pad_handle_notify(acpi_handle handle)
411{
412 int num_cpus, ret;
413 uint32_t idle_cpus;
414
415 mutex_lock(&isolated_cpus_lock);
416 if (acpi_pad_pur(handle, &num_cpus)) {
417 mutex_unlock(&isolated_cpus_lock);
418 return;
419 }
420 ret = acpi_pad_idle_cpus(num_cpus);
421 idle_cpus = acpi_pad_idle_cpus_num();
422 if (!ret)
423 acpi_pad_ost(handle, 0, idle_cpus);
424 else
425 acpi_pad_ost(handle, 1, 0);
426 mutex_unlock(&isolated_cpus_lock);
427}
428
429static void acpi_pad_notify(acpi_handle handle, u32 event,
430 void *data)
431{
432 struct acpi_device *device = data;
433
434 switch (event) {
435 case ACPI_PROCESSOR_AGGREGATOR_NOTIFY:
436 acpi_pad_handle_notify(handle);
437 acpi_bus_generate_proc_event(device, event, 0);
438 acpi_bus_generate_netlink_event(device->pnp.device_class,
439 dev_name(&device->dev), event, 0);
440 break;
441 default:
442 printk(KERN_WARNING"Unsupported event [0x%x]\n", event);
443 break;
444 }
445}
446
447static int acpi_pad_add(struct acpi_device *device)
448{
449 acpi_status status;
450
451 strcpy(acpi_device_name(device), ACPI_PROCESSOR_AGGREGATOR_DEVICE_NAME);
452 strcpy(acpi_device_class(device), ACPI_PROCESSOR_AGGREGATOR_CLASS);
453
454 if (acpi_pad_add_sysfs(device))
455 return -ENODEV;
456
457 status = acpi_install_notify_handler(device->handle,
458 ACPI_DEVICE_NOTIFY, acpi_pad_notify, device);
459 if (ACPI_FAILURE(status)) {
460 acpi_pad_remove_sysfs(device);
461 return -ENODEV;
462 }
463
464 return 0;
465}
466
467static int acpi_pad_remove(struct acpi_device *device,
468 int type)
469{
470 mutex_lock(&isolated_cpus_lock);
471 acpi_pad_idle_cpus(0);
472 mutex_unlock(&isolated_cpus_lock);
473
474 acpi_remove_notify_handler(device->handle,
475 ACPI_DEVICE_NOTIFY, acpi_pad_notify);
476 acpi_pad_remove_sysfs(device);
477 return 0;
478}
479
480static const struct acpi_device_id pad_device_ids[] = {
481 {"ACPI000C", 0},
482 {"", 0},
483};
484MODULE_DEVICE_TABLE(acpi, pad_device_ids);
485
486static struct acpi_driver acpi_pad_driver = {
487 .name = "processor_aggregator",
488 .class = ACPI_PROCESSOR_AGGREGATOR_CLASS,
489 .ids = pad_device_ids,
490 .ops = {
491 .add = acpi_pad_add,
492 .remove = acpi_pad_remove,
493 },
494};
495
496static int __init acpi_pad_init(void)
497{
498 power_saving_mwait_init();
499 if (power_saving_mwait_eax == 0)
500 return -EINVAL;
501
502 return acpi_bus_register_driver(&acpi_pad_driver);
503}
504
505static void __exit acpi_pad_exit(void)
506{
507 acpi_bus_unregister_driver(&acpi_pad_driver);
508}
509
510module_init(acpi_pad_init);
511module_exit(acpi_pad_exit);
512MODULE_AUTHOR("Shaohua Li<shaohua.li@intel.com>");
513MODULE_DESCRIPTION("ACPI Processor Aggregator Driver");
514MODULE_LICENSE("GPL");
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index 9335b87c5174..0c9c6a9a002c 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -251,6 +251,9 @@ int acpi_lid_open(void)
251 acpi_status status; 251 acpi_status status;
252 unsigned long long state; 252 unsigned long long state;
253 253
254 if (!lid_device)
255 return -ENODEV;
256
254 status = acpi_evaluate_integer(lid_device->handle, "_LID", NULL, 257 status = acpi_evaluate_integer(lid_device->handle, "_LID", NULL,
255 &state); 258 &state);
256 if (ACPI_FAILURE(status)) 259 if (ACPI_FAILURE(status))
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index 3a2cfefc71ab..7338b6a3e049 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -67,7 +67,7 @@ struct dock_station {
67 struct list_head dependent_devices; 67 struct list_head dependent_devices;
68 struct list_head hotplug_devices; 68 struct list_head hotplug_devices;
69 69
70 struct list_head sibiling; 70 struct list_head sibling;
71 struct platform_device *dock_device; 71 struct platform_device *dock_device;
72}; 72};
73static LIST_HEAD(dock_stations); 73static LIST_HEAD(dock_stations);
@@ -275,7 +275,7 @@ int is_dock_device(acpi_handle handle)
275 275
276 if (is_dock(handle)) 276 if (is_dock(handle))
277 return 1; 277 return 1;
278 list_for_each_entry(dock_station, &dock_stations, sibiling) { 278 list_for_each_entry(dock_station, &dock_stations, sibling) {
279 if (find_dock_dependent_device(dock_station, handle)) 279 if (find_dock_dependent_device(dock_station, handle))
280 return 1; 280 return 1;
281 } 281 }
@@ -619,7 +619,7 @@ register_hotplug_dock_device(acpi_handle handle, struct acpi_dock_ops *ops,
619 * make sure this handle is for a device dependent on the dock, 619 * make sure this handle is for a device dependent on the dock,
620 * this would include the dock station itself 620 * this would include the dock station itself
621 */ 621 */
622 list_for_each_entry(dock_station, &dock_stations, sibiling) { 622 list_for_each_entry(dock_station, &dock_stations, sibling) {
623 /* 623 /*
624 * An ATA bay can be in a dock and itself can be ejected 624 * An ATA bay can be in a dock and itself can be ejected
625 * seperately, so there are two 'dock stations' which need the 625 * seperately, so there are two 'dock stations' which need the
@@ -651,7 +651,7 @@ void unregister_hotplug_dock_device(acpi_handle handle)
651 if (!dock_station_count) 651 if (!dock_station_count)
652 return; 652 return;
653 653
654 list_for_each_entry(dock_station, &dock_stations, sibiling) { 654 list_for_each_entry(dock_station, &dock_stations, sibling) {
655 dd = find_dock_dependent_device(dock_station, handle); 655 dd = find_dock_dependent_device(dock_station, handle);
656 if (dd) 656 if (dd)
657 dock_del_hotplug_device(dock_station, dd); 657 dock_del_hotplug_device(dock_station, dd);
@@ -787,7 +787,7 @@ static int acpi_dock_notifier_call(struct notifier_block *this,
787 if (event != ACPI_NOTIFY_BUS_CHECK && event != ACPI_NOTIFY_DEVICE_CHECK 787 if (event != ACPI_NOTIFY_BUS_CHECK && event != ACPI_NOTIFY_DEVICE_CHECK
788 && event != ACPI_NOTIFY_EJECT_REQUEST) 788 && event != ACPI_NOTIFY_EJECT_REQUEST)
789 return 0; 789 return 0;
790 list_for_each_entry(dock_station, &dock_stations, sibiling) { 790 list_for_each_entry(dock_station, &dock_stations, sibling) {
791 if (dock_station->handle == handle) { 791 if (dock_station->handle == handle) {
792 struct dock_data *dock_data; 792 struct dock_data *dock_data;
793 793
@@ -958,7 +958,7 @@ static int dock_add(acpi_handle handle)
958 dock_station->last_dock_time = jiffies - HZ; 958 dock_station->last_dock_time = jiffies - HZ;
959 INIT_LIST_HEAD(&dock_station->dependent_devices); 959 INIT_LIST_HEAD(&dock_station->dependent_devices);
960 INIT_LIST_HEAD(&dock_station->hotplug_devices); 960 INIT_LIST_HEAD(&dock_station->hotplug_devices);
961 INIT_LIST_HEAD(&dock_station->sibiling); 961 INIT_LIST_HEAD(&dock_station->sibling);
962 spin_lock_init(&dock_station->dd_lock); 962 spin_lock_init(&dock_station->dd_lock);
963 mutex_init(&dock_station->hp_lock); 963 mutex_init(&dock_station->hp_lock);
964 ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list); 964 ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list);
@@ -1044,7 +1044,7 @@ static int dock_add(acpi_handle handle)
1044 add_dock_dependent_device(dock_station, dd); 1044 add_dock_dependent_device(dock_station, dd);
1045 1045
1046 dock_station_count++; 1046 dock_station_count++;
1047 list_add(&dock_station->sibiling, &dock_stations); 1047 list_add(&dock_station->sibling, &dock_stations);
1048 return 0; 1048 return 0;
1049 1049
1050dock_add_err_unregister: 1050dock_add_err_unregister:
@@ -1149,7 +1149,7 @@ static void __exit dock_exit(void)
1149 struct dock_station *tmp; 1149 struct dock_station *tmp;
1150 1150
1151 unregister_acpi_bus_notifier(&dock_acpi_notifier); 1151 unregister_acpi_bus_notifier(&dock_acpi_notifier);
1152 list_for_each_entry_safe(dock_station, tmp, &dock_stations, sibiling) 1152 list_for_each_entry_safe(dock_station, tmp, &dock_stations, sibling)
1153 dock_remove(dock_station); 1153 dock_remove(dock_station);
1154} 1154}
1155 1155
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index f70796081c4c..baef28c1e630 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -119,6 +119,8 @@ static struct acpi_ec {
119} *boot_ec, *first_ec; 119} *boot_ec, *first_ec;
120 120
121static int EC_FLAGS_MSI; /* Out-of-spec MSI controller */ 121static int EC_FLAGS_MSI; /* Out-of-spec MSI controller */
122static int EC_FLAGS_VALIDATE_ECDT; /* ASUStec ECDTs need to be validated */
123static int EC_FLAGS_SKIP_DSDT_SCAN; /* Not all BIOS survive early DSDT scan */
122 124
123/* -------------------------------------------------------------------------- 125/* --------------------------------------------------------------------------
124 Transaction Management 126 Transaction Management
@@ -232,10 +234,8 @@ static int ec_poll(struct acpi_ec *ec)
232 } 234 }
233 advance_transaction(ec, acpi_ec_read_status(ec)); 235 advance_transaction(ec, acpi_ec_read_status(ec));
234 } while (time_before(jiffies, delay)); 236 } while (time_before(jiffies, delay));
235 if (!ec->curr->irq_count || 237 if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF)
236 (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF))
237 break; 238 break;
238 /* try restart command if we get any false interrupts */
239 pr_debug(PREFIX "controller reset, restart transaction\n"); 239 pr_debug(PREFIX "controller reset, restart transaction\n");
240 spin_lock_irqsave(&ec->curr_lock, flags); 240 spin_lock_irqsave(&ec->curr_lock, flags);
241 start_transaction(ec); 241 start_transaction(ec);
@@ -899,6 +899,44 @@ static const struct acpi_device_id ec_device_ids[] = {
899 {"", 0}, 899 {"", 0},
900}; 900};
901 901
902/* Some BIOS do not survive early DSDT scan, skip it */
903static int ec_skip_dsdt_scan(const struct dmi_system_id *id)
904{
905 EC_FLAGS_SKIP_DSDT_SCAN = 1;
906 return 0;
907}
908
909/* ASUStek often supplies us with broken ECDT, validate it */
910static int ec_validate_ecdt(const struct dmi_system_id *id)
911{
912 EC_FLAGS_VALIDATE_ECDT = 1;
913 return 0;
914}
915
916/* MSI EC needs special treatment, enable it */
917static int ec_flag_msi(const struct dmi_system_id *id)
918{
919 EC_FLAGS_MSI = 1;
920 EC_FLAGS_VALIDATE_ECDT = 1;
921 return 0;
922}
923
924static struct dmi_system_id __initdata ec_dmi_table[] = {
925 {
926 ec_skip_dsdt_scan, "Compal JFL92", {
927 DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"),
928 DMI_MATCH(DMI_BOARD_NAME, "JFL92") }, NULL},
929 {
930 ec_flag_msi, "MSI hardware", {
931 DMI_MATCH(DMI_BIOS_VENDOR, "Micro-Star"),
932 DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-Star") }, NULL},
933 {
934 ec_validate_ecdt, "ASUS hardware", {
935 DMI_MATCH(DMI_BIOS_VENDOR, "ASUS") }, NULL},
936 {},
937};
938
939
902int __init acpi_ec_ecdt_probe(void) 940int __init acpi_ec_ecdt_probe(void)
903{ 941{
904 acpi_status status; 942 acpi_status status;
@@ -911,11 +949,7 @@ int __init acpi_ec_ecdt_probe(void)
911 /* 949 /*
912 * Generate a boot ec context 950 * Generate a boot ec context
913 */ 951 */
914 if (dmi_name_in_vendors("Micro-Star") || 952 dmi_check_system(ec_dmi_table);
915 dmi_name_in_vendors("Notebook")) {
916 pr_info(PREFIX "Enabling special treatment for EC from MSI.\n");
917 EC_FLAGS_MSI = 1;
918 }
919 status = acpi_get_table(ACPI_SIG_ECDT, 1, 953 status = acpi_get_table(ACPI_SIG_ECDT, 1,
920 (struct acpi_table_header **)&ecdt_ptr); 954 (struct acpi_table_header **)&ecdt_ptr);
921 if (ACPI_SUCCESS(status)) { 955 if (ACPI_SUCCESS(status)) {
@@ -926,7 +960,7 @@ int __init acpi_ec_ecdt_probe(void)
926 boot_ec->handle = ACPI_ROOT_OBJECT; 960 boot_ec->handle = ACPI_ROOT_OBJECT;
927 acpi_get_handle(ACPI_ROOT_OBJECT, ecdt_ptr->id, &boot_ec->handle); 961 acpi_get_handle(ACPI_ROOT_OBJECT, ecdt_ptr->id, &boot_ec->handle);
928 /* Don't trust ECDT, which comes from ASUSTek */ 962 /* Don't trust ECDT, which comes from ASUSTek */
929 if (!dmi_name_in_vendors("ASUS") && EC_FLAGS_MSI == 0) 963 if (!EC_FLAGS_VALIDATE_ECDT)
930 goto install; 964 goto install;
931 saved_ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL); 965 saved_ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL);
932 if (!saved_ec) 966 if (!saved_ec)
@@ -934,6 +968,10 @@ int __init acpi_ec_ecdt_probe(void)
934 memcpy(saved_ec, boot_ec, sizeof(struct acpi_ec)); 968 memcpy(saved_ec, boot_ec, sizeof(struct acpi_ec));
935 /* fall through */ 969 /* fall through */
936 } 970 }
971
972 if (EC_FLAGS_SKIP_DSDT_SCAN)
973 return -ENODEV;
974
937 /* This workaround is needed only on some broken machines, 975 /* This workaround is needed only on some broken machines,
938 * which require early EC, but fail to provide ECDT */ 976 * which require early EC, but fail to provide ECDT */
939 printk(KERN_DEBUG PREFIX "Look up EC in DSDT\n"); 977 printk(KERN_DEBUG PREFIX "Look up EC in DSDT\n");
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 31122214e0ec..1af808171d46 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -389,6 +389,17 @@ struct pci_dev *acpi_get_pci_dev(acpi_handle handle)
389 389
390 pbus = pdev->subordinate; 390 pbus = pdev->subordinate;
391 pci_dev_put(pdev); 391 pci_dev_put(pdev);
392
393 /*
394 * This function may be called for a non-PCI device that has a
395 * PCI parent (eg. a disk under a PCI SATA controller). In that
396 * case pdev->subordinate will be NULL for the parent.
397 */
398 if (!pbus) {
399 dev_dbg(&pdev->dev, "Not a PCI-to-PCI bridge\n");
400 pdev = NULL;
401 break;
402 }
392 } 403 }
393out: 404out:
394 list_for_each_entry_safe(node, tmp, &device_list, node) 405 list_for_each_entry_safe(node, tmp, &device_list, node)
diff --git a/drivers/acpi/proc.c b/drivers/acpi/proc.c
index d0d550d22a6d..f8b6f555ba52 100644
--- a/drivers/acpi/proc.c
+++ b/drivers/acpi/proc.c
@@ -398,6 +398,8 @@ acpi_system_write_wakeup_device(struct file *file,
398 398
399 if (len > 4) 399 if (len > 4)
400 len = 4; 400 len = 4;
401 if (len < 0)
402 return -EFAULT;
401 403
402 if (copy_from_user(strbuf, buffer, len)) 404 if (copy_from_user(strbuf, buffer, len))
403 return -EFAULT; 405 return -EFAULT;
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index c2d4d6e09364..c567b46dfa0f 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -863,13 +863,6 @@ static int acpi_processor_add(struct acpi_device *device)
863 goto err_remove_sysfs; 863 goto err_remove_sysfs;
864 } 864 }
865 865
866 if (pr->flags.throttling) {
867 printk(KERN_INFO PREFIX "%s [%s] (supports",
868 acpi_device_name(device), acpi_device_bid(device));
869 printk(" %d throttling states", pr->throttling.state_count);
870 printk(")\n");
871 }
872
873 return 0; 866 return 0;
874 867
875err_remove_sysfs: 868err_remove_sysfs:
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 468921bed22f..14a7481c97d7 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1052,6 +1052,8 @@ static void acpi_device_set_id(struct acpi_device *device)
1052 device->flags.bus_address = 1; 1052 device->flags.bus_address = 1;
1053 } 1053 }
1054 1054
1055 kfree(info);
1056
1055 /* 1057 /*
1056 * Some devices don't reliably have _HIDs & _CIDs, so add 1058 * Some devices don't reliably have _HIDs & _CIDs, so add
1057 * synthetic HIDs to make sure drivers can find them. 1059 * synthetic HIDs to make sure drivers can find them.
@@ -1325,13 +1327,8 @@ static int acpi_bus_scan(acpi_handle handle, struct acpi_bus_ops *ops,
1325 struct acpi_device **child) 1327 struct acpi_device **child)
1326{ 1328{
1327 acpi_status status; 1329 acpi_status status;
1328 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
1329 void *device = NULL; 1330 void *device = NULL;
1330 1331
1331 acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
1332 printk(KERN_INFO PREFIX "Enumerating devices from [%s]\n",
1333 (char *) buffer.pointer);
1334
1335 status = acpi_bus_check_add(handle, 0, ops, &device); 1332 status = acpi_bus_check_add(handle, 0, ops, &device);
1336 if (ACPI_SUCCESS(status)) 1333 if (ACPI_SUCCESS(status))
1337 acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, 1334 acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX,
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index a4fddb24476f..64e3c581b7a9 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -285,7 +285,7 @@ static int acpi_video_device_brightness_open_fs(struct inode *inode,
285 struct file *file); 285 struct file *file);
286static ssize_t acpi_video_device_write_brightness(struct file *file, 286static ssize_t acpi_video_device_write_brightness(struct file *file,
287 const char __user *buffer, size_t count, loff_t *data); 287 const char __user *buffer, size_t count, loff_t *data);
288static struct file_operations acpi_video_device_brightness_fops = { 288static const struct file_operations acpi_video_device_brightness_fops = {
289 .owner = THIS_MODULE, 289 .owner = THIS_MODULE,
290 .open = acpi_video_device_brightness_open_fs, 290 .open = acpi_video_device_brightness_open_fs,
291 .read = seq_read, 291 .read = seq_read,
@@ -1109,7 +1109,12 @@ static int acpi_video_bus_check(struct acpi_video_bus *video)
1109 */ 1109 */
1110 1110
1111 /* Does this device support video switching? */ 1111 /* Does this device support video switching? */
1112 if (video->cap._DOS) { 1112 if (video->cap._DOS || video->cap._DOD) {
1113 if (!video->cap._DOS) {
1114 printk(KERN_WARNING FW_BUG
1115 "ACPI(%s) defines _DOD but not _DOS\n",
1116 acpi_device_bid(video->device));
1117 }
1113 video->flags.multihead = 1; 1118 video->flags.multihead = 1;
1114 status = 0; 1119 status = 0;
1115 } 1120 }
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
index 7032f25da9b5..575593a8b4e6 100644
--- a/drivers/acpi/video_detect.c
+++ b/drivers/acpi/video_detect.c
@@ -84,7 +84,7 @@ long acpi_is_video_device(struct acpi_device *device)
84 return 0; 84 return 0;
85 85
86 /* Does this device able to support video switching ? */ 86 /* Does this device able to support video switching ? */
87 if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy)) && 87 if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy)) ||
88 ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS", &h_dummy))) 88 ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS", &h_dummy)))
89 video_caps |= ACPI_VIDEO_OUTPUT_SWITCHING; 89 video_caps |= ACPI_VIDEO_OUTPUT_SWITCHING;
90 90
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index acd1162712b1..b1a257746a19 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -122,6 +122,7 @@ enum {
122 HOST_VERSION = 0x10, /* AHCI spec. version compliancy */ 122 HOST_VERSION = 0x10, /* AHCI spec. version compliancy */
123 HOST_EM_LOC = 0x1c, /* Enclosure Management location */ 123 HOST_EM_LOC = 0x1c, /* Enclosure Management location */
124 HOST_EM_CTL = 0x20, /* Enclosure Management Control */ 124 HOST_EM_CTL = 0x20, /* Enclosure Management Control */
125 HOST_CAP2 = 0x24, /* host capabilities, extended */
125 126
126 /* HOST_CTL bits */ 127 /* HOST_CTL bits */
127 HOST_RESET = (1 << 0), /* reset controller; self-clear */ 128 HOST_RESET = (1 << 0), /* reset controller; self-clear */
@@ -129,16 +130,29 @@ enum {
129 HOST_AHCI_EN = (1 << 31), /* AHCI enabled */ 130 HOST_AHCI_EN = (1 << 31), /* AHCI enabled */
130 131
131 /* HOST_CAP bits */ 132 /* HOST_CAP bits */
133 HOST_CAP_SXS = (1 << 5), /* Supports External SATA */
132 HOST_CAP_EMS = (1 << 6), /* Enclosure Management support */ 134 HOST_CAP_EMS = (1 << 6), /* Enclosure Management support */
133 HOST_CAP_SSC = (1 << 14), /* Slumber capable */ 135 HOST_CAP_CCC = (1 << 7), /* Command Completion Coalescing */
136 HOST_CAP_PART = (1 << 13), /* Partial state capable */
137 HOST_CAP_SSC = (1 << 14), /* Slumber state capable */
138 HOST_CAP_PIO_MULTI = (1 << 15), /* PIO multiple DRQ support */
139 HOST_CAP_FBS = (1 << 16), /* FIS-based switching support */
134 HOST_CAP_PMP = (1 << 17), /* Port Multiplier support */ 140 HOST_CAP_PMP = (1 << 17), /* Port Multiplier support */
141 HOST_CAP_ONLY = (1 << 18), /* Supports AHCI mode only */
135 HOST_CAP_CLO = (1 << 24), /* Command List Override support */ 142 HOST_CAP_CLO = (1 << 24), /* Command List Override support */
143 HOST_CAP_LED = (1 << 25), /* Supports activity LED */
136 HOST_CAP_ALPM = (1 << 26), /* Aggressive Link PM support */ 144 HOST_CAP_ALPM = (1 << 26), /* Aggressive Link PM support */
137 HOST_CAP_SSS = (1 << 27), /* Staggered Spin-up */ 145 HOST_CAP_SSS = (1 << 27), /* Staggered Spin-up */
146 HOST_CAP_MPS = (1 << 28), /* Mechanical presence switch */
138 HOST_CAP_SNTF = (1 << 29), /* SNotification register */ 147 HOST_CAP_SNTF = (1 << 29), /* SNotification register */
139 HOST_CAP_NCQ = (1 << 30), /* Native Command Queueing */ 148 HOST_CAP_NCQ = (1 << 30), /* Native Command Queueing */
140 HOST_CAP_64 = (1 << 31), /* PCI DAC (64-bit DMA) support */ 149 HOST_CAP_64 = (1 << 31), /* PCI DAC (64-bit DMA) support */
141 150
151 /* HOST_CAP2 bits */
152 HOST_CAP2_BOH = (1 << 0), /* BIOS/OS handoff supported */
153 HOST_CAP2_NVMHCI = (1 << 1), /* NVMHCI supported */
154 HOST_CAP2_APST = (1 << 2), /* Automatic partial to slumber */
155
142 /* registers for each SATA port */ 156 /* registers for each SATA port */
143 PORT_LST_ADDR = 0x00, /* command list DMA addr */ 157 PORT_LST_ADDR = 0x00, /* command list DMA addr */
144 PORT_LST_ADDR_HI = 0x04, /* command list DMA addr hi */ 158 PORT_LST_ADDR_HI = 0x04, /* command list DMA addr hi */
@@ -267,8 +281,10 @@ struct ahci_em_priv {
267struct ahci_host_priv { 281struct ahci_host_priv {
268 unsigned int flags; /* AHCI_HFLAG_* */ 282 unsigned int flags; /* AHCI_HFLAG_* */
269 u32 cap; /* cap to use */ 283 u32 cap; /* cap to use */
284 u32 cap2; /* cap2 to use */
270 u32 port_map; /* port map to use */ 285 u32 port_map; /* port map to use */
271 u32 saved_cap; /* saved initial cap */ 286 u32 saved_cap; /* saved initial cap */
287 u32 saved_cap2; /* saved initial cap2 */
272 u32 saved_port_map; /* saved initial port_map */ 288 u32 saved_port_map; /* saved initial port_map */
273 u32 em_loc; /* enclosure management location */ 289 u32 em_loc; /* enclosure management location */
274}; 290};
@@ -331,12 +347,15 @@ static void ahci_init_sw_activity(struct ata_link *link);
331 347
332static ssize_t ahci_show_host_caps(struct device *dev, 348static ssize_t ahci_show_host_caps(struct device *dev,
333 struct device_attribute *attr, char *buf); 349 struct device_attribute *attr, char *buf);
350static ssize_t ahci_show_host_cap2(struct device *dev,
351 struct device_attribute *attr, char *buf);
334static ssize_t ahci_show_host_version(struct device *dev, 352static ssize_t ahci_show_host_version(struct device *dev,
335 struct device_attribute *attr, char *buf); 353 struct device_attribute *attr, char *buf);
336static ssize_t ahci_show_port_cmd(struct device *dev, 354static ssize_t ahci_show_port_cmd(struct device *dev,
337 struct device_attribute *attr, char *buf); 355 struct device_attribute *attr, char *buf);
338 356
339DEVICE_ATTR(ahci_host_caps, S_IRUGO, ahci_show_host_caps, NULL); 357DEVICE_ATTR(ahci_host_caps, S_IRUGO, ahci_show_host_caps, NULL);
358DEVICE_ATTR(ahci_host_cap2, S_IRUGO, ahci_show_host_cap2, NULL);
340DEVICE_ATTR(ahci_host_version, S_IRUGO, ahci_show_host_version, NULL); 359DEVICE_ATTR(ahci_host_version, S_IRUGO, ahci_show_host_version, NULL);
341DEVICE_ATTR(ahci_port_cmd, S_IRUGO, ahci_show_port_cmd, NULL); 360DEVICE_ATTR(ahci_port_cmd, S_IRUGO, ahci_show_port_cmd, NULL);
342 361
@@ -345,6 +364,7 @@ static struct device_attribute *ahci_shost_attrs[] = {
345 &dev_attr_em_message_type, 364 &dev_attr_em_message_type,
346 &dev_attr_em_message, 365 &dev_attr_em_message,
347 &dev_attr_ahci_host_caps, 366 &dev_attr_ahci_host_caps,
367 &dev_attr_ahci_host_cap2,
348 &dev_attr_ahci_host_version, 368 &dev_attr_ahci_host_version,
349 &dev_attr_ahci_port_cmd, 369 &dev_attr_ahci_port_cmd,
350 NULL 370 NULL
@@ -447,7 +467,8 @@ static const struct ata_port_info ahci_port_info[] = {
447 [board_ahci_sb600] = 467 [board_ahci_sb600] =
448 { 468 {
449 AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL | 469 AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL |
450 AHCI_HFLAG_NO_MSI | AHCI_HFLAG_SECT255), 470 AHCI_HFLAG_NO_MSI | AHCI_HFLAG_SECT255 |
471 AHCI_HFLAG_32BIT_ONLY),
451 .flags = AHCI_FLAG_COMMON, 472 .flags = AHCI_FLAG_COMMON,
452 .pio_mask = ATA_PIO4, 473 .pio_mask = ATA_PIO4,
453 .udma_mask = ATA_UDMA6, 474 .udma_mask = ATA_UDMA6,
@@ -732,6 +753,16 @@ static ssize_t ahci_show_host_caps(struct device *dev,
732 return sprintf(buf, "%x\n", hpriv->cap); 753 return sprintf(buf, "%x\n", hpriv->cap);
733} 754}
734 755
756static ssize_t ahci_show_host_cap2(struct device *dev,
757 struct device_attribute *attr, char *buf)
758{
759 struct Scsi_Host *shost = class_to_shost(dev);
760 struct ata_port *ap = ata_shost_to_port(shost);
761 struct ahci_host_priv *hpriv = ap->host->private_data;
762
763 return sprintf(buf, "%x\n", hpriv->cap2);
764}
765
735static ssize_t ahci_show_host_version(struct device *dev, 766static ssize_t ahci_show_host_version(struct device *dev,
736 struct device_attribute *attr, char *buf) 767 struct device_attribute *attr, char *buf)
737{ 768{
@@ -771,7 +802,7 @@ static void ahci_save_initial_config(struct pci_dev *pdev,
771 struct ahci_host_priv *hpriv) 802 struct ahci_host_priv *hpriv)
772{ 803{
773 void __iomem *mmio = pcim_iomap_table(pdev)[AHCI_PCI_BAR]; 804 void __iomem *mmio = pcim_iomap_table(pdev)[AHCI_PCI_BAR];
774 u32 cap, port_map; 805 u32 cap, cap2, vers, port_map;
775 int i; 806 int i;
776 int mv; 807 int mv;
777 808
@@ -784,6 +815,14 @@ static void ahci_save_initial_config(struct pci_dev *pdev,
784 hpriv->saved_cap = cap = readl(mmio + HOST_CAP); 815 hpriv->saved_cap = cap = readl(mmio + HOST_CAP);
785 hpriv->saved_port_map = port_map = readl(mmio + HOST_PORTS_IMPL); 816 hpriv->saved_port_map = port_map = readl(mmio + HOST_PORTS_IMPL);
786 817
818 /* CAP2 register is only defined for AHCI 1.2 and later */
819 vers = readl(mmio + HOST_VERSION);
820 if ((vers >> 16) > 1 ||
821 ((vers >> 16) == 1 && (vers & 0xFFFF) >= 0x200))
822 hpriv->saved_cap2 = cap2 = readl(mmio + HOST_CAP2);
823 else
824 hpriv->saved_cap2 = cap2 = 0;
825
787 /* some chips have errata preventing 64bit use */ 826 /* some chips have errata preventing 64bit use */
788 if ((cap & HOST_CAP_64) && (hpriv->flags & AHCI_HFLAG_32BIT_ONLY)) { 827 if ((cap & HOST_CAP_64) && (hpriv->flags & AHCI_HFLAG_32BIT_ONLY)) {
789 dev_printk(KERN_INFO, &pdev->dev, 828 dev_printk(KERN_INFO, &pdev->dev,
@@ -869,6 +908,7 @@ static void ahci_save_initial_config(struct pci_dev *pdev,
869 908
870 /* record values to use during operation */ 909 /* record values to use during operation */
871 hpriv->cap = cap; 910 hpriv->cap = cap;
911 hpriv->cap2 = cap2;
872 hpriv->port_map = port_map; 912 hpriv->port_map = port_map;
873} 913}
874 914
@@ -887,6 +927,8 @@ static void ahci_restore_initial_config(struct ata_host *host)
887 void __iomem *mmio = host->iomap[AHCI_PCI_BAR]; 927 void __iomem *mmio = host->iomap[AHCI_PCI_BAR];
888 928
889 writel(hpriv->saved_cap, mmio + HOST_CAP); 929 writel(hpriv->saved_cap, mmio + HOST_CAP);
930 if (hpriv->saved_cap2)
931 writel(hpriv->saved_cap2, mmio + HOST_CAP2);
890 writel(hpriv->saved_port_map, mmio + HOST_PORTS_IMPL); 932 writel(hpriv->saved_port_map, mmio + HOST_PORTS_IMPL);
891 (void) readl(mmio + HOST_PORTS_IMPL); /* flush */ 933 (void) readl(mmio + HOST_PORTS_IMPL); /* flush */
892} 934}
@@ -2534,13 +2576,14 @@ static void ahci_print_info(struct ata_host *host)
2534 struct ahci_host_priv *hpriv = host->private_data; 2576 struct ahci_host_priv *hpriv = host->private_data;
2535 struct pci_dev *pdev = to_pci_dev(host->dev); 2577 struct pci_dev *pdev = to_pci_dev(host->dev);
2536 void __iomem *mmio = host->iomap[AHCI_PCI_BAR]; 2578 void __iomem *mmio = host->iomap[AHCI_PCI_BAR];
2537 u32 vers, cap, impl, speed; 2579 u32 vers, cap, cap2, impl, speed;
2538 const char *speed_s; 2580 const char *speed_s;
2539 u16 cc; 2581 u16 cc;
2540 const char *scc_s; 2582 const char *scc_s;
2541 2583
2542 vers = readl(mmio + HOST_VERSION); 2584 vers = readl(mmio + HOST_VERSION);
2543 cap = hpriv->cap; 2585 cap = hpriv->cap;
2586 cap2 = hpriv->cap2;
2544 impl = hpriv->port_map; 2587 impl = hpriv->port_map;
2545 2588
2546 speed = (cap >> 20) & 0xf; 2589 speed = (cap >> 20) & 0xf;
@@ -2583,25 +2626,29 @@ static void ahci_print_info(struct ata_host *host)
2583 "flags: " 2626 "flags: "
2584 "%s%s%s%s%s%s%s" 2627 "%s%s%s%s%s%s%s"
2585 "%s%s%s%s%s%s%s" 2628 "%s%s%s%s%s%s%s"
2586 "%s\n" 2629 "%s%s%s%s%s%s\n"
2587 , 2630 ,
2588 2631
2589 cap & (1 << 31) ? "64bit " : "", 2632 cap & HOST_CAP_64 ? "64bit " : "",
2590 cap & (1 << 30) ? "ncq " : "", 2633 cap & HOST_CAP_NCQ ? "ncq " : "",
2591 cap & (1 << 29) ? "sntf " : "", 2634 cap & HOST_CAP_SNTF ? "sntf " : "",
2592 cap & (1 << 28) ? "ilck " : "", 2635 cap & HOST_CAP_MPS ? "ilck " : "",
2593 cap & (1 << 27) ? "stag " : "", 2636 cap & HOST_CAP_SSS ? "stag " : "",
2594 cap & (1 << 26) ? "pm " : "", 2637 cap & HOST_CAP_ALPM ? "pm " : "",
2595 cap & (1 << 25) ? "led " : "", 2638 cap & HOST_CAP_LED ? "led " : "",
2596 2639 cap & HOST_CAP_CLO ? "clo " : "",
2597 cap & (1 << 24) ? "clo " : "", 2640 cap & HOST_CAP_ONLY ? "only " : "",
2598 cap & (1 << 19) ? "nz " : "", 2641 cap & HOST_CAP_PMP ? "pmp " : "",
2599 cap & (1 << 18) ? "only " : "", 2642 cap & HOST_CAP_FBS ? "fbs " : "",
2600 cap & (1 << 17) ? "pmp " : "", 2643 cap & HOST_CAP_PIO_MULTI ? "pio " : "",
2601 cap & (1 << 15) ? "pio " : "", 2644 cap & HOST_CAP_SSC ? "slum " : "",
2602 cap & (1 << 14) ? "slum " : "", 2645 cap & HOST_CAP_PART ? "part " : "",
2603 cap & (1 << 13) ? "part " : "", 2646 cap & HOST_CAP_CCC ? "ccc " : "",
2604 cap & (1 << 6) ? "ems ": "" 2647 cap & HOST_CAP_EMS ? "ems " : "",
2648 cap & HOST_CAP_SXS ? "sxs " : "",
2649 cap2 & HOST_CAP2_APST ? "apst " : "",
2650 cap2 & HOST_CAP2_NVMHCI ? "nvmp " : "",
2651 cap2 & HOST_CAP2_BOH ? "boh " : ""
2605 ); 2652 );
2606} 2653}
2607 2654
@@ -2650,17 +2697,15 @@ static void ahci_p5wdh_workaround(struct ata_host *host)
2650 } 2697 }
2651} 2698}
2652 2699
2653/* 2700/* only some SB600 ahci controllers can do 64bit DMA */
2654 * SB600 ahci controller on certain boards can't do 64bit DMA with 2701static bool ahci_sb600_enable_64bit(struct pci_dev *pdev)
2655 * older BIOS.
2656 */
2657static bool ahci_sb600_32bit_only(struct pci_dev *pdev)
2658{ 2702{
2659 static const struct dmi_system_id sysids[] = { 2703 static const struct dmi_system_id sysids[] = {
2660 /* 2704 /*
2661 * The oldest version known to be broken is 0901 and 2705 * The oldest version known to be broken is 0901 and
2662 * working is 1501 which was released on 2007-10-26. 2706 * working is 1501 which was released on 2007-10-26.
2663 * Force 32bit DMA on anything older than 1501. 2707 * Enable 64bit DMA on 1501 and anything newer.
2708 *
2664 * Please read bko#9412 for more info. 2709 * Please read bko#9412 for more info.
2665 */ 2710 */
2666 { 2711 {
@@ -2672,48 +2717,29 @@ static bool ahci_sb600_32bit_only(struct pci_dev *pdev)
2672 }, 2717 },
2673 .driver_data = "20071026", /* yyyymmdd */ 2718 .driver_data = "20071026", /* yyyymmdd */
2674 }, 2719 },
2675 /*
2676 * It's yet unknown whether more recent BIOS fixes the
2677 * problem. Blacklist the whole board for the time
2678 * being. Please read the following thread for more
2679 * info.
2680 *
2681 * http://thread.gmane.org/gmane.linux.ide/42326
2682 */
2683 {
2684 .ident = "Gigabyte GA-MA69VM-S2",
2685 .matches = {
2686 DMI_MATCH(DMI_BOARD_VENDOR,
2687 "Gigabyte Technology Co., Ltd."),
2688 DMI_MATCH(DMI_BOARD_NAME, "GA-MA69VM-S2"),
2689 },
2690 },
2691 { } 2720 { }
2692 }; 2721 };
2693 const struct dmi_system_id *match; 2722 const struct dmi_system_id *match;
2723 int year, month, date;
2724 char buf[9];
2694 2725
2695 match = dmi_first_match(sysids); 2726 match = dmi_first_match(sysids);
2696 if (pdev->bus->number != 0 || pdev->devfn != PCI_DEVFN(0x12, 0) || 2727 if (pdev->bus->number != 0 || pdev->devfn != PCI_DEVFN(0x12, 0) ||
2697 !match) 2728 !match)
2698 return false; 2729 return false;
2699 2730
2700 if (match->driver_data) { 2731 dmi_get_date(DMI_BIOS_DATE, &year, &month, &date);
2701 int year, month, date; 2732 snprintf(buf, sizeof(buf), "%04d%02d%02d", year, month, date);
2702 char buf[9];
2703
2704 dmi_get_date(DMI_BIOS_DATE, &year, &month, &date);
2705 snprintf(buf, sizeof(buf), "%04d%02d%02d", year, month, date);
2706
2707 if (strcmp(buf, match->driver_data) >= 0)
2708 return false;
2709 2733
2734 if (strcmp(buf, match->driver_data) >= 0) {
2735 dev_printk(KERN_WARNING, &pdev->dev, "%s: enabling 64bit DMA\n",
2736 match->ident);
2737 return true;
2738 } else {
2710 dev_printk(KERN_WARNING, &pdev->dev, "%s: BIOS too old, " 2739 dev_printk(KERN_WARNING, &pdev->dev, "%s: BIOS too old, "
2711 "forcing 32bit DMA, update BIOS\n", match->ident); 2740 "forcing 32bit DMA, update BIOS\n", match->ident);
2712 } else 2741 return false;
2713 dev_printk(KERN_WARNING, &pdev->dev, "%s: this board can't " 2742 }
2714 "do 64bit DMA, forcing 32bit\n", match->ident);
2715
2716 return true;
2717} 2743}
2718 2744
2719static bool ahci_broken_system_poweroff(struct pci_dev *pdev) 2745static bool ahci_broken_system_poweroff(struct pci_dev *pdev)
@@ -2858,6 +2884,55 @@ static bool ahci_broken_online(struct pci_dev *pdev)
2858 return pdev->bus->number == (val >> 8) && pdev->devfn == (val & 0xff); 2884 return pdev->bus->number == (val >> 8) && pdev->devfn == (val & 0xff);
2859} 2885}
2860 2886
2887#ifdef CONFIG_ATA_ACPI
2888static void ahci_gtf_filter_workaround(struct ata_host *host)
2889{
2890 static const struct dmi_system_id sysids[] = {
2891 /*
2892 * Aspire 3810T issues a bunch of SATA enable commands
2893 * via _GTF including an invalid one and one which is
2894 * rejected by the device. Among the successful ones
2895 * is FPDMA non-zero offset enable which when enabled
2896 * only on the drive side leads to NCQ command
2897 * failures. Filter it out.
2898 */
2899 {
2900 .ident = "Aspire 3810T",
2901 .matches = {
2902 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
2903 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3810T"),
2904 },
2905 .driver_data = (void *)ATA_ACPI_FILTER_FPDMA_OFFSET,
2906 },
2907 { }
2908 };
2909 const struct dmi_system_id *dmi = dmi_first_match(sysids);
2910 unsigned int filter;
2911 int i;
2912
2913 if (!dmi)
2914 return;
2915
2916 filter = (unsigned long)dmi->driver_data;
2917 dev_printk(KERN_INFO, host->dev,
2918 "applying extra ACPI _GTF filter 0x%x for %s\n",
2919 filter, dmi->ident);
2920
2921 for (i = 0; i < host->n_ports; i++) {
2922 struct ata_port *ap = host->ports[i];
2923 struct ata_link *link;
2924 struct ata_device *dev;
2925
2926 ata_for_each_link(link, ap, EDGE)
2927 ata_for_each_dev(dev, link, ALL)
2928 dev->gtf_filter |= filter;
2929 }
2930}
2931#else
2932static inline void ahci_gtf_filter_workaround(struct ata_host *host)
2933{}
2934#endif
2935
2861static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) 2936static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
2862{ 2937{
2863 static int printed_version; 2938 static int printed_version;
@@ -2926,9 +3001,9 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
2926 if (board_id == board_ahci_sb700 && pdev->revision >= 0x40) 3001 if (board_id == board_ahci_sb700 && pdev->revision >= 0x40)
2927 hpriv->flags &= ~AHCI_HFLAG_IGN_SERR_INTERNAL; 3002 hpriv->flags &= ~AHCI_HFLAG_IGN_SERR_INTERNAL;
2928 3003
2929 /* apply sb600 32bit only quirk */ 3004 /* only some SB600s can do 64bit DMA */
2930 if (ahci_sb600_32bit_only(pdev)) 3005 if (ahci_sb600_enable_64bit(pdev))
2931 hpriv->flags |= AHCI_HFLAG_32BIT_ONLY; 3006 hpriv->flags &= ~AHCI_HFLAG_32BIT_ONLY;
2932 3007
2933 if ((hpriv->flags & AHCI_HFLAG_NO_MSI) || pci_enable_msi(pdev)) 3008 if ((hpriv->flags & AHCI_HFLAG_NO_MSI) || pci_enable_msi(pdev))
2934 pci_intx(pdev, 1); 3009 pci_intx(pdev, 1);
@@ -3023,6 +3098,9 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
3023 /* apply workaround for ASUS P5W DH Deluxe mainboard */ 3098 /* apply workaround for ASUS P5W DH Deluxe mainboard */
3024 ahci_p5wdh_workaround(host); 3099 ahci_p5wdh_workaround(host);
3025 3100
3101 /* apply gtf filter quirk */
3102 ahci_gtf_filter_workaround(host);
3103
3026 /* initialize adapter */ 3104 /* initialize adapter */
3027 rc = ahci_configure_dma_masks(pdev, hpriv->cap & HOST_CAP_64); 3105 rc = ahci_configure_dma_masks(pdev, hpriv->cap & HOST_CAP_64);
3028 if (rc) 3106 if (rc)
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c
index 01964b6e6f6b..b0882cddfd4c 100644
--- a/drivers/ata/libata-acpi.c
+++ b/drivers/ata/libata-acpi.c
@@ -20,19 +20,9 @@
20 20
21#include <acpi/acpi_bus.h> 21#include <acpi/acpi_bus.h>
22 22
23enum { 23unsigned int ata_acpi_gtf_filter = ATA_ACPI_FILTER_DEFAULT;
24 ATA_ACPI_FILTER_SETXFER = 1 << 0,
25 ATA_ACPI_FILTER_LOCK = 1 << 1,
26 ATA_ACPI_FILTER_DIPM = 1 << 2,
27
28 ATA_ACPI_FILTER_DEFAULT = ATA_ACPI_FILTER_SETXFER |
29 ATA_ACPI_FILTER_LOCK |
30 ATA_ACPI_FILTER_DIPM,
31};
32
33static unsigned int ata_acpi_gtf_filter = ATA_ACPI_FILTER_DEFAULT;
34module_param_named(acpi_gtf_filter, ata_acpi_gtf_filter, int, 0644); 24module_param_named(acpi_gtf_filter, ata_acpi_gtf_filter, int, 0644);
35MODULE_PARM_DESC(acpi_gtf_filter, "filter mask for ACPI _GTF commands, set to filter out (0x1=set xfermode, 0x2=lock/freeze lock, 0x4=DIPM)"); 25MODULE_PARM_DESC(acpi_gtf_filter, "filter mask for ACPI _GTF commands, set to filter out (0x1=set xfermode, 0x2=lock/freeze lock, 0x4=DIPM, 0x8=FPDMA non-zero offset, 0x10=FPDMA DMA Setup FIS auto-activate)");
36 26
37#define NO_PORT_MULT 0xffff 27#define NO_PORT_MULT 0xffff
38#define SATA_ADR(root, pmp) (((root) << 16) | (pmp)) 28#define SATA_ADR(root, pmp) (((root) << 16) | (pmp))
@@ -613,10 +603,11 @@ static void ata_acpi_gtf_to_tf(struct ata_device *dev,
613 tf->command = gtf->tf[6]; /* 0x1f7 */ 603 tf->command = gtf->tf[6]; /* 0x1f7 */
614} 604}
615 605
616static int ata_acpi_filter_tf(const struct ata_taskfile *tf, 606static int ata_acpi_filter_tf(struct ata_device *dev,
607 const struct ata_taskfile *tf,
617 const struct ata_taskfile *ptf) 608 const struct ata_taskfile *ptf)
618{ 609{
619 if (ata_acpi_gtf_filter & ATA_ACPI_FILTER_SETXFER) { 610 if (dev->gtf_filter & ATA_ACPI_FILTER_SETXFER) {
620 /* libata doesn't use ACPI to configure transfer mode. 611 /* libata doesn't use ACPI to configure transfer mode.
621 * It will only confuse device configuration. Skip. 612 * It will only confuse device configuration. Skip.
622 */ 613 */
@@ -625,7 +616,7 @@ static int ata_acpi_filter_tf(const struct ata_taskfile *tf,
625 return 1; 616 return 1;
626 } 617 }
627 618
628 if (ata_acpi_gtf_filter & ATA_ACPI_FILTER_LOCK) { 619 if (dev->gtf_filter & ATA_ACPI_FILTER_LOCK) {
629 /* BIOS writers, sorry but we don't wanna lock 620 /* BIOS writers, sorry but we don't wanna lock
630 * features unless the user explicitly said so. 621 * features unless the user explicitly said so.
631 */ 622 */
@@ -647,12 +638,23 @@ static int ata_acpi_filter_tf(const struct ata_taskfile *tf,
647 return 1; 638 return 1;
648 } 639 }
649 640
650 if (ata_acpi_gtf_filter & ATA_ACPI_FILTER_DIPM) { 641 if (tf->command == ATA_CMD_SET_FEATURES &&
642 tf->feature == SETFEATURES_SATA_ENABLE) {
651 /* inhibit enabling DIPM */ 643 /* inhibit enabling DIPM */
652 if (tf->command == ATA_CMD_SET_FEATURES && 644 if (dev->gtf_filter & ATA_ACPI_FILTER_DIPM &&
653 tf->feature == SETFEATURES_SATA_ENABLE &&
654 tf->nsect == SATA_DIPM) 645 tf->nsect == SATA_DIPM)
655 return 1; 646 return 1;
647
648 /* inhibit FPDMA non-zero offset */
649 if (dev->gtf_filter & ATA_ACPI_FILTER_FPDMA_OFFSET &&
650 (tf->nsect == SATA_FPDMA_OFFSET ||
651 tf->nsect == SATA_FPDMA_IN_ORDER))
652 return 1;
653
654 /* inhibit FPDMA auto activation */
655 if (dev->gtf_filter & ATA_ACPI_FILTER_FPDMA_AA &&
656 tf->nsect == SATA_FPDMA_AA)
657 return 1;
656 } 658 }
657 659
658 return 0; 660 return 0;
@@ -704,7 +706,7 @@ static int ata_acpi_run_tf(struct ata_device *dev,
704 pptf = &ptf; 706 pptf = &ptf;
705 } 707 }
706 708
707 if (!ata_acpi_filter_tf(&tf, pptf)) { 709 if (!ata_acpi_filter_tf(dev, &tf, pptf)) {
708 rtf = tf; 710 rtf = tf;
709 err_mask = ata_exec_internal(dev, &rtf, NULL, 711 err_mask = ata_exec_internal(dev, &rtf, NULL,
710 DMA_NONE, NULL, 0, 0); 712 DMA_NONE, NULL, 0, 0);
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 0ddaf43d68c6..b525a0981348 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -5591,6 +5591,9 @@ void ata_link_init(struct ata_port *ap, struct ata_link *link, int pmp)
5591 5591
5592 dev->link = link; 5592 dev->link = link;
5593 dev->devno = dev - link->device; 5593 dev->devno = dev - link->device;
5594#ifdef CONFIG_ATA_ACPI
5595 dev->gtf_filter = ata_acpi_gtf_filter;
5596#endif
5594 ata_dev_init(dev); 5597 ata_dev_init(dev);
5595 } 5598 }
5596} 5599}
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index a04488f0de88..0a97822da211 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -2667,14 +2667,14 @@ int ata_eh_reset(struct ata_link *link, int classify,
2667 dev->pio_mode = XFER_PIO_0; 2667 dev->pio_mode = XFER_PIO_0;
2668 dev->flags &= ~ATA_DFLAG_SLEEPING; 2668 dev->flags &= ~ATA_DFLAG_SLEEPING;
2669 2669
2670 if (!ata_phys_link_offline(ata_dev_phys_link(dev))) { 2670 if (ata_phys_link_offline(ata_dev_phys_link(dev)))
2671 /* apply class override */ 2671 continue;
2672 if (lflags & ATA_LFLAG_ASSUME_ATA) 2672
2673 classes[dev->devno] = ATA_DEV_ATA; 2673 /* apply class override */
2674 else if (lflags & ATA_LFLAG_ASSUME_SEMB) 2674 if (lflags & ATA_LFLAG_ASSUME_ATA)
2675 classes[dev->devno] = ATA_DEV_SEMB_UNSUP; 2675 classes[dev->devno] = ATA_DEV_ATA;
2676 } else 2676 else if (lflags & ATA_LFLAG_ASSUME_SEMB)
2677 classes[dev->devno] = ATA_DEV_NONE; 2677 classes[dev->devno] = ATA_DEV_SEMB_UNSUP;
2678 } 2678 }
2679 2679
2680 /* record current link speed */ 2680 /* record current link speed */
@@ -2713,34 +2713,48 @@ int ata_eh_reset(struct ata_link *link, int classify,
2713 ap->pflags &= ~ATA_PFLAG_EH_PENDING; 2713 ap->pflags &= ~ATA_PFLAG_EH_PENDING;
2714 spin_unlock_irqrestore(link->ap->lock, flags); 2714 spin_unlock_irqrestore(link->ap->lock, flags);
2715 2715
2716 /* Make sure onlineness and classification result correspond. 2716 /*
2717 * Make sure onlineness and classification result correspond.
2717 * Hotplug could have happened during reset and some 2718 * Hotplug could have happened during reset and some
2718 * controllers fail to wait while a drive is spinning up after 2719 * controllers fail to wait while a drive is spinning up after
2719 * being hotplugged causing misdetection. By cross checking 2720 * being hotplugged causing misdetection. By cross checking
2720 * link onlineness and classification result, those conditions 2721 * link on/offlineness and classification result, those
2721 * can be reliably detected and retried. 2722 * conditions can be reliably detected and retried.
2722 */ 2723 */
2723 nr_unknown = 0; 2724 nr_unknown = 0;
2724 ata_for_each_dev(dev, link, ALL) { 2725 ata_for_each_dev(dev, link, ALL) {
2725 /* convert all ATA_DEV_UNKNOWN to ATA_DEV_NONE */ 2726 if (ata_phys_link_online(ata_dev_phys_link(dev))) {
2726 if (classes[dev->devno] == ATA_DEV_UNKNOWN) { 2727 if (classes[dev->devno] == ATA_DEV_UNKNOWN) {
2727 classes[dev->devno] = ATA_DEV_NONE; 2728 ata_dev_printk(dev, KERN_DEBUG, "link online "
2728 if (ata_phys_link_online(ata_dev_phys_link(dev))) 2729 "but device misclassifed\n");
2730 classes[dev->devno] = ATA_DEV_NONE;
2729 nr_unknown++; 2731 nr_unknown++;
2732 }
2733 } else if (ata_phys_link_offline(ata_dev_phys_link(dev))) {
2734 if (ata_class_enabled(classes[dev->devno]))
2735 ata_dev_printk(dev, KERN_DEBUG, "link offline, "
2736 "clearing class %d to NONE\n",
2737 classes[dev->devno]);
2738 classes[dev->devno] = ATA_DEV_NONE;
2739 } else if (classes[dev->devno] == ATA_DEV_UNKNOWN) {
2740 ata_dev_printk(dev, KERN_DEBUG, "link status unknown, "
2741 "clearing UNKNOWN to NONE\n");
2742 classes[dev->devno] = ATA_DEV_NONE;
2730 } 2743 }
2731 } 2744 }
2732 2745
2733 if (classify && nr_unknown) { 2746 if (classify && nr_unknown) {
2734 if (try < max_tries) { 2747 if (try < max_tries) {
2735 ata_link_printk(link, KERN_WARNING, "link online but " 2748 ata_link_printk(link, KERN_WARNING, "link online but "
2736 "device misclassified, retrying\n"); 2749 "%d devices misclassified, retrying\n",
2750 nr_unknown);
2737 failed_link = link; 2751 failed_link = link;
2738 rc = -EAGAIN; 2752 rc = -EAGAIN;
2739 goto fail; 2753 goto fail;
2740 } 2754 }
2741 ata_link_printk(link, KERN_WARNING, 2755 ata_link_printk(link, KERN_WARNING,
2742 "link online but device misclassified, " 2756 "link online but %d devices misclassified, "
2743 "device detection might fail\n"); 2757 "device detection might fail\n", nr_unknown);
2744 } 2758 }
2745 2759
2746 /* reset successful, schedule revalidation */ 2760 /* reset successful, schedule revalidation */
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index be8e2628f82c..823e63096362 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -118,6 +118,8 @@ extern void ata_lpm_schedule(struct ata_port *ap, enum link_pm);
118 118
119/* libata-acpi.c */ 119/* libata-acpi.c */
120#ifdef CONFIG_ATA_ACPI 120#ifdef CONFIG_ATA_ACPI
121extern unsigned int ata_acpi_gtf_filter;
122
121extern void ata_acpi_associate_sata_port(struct ata_port *ap); 123extern void ata_acpi_associate_sata_port(struct ata_port *ap);
122extern void ata_acpi_associate(struct ata_host *host); 124extern void ata_acpi_associate(struct ata_host *host);
123extern void ata_acpi_dissociate(struct ata_host *host); 125extern void ata_acpi_dissociate(struct ata_host *host);
diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c
index fc9c5d6d7d80..1432dc9d0ab8 100644
--- a/drivers/ata/pata_ali.c
+++ b/drivers/ata/pata_ali.c
@@ -290,7 +290,7 @@ static void ali_warn_atapi_dma(struct ata_device *adev)
290 290
291 if (print_info && adev->class == ATA_DEV_ATAPI && !ali_atapi_dma) { 291 if (print_info && adev->class == ATA_DEV_ATAPI && !ali_atapi_dma) {
292 ata_dev_printk(adev, KERN_WARNING, 292 ata_dev_printk(adev, KERN_WARNING,
293 "WARNING: ATAPI DMA disabled for reliablity issues. It can be enabled\n"); 293 "WARNING: ATAPI DMA disabled for reliability issues. It can be enabled\n");
294 ata_dev_printk(adev, KERN_WARNING, 294 ata_dev_printk(adev, KERN_WARNING,
295 "WARNING: via pata_ali.atapi_dma modparam or corresponding sysfs node.\n"); 295 "WARNING: via pata_ali.atapi_dma modparam or corresponding sysfs node.\n");
296 } 296 }
diff --git a/drivers/ata/pata_atp867x.c b/drivers/ata/pata_atp867x.c
index 7990de925d2e..6fe7ded40c6a 100644
--- a/drivers/ata/pata_atp867x.c
+++ b/drivers/ata/pata_atp867x.c
@@ -118,20 +118,13 @@ struct atp867x_priv {
118 int pci66mhz; 118 int pci66mhz;
119}; 119};
120 120
121static inline u8 atp867x_speed_to_mode(u8 speed)
122{
123 return speed - XFER_UDMA_0 + 1;
124}
125
126static void atp867x_set_dmamode(struct ata_port *ap, struct ata_device *adev) 121static void atp867x_set_dmamode(struct ata_port *ap, struct ata_device *adev)
127{ 122{
128 struct pci_dev *pdev = to_pci_dev(ap->host->dev); 123 struct pci_dev *pdev = to_pci_dev(ap->host->dev);
129 struct atp867x_priv *dp = ap->private_data; 124 struct atp867x_priv *dp = ap->private_data;
130 u8 speed = adev->dma_mode; 125 u8 speed = adev->dma_mode;
131 u8 b; 126 u8 b;
132 u8 mode; 127 u8 mode = speed - XFER_UDMA_0 + 1;
133
134 mode = atp867x_speed_to_mode(speed);
135 128
136 /* 129 /*
137 * Doc 6.6.9: decrease the udma mode value by 1 for safer UDMA speed 130 * Doc 6.6.9: decrease the udma mode value by 1 for safer UDMA speed
@@ -156,25 +149,38 @@ static void atp867x_set_dmamode(struct ata_port *ap, struct ata_device *adev)
156 iowrite8(b, dp->dma_mode); 149 iowrite8(b, dp->dma_mode);
157} 150}
158 151
159static int atp867x_get_active_clocks_shifted(unsigned int clk) 152static int atp867x_get_active_clocks_shifted(struct ata_port *ap,
153 unsigned int clk)
160{ 154{
155 struct atp867x_priv *dp = ap->private_data;
161 unsigned char clocks = clk; 156 unsigned char clocks = clk;
162 157
158 /*
159 * Doc 6.6.9: increase the clock value by 1 for safer PIO speed
160 * on 66MHz bus
161 */
162 if (dp->pci66mhz)
163 clocks++;
164
163 switch (clocks) { 165 switch (clocks) {
164 case 0: 166 case 0:
165 clocks = 1; 167 clocks = 1;
166 break; 168 break;
167 case 1 ... 7: 169 case 1 ... 6:
168 break;
169 case 8 ... 12:
170 clocks = 7;
171 break; 170 break;
172 default: 171 default:
173 printk(KERN_WARNING "ATP867X: active %dclk is invalid. " 172 printk(KERN_WARNING "ATP867X: active %dclk is invalid. "
174 "Using default 8clk.\n", clk); 173 "Using 12clk.\n", clk);
175 clocks = 0; /* 8 clk */ 174 case 9 ... 12:
175 clocks = 7; /* 12 clk */
176 break; 176 break;
177 case 7:
178 case 8: /* default 8 clk */
179 clocks = 0;
180 goto active_clock_shift_done;
177 } 181 }
182
183active_clock_shift_done:
178 return clocks << ATP867X_IO_PIOSPD_ACTIVE_SHIFT; 184 return clocks << ATP867X_IO_PIOSPD_ACTIVE_SHIFT;
179} 185}
180 186
@@ -188,20 +194,20 @@ static int atp867x_get_recover_clocks_shifted(unsigned int clk)
188 break; 194 break;
189 case 1 ... 11: 195 case 1 ... 11:
190 break; 196 break;
191 case 12: 197 case 13:
192 clocks = 0; 198 case 14:
193 break; 199 --clocks; /* by the spec */
194 case 13: case 14:
195 --clocks;
196 break; 200 break;
197 case 15: 201 case 15:
198 break; 202 break;
199 default: 203 default:
200 printk(KERN_WARNING "ATP867X: recover %dclk is invalid. " 204 printk(KERN_WARNING "ATP867X: recover %dclk is invalid. "
201 "Using default 15clk.\n", clk); 205 "Using default 12clk.\n", clk);
202 clocks = 0; /* 12 clk */ 206 case 12: /* default 12 clk */
207 clocks = 0;
203 break; 208 break;
204 } 209 }
210
205 return clocks << ATP867X_IO_PIOSPD_RECOVER_SHIFT; 211 return clocks << ATP867X_IO_PIOSPD_RECOVER_SHIFT;
206} 212}
207 213
@@ -230,25 +236,38 @@ static void atp867x_set_piomode(struct ata_port *ap, struct ata_device *adev)
230 b = (b & ~ATP867X_IO_DMAMODE_MSTR_MASK); 236 b = (b & ~ATP867X_IO_DMAMODE_MSTR_MASK);
231 iowrite8(b, dp->dma_mode); 237 iowrite8(b, dp->dma_mode);
232 238
233 b = atp867x_get_active_clocks_shifted(t.active) | 239 b = atp867x_get_active_clocks_shifted(ap, t.active) |
234 atp867x_get_recover_clocks_shifted(t.recover); 240 atp867x_get_recover_clocks_shifted(t.recover);
235 if (dp->pci66mhz)
236 b += 0x10;
237 241
238 if (adev->devno & 1) 242 if (adev->devno & 1)
239 iowrite8(b, dp->slave_piospd); 243 iowrite8(b, dp->slave_piospd);
240 else 244 else
241 iowrite8(b, dp->mstr_piospd); 245 iowrite8(b, dp->mstr_piospd);
242 246
243 /* 247 b = atp867x_get_active_clocks_shifted(ap, t.act8b) |
244 * use the same value for comand timing as for PIO timimg 248 atp867x_get_recover_clocks_shifted(t.rec8b);
245 */ 249
246 iowrite8(b, dp->eightb_piospd); 250 iowrite8(b, dp->eightb_piospd);
247} 251}
248 252
253static int atp867x_cable_override(struct pci_dev *pdev)
254{
255 if (pdev->subsystem_vendor == PCI_VENDOR_ID_ARTOP &&
256 (pdev->subsystem_device == PCI_DEVICE_ID_ARTOP_ATP867A ||
257 pdev->subsystem_device == PCI_DEVICE_ID_ARTOP_ATP867B)) {
258 return 1;
259 }
260 return 0;
261}
262
249static int atp867x_cable_detect(struct ata_port *ap) 263static int atp867x_cable_detect(struct ata_port *ap)
250{ 264{
251 return ATA_CBL_PATA40_SHORT; 265 struct pci_dev *pdev = to_pci_dev(ap->host->dev);
266
267 if (atp867x_cable_override(pdev))
268 return ATA_CBL_PATA40_SHORT;
269
270 return ATA_CBL_PATA_UNK;
252} 271}
253 272
254static struct scsi_host_template atp867x_sht = { 273static struct scsi_host_template atp867x_sht = {
@@ -471,7 +490,6 @@ static int atp867x_init_one(struct pci_dev *pdev,
471 static const struct ata_port_info info_867x = { 490 static const struct ata_port_info info_867x = {
472 .flags = ATA_FLAG_SLAVE_POSS, 491 .flags = ATA_FLAG_SLAVE_POSS,
473 .pio_mask = ATA_PIO4, 492 .pio_mask = ATA_PIO4,
474 .mwdma_mask = ATA_MWDMA2,
475 .udma_mask = ATA_UDMA6, 493 .udma_mask = ATA_UDMA6,
476 .port_ops = &atp867x_ops, 494 .port_ops = &atp867x_ops,
477 }; 495 };
@@ -515,6 +533,23 @@ err_out:
515 return rc; 533 return rc;
516} 534}
517 535
536#ifdef CONFIG_PM
537static int atp867x_reinit_one(struct pci_dev *pdev)
538{
539 struct ata_host *host = dev_get_drvdata(&pdev->dev);
540 int rc;
541
542 rc = ata_pci_device_do_resume(pdev);
543 if (rc)
544 return rc;
545
546 atp867x_fixup(host);
547
548 ata_host_resume(host);
549 return 0;
550}
551#endif
552
518static struct pci_device_id atp867x_pci_tbl[] = { 553static struct pci_device_id atp867x_pci_tbl[] = {
519 { PCI_VDEVICE(ARTOP, PCI_DEVICE_ID_ARTOP_ATP867A), 0 }, 554 { PCI_VDEVICE(ARTOP, PCI_DEVICE_ID_ARTOP_ATP867A), 0 },
520 { PCI_VDEVICE(ARTOP, PCI_DEVICE_ID_ARTOP_ATP867B), 0 }, 555 { PCI_VDEVICE(ARTOP, PCI_DEVICE_ID_ARTOP_ATP867B), 0 },
@@ -526,6 +561,10 @@ static struct pci_driver atp867x_driver = {
526 .id_table = atp867x_pci_tbl, 561 .id_table = atp867x_pci_tbl,
527 .probe = atp867x_init_one, 562 .probe = atp867x_init_one,
528 .remove = ata_pci_remove_one, 563 .remove = ata_pci_remove_one,
564#ifdef CONFIG_PM
565 .suspend = ata_pci_device_suspend,
566 .resume = atp867x_reinit_one,
567#endif
529}; 568};
530 569
531static int __init atp867x_init(void) 570static int __init atp867x_init(void)
diff --git a/drivers/atm/ambassador.c b/drivers/atm/ambassador.c
index 703364b52170..66e181345b3a 100644
--- a/drivers/atm/ambassador.c
+++ b/drivers/atm/ambassador.c
@@ -1306,14 +1306,6 @@ static void amb_close (struct atm_vcc * atm_vcc) {
1306 return; 1306 return;
1307} 1307}
1308 1308
1309/********** Set socket options for a VC **********/
1310
1311// int amb_getsockopt (struct atm_vcc * atm_vcc, int level, int optname, void * optval, int optlen);
1312
1313/********** Set socket options for a VC **********/
1314
1315// int amb_setsockopt (struct atm_vcc * atm_vcc, int level, int optname, void * optval, int optlen);
1316
1317/********** Send **********/ 1309/********** Send **********/
1318 1310
1319static int amb_send (struct atm_vcc * atm_vcc, struct sk_buff * skb) { 1311static int amb_send (struct atm_vcc * atm_vcc, struct sk_buff * skb) {
diff --git a/drivers/atm/eni.c b/drivers/atm/eni.c
index 5503bfc8e132..0c3026145443 100644
--- a/drivers/atm/eni.c
+++ b/drivers/atm/eni.c
@@ -2031,7 +2031,7 @@ static int eni_getsockopt(struct atm_vcc *vcc,int level,int optname,
2031 2031
2032 2032
2033static int eni_setsockopt(struct atm_vcc *vcc,int level,int optname, 2033static int eni_setsockopt(struct atm_vcc *vcc,int level,int optname,
2034 void __user *optval,int optlen) 2034 void __user *optval,unsigned int optlen)
2035{ 2035{
2036 return -EINVAL; 2036 return -EINVAL;
2037} 2037}
diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c
index b119640e1ee9..cd5049af47a9 100644
--- a/drivers/atm/firestream.c
+++ b/drivers/atm/firestream.c
@@ -1244,7 +1244,7 @@ static int fs_getsockopt(struct atm_vcc *vcc,int level,int optname,
1244 1244
1245 1245
1246static int fs_setsockopt(struct atm_vcc *vcc,int level,int optname, 1246static int fs_setsockopt(struct atm_vcc *vcc,int level,int optname,
1247 void __user *optval,int optlen) 1247 void __user *optval,unsigned int optlen)
1248{ 1248{
1249 func_enter (); 1249 func_enter ();
1250 func_exit (); 1250 func_exit ();
diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c
index 10f000dbe448..f766cc46b4c4 100644
--- a/drivers/atm/fore200e.c
+++ b/drivers/atm/fore200e.c
@@ -1795,7 +1795,7 @@ fore200e_getsockopt(struct atm_vcc* vcc, int level, int optname, void __user *op
1795 1795
1796 1796
1797static int 1797static int
1798fore200e_setsockopt(struct atm_vcc* vcc, int level, int optname, void __user *optval, int optlen) 1798fore200e_setsockopt(struct atm_vcc* vcc, int level, int optname, void __user *optval, unsigned int optlen)
1799{ 1799{
1800 /* struct fore200e* fore200e = FORE200E_DEV(vcc->dev); */ 1800 /* struct fore200e* fore200e = FORE200E_DEV(vcc->dev); */
1801 1801
diff --git a/drivers/atm/horizon.c b/drivers/atm/horizon.c
index 01ce241dbeae..4e49021e67ee 100644
--- a/drivers/atm/horizon.c
+++ b/drivers/atm/horizon.c
@@ -2590,7 +2590,7 @@ static int hrz_getsockopt (struct atm_vcc * atm_vcc, int level, int optname,
2590} 2590}
2591 2591
2592static int hrz_setsockopt (struct atm_vcc * atm_vcc, int level, int optname, 2592static int hrz_setsockopt (struct atm_vcc * atm_vcc, int level, int optname,
2593 void *optval, int optlen) { 2593 void *optval, unsigned int optlen) {
2594 hrz_dev * dev = HRZ_DEV(atm_vcc->dev); 2594 hrz_dev * dev = HRZ_DEV(atm_vcc->dev);
2595 PRINTD (DBG_FLOW|DBG_VCC, "hrz_setsockopt"); 2595 PRINTD (DBG_FLOW|DBG_VCC, "hrz_setsockopt");
2596 switch (level) { 2596 switch (level) {
diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c
index 78c9736c3579..b2c1b37ab2e4 100644
--- a/drivers/atm/iphase.c
+++ b/drivers/atm/iphase.c
@@ -2862,7 +2862,7 @@ static int ia_getsockopt(struct atm_vcc *vcc, int level, int optname,
2862} 2862}
2863 2863
2864static int ia_setsockopt(struct atm_vcc *vcc, int level, int optname, 2864static int ia_setsockopt(struct atm_vcc *vcc, int level, int optname,
2865 void __user *optval, int optlen) 2865 void __user *optval, unsigned int optlen)
2866{ 2866{
2867 IF_EVENT(printk(">ia_setsockopt\n");) 2867 IF_EVENT(printk(">ia_setsockopt\n");)
2868 return -EINVAL; 2868 return -EINVAL;
diff --git a/drivers/atm/zatm.c b/drivers/atm/zatm.c
index 752b1ba81f7e..2e9635be048c 100644
--- a/drivers/atm/zatm.c
+++ b/drivers/atm/zatm.c
@@ -1517,7 +1517,7 @@ static int zatm_getsockopt(struct atm_vcc *vcc,int level,int optname,
1517 1517
1518 1518
1519static int zatm_setsockopt(struct atm_vcc *vcc,int level,int optname, 1519static int zatm_setsockopt(struct atm_vcc *vcc,int level,int optname,
1520 void __user *optval,int optlen) 1520 void __user *optval,unsigned int optlen)
1521{ 1521{
1522 return -EINVAL; 1522 return -EINVAL;
1523} 1523}
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c
index 6fa7b0fdbdfd..eb4fa1943944 100644
--- a/drivers/block/DAC960.c
+++ b/drivers/block/DAC960.c
@@ -38,6 +38,7 @@
38#include <linux/slab.h> 38#include <linux/slab.h>
39#include <linux/smp_lock.h> 39#include <linux/smp_lock.h>
40#include <linux/proc_fs.h> 40#include <linux/proc_fs.h>
41#include <linux/seq_file.h>
41#include <linux/reboot.h> 42#include <linux/reboot.h>
42#include <linux/spinlock.h> 43#include <linux/spinlock.h>
43#include <linux/timer.h> 44#include <linux/timer.h>
@@ -6422,16 +6423,10 @@ static bool DAC960_V2_ExecuteUserCommand(DAC960_Controller_T *Controller,
6422 return true; 6423 return true;
6423} 6424}
6424 6425
6425 6426static int dac960_proc_show(struct seq_file *m, void *v)
6426/*
6427 DAC960_ProcReadStatus implements reading /proc/rd/status.
6428*/
6429
6430static int DAC960_ProcReadStatus(char *Page, char **Start, off_t Offset,
6431 int Count, int *EOF, void *Data)
6432{ 6427{
6433 unsigned char *StatusMessage = "OK\n"; 6428 unsigned char *StatusMessage = "OK\n";
6434 int ControllerNumber, BytesAvailable; 6429 int ControllerNumber;
6435 for (ControllerNumber = 0; 6430 for (ControllerNumber = 0;
6436 ControllerNumber < DAC960_ControllerCount; 6431 ControllerNumber < DAC960_ControllerCount;
6437 ControllerNumber++) 6432 ControllerNumber++)
@@ -6444,52 +6439,49 @@ static int DAC960_ProcReadStatus(char *Page, char **Start, off_t Offset,
6444 break; 6439 break;
6445 } 6440 }
6446 } 6441 }
6447 BytesAvailable = strlen(StatusMessage) - Offset; 6442 seq_puts(m, StatusMessage);
6448 if (Count >= BytesAvailable) 6443 return 0;
6449 {
6450 Count = BytesAvailable;
6451 *EOF = true;
6452 }
6453 if (Count <= 0) return 0;
6454 *Start = Page;
6455 memcpy(Page, &StatusMessage[Offset], Count);
6456 return Count;
6457} 6444}
6458 6445
6446static int dac960_proc_open(struct inode *inode, struct file *file)
6447{
6448 return single_open(file, dac960_proc_show, NULL);
6449}
6459 6450
6460/* 6451static const struct file_operations dac960_proc_fops = {
6461 DAC960_ProcReadInitialStatus implements reading /proc/rd/cN/initial_status. 6452 .owner = THIS_MODULE,
6462*/ 6453 .open = dac960_proc_open,
6454 .read = seq_read,
6455 .llseek = seq_lseek,
6456 .release = single_release,
6457};
6463 6458
6464static int DAC960_ProcReadInitialStatus(char *Page, char **Start, off_t Offset, 6459static int dac960_initial_status_proc_show(struct seq_file *m, void *v)
6465 int Count, int *EOF, void *Data)
6466{ 6460{
6467 DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data; 6461 DAC960_Controller_T *Controller = (DAC960_Controller_T *)m->private;
6468 int BytesAvailable = Controller->InitialStatusLength - Offset; 6462 seq_printf(m, "%.*s", Controller->InitialStatusLength, Controller->CombinedStatusBuffer);
6469 if (Count >= BytesAvailable) 6463 return 0;
6470 {
6471 Count = BytesAvailable;
6472 *EOF = true;
6473 }
6474 if (Count <= 0) return 0;
6475 *Start = Page;
6476 memcpy(Page, &Controller->CombinedStatusBuffer[Offset], Count);
6477 return Count;
6478} 6464}
6479 6465
6466static int dac960_initial_status_proc_open(struct inode *inode, struct file *file)
6467{
6468 return single_open(file, dac960_initial_status_proc_show, PDE(inode)->data);
6469}
6480 6470
6481/* 6471static const struct file_operations dac960_initial_status_proc_fops = {
6482 DAC960_ProcReadCurrentStatus implements reading /proc/rd/cN/current_status. 6472 .owner = THIS_MODULE,
6483*/ 6473 .open = dac960_initial_status_proc_open,
6474 .read = seq_read,
6475 .llseek = seq_lseek,
6476 .release = single_release,
6477};
6484 6478
6485static int DAC960_ProcReadCurrentStatus(char *Page, char **Start, off_t Offset, 6479static int dac960_current_status_proc_show(struct seq_file *m, void *v)
6486 int Count, int *EOF, void *Data)
6487{ 6480{
6488 DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data; 6481 DAC960_Controller_T *Controller = (DAC960_Controller_T *) m->private;
6489 unsigned char *StatusMessage = 6482 unsigned char *StatusMessage =
6490 "No Rebuild or Consistency Check in Progress\n"; 6483 "No Rebuild or Consistency Check in Progress\n";
6491 int ProgressMessageLength = strlen(StatusMessage); 6484 int ProgressMessageLength = strlen(StatusMessage);
6492 int BytesAvailable;
6493 if (jiffies != Controller->LastCurrentStatusTime) 6485 if (jiffies != Controller->LastCurrentStatusTime)
6494 { 6486 {
6495 Controller->CurrentStatusLength = 0; 6487 Controller->CurrentStatusLength = 0;
@@ -6513,49 +6505,41 @@ static int DAC960_ProcReadCurrentStatus(char *Page, char **Start, off_t Offset,
6513 } 6505 }
6514 Controller->LastCurrentStatusTime = jiffies; 6506 Controller->LastCurrentStatusTime = jiffies;
6515 } 6507 }
6516 BytesAvailable = Controller->CurrentStatusLength - Offset; 6508 seq_printf(m, "%.*s", Controller->CurrentStatusLength, Controller->CurrentStatusBuffer);
6517 if (Count >= BytesAvailable) 6509 return 0;
6518 {
6519 Count = BytesAvailable;
6520 *EOF = true;
6521 }
6522 if (Count <= 0) return 0;
6523 *Start = Page;
6524 memcpy(Page, &Controller->CurrentStatusBuffer[Offset], Count);
6525 return Count;
6526} 6510}
6527 6511
6512static int dac960_current_status_proc_open(struct inode *inode, struct file *file)
6513{
6514 return single_open(file, dac960_current_status_proc_show, PDE(inode)->data);
6515}
6528 6516
6529/* 6517static const struct file_operations dac960_current_status_proc_fops = {
6530 DAC960_ProcReadUserCommand implements reading /proc/rd/cN/user_command. 6518 .owner = THIS_MODULE,
6531*/ 6519 .open = dac960_current_status_proc_open,
6520 .read = seq_read,
6521 .llseek = seq_lseek,
6522 .release = single_release,
6523};
6532 6524
6533static int DAC960_ProcReadUserCommand(char *Page, char **Start, off_t Offset, 6525static int dac960_user_command_proc_show(struct seq_file *m, void *v)
6534 int Count, int *EOF, void *Data)
6535{ 6526{
6536 DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data; 6527 DAC960_Controller_T *Controller = (DAC960_Controller_T *)m->private;
6537 int BytesAvailable = Controller->UserStatusLength - Offset;
6538 if (Count >= BytesAvailable)
6539 {
6540 Count = BytesAvailable;
6541 *EOF = true;
6542 }
6543 if (Count <= 0) return 0;
6544 *Start = Page;
6545 memcpy(Page, &Controller->UserStatusBuffer[Offset], Count);
6546 return Count;
6547}
6548 6528
6529 seq_printf(m, "%.*s", Controller->UserStatusLength, Controller->UserStatusBuffer);
6530 return 0;
6531}
6549 6532
6550/* 6533static int dac960_user_command_proc_open(struct inode *inode, struct file *file)
6551 DAC960_ProcWriteUserCommand implements writing /proc/rd/cN/user_command. 6534{
6552*/ 6535 return single_open(file, dac960_user_command_proc_show, PDE(inode)->data);
6536}
6553 6537
6554static int DAC960_ProcWriteUserCommand(struct file *file, 6538static ssize_t dac960_user_command_proc_write(struct file *file,
6555 const char __user *Buffer, 6539 const char __user *Buffer,
6556 unsigned long Count, void *Data) 6540 size_t Count, loff_t *pos)
6557{ 6541{
6558 DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data; 6542 DAC960_Controller_T *Controller = (DAC960_Controller_T *) PDE(file->f_path.dentry->d_inode)->data;
6559 unsigned char CommandBuffer[80]; 6543 unsigned char CommandBuffer[80];
6560 int Length; 6544 int Length;
6561 if (Count > sizeof(CommandBuffer)-1) return -EINVAL; 6545 if (Count > sizeof(CommandBuffer)-1) return -EINVAL;
@@ -6572,6 +6556,14 @@ static int DAC960_ProcWriteUserCommand(struct file *file,
6572 ? Count : -EBUSY); 6556 ? Count : -EBUSY);
6573} 6557}
6574 6558
6559static const struct file_operations dac960_user_command_proc_fops = {
6560 .owner = THIS_MODULE,
6561 .open = dac960_user_command_proc_open,
6562 .read = seq_read,
6563 .llseek = seq_lseek,
6564 .release = single_release,
6565 .write = dac960_user_command_proc_write,
6566};
6575 6567
6576/* 6568/*
6577 DAC960_CreateProcEntries creates the /proc/rd/... entries for the 6569 DAC960_CreateProcEntries creates the /proc/rd/... entries for the
@@ -6586,23 +6578,17 @@ static void DAC960_CreateProcEntries(DAC960_Controller_T *Controller)
6586 6578
6587 if (DAC960_ProcDirectoryEntry == NULL) { 6579 if (DAC960_ProcDirectoryEntry == NULL) {
6588 DAC960_ProcDirectoryEntry = proc_mkdir("rd", NULL); 6580 DAC960_ProcDirectoryEntry = proc_mkdir("rd", NULL);
6589 StatusProcEntry = create_proc_read_entry("status", 0, 6581 StatusProcEntry = proc_create("status", 0,
6590 DAC960_ProcDirectoryEntry, 6582 DAC960_ProcDirectoryEntry,
6591 DAC960_ProcReadStatus, NULL); 6583 &dac960_proc_fops);
6592 } 6584 }
6593 6585
6594 sprintf(Controller->ControllerName, "c%d", Controller->ControllerNumber); 6586 sprintf(Controller->ControllerName, "c%d", Controller->ControllerNumber);
6595 ControllerProcEntry = proc_mkdir(Controller->ControllerName, 6587 ControllerProcEntry = proc_mkdir(Controller->ControllerName,
6596 DAC960_ProcDirectoryEntry); 6588 DAC960_ProcDirectoryEntry);
6597 create_proc_read_entry("initial_status", 0, ControllerProcEntry, 6589 proc_create_data("initial_status", 0, ControllerProcEntry, &dac960_initial_status_proc_fops, Controller);
6598 DAC960_ProcReadInitialStatus, Controller); 6590 proc_create_data("current_status", 0, ControllerProcEntry, &dac960_current_status_proc_fops, Controller);
6599 create_proc_read_entry("current_status", 0, ControllerProcEntry, 6591 UserCommandProcEntry = proc_create_data("user_command", S_IWUSR | S_IRUSR, ControllerProcEntry, &dac960_user_command_proc_fops, Controller);
6600 DAC960_ProcReadCurrentStatus, Controller);
6601 UserCommandProcEntry =
6602 create_proc_read_entry("user_command", S_IWUSR | S_IRUSR,
6603 ControllerProcEntry, DAC960_ProcReadUserCommand,
6604 Controller);
6605 UserCommandProcEntry->write_proc = DAC960_ProcWriteUserCommand;
6606 Controller->ControllerProcEntry = ControllerProcEntry; 6592 Controller->ControllerProcEntry = ControllerProcEntry;
6607} 6593}
6608 6594
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 24c3e21ab263..6399e5090df4 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -36,9 +36,11 @@
36#include <linux/proc_fs.h> 36#include <linux/proc_fs.h>
37#include <linux/seq_file.h> 37#include <linux/seq_file.h>
38#include <linux/init.h> 38#include <linux/init.h>
39#include <linux/jiffies.h>
39#include <linux/hdreg.h> 40#include <linux/hdreg.h>
40#include <linux/spinlock.h> 41#include <linux/spinlock.h>
41#include <linux/compat.h> 42#include <linux/compat.h>
43#include <linux/mutex.h>
42#include <asm/uaccess.h> 44#include <asm/uaccess.h>
43#include <asm/io.h> 45#include <asm/io.h>
44 46
@@ -66,6 +68,12 @@ MODULE_SUPPORTED_DEVICE("HP SA5i SA5i+ SA532 SA5300 SA5312 SA641 SA642 SA6400"
66MODULE_VERSION("3.6.20"); 68MODULE_VERSION("3.6.20");
67MODULE_LICENSE("GPL"); 69MODULE_LICENSE("GPL");
68 70
71static int cciss_allow_hpsa;
72module_param(cciss_allow_hpsa, int, S_IRUGO|S_IWUSR);
73MODULE_PARM_DESC(cciss_allow_hpsa,
74 "Prevent cciss driver from accessing hardware known to be "
75 " supported by the hpsa driver");
76
69#include "cciss_cmd.h" 77#include "cciss_cmd.h"
70#include "cciss.h" 78#include "cciss.h"
71#include <linux/cciss_ioctl.h> 79#include <linux/cciss_ioctl.h>
@@ -99,8 +107,6 @@ static const struct pci_device_id cciss_pci_device_id[] = {
99 {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3249}, 107 {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3249},
100 {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x324A}, 108 {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x324A},
101 {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x324B}, 109 {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x324B},
102 {PCI_VENDOR_ID_HP, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
103 PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0},
104 {0,} 110 {0,}
105}; 111};
106 112
@@ -121,8 +127,6 @@ static struct board_type products[] = {
121 {0x409D0E11, "Smart Array 6400 EM", &SA5_access}, 127 {0x409D0E11, "Smart Array 6400 EM", &SA5_access},
122 {0x40910E11, "Smart Array 6i", &SA5_access}, 128 {0x40910E11, "Smart Array 6i", &SA5_access},
123 {0x3225103C, "Smart Array P600", &SA5_access}, 129 {0x3225103C, "Smart Array P600", &SA5_access},
124 {0x3223103C, "Smart Array P800", &SA5_access},
125 {0x3234103C, "Smart Array P400", &SA5_access},
126 {0x3235103C, "Smart Array P400i", &SA5_access}, 130 {0x3235103C, "Smart Array P400i", &SA5_access},
127 {0x3211103C, "Smart Array E200i", &SA5_access}, 131 {0x3211103C, "Smart Array E200i", &SA5_access},
128 {0x3212103C, "Smart Array E200", &SA5_access}, 132 {0x3212103C, "Smart Array E200", &SA5_access},
@@ -130,6 +134,10 @@ static struct board_type products[] = {
130 {0x3214103C, "Smart Array E200i", &SA5_access}, 134 {0x3214103C, "Smart Array E200i", &SA5_access},
131 {0x3215103C, "Smart Array E200i", &SA5_access}, 135 {0x3215103C, "Smart Array E200i", &SA5_access},
132 {0x3237103C, "Smart Array E500", &SA5_access}, 136 {0x3237103C, "Smart Array E500", &SA5_access},
137/* controllers below this line are also supported by the hpsa driver. */
138#define HPSA_BOUNDARY 0x3223103C
139 {0x3223103C, "Smart Array P800", &SA5_access},
140 {0x3234103C, "Smart Array P400", &SA5_access},
133 {0x323D103C, "Smart Array P700m", &SA5_access}, 141 {0x323D103C, "Smart Array P700m", &SA5_access},
134 {0x3241103C, "Smart Array P212", &SA5_access}, 142 {0x3241103C, "Smart Array P212", &SA5_access},
135 {0x3243103C, "Smart Array P410", &SA5_access}, 143 {0x3243103C, "Smart Array P410", &SA5_access},
@@ -138,7 +146,6 @@ static struct board_type products[] = {
138 {0x3249103C, "Smart Array P812", &SA5_access}, 146 {0x3249103C, "Smart Array P812", &SA5_access},
139 {0x324A103C, "Smart Array P712m", &SA5_access}, 147 {0x324A103C, "Smart Array P712m", &SA5_access},
140 {0x324B103C, "Smart Array P711m", &SA5_access}, 148 {0x324B103C, "Smart Array P711m", &SA5_access},
141 {0xFFFF103C, "Unknown Smart Array", &SA5_access},
142}; 149};
143 150
144/* How long to wait (in milliseconds) for board to go into simple mode */ 151/* How long to wait (in milliseconds) for board to go into simple mode */
@@ -155,6 +162,10 @@ static struct board_type products[] = {
155 162
156static ctlr_info_t *hba[MAX_CTLR]; 163static ctlr_info_t *hba[MAX_CTLR];
157 164
165static struct task_struct *cciss_scan_thread;
166static DEFINE_MUTEX(scan_mutex);
167static LIST_HEAD(scan_q);
168
158static void do_cciss_request(struct request_queue *q); 169static void do_cciss_request(struct request_queue *q);
159static irqreturn_t do_cciss_intr(int irq, void *dev_id); 170static irqreturn_t do_cciss_intr(int irq, void *dev_id);
160static int cciss_open(struct block_device *bdev, fmode_t mode); 171static int cciss_open(struct block_device *bdev, fmode_t mode);
@@ -164,9 +175,9 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
164static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo); 175static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo);
165 176
166static int cciss_revalidate(struct gendisk *disk); 177static int cciss_revalidate(struct gendisk *disk);
167static int rebuild_lun_table(ctlr_info_t *h, int first_time); 178static int rebuild_lun_table(ctlr_info_t *h, int first_time, int via_ioctl);
168static int deregister_disk(ctlr_info_t *h, int drv_index, 179static int deregister_disk(ctlr_info_t *h, int drv_index,
169 int clear_all); 180 int clear_all, int via_ioctl);
170 181
171static void cciss_read_capacity(int ctlr, int logvol, int withirq, 182static void cciss_read_capacity(int ctlr, int logvol, int withirq,
172 sector_t *total_size, unsigned int *block_size); 183 sector_t *total_size, unsigned int *block_size);
@@ -189,8 +200,13 @@ static int sendcmd_withirq_core(ctlr_info_t *h, CommandList_struct *c,
189static int process_sendcmd_error(ctlr_info_t *h, CommandList_struct *c); 200static int process_sendcmd_error(ctlr_info_t *h, CommandList_struct *c);
190 201
191static void fail_all_cmds(unsigned long ctlr); 202static void fail_all_cmds(unsigned long ctlr);
203static int add_to_scan_list(struct ctlr_info *h);
192static int scan_thread(void *data); 204static int scan_thread(void *data);
193static int check_for_unit_attention(ctlr_info_t *h, CommandList_struct *c); 205static int check_for_unit_attention(ctlr_info_t *h, CommandList_struct *c);
206static void cciss_hba_release(struct device *dev);
207static void cciss_device_release(struct device *dev);
208static void cciss_free_gendisk(ctlr_info_t *h, int drv_index);
209static void cciss_free_drive_info(ctlr_info_t *h, int drv_index);
194 210
195#ifdef CONFIG_PROC_FS 211#ifdef CONFIG_PROC_FS
196static void cciss_procinit(int i); 212static void cciss_procinit(int i);
@@ -245,7 +261,10 @@ static inline void removeQ(CommandList_struct *c)
245 261
246#include "cciss_scsi.c" /* For SCSI tape support */ 262#include "cciss_scsi.c" /* For SCSI tape support */
247 263
248#define RAID_UNKNOWN 6 264static const char *raid_label[] = { "0", "4", "1(1+0)", "5", "5+1", "ADG",
265 "UNKNOWN"
266};
267#define RAID_UNKNOWN (sizeof(raid_label) / sizeof(raid_label[0])-1)
249 268
250#ifdef CONFIG_PROC_FS 269#ifdef CONFIG_PROC_FS
251 270
@@ -255,9 +274,6 @@ static inline void removeQ(CommandList_struct *c)
255#define ENG_GIG 1000000000 274#define ENG_GIG 1000000000
256#define ENG_GIG_FACTOR (ENG_GIG/512) 275#define ENG_GIG_FACTOR (ENG_GIG/512)
257#define ENGAGE_SCSI "engage scsi" 276#define ENGAGE_SCSI "engage scsi"
258static const char *raid_label[] = { "0", "4", "1(1+0)", "5", "5+1", "ADG",
259 "UNKNOWN"
260};
261 277
262static struct proc_dir_entry *proc_cciss; 278static struct proc_dir_entry *proc_cciss;
263 279
@@ -318,7 +334,7 @@ static int cciss_seq_show(struct seq_file *seq, void *v)
318 ctlr_info_t *h = seq->private; 334 ctlr_info_t *h = seq->private;
319 unsigned ctlr = h->ctlr; 335 unsigned ctlr = h->ctlr;
320 loff_t *pos = v; 336 loff_t *pos = v;
321 drive_info_struct *drv = &h->drv[*pos]; 337 drive_info_struct *drv = h->drv[*pos];
322 338
323 if (*pos > h->highest_lun) 339 if (*pos > h->highest_lun)
324 return 0; 340 return 0;
@@ -331,7 +347,7 @@ static int cciss_seq_show(struct seq_file *seq, void *v)
331 vol_sz_frac *= 100; 347 vol_sz_frac *= 100;
332 sector_div(vol_sz_frac, ENG_GIG_FACTOR); 348 sector_div(vol_sz_frac, ENG_GIG_FACTOR);
333 349
334 if (drv->raid_level > 5) 350 if (drv->raid_level < 0 || drv->raid_level > RAID_UNKNOWN)
335 drv->raid_level = RAID_UNKNOWN; 351 drv->raid_level = RAID_UNKNOWN;
336 seq_printf(seq, "cciss/c%dd%d:" 352 seq_printf(seq, "cciss/c%dd%d:"
337 "\t%4u.%02uGB\tRAID %s\n", 353 "\t%4u.%02uGB\tRAID %s\n",
@@ -426,7 +442,7 @@ out:
426 return err; 442 return err;
427} 443}
428 444
429static struct file_operations cciss_proc_fops = { 445static const struct file_operations cciss_proc_fops = {
430 .owner = THIS_MODULE, 446 .owner = THIS_MODULE,
431 .open = cciss_seq_open, 447 .open = cciss_seq_open,
432 .read = seq_read, 448 .read = seq_read,
@@ -454,9 +470,19 @@ static void __devinit cciss_procinit(int i)
454#define to_hba(n) container_of(n, struct ctlr_info, dev) 470#define to_hba(n) container_of(n, struct ctlr_info, dev)
455#define to_drv(n) container_of(n, drive_info_struct, dev) 471#define to_drv(n) container_of(n, drive_info_struct, dev)
456 472
457static struct device_type cciss_host_type = { 473static ssize_t host_store_rescan(struct device *dev,
458 .name = "cciss_host", 474 struct device_attribute *attr,
459}; 475 const char *buf, size_t count)
476{
477 struct ctlr_info *h = to_hba(dev);
478
479 add_to_scan_list(h);
480 wake_up_process(cciss_scan_thread);
481 wait_for_completion_interruptible(&h->scan_wait);
482
483 return count;
484}
485DEVICE_ATTR(rescan, S_IWUSR, NULL, host_store_rescan);
460 486
461static ssize_t dev_show_unique_id(struct device *dev, 487static ssize_t dev_show_unique_id(struct device *dev,
462 struct device_attribute *attr, 488 struct device_attribute *attr,
@@ -560,11 +586,101 @@ static ssize_t dev_show_rev(struct device *dev,
560} 586}
561DEVICE_ATTR(rev, S_IRUGO, dev_show_rev, NULL); 587DEVICE_ATTR(rev, S_IRUGO, dev_show_rev, NULL);
562 588
589static ssize_t cciss_show_lunid(struct device *dev,
590 struct device_attribute *attr, char *buf)
591{
592 drive_info_struct *drv = to_drv(dev);
593 struct ctlr_info *h = to_hba(drv->dev.parent);
594 unsigned long flags;
595 unsigned char lunid[8];
596
597 spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
598 if (h->busy_configuring) {
599 spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
600 return -EBUSY;
601 }
602 if (!drv->heads) {
603 spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
604 return -ENOTTY;
605 }
606 memcpy(lunid, drv->LunID, sizeof(lunid));
607 spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
608 return snprintf(buf, 20, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
609 lunid[0], lunid[1], lunid[2], lunid[3],
610 lunid[4], lunid[5], lunid[6], lunid[7]);
611}
612DEVICE_ATTR(lunid, S_IRUGO, cciss_show_lunid, NULL);
613
614static ssize_t cciss_show_raid_level(struct device *dev,
615 struct device_attribute *attr, char *buf)
616{
617 drive_info_struct *drv = to_drv(dev);
618 struct ctlr_info *h = to_hba(drv->dev.parent);
619 int raid;
620 unsigned long flags;
621
622 spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
623 if (h->busy_configuring) {
624 spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
625 return -EBUSY;
626 }
627 raid = drv->raid_level;
628 spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
629 if (raid < 0 || raid > RAID_UNKNOWN)
630 raid = RAID_UNKNOWN;
631
632 return snprintf(buf, strlen(raid_label[raid]) + 7, "RAID %s\n",
633 raid_label[raid]);
634}
635DEVICE_ATTR(raid_level, S_IRUGO, cciss_show_raid_level, NULL);
636
637static ssize_t cciss_show_usage_count(struct device *dev,
638 struct device_attribute *attr, char *buf)
639{
640 drive_info_struct *drv = to_drv(dev);
641 struct ctlr_info *h = to_hba(drv->dev.parent);
642 unsigned long flags;
643 int count;
644
645 spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
646 if (h->busy_configuring) {
647 spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
648 return -EBUSY;
649 }
650 count = drv->usage_count;
651 spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
652 return snprintf(buf, 20, "%d\n", count);
653}
654DEVICE_ATTR(usage_count, S_IRUGO, cciss_show_usage_count, NULL);
655
656static struct attribute *cciss_host_attrs[] = {
657 &dev_attr_rescan.attr,
658 NULL
659};
660
661static struct attribute_group cciss_host_attr_group = {
662 .attrs = cciss_host_attrs,
663};
664
665static const struct attribute_group *cciss_host_attr_groups[] = {
666 &cciss_host_attr_group,
667 NULL
668};
669
670static struct device_type cciss_host_type = {
671 .name = "cciss_host",
672 .groups = cciss_host_attr_groups,
673 .release = cciss_hba_release,
674};
675
563static struct attribute *cciss_dev_attrs[] = { 676static struct attribute *cciss_dev_attrs[] = {
564 &dev_attr_unique_id.attr, 677 &dev_attr_unique_id.attr,
565 &dev_attr_model.attr, 678 &dev_attr_model.attr,
566 &dev_attr_vendor.attr, 679 &dev_attr_vendor.attr,
567 &dev_attr_rev.attr, 680 &dev_attr_rev.attr,
681 &dev_attr_lunid.attr,
682 &dev_attr_raid_level.attr,
683 &dev_attr_usage_count.attr,
568 NULL 684 NULL
569}; 685};
570 686
@@ -580,12 +696,24 @@ static const struct attribute_group *cciss_dev_attr_groups[] = {
580static struct device_type cciss_dev_type = { 696static struct device_type cciss_dev_type = {
581 .name = "cciss_device", 697 .name = "cciss_device",
582 .groups = cciss_dev_attr_groups, 698 .groups = cciss_dev_attr_groups,
699 .release = cciss_device_release,
583}; 700};
584 701
585static struct bus_type cciss_bus_type = { 702static struct bus_type cciss_bus_type = {
586 .name = "cciss", 703 .name = "cciss",
587}; 704};
588 705
706/*
707 * cciss_hba_release is called when the reference count
708 * of h->dev goes to zero.
709 */
710static void cciss_hba_release(struct device *dev)
711{
712 /*
713 * nothing to do, but need this to avoid a warning
714 * about not having a release handler from lib/kref.c.
715 */
716}
589 717
590/* 718/*
591 * Initialize sysfs entry for each controller. This sets up and registers 719 * Initialize sysfs entry for each controller. This sets up and registers
@@ -609,6 +737,16 @@ static int cciss_create_hba_sysfs_entry(struct ctlr_info *h)
609static void cciss_destroy_hba_sysfs_entry(struct ctlr_info *h) 737static void cciss_destroy_hba_sysfs_entry(struct ctlr_info *h)
610{ 738{
611 device_del(&h->dev); 739 device_del(&h->dev);
740 put_device(&h->dev); /* final put. */
741}
742
743/* cciss_device_release is called when the reference count
744 * of h->drv[x]dev goes to zero.
745 */
746static void cciss_device_release(struct device *dev)
747{
748 drive_info_struct *drv = to_drv(dev);
749 kfree(drv);
612} 750}
613 751
614/* 752/*
@@ -617,24 +755,39 @@ static void cciss_destroy_hba_sysfs_entry(struct ctlr_info *h)
617 * /sys/bus/pci/devices/<dev/ccis#/. We also create a link from 755 * /sys/bus/pci/devices/<dev/ccis#/. We also create a link from
618 * /sys/block/cciss!c#d# to this entry. 756 * /sys/block/cciss!c#d# to this entry.
619 */ 757 */
620static int cciss_create_ld_sysfs_entry(struct ctlr_info *h, 758static long cciss_create_ld_sysfs_entry(struct ctlr_info *h,
621 drive_info_struct *drv,
622 int drv_index) 759 int drv_index)
623{ 760{
624 device_initialize(&drv->dev); 761 struct device *dev;
625 drv->dev.type = &cciss_dev_type; 762
626 drv->dev.bus = &cciss_bus_type; 763 if (h->drv[drv_index]->device_initialized)
627 dev_set_name(&drv->dev, "c%dd%d", h->ctlr, drv_index); 764 return 0;
628 drv->dev.parent = &h->dev; 765
629 return device_add(&drv->dev); 766 dev = &h->drv[drv_index]->dev;
767 device_initialize(dev);
768 dev->type = &cciss_dev_type;
769 dev->bus = &cciss_bus_type;
770 dev_set_name(dev, "c%dd%d", h->ctlr, drv_index);
771 dev->parent = &h->dev;
772 h->drv[drv_index]->device_initialized = 1;
773 return device_add(dev);
630} 774}
631 775
632/* 776/*
633 * Remove sysfs entries for a logical drive. 777 * Remove sysfs entries for a logical drive.
634 */ 778 */
635static void cciss_destroy_ld_sysfs_entry(drive_info_struct *drv) 779static void cciss_destroy_ld_sysfs_entry(struct ctlr_info *h, int drv_index,
780 int ctlr_exiting)
636{ 781{
637 device_del(&drv->dev); 782 struct device *dev = &h->drv[drv_index]->dev;
783
784 /* special case for c*d0, we only destroy it on controller exit */
785 if (drv_index == 0 && !ctlr_exiting)
786 return;
787
788 device_del(dev);
789 put_device(dev); /* the "final" put. */
790 h->drv[drv_index] = NULL;
638} 791}
639 792
640/* 793/*
@@ -751,7 +904,7 @@ static int cciss_open(struct block_device *bdev, fmode_t mode)
751 printk(KERN_DEBUG "cciss_open %s\n", bdev->bd_disk->disk_name); 904 printk(KERN_DEBUG "cciss_open %s\n", bdev->bd_disk->disk_name);
752#endif /* CCISS_DEBUG */ 905#endif /* CCISS_DEBUG */
753 906
754 if (host->busy_initializing || drv->busy_configuring) 907 if (drv->busy_configuring)
755 return -EBUSY; 908 return -EBUSY;
756 /* 909 /*
757 * Root is allowed to open raw volume zero even if it's not configured 910 * Root is allowed to open raw volume zero even if it's not configured
@@ -767,7 +920,8 @@ static int cciss_open(struct block_device *bdev, fmode_t mode)
767 if (MINOR(bdev->bd_dev) & 0x0f) { 920 if (MINOR(bdev->bd_dev) & 0x0f) {
768 return -ENXIO; 921 return -ENXIO;
769 /* if it is, make sure we have a LUN ID */ 922 /* if it is, make sure we have a LUN ID */
770 } else if (drv->LunID == 0) { 923 } else if (memcmp(drv->LunID, CTLR_LUNID,
924 sizeof(drv->LunID))) {
771 return -ENXIO; 925 return -ENXIO;
772 } 926 }
773 } 927 }
@@ -1132,12 +1286,13 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
1132 case CCISS_DEREGDISK: 1286 case CCISS_DEREGDISK:
1133 case CCISS_REGNEWD: 1287 case CCISS_REGNEWD:
1134 case CCISS_REVALIDVOLS: 1288 case CCISS_REVALIDVOLS:
1135 return rebuild_lun_table(host, 0); 1289 return rebuild_lun_table(host, 0, 1);
1136 1290
1137 case CCISS_GETLUNINFO:{ 1291 case CCISS_GETLUNINFO:{
1138 LogvolInfo_struct luninfo; 1292 LogvolInfo_struct luninfo;
1139 1293
1140 luninfo.LunID = drv->LunID; 1294 memcpy(&luninfo.LunID, drv->LunID,
1295 sizeof(luninfo.LunID));
1141 luninfo.num_opens = drv->usage_count; 1296 luninfo.num_opens = drv->usage_count;
1142 luninfo.num_parts = 0; 1297 luninfo.num_parts = 0;
1143 if (copy_to_user(argp, &luninfo, 1298 if (copy_to_user(argp, &luninfo,
@@ -1475,7 +1630,10 @@ static void cciss_check_queues(ctlr_info_t *h)
1475 /* make sure the disk has been added and the drive is real 1630 /* make sure the disk has been added and the drive is real
1476 * because this can be called from the middle of init_one. 1631 * because this can be called from the middle of init_one.
1477 */ 1632 */
1478 if (!(h->drv[curr_queue].queue) || !(h->drv[curr_queue].heads)) 1633 if (!h->drv[curr_queue])
1634 continue;
1635 if (!(h->drv[curr_queue]->queue) ||
1636 !(h->drv[curr_queue]->heads))
1479 continue; 1637 continue;
1480 blk_start_queue(h->gendisk[curr_queue]->queue); 1638 blk_start_queue(h->gendisk[curr_queue]->queue);
1481 1639
@@ -1532,13 +1690,11 @@ static void cciss_softirq_done(struct request *rq)
1532 spin_unlock_irqrestore(&h->lock, flags); 1690 spin_unlock_irqrestore(&h->lock, flags);
1533} 1691}
1534 1692
1535static void log_unit_to_scsi3addr(ctlr_info_t *h, unsigned char scsi3addr[], 1693static inline void log_unit_to_scsi3addr(ctlr_info_t *h,
1536 uint32_t log_unit) 1694 unsigned char scsi3addr[], uint32_t log_unit)
1537{ 1695{
1538 log_unit = h->drv[log_unit].LunID & 0x03fff; 1696 memcpy(scsi3addr, h->drv[log_unit]->LunID,
1539 memset(&scsi3addr[4], 0, 4); 1697 sizeof(h->drv[log_unit]->LunID));
1540 memcpy(&scsi3addr[0], &log_unit, 4);
1541 scsi3addr[3] |= 0x40;
1542} 1698}
1543 1699
1544/* This function gets the SCSI vendor, model, and revision of a logical drive 1700/* This function gets the SCSI vendor, model, and revision of a logical drive
@@ -1615,16 +1771,23 @@ static void cciss_get_serial_no(int ctlr, int logvol, int withirq,
1615 return; 1771 return;
1616} 1772}
1617 1773
1618static void cciss_add_disk(ctlr_info_t *h, struct gendisk *disk, 1774/*
1775 * cciss_add_disk sets up the block device queue for a logical drive
1776 */
1777static int cciss_add_disk(ctlr_info_t *h, struct gendisk *disk,
1619 int drv_index) 1778 int drv_index)
1620{ 1779{
1621 disk->queue = blk_init_queue(do_cciss_request, &h->lock); 1780 disk->queue = blk_init_queue(do_cciss_request, &h->lock);
1781 if (!disk->queue)
1782 goto init_queue_failure;
1622 sprintf(disk->disk_name, "cciss/c%dd%d", h->ctlr, drv_index); 1783 sprintf(disk->disk_name, "cciss/c%dd%d", h->ctlr, drv_index);
1623 disk->major = h->major; 1784 disk->major = h->major;
1624 disk->first_minor = drv_index << NWD_SHIFT; 1785 disk->first_minor = drv_index << NWD_SHIFT;
1625 disk->fops = &cciss_fops; 1786 disk->fops = &cciss_fops;
1626 disk->private_data = &h->drv[drv_index]; 1787 if (cciss_create_ld_sysfs_entry(h, drv_index))
1627 disk->driverfs_dev = &h->drv[drv_index].dev; 1788 goto cleanup_queue;
1789 disk->private_data = h->drv[drv_index];
1790 disk->driverfs_dev = &h->drv[drv_index]->dev;
1628 1791
1629 /* Set up queue information */ 1792 /* Set up queue information */
1630 blk_queue_bounce_limit(disk->queue, h->pdev->dma_mask); 1793 blk_queue_bounce_limit(disk->queue, h->pdev->dma_mask);
@@ -1642,14 +1805,21 @@ static void cciss_add_disk(ctlr_info_t *h, struct gendisk *disk,
1642 disk->queue->queuedata = h; 1805 disk->queue->queuedata = h;
1643 1806
1644 blk_queue_logical_block_size(disk->queue, 1807 blk_queue_logical_block_size(disk->queue,
1645 h->drv[drv_index].block_size); 1808 h->drv[drv_index]->block_size);
1646 1809
1647 /* Make sure all queue data is written out before */ 1810 /* Make sure all queue data is written out before */
1648 /* setting h->drv[drv_index].queue, as setting this */ 1811 /* setting h->drv[drv_index]->queue, as setting this */
1649 /* allows the interrupt handler to start the queue */ 1812 /* allows the interrupt handler to start the queue */
1650 wmb(); 1813 wmb();
1651 h->drv[drv_index].queue = disk->queue; 1814 h->drv[drv_index]->queue = disk->queue;
1652 add_disk(disk); 1815 add_disk(disk);
1816 return 0;
1817
1818cleanup_queue:
1819 blk_cleanup_queue(disk->queue);
1820 disk->queue = NULL;
1821init_queue_failure:
1822 return -1;
1653} 1823}
1654 1824
1655/* This function will check the usage_count of the drive to be updated/added. 1825/* This function will check the usage_count of the drive to be updated/added.
@@ -1662,7 +1832,8 @@ static void cciss_add_disk(ctlr_info_t *h, struct gendisk *disk,
1662 * is also the controller node. Any changes to disk 0 will show up on 1832 * is also the controller node. Any changes to disk 0 will show up on
1663 * the next reboot. 1833 * the next reboot.
1664 */ 1834 */
1665static void cciss_update_drive_info(int ctlr, int drv_index, int first_time) 1835static void cciss_update_drive_info(int ctlr, int drv_index, int first_time,
1836 int via_ioctl)
1666{ 1837{
1667 ctlr_info_t *h = hba[ctlr]; 1838 ctlr_info_t *h = hba[ctlr];
1668 struct gendisk *disk; 1839 struct gendisk *disk;
@@ -1672,21 +1843,13 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time)
1672 unsigned long flags = 0; 1843 unsigned long flags = 0;
1673 int ret = 0; 1844 int ret = 0;
1674 drive_info_struct *drvinfo; 1845 drive_info_struct *drvinfo;
1675 int was_only_controller_node;
1676 1846
1677 /* Get information about the disk and modify the driver structure */ 1847 /* Get information about the disk and modify the driver structure */
1678 inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL); 1848 inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL);
1679 drvinfo = kmalloc(sizeof(*drvinfo), GFP_KERNEL); 1849 drvinfo = kzalloc(sizeof(*drvinfo), GFP_KERNEL);
1680 if (inq_buff == NULL || drvinfo == NULL) 1850 if (inq_buff == NULL || drvinfo == NULL)
1681 goto mem_msg; 1851 goto mem_msg;
1682 1852
1683 /* See if we're trying to update the "controller node"
1684 * this will happen the when the first logical drive gets
1685 * created by ACU.
1686 */
1687 was_only_controller_node = (drv_index == 0 &&
1688 h->drv[0].raid_level == -1);
1689
1690 /* testing to see if 16-byte CDBs are already being used */ 1853 /* testing to see if 16-byte CDBs are already being used */
1691 if (h->cciss_read == CCISS_READ_16) { 1854 if (h->cciss_read == CCISS_READ_16) {
1692 cciss_read_capacity_16(h->ctlr, drv_index, 1, 1855 cciss_read_capacity_16(h->ctlr, drv_index, 1,
@@ -1719,16 +1882,19 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time)
1719 drvinfo->model, drvinfo->rev); 1882 drvinfo->model, drvinfo->rev);
1720 cciss_get_serial_no(ctlr, drv_index, 1, drvinfo->serial_no, 1883 cciss_get_serial_no(ctlr, drv_index, 1, drvinfo->serial_no,
1721 sizeof(drvinfo->serial_no)); 1884 sizeof(drvinfo->serial_no));
1885 /* Save the lunid in case we deregister the disk, below. */
1886 memcpy(drvinfo->LunID, h->drv[drv_index]->LunID,
1887 sizeof(drvinfo->LunID));
1722 1888
1723 /* Is it the same disk we already know, and nothing's changed? */ 1889 /* Is it the same disk we already know, and nothing's changed? */
1724 if (h->drv[drv_index].raid_level != -1 && 1890 if (h->drv[drv_index]->raid_level != -1 &&
1725 ((memcmp(drvinfo->serial_no, 1891 ((memcmp(drvinfo->serial_no,
1726 h->drv[drv_index].serial_no, 16) == 0) && 1892 h->drv[drv_index]->serial_no, 16) == 0) &&
1727 drvinfo->block_size == h->drv[drv_index].block_size && 1893 drvinfo->block_size == h->drv[drv_index]->block_size &&
1728 drvinfo->nr_blocks == h->drv[drv_index].nr_blocks && 1894 drvinfo->nr_blocks == h->drv[drv_index]->nr_blocks &&
1729 drvinfo->heads == h->drv[drv_index].heads && 1895 drvinfo->heads == h->drv[drv_index]->heads &&
1730 drvinfo->sectors == h->drv[drv_index].sectors && 1896 drvinfo->sectors == h->drv[drv_index]->sectors &&
1731 drvinfo->cylinders == h->drv[drv_index].cylinders)) 1897 drvinfo->cylinders == h->drv[drv_index]->cylinders))
1732 /* The disk is unchanged, nothing to update */ 1898 /* The disk is unchanged, nothing to update */
1733 goto freeret; 1899 goto freeret;
1734 1900
@@ -1738,18 +1904,17 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time)
1738 * If the disk already exists then deregister it before proceeding 1904 * If the disk already exists then deregister it before proceeding
1739 * (unless it's the first disk (for the controller node). 1905 * (unless it's the first disk (for the controller node).
1740 */ 1906 */
1741 if (h->drv[drv_index].raid_level != -1 && drv_index != 0) { 1907 if (h->drv[drv_index]->raid_level != -1 && drv_index != 0) {
1742 printk(KERN_WARNING "disk %d has changed.\n", drv_index); 1908 printk(KERN_WARNING "disk %d has changed.\n", drv_index);
1743 spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); 1909 spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
1744 h->drv[drv_index].busy_configuring = 1; 1910 h->drv[drv_index]->busy_configuring = 1;
1745 spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); 1911 spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
1746 1912
1747 /* deregister_disk sets h->drv[drv_index].queue = NULL 1913 /* deregister_disk sets h->drv[drv_index]->queue = NULL
1748 * which keeps the interrupt handler from starting 1914 * which keeps the interrupt handler from starting
1749 * the queue. 1915 * the queue.
1750 */ 1916 */
1751 ret = deregister_disk(h, drv_index, 0); 1917 ret = deregister_disk(h, drv_index, 0, via_ioctl);
1752 h->drv[drv_index].busy_configuring = 0;
1753 } 1918 }
1754 1919
1755 /* If the disk is in use return */ 1920 /* If the disk is in use return */
@@ -1757,22 +1922,31 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time)
1757 goto freeret; 1922 goto freeret;
1758 1923
1759 /* Save the new information from cciss_geometry_inquiry 1924 /* Save the new information from cciss_geometry_inquiry
1760 * and serial number inquiry. 1925 * and serial number inquiry. If the disk was deregistered
1926 * above, then h->drv[drv_index] will be NULL.
1761 */ 1927 */
1762 h->drv[drv_index].block_size = drvinfo->block_size; 1928 if (h->drv[drv_index] == NULL) {
1763 h->drv[drv_index].nr_blocks = drvinfo->nr_blocks; 1929 drvinfo->device_initialized = 0;
1764 h->drv[drv_index].heads = drvinfo->heads; 1930 h->drv[drv_index] = drvinfo;
1765 h->drv[drv_index].sectors = drvinfo->sectors; 1931 drvinfo = NULL; /* so it won't be freed below. */
1766 h->drv[drv_index].cylinders = drvinfo->cylinders; 1932 } else {
1767 h->drv[drv_index].raid_level = drvinfo->raid_level; 1933 /* special case for cxd0 */
1768 memcpy(h->drv[drv_index].serial_no, drvinfo->serial_no, 16); 1934 h->drv[drv_index]->block_size = drvinfo->block_size;
1769 memcpy(h->drv[drv_index].vendor, drvinfo->vendor, VENDOR_LEN + 1); 1935 h->drv[drv_index]->nr_blocks = drvinfo->nr_blocks;
1770 memcpy(h->drv[drv_index].model, drvinfo->model, MODEL_LEN + 1); 1936 h->drv[drv_index]->heads = drvinfo->heads;
1771 memcpy(h->drv[drv_index].rev, drvinfo->rev, REV_LEN + 1); 1937 h->drv[drv_index]->sectors = drvinfo->sectors;
1938 h->drv[drv_index]->cylinders = drvinfo->cylinders;
1939 h->drv[drv_index]->raid_level = drvinfo->raid_level;
1940 memcpy(h->drv[drv_index]->serial_no, drvinfo->serial_no, 16);
1941 memcpy(h->drv[drv_index]->vendor, drvinfo->vendor,
1942 VENDOR_LEN + 1);
1943 memcpy(h->drv[drv_index]->model, drvinfo->model, MODEL_LEN + 1);
1944 memcpy(h->drv[drv_index]->rev, drvinfo->rev, REV_LEN + 1);
1945 }
1772 1946
1773 ++h->num_luns; 1947 ++h->num_luns;
1774 disk = h->gendisk[drv_index]; 1948 disk = h->gendisk[drv_index];
1775 set_capacity(disk, h->drv[drv_index].nr_blocks); 1949 set_capacity(disk, h->drv[drv_index]->nr_blocks);
1776 1950
1777 /* If it's not disk 0 (drv_index != 0) 1951 /* If it's not disk 0 (drv_index != 0)
1778 * or if it was disk 0, but there was previously 1952 * or if it was disk 0, but there was previously
@@ -1780,8 +1954,15 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time)
1780 * (raid_leve == -1) then we want to update the 1954 * (raid_leve == -1) then we want to update the
1781 * logical drive's information. 1955 * logical drive's information.
1782 */ 1956 */
1783 if (drv_index || first_time) 1957 if (drv_index || first_time) {
1784 cciss_add_disk(h, disk, drv_index); 1958 if (cciss_add_disk(h, disk, drv_index) != 0) {
1959 cciss_free_gendisk(h, drv_index);
1960 cciss_free_drive_info(h, drv_index);
1961 printk(KERN_WARNING "cciss:%d could not update "
1962 "disk %d\n", h->ctlr, drv_index);
1963 --h->num_luns;
1964 }
1965 }
1785 1966
1786freeret: 1967freeret:
1787 kfree(inq_buff); 1968 kfree(inq_buff);
@@ -1793,28 +1974,70 @@ mem_msg:
1793} 1974}
1794 1975
1795/* This function will find the first index of the controllers drive array 1976/* This function will find the first index of the controllers drive array
1796 * that has a -1 for the raid_level and will return that index. This is 1977 * that has a null drv pointer and allocate the drive info struct and
1797 * where new drives will be added. If the index to be returned is greater 1978 * will return that index This is where new drives will be added.
1798 * than the highest_lun index for the controller then highest_lun is set 1979 * If the index to be returned is greater than the highest_lun index for
1799 * to this new index. If there are no available indexes then -1 is returned. 1980 * the controller then highest_lun is set * to this new index.
1800 * "controller_node" is used to know if this is a real logical drive, or just 1981 * If there are no available indexes or if tha allocation fails, then -1
1801 * the controller node, which determines if this counts towards highest_lun. 1982 * is returned. * "controller_node" is used to know if this is a real
1983 * logical drive, or just the controller node, which determines if this
1984 * counts towards highest_lun.
1802 */ 1985 */
1803static int cciss_find_free_drive_index(int ctlr, int controller_node) 1986static int cciss_alloc_drive_info(ctlr_info_t *h, int controller_node)
1804{ 1987{
1805 int i; 1988 int i;
1989 drive_info_struct *drv;
1806 1990
1991 /* Search for an empty slot for our drive info */
1807 for (i = 0; i < CISS_MAX_LUN; i++) { 1992 for (i = 0; i < CISS_MAX_LUN; i++) {
1808 if (hba[ctlr]->drv[i].raid_level == -1) { 1993
1809 if (i > hba[ctlr]->highest_lun) 1994 /* if not cxd0 case, and it's occupied, skip it. */
1810 if (!controller_node) 1995 if (h->drv[i] && i != 0)
1811 hba[ctlr]->highest_lun = i; 1996 continue;
1997 /*
1998 * If it's cxd0 case, and drv is alloc'ed already, and a
1999 * disk is configured there, skip it.
2000 */
2001 if (i == 0 && h->drv[i] && h->drv[i]->raid_level != -1)
2002 continue;
2003
2004 /*
2005 * We've found an empty slot. Update highest_lun
2006 * provided this isn't just the fake cxd0 controller node.
2007 */
2008 if (i > h->highest_lun && !controller_node)
2009 h->highest_lun = i;
2010
2011 /* If adding a real disk at cxd0, and it's already alloc'ed */
2012 if (i == 0 && h->drv[i] != NULL)
1812 return i; 2013 return i;
1813 } 2014
2015 /*
2016 * Found an empty slot, not already alloc'ed. Allocate it.
2017 * Mark it with raid_level == -1, so we know it's new later on.
2018 */
2019 drv = kzalloc(sizeof(*drv), GFP_KERNEL);
2020 if (!drv)
2021 return -1;
2022 drv->raid_level = -1; /* so we know it's new */
2023 h->drv[i] = drv;
2024 return i;
1814 } 2025 }
1815 return -1; 2026 return -1;
1816} 2027}
1817 2028
2029static void cciss_free_drive_info(ctlr_info_t *h, int drv_index)
2030{
2031 kfree(h->drv[drv_index]);
2032 h->drv[drv_index] = NULL;
2033}
2034
2035static void cciss_free_gendisk(ctlr_info_t *h, int drv_index)
2036{
2037 put_disk(h->gendisk[drv_index]);
2038 h->gendisk[drv_index] = NULL;
2039}
2040
1818/* cciss_add_gendisk finds a free hba[]->drv structure 2041/* cciss_add_gendisk finds a free hba[]->drv structure
1819 * and allocates a gendisk if needed, and sets the lunid 2042 * and allocates a gendisk if needed, and sets the lunid
1820 * in the drvinfo structure. It returns the index into 2043 * in the drvinfo structure. It returns the index into
@@ -1824,13 +2047,15 @@ static int cciss_find_free_drive_index(int ctlr, int controller_node)
1824 * a means to talk to the controller in case no logical 2047 * a means to talk to the controller in case no logical
1825 * drives have yet been configured. 2048 * drives have yet been configured.
1826 */ 2049 */
1827static int cciss_add_gendisk(ctlr_info_t *h, __u32 lunid, int controller_node) 2050static int cciss_add_gendisk(ctlr_info_t *h, unsigned char lunid[],
2051 int controller_node)
1828{ 2052{
1829 int drv_index; 2053 int drv_index;
1830 2054
1831 drv_index = cciss_find_free_drive_index(h->ctlr, controller_node); 2055 drv_index = cciss_alloc_drive_info(h, controller_node);
1832 if (drv_index == -1) 2056 if (drv_index == -1)
1833 return -1; 2057 return -1;
2058
1834 /*Check if the gendisk needs to be allocated */ 2059 /*Check if the gendisk needs to be allocated */
1835 if (!h->gendisk[drv_index]) { 2060 if (!h->gendisk[drv_index]) {
1836 h->gendisk[drv_index] = 2061 h->gendisk[drv_index] =
@@ -1839,23 +2064,24 @@ static int cciss_add_gendisk(ctlr_info_t *h, __u32 lunid, int controller_node)
1839 printk(KERN_ERR "cciss%d: could not " 2064 printk(KERN_ERR "cciss%d: could not "
1840 "allocate a new disk %d\n", 2065 "allocate a new disk %d\n",
1841 h->ctlr, drv_index); 2066 h->ctlr, drv_index);
1842 return -1; 2067 goto err_free_drive_info;
1843 } 2068 }
1844 } 2069 }
1845 h->drv[drv_index].LunID = lunid; 2070 memcpy(h->drv[drv_index]->LunID, lunid,
1846 if (cciss_create_ld_sysfs_entry(h, &h->drv[drv_index], drv_index)) 2071 sizeof(h->drv[drv_index]->LunID));
2072 if (cciss_create_ld_sysfs_entry(h, drv_index))
1847 goto err_free_disk; 2073 goto err_free_disk;
1848
1849 /* Don't need to mark this busy because nobody */ 2074 /* Don't need to mark this busy because nobody */
1850 /* else knows about this disk yet to contend */ 2075 /* else knows about this disk yet to contend */
1851 /* for access to it. */ 2076 /* for access to it. */
1852 h->drv[drv_index].busy_configuring = 0; 2077 h->drv[drv_index]->busy_configuring = 0;
1853 wmb(); 2078 wmb();
1854 return drv_index; 2079 return drv_index;
1855 2080
1856err_free_disk: 2081err_free_disk:
1857 put_disk(h->gendisk[drv_index]); 2082 cciss_free_gendisk(h, drv_index);
1858 h->gendisk[drv_index] = NULL; 2083err_free_drive_info:
2084 cciss_free_drive_info(h, drv_index);
1859 return -1; 2085 return -1;
1860} 2086}
1861 2087
@@ -1872,21 +2098,25 @@ static void cciss_add_controller_node(ctlr_info_t *h)
1872 if (h->gendisk[0] != NULL) /* already did this? Then bail. */ 2098 if (h->gendisk[0] != NULL) /* already did this? Then bail. */
1873 return; 2099 return;
1874 2100
1875 drv_index = cciss_add_gendisk(h, 0, 1); 2101 drv_index = cciss_add_gendisk(h, CTLR_LUNID, 1);
1876 if (drv_index == -1) { 2102 if (drv_index == -1)
1877 printk(KERN_WARNING "cciss%d: could not " 2103 goto error;
1878 "add disk 0.\n", h->ctlr); 2104 h->drv[drv_index]->block_size = 512;
1879 return; 2105 h->drv[drv_index]->nr_blocks = 0;
1880 } 2106 h->drv[drv_index]->heads = 0;
1881 h->drv[drv_index].block_size = 512; 2107 h->drv[drv_index]->sectors = 0;
1882 h->drv[drv_index].nr_blocks = 0; 2108 h->drv[drv_index]->cylinders = 0;
1883 h->drv[drv_index].heads = 0; 2109 h->drv[drv_index]->raid_level = -1;
1884 h->drv[drv_index].sectors = 0; 2110 memset(h->drv[drv_index]->serial_no, 0, 16);
1885 h->drv[drv_index].cylinders = 0;
1886 h->drv[drv_index].raid_level = -1;
1887 memset(h->drv[drv_index].serial_no, 0, 16);
1888 disk = h->gendisk[drv_index]; 2111 disk = h->gendisk[drv_index];
1889 cciss_add_disk(h, disk, drv_index); 2112 if (cciss_add_disk(h, disk, drv_index) == 0)
2113 return;
2114 cciss_free_gendisk(h, drv_index);
2115 cciss_free_drive_info(h, drv_index);
2116error:
2117 printk(KERN_WARNING "cciss%d: could not "
2118 "add disk 0.\n", h->ctlr);
2119 return;
1890} 2120}
1891 2121
1892/* This function will add and remove logical drives from the Logical 2122/* This function will add and remove logical drives from the Logical
@@ -1897,7 +2127,8 @@ static void cciss_add_controller_node(ctlr_info_t *h)
1897 * INPUT 2127 * INPUT
1898 * h = The controller to perform the operations on 2128 * h = The controller to perform the operations on
1899 */ 2129 */
1900static int rebuild_lun_table(ctlr_info_t *h, int first_time) 2130static int rebuild_lun_table(ctlr_info_t *h, int first_time,
2131 int via_ioctl)
1901{ 2132{
1902 int ctlr = h->ctlr; 2133 int ctlr = h->ctlr;
1903 int num_luns; 2134 int num_luns;
@@ -1907,7 +2138,7 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time)
1907 int i; 2138 int i;
1908 int drv_found; 2139 int drv_found;
1909 int drv_index = 0; 2140 int drv_index = 0;
1910 __u32 lunid = 0; 2141 unsigned char lunid[8] = CTLR_LUNID;
1911 unsigned long flags; 2142 unsigned long flags;
1912 2143
1913 if (!capable(CAP_SYS_RAWIO)) 2144 if (!capable(CAP_SYS_RAWIO))
@@ -1960,13 +2191,13 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time)
1960 drv_found = 0; 2191 drv_found = 0;
1961 2192
1962 /* skip holes in the array from already deleted drives */ 2193 /* skip holes in the array from already deleted drives */
1963 if (h->drv[i].raid_level == -1) 2194 if (h->drv[i] == NULL)
1964 continue; 2195 continue;
1965 2196
1966 for (j = 0; j < num_luns; j++) { 2197 for (j = 0; j < num_luns; j++) {
1967 memcpy(&lunid, &ld_buff->LUN[j][0], 4); 2198 memcpy(lunid, &ld_buff->LUN[j][0], sizeof(lunid));
1968 lunid = le32_to_cpu(lunid); 2199 if (memcmp(h->drv[i]->LunID, lunid,
1969 if (h->drv[i].LunID == lunid) { 2200 sizeof(lunid)) == 0) {
1970 drv_found = 1; 2201 drv_found = 1;
1971 break; 2202 break;
1972 } 2203 }
@@ -1974,11 +2205,11 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time)
1974 if (!drv_found) { 2205 if (!drv_found) {
1975 /* Deregister it from the OS, it's gone. */ 2206 /* Deregister it from the OS, it's gone. */
1976 spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); 2207 spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
1977 h->drv[i].busy_configuring = 1; 2208 h->drv[i]->busy_configuring = 1;
1978 spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); 2209 spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
1979 return_code = deregister_disk(h, i, 1); 2210 return_code = deregister_disk(h, i, 1, via_ioctl);
1980 cciss_destroy_ld_sysfs_entry(&h->drv[i]); 2211 if (h->drv[i] != NULL)
1981 h->drv[i].busy_configuring = 0; 2212 h->drv[i]->busy_configuring = 0;
1982 } 2213 }
1983 } 2214 }
1984 2215
@@ -1992,17 +2223,16 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time)
1992 2223
1993 drv_found = 0; 2224 drv_found = 0;
1994 2225
1995 memcpy(&lunid, &ld_buff->LUN[i][0], 4); 2226 memcpy(lunid, &ld_buff->LUN[i][0], sizeof(lunid));
1996 lunid = le32_to_cpu(lunid);
1997
1998 /* Find if the LUN is already in the drive array 2227 /* Find if the LUN is already in the drive array
1999 * of the driver. If so then update its info 2228 * of the driver. If so then update its info
2000 * if not in use. If it does not exist then find 2229 * if not in use. If it does not exist then find
2001 * the first free index and add it. 2230 * the first free index and add it.
2002 */ 2231 */
2003 for (j = 0; j <= h->highest_lun; j++) { 2232 for (j = 0; j <= h->highest_lun; j++) {
2004 if (h->drv[j].raid_level != -1 && 2233 if (h->drv[j] != NULL &&
2005 h->drv[j].LunID == lunid) { 2234 memcmp(h->drv[j]->LunID, lunid,
2235 sizeof(h->drv[j]->LunID)) == 0) {
2006 drv_index = j; 2236 drv_index = j;
2007 drv_found = 1; 2237 drv_found = 1;
2008 break; 2238 break;
@@ -2015,7 +2245,8 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time)
2015 if (drv_index == -1) 2245 if (drv_index == -1)
2016 goto freeret; 2246 goto freeret;
2017 } 2247 }
2018 cciss_update_drive_info(ctlr, drv_index, first_time); 2248 cciss_update_drive_info(ctlr, drv_index, first_time,
2249 via_ioctl);
2019 } /* end for */ 2250 } /* end for */
2020 2251
2021freeret: 2252freeret:
@@ -2032,6 +2263,25 @@ mem_msg:
2032 goto freeret; 2263 goto freeret;
2033} 2264}
2034 2265
2266static void cciss_clear_drive_info(drive_info_struct *drive_info)
2267{
2268 /* zero out the disk size info */
2269 drive_info->nr_blocks = 0;
2270 drive_info->block_size = 0;
2271 drive_info->heads = 0;
2272 drive_info->sectors = 0;
2273 drive_info->cylinders = 0;
2274 drive_info->raid_level = -1;
2275 memset(drive_info->serial_no, 0, sizeof(drive_info->serial_no));
2276 memset(drive_info->model, 0, sizeof(drive_info->model));
2277 memset(drive_info->rev, 0, sizeof(drive_info->rev));
2278 memset(drive_info->vendor, 0, sizeof(drive_info->vendor));
2279 /*
2280 * don't clear the LUNID though, we need to remember which
2281 * one this one is.
2282 */
2283}
2284
2035/* This function will deregister the disk and it's queue from the 2285/* This function will deregister the disk and it's queue from the
2036 * kernel. It must be called with the controller lock held and the 2286 * kernel. It must be called with the controller lock held and the
2037 * drv structures busy_configuring flag set. It's parameters are: 2287 * drv structures busy_configuring flag set. It's parameters are:
@@ -2046,43 +2296,48 @@ mem_msg:
2046 * the disk in preparation for re-adding it. In this case 2296 * the disk in preparation for re-adding it. In this case
2047 * the highest_lun should be left unchanged and the LunID 2297 * the highest_lun should be left unchanged and the LunID
2048 * should not be cleared. 2298 * should not be cleared.
2299 * via_ioctl
2300 * This indicates whether we've reached this path via ioctl.
2301 * This affects the maximum usage count allowed for c0d0 to be messed with.
2302 * If this path is reached via ioctl(), then the max_usage_count will
2303 * be 1, as the process calling ioctl() has got to have the device open.
2304 * If we get here via sysfs, then the max usage count will be zero.
2049*/ 2305*/
2050static int deregister_disk(ctlr_info_t *h, int drv_index, 2306static int deregister_disk(ctlr_info_t *h, int drv_index,
2051 int clear_all) 2307 int clear_all, int via_ioctl)
2052{ 2308{
2053 int i; 2309 int i;
2054 struct gendisk *disk; 2310 struct gendisk *disk;
2055 drive_info_struct *drv; 2311 drive_info_struct *drv;
2312 int recalculate_highest_lun;
2056 2313
2057 if (!capable(CAP_SYS_RAWIO)) 2314 if (!capable(CAP_SYS_RAWIO))
2058 return -EPERM; 2315 return -EPERM;
2059 2316
2060 drv = &h->drv[drv_index]; 2317 drv = h->drv[drv_index];
2061 disk = h->gendisk[drv_index]; 2318 disk = h->gendisk[drv_index];
2062 2319
2063 /* make sure logical volume is NOT is use */ 2320 /* make sure logical volume is NOT is use */
2064 if (clear_all || (h->gendisk[0] == disk)) { 2321 if (clear_all || (h->gendisk[0] == disk)) {
2065 if (drv->usage_count > 1) 2322 if (drv->usage_count > via_ioctl)
2066 return -EBUSY; 2323 return -EBUSY;
2067 } else if (drv->usage_count > 0) 2324 } else if (drv->usage_count > 0)
2068 return -EBUSY; 2325 return -EBUSY;
2069 2326
2327 recalculate_highest_lun = (drv == h->drv[h->highest_lun]);
2328
2070 /* invalidate the devices and deregister the disk. If it is disk 2329 /* invalidate the devices and deregister the disk. If it is disk
2071 * zero do not deregister it but just zero out it's values. This 2330 * zero do not deregister it but just zero out it's values. This
2072 * allows us to delete disk zero but keep the controller registered. 2331 * allows us to delete disk zero but keep the controller registered.
2073 */ 2332 */
2074 if (h->gendisk[0] != disk) { 2333 if (h->gendisk[0] != disk) {
2075 struct request_queue *q = disk->queue; 2334 struct request_queue *q = disk->queue;
2076 if (disk->flags & GENHD_FL_UP) 2335 if (disk->flags & GENHD_FL_UP) {
2336 cciss_destroy_ld_sysfs_entry(h, drv_index, 0);
2077 del_gendisk(disk); 2337 del_gendisk(disk);
2078 if (q) {
2079 blk_cleanup_queue(q);
2080 /* Set drv->queue to NULL so that we do not try
2081 * to call blk_start_queue on this queue in the
2082 * interrupt handler
2083 */
2084 drv->queue = NULL;
2085 } 2338 }
2339 if (q)
2340 blk_cleanup_queue(q);
2086 /* If clear_all is set then we are deleting the logical 2341 /* If clear_all is set then we are deleting the logical
2087 * drive, not just refreshing its info. For drives 2342 * drive, not just refreshing its info. For drives
2088 * other than disk 0 we will call put_disk. We do not 2343 * other than disk 0 we will call put_disk. We do not
@@ -2105,34 +2360,20 @@ static int deregister_disk(ctlr_info_t *h, int drv_index,
2105 } 2360 }
2106 } else { 2361 } else {
2107 set_capacity(disk, 0); 2362 set_capacity(disk, 0);
2363 cciss_clear_drive_info(drv);
2108 } 2364 }
2109 2365
2110 --h->num_luns; 2366 --h->num_luns;
2111 /* zero out the disk size info */
2112 drv->nr_blocks = 0;
2113 drv->block_size = 0;
2114 drv->heads = 0;
2115 drv->sectors = 0;
2116 drv->cylinders = 0;
2117 drv->raid_level = -1; /* This can be used as a flag variable to
2118 * indicate that this element of the drive
2119 * array is free.
2120 */
2121
2122 if (clear_all) {
2123 /* check to see if it was the last disk */
2124 if (drv == h->drv + h->highest_lun) {
2125 /* if so, find the new hightest lun */
2126 int i, newhighest = -1;
2127 for (i = 0; i <= h->highest_lun; i++) {
2128 /* if the disk has size > 0, it is available */
2129 if (h->drv[i].heads)
2130 newhighest = i;
2131 }
2132 h->highest_lun = newhighest;
2133 }
2134 2367
2135 drv->LunID = 0; 2368 /* if it was the last disk, find the new hightest lun */
2369 if (clear_all && recalculate_highest_lun) {
2370 int i, newhighest = -1;
2371 for (i = 0; i <= h->highest_lun; i++) {
2372 /* if the disk has size > 0, it is available */
2373 if (h->drv[i] && h->drv[i]->heads)
2374 newhighest = i;
2375 }
2376 h->highest_lun = newhighest;
2136 } 2377 }
2137 return 0; 2378 return 0;
2138} 2379}
@@ -2479,8 +2720,6 @@ static void cciss_geometry_inquiry(int ctlr, int logvol,
2479 } else { /* Get geometry failed */ 2720 } else { /* Get geometry failed */
2480 printk(KERN_WARNING "cciss: reading geometry failed\n"); 2721 printk(KERN_WARNING "cciss: reading geometry failed\n");
2481 } 2722 }
2482 printk(KERN_INFO " heads=%d, sectors=%d, cylinders=%d\n\n",
2483 drv->heads, drv->sectors, drv->cylinders);
2484} 2723}
2485 2724
2486static void 2725static void
@@ -2514,9 +2753,6 @@ cciss_read_capacity(int ctlr, int logvol, int withirq, sector_t *total_size,
2514 *total_size = 0; 2753 *total_size = 0;
2515 *block_size = BLOCK_SIZE; 2754 *block_size = BLOCK_SIZE;
2516 } 2755 }
2517 if (*total_size != 0)
2518 printk(KERN_INFO " blocks= %llu block_size= %d\n",
2519 (unsigned long long)*total_size+1, *block_size);
2520 kfree(buf); 2756 kfree(buf);
2521} 2757}
2522 2758
@@ -2568,7 +2804,8 @@ static int cciss_revalidate(struct gendisk *disk)
2568 InquiryData_struct *inq_buff = NULL; 2804 InquiryData_struct *inq_buff = NULL;
2569 2805
2570 for (logvol = 0; logvol < CISS_MAX_LUN; logvol++) { 2806 for (logvol = 0; logvol < CISS_MAX_LUN; logvol++) {
2571 if (h->drv[logvol].LunID == drv->LunID) { 2807 if (memcmp(h->drv[logvol]->LunID, drv->LunID,
2808 sizeof(drv->LunID)) == 0) {
2572 FOUND = 1; 2809 FOUND = 1;
2573 break; 2810 break;
2574 } 2811 }
@@ -3053,8 +3290,7 @@ static void do_cciss_request(struct request_queue *q)
3053 /* The first 2 bits are reserved for controller error reporting. */ 3290 /* The first 2 bits are reserved for controller error reporting. */
3054 c->Header.Tag.lower = (c->cmdindex << 3); 3291 c->Header.Tag.lower = (c->cmdindex << 3);
3055 c->Header.Tag.lower |= 0x04; /* flag for direct lookup. */ 3292 c->Header.Tag.lower |= 0x04; /* flag for direct lookup. */
3056 c->Header.LUN.LogDev.VolId = drv->LunID; 3293 memcpy(&c->Header.LUN, drv->LunID, sizeof(drv->LunID));
3057 c->Header.LUN.LogDev.Mode = 1;
3058 c->Request.CDBLen = 10; // 12 byte commands not in FW yet; 3294 c->Request.CDBLen = 10; // 12 byte commands not in FW yet;
3059 c->Request.Type.Type = TYPE_CMD; // It is a command. 3295 c->Request.Type.Type = TYPE_CMD; // It is a command.
3060 c->Request.Type.Attribute = ATTR_SIMPLE; 3296 c->Request.Type.Attribute = ATTR_SIMPLE;
@@ -3232,20 +3468,121 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id)
3232 return IRQ_HANDLED; 3468 return IRQ_HANDLED;
3233} 3469}
3234 3470
3471/**
3472 * add_to_scan_list() - add controller to rescan queue
3473 * @h: Pointer to the controller.
3474 *
3475 * Adds the controller to the rescan queue if not already on the queue.
3476 *
3477 * returns 1 if added to the queue, 0 if skipped (could be on the
3478 * queue already, or the controller could be initializing or shutting
3479 * down).
3480 **/
3481static int add_to_scan_list(struct ctlr_info *h)
3482{
3483 struct ctlr_info *test_h;
3484 int found = 0;
3485 int ret = 0;
3486
3487 if (h->busy_initializing)
3488 return 0;
3489
3490 if (!mutex_trylock(&h->busy_shutting_down))
3491 return 0;
3492
3493 mutex_lock(&scan_mutex);
3494 list_for_each_entry(test_h, &scan_q, scan_list) {
3495 if (test_h == h) {
3496 found = 1;
3497 break;
3498 }
3499 }
3500 if (!found && !h->busy_scanning) {
3501 INIT_COMPLETION(h->scan_wait);
3502 list_add_tail(&h->scan_list, &scan_q);
3503 ret = 1;
3504 }
3505 mutex_unlock(&scan_mutex);
3506 mutex_unlock(&h->busy_shutting_down);
3507
3508 return ret;
3509}
3510
3511/**
3512 * remove_from_scan_list() - remove controller from rescan queue
3513 * @h: Pointer to the controller.
3514 *
3515 * Removes the controller from the rescan queue if present. Blocks if
3516 * the controller is currently conducting a rescan.
3517 **/
3518static void remove_from_scan_list(struct ctlr_info *h)
3519{
3520 struct ctlr_info *test_h, *tmp_h;
3521 int scanning = 0;
3522
3523 mutex_lock(&scan_mutex);
3524 list_for_each_entry_safe(test_h, tmp_h, &scan_q, scan_list) {
3525 if (test_h == h) {
3526 list_del(&h->scan_list);
3527 complete_all(&h->scan_wait);
3528 mutex_unlock(&scan_mutex);
3529 return;
3530 }
3531 }
3532 if (&h->busy_scanning)
3533 scanning = 0;
3534 mutex_unlock(&scan_mutex);
3535
3536 if (scanning)
3537 wait_for_completion(&h->scan_wait);
3538}
3539
3540/**
3541 * scan_thread() - kernel thread used to rescan controllers
3542 * @data: Ignored.
3543 *
3544 * A kernel thread used scan for drive topology changes on
3545 * controllers. The thread processes only one controller at a time
3546 * using a queue. Controllers are added to the queue using
3547 * add_to_scan_list() and removed from the queue either after done
3548 * processing or using remove_from_scan_list().
3549 *
3550 * returns 0.
3551 **/
3235static int scan_thread(void *data) 3552static int scan_thread(void *data)
3236{ 3553{
3237 ctlr_info_t *h = data; 3554 struct ctlr_info *h;
3238 int rc;
3239 DECLARE_COMPLETION_ONSTACK(wait);
3240 h->rescan_wait = &wait;
3241 3555
3242 for (;;) { 3556 while (1) {
3243 rc = wait_for_completion_interruptible(&wait); 3557 set_current_state(TASK_INTERRUPTIBLE);
3558 schedule();
3244 if (kthread_should_stop()) 3559 if (kthread_should_stop())
3245 break; 3560 break;
3246 if (!rc) 3561
3247 rebuild_lun_table(h, 0); 3562 while (1) {
3563 mutex_lock(&scan_mutex);
3564 if (list_empty(&scan_q)) {
3565 mutex_unlock(&scan_mutex);
3566 break;
3567 }
3568
3569 h = list_entry(scan_q.next,
3570 struct ctlr_info,
3571 scan_list);
3572 list_del(&h->scan_list);
3573 h->busy_scanning = 1;
3574 mutex_unlock(&scan_mutex);
3575
3576 if (h) {
3577 rebuild_lun_table(h, 0, 0);
3578 complete_all(&h->scan_wait);
3579 mutex_lock(&scan_mutex);
3580 h->busy_scanning = 0;
3581 mutex_unlock(&scan_mutex);
3582 }
3583 }
3248 } 3584 }
3585
3249 return 0; 3586 return 0;
3250} 3587}
3251 3588
@@ -3268,8 +3605,8 @@ static int check_for_unit_attention(ctlr_info_t *h, CommandList_struct *c)
3268 case REPORT_LUNS_CHANGED: 3605 case REPORT_LUNS_CHANGED:
3269 printk(KERN_WARNING "cciss%d: report LUN data " 3606 printk(KERN_WARNING "cciss%d: report LUN data "
3270 "changed\n", h->ctlr); 3607 "changed\n", h->ctlr);
3271 if (h->rescan_wait) 3608 add_to_scan_list(h);
3272 complete(h->rescan_wait); 3609 wake_up_process(cciss_scan_thread);
3273 return 1; 3610 return 1;
3274 break; 3611 break;
3275 case POWER_OR_RESET: 3612 case POWER_OR_RESET:
@@ -3422,7 +3759,27 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
3422 __u64 cfg_offset; 3759 __u64 cfg_offset;
3423 __u32 cfg_base_addr; 3760 __u32 cfg_base_addr;
3424 __u64 cfg_base_addr_index; 3761 __u64 cfg_base_addr_index;
3425 int i, err; 3762 int i, prod_index, err;
3763
3764 subsystem_vendor_id = pdev->subsystem_vendor;
3765 subsystem_device_id = pdev->subsystem_device;
3766 board_id = (((__u32) (subsystem_device_id << 16) & 0xffff0000) |
3767 subsystem_vendor_id);
3768
3769 for (i = 0; i < ARRAY_SIZE(products); i++) {
3770 /* Stand aside for hpsa driver on request */
3771 if (cciss_allow_hpsa && products[i].board_id == HPSA_BOUNDARY)
3772 return -ENODEV;
3773 if (board_id == products[i].board_id)
3774 break;
3775 }
3776 prod_index = i;
3777 if (prod_index == ARRAY_SIZE(products)) {
3778 dev_warn(&pdev->dev,
3779 "unrecognized board ID: 0x%08lx, ignoring.\n",
3780 (unsigned long) board_id);
3781 return -ENODEV;
3782 }
3426 3783
3427 /* check to see if controller has been disabled */ 3784 /* check to see if controller has been disabled */
3428 /* BEFORE trying to enable it */ 3785 /* BEFORE trying to enable it */
@@ -3446,11 +3803,6 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
3446 return err; 3803 return err;
3447 } 3804 }
3448 3805
3449 subsystem_vendor_id = pdev->subsystem_vendor;
3450 subsystem_device_id = pdev->subsystem_device;
3451 board_id = (((__u32) (subsystem_device_id << 16) & 0xffff0000) |
3452 subsystem_vendor_id);
3453
3454#ifdef CCISS_DEBUG 3806#ifdef CCISS_DEBUG
3455 printk("command = %x\n", command); 3807 printk("command = %x\n", command);
3456 printk("irq = %x\n", pdev->irq); 3808 printk("irq = %x\n", pdev->irq);
@@ -3489,7 +3841,7 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
3489 if (scratchpad == CCISS_FIRMWARE_READY) 3841 if (scratchpad == CCISS_FIRMWARE_READY)
3490 break; 3842 break;
3491 set_current_state(TASK_INTERRUPTIBLE); 3843 set_current_state(TASK_INTERRUPTIBLE);
3492 schedule_timeout(HZ / 10); /* wait 100ms */ 3844 schedule_timeout(msecs_to_jiffies(100)); /* wait 100ms */
3493 } 3845 }
3494 if (scratchpad != CCISS_FIRMWARE_READY) { 3846 if (scratchpad != CCISS_FIRMWARE_READY) {
3495 printk(KERN_WARNING "cciss: Board not ready. Timed out.\n"); 3847 printk(KERN_WARNING "cciss: Board not ready. Timed out.\n");
@@ -3536,14 +3888,9 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
3536 * leave a little room for ioctl calls. 3888 * leave a little room for ioctl calls.
3537 */ 3889 */
3538 c->max_commands = readl(&(c->cfgtable->CmdsOutMax)); 3890 c->max_commands = readl(&(c->cfgtable->CmdsOutMax));
3539 for (i = 0; i < ARRAY_SIZE(products); i++) { 3891 c->product_name = products[prod_index].product_name;
3540 if (board_id == products[i].board_id) { 3892 c->access = *(products[prod_index].access);
3541 c->product_name = products[i].product_name; 3893 c->nr_cmds = c->max_commands - 4;
3542 c->access = *(products[i].access);
3543 c->nr_cmds = c->max_commands - 4;
3544 break;
3545 }
3546 }
3547 if ((readb(&c->cfgtable->Signature[0]) != 'C') || 3894 if ((readb(&c->cfgtable->Signature[0]) != 'C') ||
3548 (readb(&c->cfgtable->Signature[1]) != 'I') || 3895 (readb(&c->cfgtable->Signature[1]) != 'I') ||
3549 (readb(&c->cfgtable->Signature[2]) != 'S') || 3896 (readb(&c->cfgtable->Signature[2]) != 'S') ||
@@ -3552,27 +3899,6 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
3552 err = -ENODEV; 3899 err = -ENODEV;
3553 goto err_out_free_res; 3900 goto err_out_free_res;
3554 } 3901 }
3555 /* We didn't find the controller in our list. We know the
3556 * signature is valid. If it's an HP device let's try to
3557 * bind to the device and fire it up. Otherwise we bail.
3558 */
3559 if (i == ARRAY_SIZE(products)) {
3560 if (subsystem_vendor_id == PCI_VENDOR_ID_HP) {
3561 c->product_name = products[i-1].product_name;
3562 c->access = *(products[i-1].access);
3563 c->nr_cmds = c->max_commands - 4;
3564 printk(KERN_WARNING "cciss: This is an unknown "
3565 "Smart Array controller.\n"
3566 "cciss: Please update to the latest driver "
3567 "available from www.hp.com.\n");
3568 } else {
3569 printk(KERN_WARNING "cciss: Sorry, I don't know how"
3570 " to access the Smart Array controller %08lx\n"
3571 , (unsigned long)board_id);
3572 err = -ENODEV;
3573 goto err_out_free_res;
3574 }
3575 }
3576#ifdef CONFIG_X86 3902#ifdef CONFIG_X86
3577 { 3903 {
3578 /* Need to enable prefetch in the SCSI core for 6400 in x86 */ 3904 /* Need to enable prefetch in the SCSI core for 6400 in x86 */
@@ -3615,7 +3941,7 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
3615 break; 3941 break;
3616 /* delay and try again */ 3942 /* delay and try again */
3617 set_current_state(TASK_INTERRUPTIBLE); 3943 set_current_state(TASK_INTERRUPTIBLE);
3618 schedule_timeout(10); 3944 schedule_timeout(msecs_to_jiffies(1));
3619 } 3945 }
3620 3946
3621#ifdef CCISS_DEBUG 3947#ifdef CCISS_DEBUG
@@ -3669,15 +3995,16 @@ Enomem:
3669 return -1; 3995 return -1;
3670} 3996}
3671 3997
3672static void free_hba(int i) 3998static void free_hba(int n)
3673{ 3999{
3674 ctlr_info_t *p = hba[i]; 4000 ctlr_info_t *h = hba[n];
3675 int n; 4001 int i;
3676 4002
3677 hba[i] = NULL; 4003 hba[n] = NULL;
3678 for (n = 0; n < CISS_MAX_LUN; n++) 4004 for (i = 0; i < h->highest_lun + 1; i++)
3679 put_disk(p->gendisk[n]); 4005 if (h->gendisk[i] != NULL)
3680 kfree(p); 4006 put_disk(h->gendisk[i]);
4007 kfree(h);
3681} 4008}
3682 4009
3683/* Send a message CDB to the firmware. */ 4010/* Send a message CDB to the firmware. */
@@ -3918,14 +4245,17 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
3918 hba[i]->busy_initializing = 1; 4245 hba[i]->busy_initializing = 1;
3919 INIT_HLIST_HEAD(&hba[i]->cmpQ); 4246 INIT_HLIST_HEAD(&hba[i]->cmpQ);
3920 INIT_HLIST_HEAD(&hba[i]->reqQ); 4247 INIT_HLIST_HEAD(&hba[i]->reqQ);
4248 mutex_init(&hba[i]->busy_shutting_down);
3921 4249
3922 if (cciss_pci_init(hba[i], pdev) != 0) 4250 if (cciss_pci_init(hba[i], pdev) != 0)
3923 goto clean0; 4251 goto clean_no_release_regions;
3924 4252
3925 sprintf(hba[i]->devname, "cciss%d", i); 4253 sprintf(hba[i]->devname, "cciss%d", i);
3926 hba[i]->ctlr = i; 4254 hba[i]->ctlr = i;
3927 hba[i]->pdev = pdev; 4255 hba[i]->pdev = pdev;
3928 4256
4257 init_completion(&hba[i]->scan_wait);
4258
3929 if (cciss_create_hba_sysfs_entry(hba[i])) 4259 if (cciss_create_hba_sysfs_entry(hba[i]))
3930 goto clean0; 4260 goto clean0;
3931 4261
@@ -4001,8 +4331,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
4001 hba[i]->num_luns = 0; 4331 hba[i]->num_luns = 0;
4002 hba[i]->highest_lun = -1; 4332 hba[i]->highest_lun = -1;
4003 for (j = 0; j < CISS_MAX_LUN; j++) { 4333 for (j = 0; j < CISS_MAX_LUN; j++) {
4004 hba[i]->drv[j].raid_level = -1; 4334 hba[i]->drv[j] = NULL;
4005 hba[i]->drv[j].queue = NULL;
4006 hba[i]->gendisk[j] = NULL; 4335 hba[i]->gendisk[j] = NULL;
4007 } 4336 }
4008 4337
@@ -4035,14 +4364,8 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
4035 4364
4036 hba[i]->cciss_max_sectors = 2048; 4365 hba[i]->cciss_max_sectors = 2048;
4037 4366
4367 rebuild_lun_table(hba[i], 1, 0);
4038 hba[i]->busy_initializing = 0; 4368 hba[i]->busy_initializing = 0;
4039
4040 rebuild_lun_table(hba[i], 1);
4041 hba[i]->cciss_scan_thread = kthread_run(scan_thread, hba[i],
4042 "cciss_scan%02d", i);
4043 if (IS_ERR(hba[i]->cciss_scan_thread))
4044 return PTR_ERR(hba[i]->cciss_scan_thread);
4045
4046 return 1; 4369 return 1;
4047 4370
4048clean4: 4371clean4:
@@ -4062,18 +4385,14 @@ clean2:
4062clean1: 4385clean1:
4063 cciss_destroy_hba_sysfs_entry(hba[i]); 4386 cciss_destroy_hba_sysfs_entry(hba[i]);
4064clean0: 4387clean0:
4388 pci_release_regions(pdev);
4389clean_no_release_regions:
4065 hba[i]->busy_initializing = 0; 4390 hba[i]->busy_initializing = 0;
4066 /* cleanup any queues that may have been initialized */ 4391
4067 for (j=0; j <= hba[i]->highest_lun; j++){
4068 drive_info_struct *drv = &(hba[i]->drv[j]);
4069 if (drv->queue)
4070 blk_cleanup_queue(drv->queue);
4071 }
4072 /* 4392 /*
4073 * Deliberately omit pci_disable_device(): it does something nasty to 4393 * Deliberately omit pci_disable_device(): it does something nasty to
4074 * Smart Array controllers that pci_enable_device does not undo 4394 * Smart Array controllers that pci_enable_device does not undo
4075 */ 4395 */
4076 pci_release_regions(pdev);
4077 pci_set_drvdata(pdev, NULL); 4396 pci_set_drvdata(pdev, NULL);
4078 free_hba(i); 4397 free_hba(i);
4079 return -1; 4398 return -1;
@@ -4125,8 +4444,9 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev)
4125 return; 4444 return;
4126 } 4445 }
4127 4446
4128 kthread_stop(hba[i]->cciss_scan_thread); 4447 mutex_lock(&hba[i]->busy_shutting_down);
4129 4448
4449 remove_from_scan_list(hba[i]);
4130 remove_proc_entry(hba[i]->devname, proc_cciss); 4450 remove_proc_entry(hba[i]->devname, proc_cciss);
4131 unregister_blkdev(hba[i]->major, hba[i]->devname); 4451 unregister_blkdev(hba[i]->major, hba[i]->devname);
4132 4452
@@ -4136,8 +4456,10 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev)
4136 if (disk) { 4456 if (disk) {
4137 struct request_queue *q = disk->queue; 4457 struct request_queue *q = disk->queue;
4138 4458
4139 if (disk->flags & GENHD_FL_UP) 4459 if (disk->flags & GENHD_FL_UP) {
4460 cciss_destroy_ld_sysfs_entry(hba[i], j, 1);
4140 del_gendisk(disk); 4461 del_gendisk(disk);
4462 }
4141 if (q) 4463 if (q)
4142 blk_cleanup_queue(q); 4464 blk_cleanup_queue(q);
4143 } 4465 }
@@ -4170,6 +4492,7 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev)
4170 pci_release_regions(pdev); 4492 pci_release_regions(pdev);
4171 pci_set_drvdata(pdev, NULL); 4493 pci_set_drvdata(pdev, NULL);
4172 cciss_destroy_hba_sysfs_entry(hba[i]); 4494 cciss_destroy_hba_sysfs_entry(hba[i]);
4495 mutex_unlock(&hba[i]->busy_shutting_down);
4173 free_hba(i); 4496 free_hba(i);
4174} 4497}
4175 4498
@@ -4202,15 +4525,25 @@ static int __init cciss_init(void)
4202 if (err) 4525 if (err)
4203 return err; 4526 return err;
4204 4527
4528 /* Start the scan thread */
4529 cciss_scan_thread = kthread_run(scan_thread, NULL, "cciss_scan");
4530 if (IS_ERR(cciss_scan_thread)) {
4531 err = PTR_ERR(cciss_scan_thread);
4532 goto err_bus_unregister;
4533 }
4534
4205 /* Register for our PCI devices */ 4535 /* Register for our PCI devices */
4206 err = pci_register_driver(&cciss_pci_driver); 4536 err = pci_register_driver(&cciss_pci_driver);
4207 if (err) 4537 if (err)
4208 goto err_bus_register; 4538 goto err_thread_stop;
4209 4539
4210 return 0; 4540 return err;
4211 4541
4212err_bus_register: 4542err_thread_stop:
4543 kthread_stop(cciss_scan_thread);
4544err_bus_unregister:
4213 bus_unregister(&cciss_bus_type); 4545 bus_unregister(&cciss_bus_type);
4546
4214 return err; 4547 return err;
4215} 4548}
4216 4549
@@ -4227,6 +4560,7 @@ static void __exit cciss_cleanup(void)
4227 cciss_remove_one(hba[i]->pdev); 4560 cciss_remove_one(hba[i]->pdev);
4228 } 4561 }
4229 } 4562 }
4563 kthread_stop(cciss_scan_thread);
4230 remove_proc_entry("driver/cciss", NULL); 4564 remove_proc_entry("driver/cciss", NULL);
4231 bus_unregister(&cciss_bus_type); 4565 bus_unregister(&cciss_bus_type);
4232} 4566}
diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h
index 06a5db25b298..31524cf42c77 100644
--- a/drivers/block/cciss.h
+++ b/drivers/block/cciss.h
@@ -2,6 +2,7 @@
2#define CCISS_H 2#define CCISS_H
3 3
4#include <linux/genhd.h> 4#include <linux/genhd.h>
5#include <linux/mutex.h>
5 6
6#include "cciss_cmd.h" 7#include "cciss_cmd.h"
7 8
@@ -29,7 +30,7 @@ struct access_method {
29}; 30};
30typedef struct _drive_info_struct 31typedef struct _drive_info_struct
31{ 32{
32 __u32 LunID; 33 unsigned char LunID[8];
33 int usage_count; 34 int usage_count;
34 struct request_queue *queue; 35 struct request_queue *queue;
35 sector_t nr_blocks; 36 sector_t nr_blocks;
@@ -51,6 +52,7 @@ typedef struct _drive_info_struct
51 char vendor[VENDOR_LEN + 1]; /* SCSI vendor string */ 52 char vendor[VENDOR_LEN + 1]; /* SCSI vendor string */
52 char model[MODEL_LEN + 1]; /* SCSI model string */ 53 char model[MODEL_LEN + 1]; /* SCSI model string */
53 char rev[REV_LEN + 1]; /* SCSI revision string */ 54 char rev[REV_LEN + 1]; /* SCSI revision string */
55 char device_initialized; /* indicates whether dev is initialized */
54} drive_info_struct; 56} drive_info_struct;
55 57
56struct ctlr_info 58struct ctlr_info
@@ -86,7 +88,7 @@ struct ctlr_info
86 BYTE cciss_read_capacity; 88 BYTE cciss_read_capacity;
87 89
88 // information about each logical volume 90 // information about each logical volume
89 drive_info_struct drv[CISS_MAX_LUN]; 91 drive_info_struct *drv[CISS_MAX_LUN];
90 92
91 struct access_method access; 93 struct access_method access;
92 94
@@ -108,6 +110,8 @@ struct ctlr_info
108 int nr_frees; 110 int nr_frees;
109 int busy_configuring; 111 int busy_configuring;
110 int busy_initializing; 112 int busy_initializing;
113 int busy_scanning;
114 struct mutex busy_shutting_down;
111 115
112 /* This element holds the zero based queue number of the last 116 /* This element holds the zero based queue number of the last
113 * queue to be started. It is used for fairness. 117 * queue to be started. It is used for fairness.
@@ -122,8 +126,8 @@ struct ctlr_info
122 /* and saved for later processing */ 126 /* and saved for later processing */
123#endif 127#endif
124 unsigned char alive; 128 unsigned char alive;
125 struct completion *rescan_wait; 129 struct list_head scan_list;
126 struct task_struct *cciss_scan_thread; 130 struct completion scan_wait;
127 struct device dev; 131 struct device dev;
128}; 132};
129 133
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
index b82d438e2607..6422651ec364 100644
--- a/drivers/block/cpqarray.c
+++ b/drivers/block/cpqarray.c
@@ -32,6 +32,7 @@
32#include <linux/blkpg.h> 32#include <linux/blkpg.h>
33#include <linux/timer.h> 33#include <linux/timer.h>
34#include <linux/proc_fs.h> 34#include <linux/proc_fs.h>
35#include <linux/seq_file.h>
35#include <linux/init.h> 36#include <linux/init.h>
36#include <linux/hdreg.h> 37#include <linux/hdreg.h>
37#include <linux/spinlock.h> 38#include <linux/spinlock.h>
@@ -177,7 +178,6 @@ static int cpqarray_register_ctlr(int ctlr, struct pci_dev *pdev);
177 178
178#ifdef CONFIG_PROC_FS 179#ifdef CONFIG_PROC_FS
179static void ida_procinit(int i); 180static void ida_procinit(int i);
180static int ida_proc_get_info(char *buffer, char **start, off_t offset, int length, int *eof, void *data);
181#else 181#else
182static void ida_procinit(int i) {} 182static void ida_procinit(int i) {}
183#endif 183#endif
@@ -206,6 +206,7 @@ static const struct block_device_operations ida_fops = {
206#ifdef CONFIG_PROC_FS 206#ifdef CONFIG_PROC_FS
207 207
208static struct proc_dir_entry *proc_array; 208static struct proc_dir_entry *proc_array;
209static const struct file_operations ida_proc_fops;
209 210
210/* 211/*
211 * Get us a file in /proc/array that says something about each controller. 212 * Get us a file in /proc/array that says something about each controller.
@@ -218,19 +219,16 @@ static void __init ida_procinit(int i)
218 if (!proc_array) return; 219 if (!proc_array) return;
219 } 220 }
220 221
221 create_proc_read_entry(hba[i]->devname, 0, proc_array, 222 proc_create_data(hba[i]->devname, 0, proc_array, &ida_proc_fops, hba[i]);
222 ida_proc_get_info, hba[i]);
223} 223}
224 224
225/* 225/*
226 * Report information about this controller. 226 * Report information about this controller.
227 */ 227 */
228static int ida_proc_get_info(char *buffer, char **start, off_t offset, int length, int *eof, void *data) 228static int ida_proc_show(struct seq_file *m, void *v)
229{ 229{
230 off_t pos = 0; 230 int i, ctlr;
231 off_t len = 0; 231 ctlr_info_t *h = (ctlr_info_t*)m->private;
232 int size, i, ctlr;
233 ctlr_info_t *h = (ctlr_info_t*)data;
234 drv_info_t *drv; 232 drv_info_t *drv;
235#ifdef CPQ_PROC_PRINT_QUEUES 233#ifdef CPQ_PROC_PRINT_QUEUES
236 cmdlist_t *c; 234 cmdlist_t *c;
@@ -238,7 +236,7 @@ static int ida_proc_get_info(char *buffer, char **start, off_t offset, int lengt
238#endif 236#endif
239 237
240 ctlr = h->ctlr; 238 ctlr = h->ctlr;
241 size = sprintf(buffer, "%s: Compaq %s Controller\n" 239 seq_printf(m, "%s: Compaq %s Controller\n"
242 " Board ID: 0x%08lx\n" 240 " Board ID: 0x%08lx\n"
243 " Firmware Revision: %c%c%c%c\n" 241 " Firmware Revision: %c%c%c%c\n"
244 " Controller Sig: 0x%08lx\n" 242 " Controller Sig: 0x%08lx\n"
@@ -258,55 +256,54 @@ static int ida_proc_get_info(char *buffer, char **start, off_t offset, int lengt
258 h->log_drives, h->phys_drives, 256 h->log_drives, h->phys_drives,
259 h->Qdepth, h->maxQsinceinit); 257 h->Qdepth, h->maxQsinceinit);
260 258
261 pos += size; len += size; 259 seq_puts(m, "Logical Drive Info:\n");
262
263 size = sprintf(buffer+len, "Logical Drive Info:\n");
264 pos += size; len += size;
265 260
266 for(i=0; i<h->log_drives; i++) { 261 for(i=0; i<h->log_drives; i++) {
267 drv = &h->drv[i]; 262 drv = &h->drv[i];
268 size = sprintf(buffer+len, "ida/c%dd%d: blksz=%d nr_blks=%d\n", 263 seq_printf(m, "ida/c%dd%d: blksz=%d nr_blks=%d\n",
269 ctlr, i, drv->blk_size, drv->nr_blks); 264 ctlr, i, drv->blk_size, drv->nr_blks);
270 pos += size; len += size;
271 } 265 }
272 266
273#ifdef CPQ_PROC_PRINT_QUEUES 267#ifdef CPQ_PROC_PRINT_QUEUES
274 spin_lock_irqsave(IDA_LOCK(h->ctlr), flags); 268 spin_lock_irqsave(IDA_LOCK(h->ctlr), flags);
275 size = sprintf(buffer+len, "\nCurrent Queues:\n"); 269 seq_puts(m, "\nCurrent Queues:\n");
276 pos += size; len += size;
277 270
278 c = h->reqQ; 271 c = h->reqQ;
279 size = sprintf(buffer+len, "reqQ = %p", c); pos += size; len += size; 272 seq_printf(m, "reqQ = %p", c);
280 if (c) c=c->next; 273 if (c) c=c->next;
281 while(c && c != h->reqQ) { 274 while(c && c != h->reqQ) {
282 size = sprintf(buffer+len, "->%p", c); 275 seq_printf(m, "->%p", c);
283 pos += size; len += size;
284 c=c->next; 276 c=c->next;
285 } 277 }
286 278
287 c = h->cmpQ; 279 c = h->cmpQ;
288 size = sprintf(buffer+len, "\ncmpQ = %p", c); pos += size; len += size; 280 seq_printf(m, "\ncmpQ = %p", c);
289 if (c) c=c->next; 281 if (c) c=c->next;
290 while(c && c != h->cmpQ) { 282 while(c && c != h->cmpQ) {
291 size = sprintf(buffer+len, "->%p", c); 283 seq_printf(m, "->%p", c);
292 pos += size; len += size;
293 c=c->next; 284 c=c->next;
294 } 285 }
295 286
296 size = sprintf(buffer+len, "\n"); pos += size; len += size; 287 seq_putc(m, '\n');
297 spin_unlock_irqrestore(IDA_LOCK(h->ctlr), flags); 288 spin_unlock_irqrestore(IDA_LOCK(h->ctlr), flags);
298#endif 289#endif
299 size = sprintf(buffer+len, "nr_allocs = %d\nnr_frees = %d\n", 290 seq_printf(m, "nr_allocs = %d\nnr_frees = %d\n",
300 h->nr_allocs, h->nr_frees); 291 h->nr_allocs, h->nr_frees);
301 pos += size; len += size; 292 return 0;
302 293}
303 *eof = 1; 294
304 *start = buffer+offset; 295static int ida_proc_open(struct inode *inode, struct file *file)
305 len -= offset; 296{
306 if (len>length) 297 return single_open(file, ida_proc_show, PDE(inode)->data);
307 len = length;
308 return len;
309} 298}
299
300static const struct file_operations ida_proc_fops = {
301 .owner = THIS_MODULE,
302 .open = ida_proc_open,
303 .read = seq_read,
304 .llseek = seq_lseek,
305 .release = single_release,
306};
310#endif /* CONFIG_PROC_FS */ 307#endif /* CONFIG_PROC_FS */
311 308
312module_param_array(eisa, int, NULL, 0); 309module_param_array(eisa, int, NULL, 0);
diff --git a/drivers/char/agp/parisc-agp.c b/drivers/char/agp/parisc-agp.c
index 60ab75104da9..1c129211302d 100644
--- a/drivers/char/agp/parisc-agp.c
+++ b/drivers/char/agp/parisc-agp.c
@@ -217,7 +217,7 @@ static const struct agp_bridge_driver parisc_agp_driver = {
217 .configure = parisc_agp_configure, 217 .configure = parisc_agp_configure,
218 .fetch_size = parisc_agp_fetch_size, 218 .fetch_size = parisc_agp_fetch_size,
219 .tlb_flush = parisc_agp_tlbflush, 219 .tlb_flush = parisc_agp_tlbflush,
220 .mask_memory = parisc_agp_page_mask_memory, 220 .mask_memory = parisc_agp_mask_memory,
221 .masks = parisc_agp_masks, 221 .masks = parisc_agp_masks,
222 .agp_enable = parisc_agp_enable, 222 .agp_enable = parisc_agp_enable,
223 .cache_flush = global_cache_flush, 223 .cache_flush = global_cache_flush,
diff --git a/drivers/char/apm-emulation.c b/drivers/char/apm-emulation.c
index aaca40283be9..4f568cb9af3f 100644
--- a/drivers/char/apm-emulation.c
+++ b/drivers/char/apm-emulation.c
@@ -393,7 +393,7 @@ static int apm_open(struct inode * inode, struct file * filp)
393 return as ? 0 : -ENOMEM; 393 return as ? 0 : -ENOMEM;
394} 394}
395 395
396static struct file_operations apm_bios_fops = { 396static const struct file_operations apm_bios_fops = {
397 .owner = THIS_MODULE, 397 .owner = THIS_MODULE,
398 .read = apm_read, 398 .read = apm_read,
399 .poll = apm_poll, 399 .poll = apm_poll,
diff --git a/drivers/char/applicom.c b/drivers/char/applicom.c
index 73a0765344b6..fe2cb2f5db17 100644
--- a/drivers/char/applicom.c
+++ b/drivers/char/applicom.c
@@ -23,6 +23,7 @@
23#include <linux/kernel.h> 23#include <linux/kernel.h>
24#include <linux/module.h> 24#include <linux/module.h>
25#include <linux/interrupt.h> 25#include <linux/interrupt.h>
26#include <linux/sched.h>
26#include <linux/slab.h> 27#include <linux/slab.h>
27#include <linux/errno.h> 28#include <linux/errno.h>
28#include <linux/miscdevice.h> 29#include <linux/miscdevice.h>
diff --git a/drivers/char/bfin-otp.c b/drivers/char/bfin-otp.c
index e3dd24bff514..836d4f0a876f 100644
--- a/drivers/char/bfin-otp.c
+++ b/drivers/char/bfin-otp.c
@@ -217,7 +217,7 @@ static long bfin_otp_ioctl(struct file *filp, unsigned cmd, unsigned long arg)
217# define bfin_otp_ioctl NULL 217# define bfin_otp_ioctl NULL
218#endif 218#endif
219 219
220static struct file_operations bfin_otp_fops = { 220static const struct file_operations bfin_otp_fops = {
221 .owner = THIS_MODULE, 221 .owner = THIS_MODULE,
222 .unlocked_ioctl = bfin_otp_ioctl, 222 .unlocked_ioctl = bfin_otp_ioctl,
223 .read = bfin_otp_read, 223 .read = bfin_otp_read,
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
index df5038bbcbc2..4254457d3911 100644
--- a/drivers/char/cyclades.c
+++ b/drivers/char/cyclades.c
@@ -3354,7 +3354,7 @@ static int __init cy_detect_isa(void)
3354 continue; 3354 continue;
3355 } 3355 }
3356#ifdef MODULE 3356#ifdef MODULE
3357 if (isparam && irq[i]) 3357 if (isparam && i < NR_CARDS && irq[i])
3358 cy_isa_irq = irq[i]; 3358 cy_isa_irq = irq[i];
3359 else 3359 else
3360#endif 3360#endif
diff --git a/drivers/char/dtlk.c b/drivers/char/dtlk.c
index 52e06589821d..045c930e6320 100644
--- a/drivers/char/dtlk.c
+++ b/drivers/char/dtlk.c
@@ -56,6 +56,7 @@
56#include <linux/errno.h> /* for -EBUSY */ 56#include <linux/errno.h> /* for -EBUSY */
57#include <linux/ioport.h> /* for request_region */ 57#include <linux/ioport.h> /* for request_region */
58#include <linux/delay.h> /* for loops_per_jiffy */ 58#include <linux/delay.h> /* for loops_per_jiffy */
59#include <linux/sched.h>
59#include <linux/smp_lock.h> /* cycle_kernel_lock() */ 60#include <linux/smp_lock.h> /* cycle_kernel_lock() */
60#include <asm/io.h> /* for inb_p, outb_p, inb, outb, etc. */ 61#include <asm/io.h> /* for inb_p, outb_p, inb, outb, etc. */
61#include <asm/uaccess.h> /* for get_user, etc. */ 62#include <asm/uaccess.h> /* for get_user, etc. */
diff --git a/drivers/char/epca.c b/drivers/char/epca.c
index 9d589e3144de..dde5134713e2 100644
--- a/drivers/char/epca.c
+++ b/drivers/char/epca.c
@@ -30,6 +30,7 @@
30#include <linux/kernel.h> 30#include <linux/kernel.h>
31#include <linux/types.h> 31#include <linux/types.h>
32#include <linux/init.h> 32#include <linux/init.h>
33#include <linux/sched.h>
33#include <linux/serial.h> 34#include <linux/serial.h>
34#include <linux/delay.h> 35#include <linux/delay.h>
35#include <linux/ctype.h> 36#include <linux/ctype.h>
diff --git a/drivers/char/generic_serial.c b/drivers/char/generic_serial.c
index 9e4e569dc00d..d400cbd280f2 100644
--- a/drivers/char/generic_serial.c
+++ b/drivers/char/generic_serial.c
@@ -22,6 +22,7 @@
22#include <linux/module.h> 22#include <linux/module.h>
23#include <linux/kernel.h> 23#include <linux/kernel.h>
24#include <linux/tty.h> 24#include <linux/tty.h>
25#include <linux/sched.h>
25#include <linux/serial.h> 26#include <linux/serial.h>
26#include <linux/mm.h> 27#include <linux/mm.h>
27#include <linux/generic_serial.h> 28#include <linux/generic_serial.h>
diff --git a/drivers/char/genrtc.c b/drivers/char/genrtc.c
index aac0985a572b..31e7c91c2d9d 100644
--- a/drivers/char/genrtc.c
+++ b/drivers/char/genrtc.c
@@ -43,6 +43,7 @@
43#define RTC_VERSION "1.07" 43#define RTC_VERSION "1.07"
44 44
45#include <linux/module.h> 45#include <linux/module.h>
46#include <linux/sched.h>
46#include <linux/errno.h> 47#include <linux/errno.h>
47#include <linux/miscdevice.h> 48#include <linux/miscdevice.h>
48#include <linux/fcntl.h> 49#include <linux/fcntl.h>
diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c
index 41fc11dc921c..65545de3dbf4 100644
--- a/drivers/char/ipmi/ipmi_devintf.c
+++ b/drivers/char/ipmi/ipmi_devintf.c
@@ -36,6 +36,7 @@
36#include <linux/errno.h> 36#include <linux/errno.h>
37#include <asm/system.h> 37#include <asm/system.h>
38#include <linux/poll.h> 38#include <linux/poll.h>
39#include <linux/sched.h>
39#include <linux/spinlock.h> 40#include <linux/spinlock.h>
40#include <linux/slab.h> 41#include <linux/slab.h>
41#include <linux/ipmi.h> 42#include <linux/ipmi.h>
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index 09050797c76a..ec5e3f8df648 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -35,6 +35,7 @@
35#include <linux/errno.h> 35#include <linux/errno.h>
36#include <asm/system.h> 36#include <asm/system.h>
37#include <linux/poll.h> 37#include <linux/poll.h>
38#include <linux/sched.h>
38#include <linux/spinlock.h> 39#include <linux/spinlock.h>
39#include <linux/mutex.h> 40#include <linux/mutex.h>
40#include <linux/slab.h> 41#include <linux/slab.h>
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index ab2f3349c5c4..402838f4083e 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -19,6 +19,7 @@
19/*****************************************************************************/ 19/*****************************************************************************/
20 20
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/sched.h>
22#include <linux/slab.h> 23#include <linux/slab.h>
23#include <linux/smp_lock.h> 24#include <linux/smp_lock.h>
24#include <linux/interrupt.h> 25#include <linux/interrupt.h>
diff --git a/drivers/char/nozomi.c b/drivers/char/nozomi.c
index ec58d8c387ff..d3400b20444f 100644
--- a/drivers/char/nozomi.c
+++ b/drivers/char/nozomi.c
@@ -48,6 +48,7 @@
48#include <linux/tty.h> 48#include <linux/tty.h>
49#include <linux/tty_driver.h> 49#include <linux/tty_driver.h>
50#include <linux/tty_flip.h> 50#include <linux/tty_flip.h>
51#include <linux/sched.h>
51#include <linux/serial.h> 52#include <linux/serial.h>
52#include <linux/interrupt.h> 53#include <linux/interrupt.h>
53#include <linux/kmod.h> 54#include <linux/kmod.h>
diff --git a/drivers/char/pty.c b/drivers/char/pty.c
index e066c4fdf81b..62f282e67638 100644
--- a/drivers/char/pty.c
+++ b/drivers/char/pty.c
@@ -18,6 +18,7 @@
18#include <linux/tty.h> 18#include <linux/tty.h>
19#include <linux/tty_flip.h> 19#include <linux/tty_flip.h>
20#include <linux/fcntl.h> 20#include <linux/fcntl.h>
21#include <linux/sched.h>
21#include <linux/string.h> 22#include <linux/string.h>
22#include <linux/major.h> 23#include <linux/major.h>
23#include <linux/mm.h> 24#include <linux/mm.h>
diff --git a/drivers/char/rio/riocmd.c b/drivers/char/rio/riocmd.c
index 01f2654d5a2e..f121357e5af0 100644
--- a/drivers/char/rio/riocmd.c
+++ b/drivers/char/rio/riocmd.c
@@ -32,6 +32,7 @@
32*/ 32*/
33 33
34#include <linux/module.h> 34#include <linux/module.h>
35#include <linux/sched.h>
35#include <linux/slab.h> 36#include <linux/slab.h>
36#include <linux/errno.h> 37#include <linux/errno.h>
37#include <linux/tty.h> 38#include <linux/tty.h>
diff --git a/drivers/char/rio/rioctrl.c b/drivers/char/rio/rioctrl.c
index 74339559f0b9..780506326a73 100644
--- a/drivers/char/rio/rioctrl.c
+++ b/drivers/char/rio/rioctrl.c
@@ -31,6 +31,7 @@
31*/ 31*/
32 32
33#include <linux/module.h> 33#include <linux/module.h>
34#include <linux/sched.h>
34#include <linux/slab.h> 35#include <linux/slab.h>
35#include <linux/errno.h> 36#include <linux/errno.h>
36#include <asm/io.h> 37#include <asm/io.h>
diff --git a/drivers/char/rio/riotty.c b/drivers/char/rio/riotty.c
index 2fb49e89b324..47fab7c33073 100644
--- a/drivers/char/rio/riotty.c
+++ b/drivers/char/rio/riotty.c
@@ -33,6 +33,7 @@
33#define __EXPLICIT_DEF_H__ 33#define __EXPLICIT_DEF_H__
34 34
35#include <linux/module.h> 35#include <linux/module.h>
36#include <linux/sched.h>
36#include <linux/slab.h> 37#include <linux/slab.h>
37#include <linux/errno.h> 38#include <linux/errno.h>
38#include <linux/tty.h> 39#include <linux/tty.h>
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c
index e0d0f8b2696b..bc4ab3e54550 100644
--- a/drivers/char/rtc.c
+++ b/drivers/char/rtc.c
@@ -74,6 +74,7 @@
74#include <linux/proc_fs.h> 74#include <linux/proc_fs.h>
75#include <linux/seq_file.h> 75#include <linux/seq_file.h>
76#include <linux/spinlock.h> 76#include <linux/spinlock.h>
77#include <linux/sched.h>
77#include <linux/sysctl.h> 78#include <linux/sysctl.h>
78#include <linux/wait.h> 79#include <linux/wait.h>
79#include <linux/bcd.h> 80#include <linux/bcd.h>
diff --git a/drivers/char/ser_a2232.c b/drivers/char/ser_a2232.c
index 33a2b531802e..9610861d1f5f 100644
--- a/drivers/char/ser_a2232.c
+++ b/drivers/char/ser_a2232.c
@@ -89,6 +89,7 @@
89#include <linux/interrupt.h> 89#include <linux/interrupt.h>
90#include <linux/kernel.h> 90#include <linux/kernel.h>
91#include <linux/errno.h> 91#include <linux/errno.h>
92#include <linux/sched.h>
92#include <linux/tty.h> 93#include <linux/tty.h>
93 94
94#include <asm/setup.h> 95#include <asm/setup.h>
diff --git a/drivers/char/serial167.c b/drivers/char/serial167.c
index 5942a9d674c0..452370af95de 100644
--- a/drivers/char/serial167.c
+++ b/drivers/char/serial167.c
@@ -220,8 +220,7 @@ static inline int serial_paranoia_check(struct cyclades_port *info, char *name,
220 return 1; 220 return 1;
221 } 221 }
222 222
223 if ((long)info < (long)(&cy_port[0]) 223 if (info < &cy_port[0] || info >= &cy_port[NR_PORTS]) {
224 || (long)(&cy_port[NR_PORTS]) < (long)info) {
225 printk("Warning: cyclades_port out of range for (%s) in %s\n", 224 printk("Warning: cyclades_port out of range for (%s) in %s\n",
226 name, routine); 225 name, routine);
227 return 1; 226 return 1;
@@ -520,15 +519,13 @@ static irqreturn_t cd2401_tx_interrupt(int irq, void *dev_id)
520 panic("TxInt on debug port!!!"); 519 panic("TxInt on debug port!!!");
521 } 520 }
522#endif 521#endif
523
524 info = &cy_port[channel];
525
526 /* validate the port number (as configured and open) */ 522 /* validate the port number (as configured and open) */
527 if ((channel < 0) || (NR_PORTS <= channel)) { 523 if ((channel < 0) || (NR_PORTS <= channel)) {
528 base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy); 524 base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy);
529 base_addr[CyTEOIR] = CyNOTRANS; 525 base_addr[CyTEOIR] = CyNOTRANS;
530 return IRQ_HANDLED; 526 return IRQ_HANDLED;
531 } 527 }
528 info = &cy_port[channel];
532 info->last_active = jiffies; 529 info->last_active = jiffies;
533 if (info->tty == 0) { 530 if (info->tty == 0) {
534 base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy); 531 base_addr[CyIER] &= ~(CyTxMpty | CyTxRdy);
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c
index fd3dced97776..8c262aaf7c26 100644
--- a/drivers/char/sonypi.c
+++ b/drivers/char/sonypi.c
@@ -36,6 +36,7 @@
36 */ 36 */
37 37
38#include <linux/module.h> 38#include <linux/module.h>
39#include <linux/sched.h>
39#include <linux/input.h> 40#include <linux/input.h>
40#include <linux/pci.h> 41#include <linux/pci.h>
41#include <linux/init.h> 42#include <linux/init.h>
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c
index 53e504f41b20..db6dcfa35ba0 100644
--- a/drivers/char/stallion.c
+++ b/drivers/char/stallion.c
@@ -27,6 +27,7 @@
27/*****************************************************************************/ 27/*****************************************************************************/
28 28
29#include <linux/module.h> 29#include <linux/module.h>
30#include <linux/sched.h>
30#include <linux/slab.h> 31#include <linux/slab.h>
31#include <linux/interrupt.h> 32#include <linux/interrupt.h>
32#include <linux/tty.h> 33#include <linux/tty.h>
diff --git a/drivers/char/tlclk.c b/drivers/char/tlclk.c
index 8f2284be68e1..80ea6bcfffdc 100644
--- a/drivers/char/tlclk.c
+++ b/drivers/char/tlclk.c
@@ -32,6 +32,7 @@
32#include <linux/kernel.h> /* printk() */ 32#include <linux/kernel.h> /* printk() */
33#include <linux/fs.h> /* everything... */ 33#include <linux/fs.h> /* everything... */
34#include <linux/errno.h> /* error codes */ 34#include <linux/errno.h> /* error codes */
35#include <linux/sched.h>
35#include <linux/slab.h> 36#include <linux/slab.h>
36#include <linux/ioport.h> 37#include <linux/ioport.h>
37#include <linux/interrupt.h> 38#include <linux/interrupt.h>
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index 45d58002b06c..47c2d2763456 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -696,8 +696,7 @@ int __tpm_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
696 696
697 cmd.header.in = pcrread_header; 697 cmd.header.in = pcrread_header;
698 cmd.params.pcrread_in.pcr_idx = cpu_to_be32(pcr_idx); 698 cmd.params.pcrread_in.pcr_idx = cpu_to_be32(pcr_idx);
699 BUG_ON(cmd.header.in.length > READ_PCR_RESULT_SIZE); 699 rc = transmit_cmd(chip, &cmd, READ_PCR_RESULT_SIZE,
700 rc = transmit_cmd(chip, &cmd, cmd.header.in.length,
701 "attempting to read a pcr value"); 700 "attempting to read a pcr value");
702 701
703 if (rc == 0) 702 if (rc == 0)
diff --git a/drivers/char/tty_buffer.c b/drivers/char/tty_buffer.c
index 3108991c5c8b..66fa4e10d76b 100644
--- a/drivers/char/tty_buffer.c
+++ b/drivers/char/tty_buffer.c
@@ -402,28 +402,26 @@ static void flush_to_ldisc(struct work_struct *work)
402 container_of(work, struct tty_struct, buf.work.work); 402 container_of(work, struct tty_struct, buf.work.work);
403 unsigned long flags; 403 unsigned long flags;
404 struct tty_ldisc *disc; 404 struct tty_ldisc *disc;
405 struct tty_buffer *tbuf, *head;
406 char *char_buf;
407 unsigned char *flag_buf;
408 405
409 disc = tty_ldisc_ref(tty); 406 disc = tty_ldisc_ref(tty);
410 if (disc == NULL) /* !TTY_LDISC */ 407 if (disc == NULL) /* !TTY_LDISC */
411 return; 408 return;
412 409
413 spin_lock_irqsave(&tty->buf.lock, flags); 410 spin_lock_irqsave(&tty->buf.lock, flags);
414 /* So we know a flush is running */ 411
415 set_bit(TTY_FLUSHING, &tty->flags); 412 if (!test_and_set_bit(TTY_FLUSHING, &tty->flags)) {
416 head = tty->buf.head; 413 struct tty_buffer *head;
417 if (head != NULL) { 414 while ((head = tty->buf.head) != NULL) {
418 tty->buf.head = NULL; 415 int count;
419 for (;;) { 416 char *char_buf;
420 int count = head->commit - head->read; 417 unsigned char *flag_buf;
418
419 count = head->commit - head->read;
421 if (!count) { 420 if (!count) {
422 if (head->next == NULL) 421 if (head->next == NULL)
423 break; 422 break;
424 tbuf = head; 423 tty->buf.head = head->next;
425 head = head->next; 424 tty_buffer_free(tty, head);
426 tty_buffer_free(tty, tbuf);
427 continue; 425 continue;
428 } 426 }
429 /* Ldisc or user is trying to flush the buffers 427 /* Ldisc or user is trying to flush the buffers
@@ -445,9 +443,9 @@ static void flush_to_ldisc(struct work_struct *work)
445 flag_buf, count); 443 flag_buf, count);
446 spin_lock_irqsave(&tty->buf.lock, flags); 444 spin_lock_irqsave(&tty->buf.lock, flags);
447 } 445 }
448 /* Restore the queue head */ 446 clear_bit(TTY_FLUSHING, &tty->flags);
449 tty->buf.head = head;
450 } 447 }
448
451 /* We may have a deferred request to flush the input buffer, 449 /* We may have a deferred request to flush the input buffer,
452 if so pull the chain under the lock and empty the queue */ 450 if so pull the chain under the lock and empty the queue */
453 if (test_bit(TTY_FLUSHPENDING, &tty->flags)) { 451 if (test_bit(TTY_FLUSHPENDING, &tty->flags)) {
@@ -455,7 +453,6 @@ static void flush_to_ldisc(struct work_struct *work)
455 clear_bit(TTY_FLUSHPENDING, &tty->flags); 453 clear_bit(TTY_FLUSHPENDING, &tty->flags);
456 wake_up(&tty->read_wait); 454 wake_up(&tty->read_wait);
457 } 455 }
458 clear_bit(TTY_FLUSHING, &tty->flags);
459 spin_unlock_irqrestore(&tty->buf.lock, flags); 456 spin_unlock_irqrestore(&tty->buf.lock, flags);
460 457
461 tty_ldisc_deref(disc); 458 tty_ldisc_deref(disc);
@@ -471,7 +468,7 @@ static void flush_to_ldisc(struct work_struct *work)
471 */ 468 */
472void tty_flush_to_ldisc(struct tty_struct *tty) 469void tty_flush_to_ldisc(struct tty_struct *tty)
473{ 470{
474 flush_to_ldisc(&tty->buf.work.work); 471 flush_delayed_work(&tty->buf.work);
475} 472}
476 473
477/** 474/**
diff --git a/drivers/char/tty_ldisc.c b/drivers/char/tty_ldisc.c
index aafdbaebc16a..feb55075819b 100644
--- a/drivers/char/tty_ldisc.c
+++ b/drivers/char/tty_ldisc.c
@@ -518,7 +518,7 @@ static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old)
518static int tty_ldisc_halt(struct tty_struct *tty) 518static int tty_ldisc_halt(struct tty_struct *tty)
519{ 519{
520 clear_bit(TTY_LDISC, &tty->flags); 520 clear_bit(TTY_LDISC, &tty->flags);
521 return cancel_delayed_work(&tty->buf.work); 521 return cancel_delayed_work_sync(&tty->buf.work);
522} 522}
523 523
524/** 524/**
@@ -756,12 +756,9 @@ void tty_ldisc_hangup(struct tty_struct *tty)
756 * N_TTY. 756 * N_TTY.
757 */ 757 */
758 if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) { 758 if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) {
759 /* Make sure the old ldisc is quiescent */
760 tty_ldisc_halt(tty);
761 flush_scheduled_work();
762
763 /* Avoid racing set_ldisc or tty_ldisc_release */ 759 /* Avoid racing set_ldisc or tty_ldisc_release */
764 mutex_lock(&tty->ldisc_mutex); 760 mutex_lock(&tty->ldisc_mutex);
761 tty_ldisc_halt(tty);
765 if (tty->ldisc) { /* Not yet closed */ 762 if (tty->ldisc) { /* Not yet closed */
766 /* Switch back to N_TTY */ 763 /* Switch back to N_TTY */
767 tty_ldisc_reinit(tty); 764 tty_ldisc_reinit(tty);
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
index 29c651ab0d78..ed86d3bf249a 100644
--- a/drivers/char/vt_ioctl.c
+++ b/drivers/char/vt_ioctl.c
@@ -981,8 +981,10 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
981 goto eperm; 981 goto eperm;
982 982
983 if (copy_from_user(&vsa, (struct vt_setactivate __user *)arg, 983 if (copy_from_user(&vsa, (struct vt_setactivate __user *)arg,
984 sizeof(struct vt_setactivate))) 984 sizeof(struct vt_setactivate))) {
985 return -EFAULT; 985 ret = -EFAULT;
986 goto out;
987 }
986 if (vsa.console == 0 || vsa.console > MAX_NR_CONSOLES) 988 if (vsa.console == 0 || vsa.console > MAX_NR_CONSOLES)
987 ret = -ENXIO; 989 ret = -ENXIO;
988 else { 990 else {
@@ -1530,7 +1532,7 @@ long vt_compat_ioctl(struct tty_struct *tty, struct file * file,
1530 1532
1531 case PIO_UNIMAP: 1533 case PIO_UNIMAP:
1532 case GIO_UNIMAP: 1534 case GIO_UNIMAP:
1533 ret = do_unimap_ioctl(cmd, up, perm, vc); 1535 ret = compat_unimap_ioctl(cmd, up, perm, vc);
1534 break; 1536 break;
1535 1537
1536 /* 1538 /*
diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c
index f40ab699860f..4846d50199f3 100644
--- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c
+++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c
@@ -559,7 +559,7 @@ static int hwicap_release(struct inode *inode, struct file *file)
559 return status; 559 return status;
560} 560}
561 561
562static struct file_operations hwicap_fops = { 562static const struct file_operations hwicap_fops = {
563 .owner = THIS_MODULE, 563 .owner = THIS_MODULE,
564 .write = hwicap_write, 564 .write = hwicap_write,
565 .read = hwicap_read, 565 .read = hwicap_read,
diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c
index abf4a2529f80..60697909ebdb 100644
--- a/drivers/connector/cn_proc.c
+++ b/drivers/connector/cn_proc.c
@@ -227,7 +227,8 @@ static void cn_proc_ack(int err, int rcvd_seq, int rcvd_ack)
227 * cn_proc_mcast_ctl 227 * cn_proc_mcast_ctl
228 * @data: message sent from userspace via the connector 228 * @data: message sent from userspace via the connector
229 */ 229 */
230static void cn_proc_mcast_ctl(struct cn_msg *msg) 230static void cn_proc_mcast_ctl(struct cn_msg *msg,
231 struct netlink_skb_parms *nsp)
231{ 232{
232 enum proc_cn_mcast_op *mc_op = NULL; 233 enum proc_cn_mcast_op *mc_op = NULL;
233 int err = 0; 234 int err = 0;
diff --git a/drivers/connector/cn_queue.c b/drivers/connector/cn_queue.c
index 4a1dfe1f4ba9..210338ea222f 100644
--- a/drivers/connector/cn_queue.c
+++ b/drivers/connector/cn_queue.c
@@ -78,18 +78,20 @@ void cn_queue_wrapper(struct work_struct *work)
78 struct cn_callback_entry *cbq = 78 struct cn_callback_entry *cbq =
79 container_of(work, struct cn_callback_entry, work); 79 container_of(work, struct cn_callback_entry, work);
80 struct cn_callback_data *d = &cbq->data; 80 struct cn_callback_data *d = &cbq->data;
81 struct cn_msg *msg = NLMSG_DATA(nlmsg_hdr(d->skb));
82 struct netlink_skb_parms *nsp = &NETLINK_CB(d->skb);
81 83
82 d->callback(d->callback_priv); 84 d->callback(msg, nsp);
83 85
84 d->destruct_data(d->ddata); 86 kfree_skb(d->skb);
85 d->ddata = NULL; 87 d->skb = NULL;
86 88
87 kfree(d->free); 89 kfree(d->free);
88} 90}
89 91
90static struct cn_callback_entry * 92static struct cn_callback_entry *
91cn_queue_alloc_callback_entry(char *name, struct cb_id *id, 93cn_queue_alloc_callback_entry(char *name, struct cb_id *id,
92 void (*callback)(struct cn_msg *)) 94 void (*callback)(struct cn_msg *, struct netlink_skb_parms *))
93{ 95{
94 struct cn_callback_entry *cbq; 96 struct cn_callback_entry *cbq;
95 97
@@ -123,7 +125,7 @@ int cn_cb_equal(struct cb_id *i1, struct cb_id *i2)
123} 125}
124 126
125int cn_queue_add_callback(struct cn_queue_dev *dev, char *name, struct cb_id *id, 127int cn_queue_add_callback(struct cn_queue_dev *dev, char *name, struct cb_id *id,
126 void (*callback)(struct cn_msg *)) 128 void (*callback)(struct cn_msg *, struct netlink_skb_parms *))
127{ 129{
128 struct cn_callback_entry *cbq, *__cbq; 130 struct cn_callback_entry *cbq, *__cbq;
129 int found = 0; 131 int found = 0;
diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c
index 74f52af79563..f06024668f99 100644
--- a/drivers/connector/connector.c
+++ b/drivers/connector/connector.c
@@ -129,21 +129,19 @@ EXPORT_SYMBOL_GPL(cn_netlink_send);
129/* 129/*
130 * Callback helper - queues work and setup destructor for given data. 130 * Callback helper - queues work and setup destructor for given data.
131 */ 131 */
132static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), void *data) 132static int cn_call_callback(struct sk_buff *skb)
133{ 133{
134 struct cn_callback_entry *__cbq, *__new_cbq; 134 struct cn_callback_entry *__cbq, *__new_cbq;
135 struct cn_dev *dev = &cdev; 135 struct cn_dev *dev = &cdev;
136 struct cn_msg *msg = NLMSG_DATA(nlmsg_hdr(skb));
136 int err = -ENODEV; 137 int err = -ENODEV;
137 138
138 spin_lock_bh(&dev->cbdev->queue_lock); 139 spin_lock_bh(&dev->cbdev->queue_lock);
139 list_for_each_entry(__cbq, &dev->cbdev->queue_list, callback_entry) { 140 list_for_each_entry(__cbq, &dev->cbdev->queue_list, callback_entry) {
140 if (cn_cb_equal(&__cbq->id.id, &msg->id)) { 141 if (cn_cb_equal(&__cbq->id.id, &msg->id)) {
141 if (likely(!work_pending(&__cbq->work) && 142 if (likely(!work_pending(&__cbq->work) &&
142 __cbq->data.ddata == NULL)) { 143 __cbq->data.skb == NULL)) {
143 __cbq->data.callback_priv = msg; 144 __cbq->data.skb = skb;
144
145 __cbq->data.ddata = data;
146 __cbq->data.destruct_data = destruct_data;
147 145
148 if (queue_cn_work(__cbq, &__cbq->work)) 146 if (queue_cn_work(__cbq, &__cbq->work))
149 err = 0; 147 err = 0;
@@ -156,10 +154,8 @@ static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), v
156 __new_cbq = kzalloc(sizeof(struct cn_callback_entry), GFP_ATOMIC); 154 __new_cbq = kzalloc(sizeof(struct cn_callback_entry), GFP_ATOMIC);
157 if (__new_cbq) { 155 if (__new_cbq) {
158 d = &__new_cbq->data; 156 d = &__new_cbq->data;
159 d->callback_priv = msg; 157 d->skb = skb;
160 d->callback = __cbq->data.callback; 158 d->callback = __cbq->data.callback;
161 d->ddata = data;
162 d->destruct_data = destruct_data;
163 d->free = __new_cbq; 159 d->free = __new_cbq;
164 160
165 __new_cbq->pdev = __cbq->pdev; 161 __new_cbq->pdev = __cbq->pdev;
@@ -191,7 +187,6 @@ static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), v
191 */ 187 */
192static void cn_rx_skb(struct sk_buff *__skb) 188static void cn_rx_skb(struct sk_buff *__skb)
193{ 189{
194 struct cn_msg *msg;
195 struct nlmsghdr *nlh; 190 struct nlmsghdr *nlh;
196 int err; 191 int err;
197 struct sk_buff *skb; 192 struct sk_buff *skb;
@@ -208,8 +203,7 @@ static void cn_rx_skb(struct sk_buff *__skb)
208 return; 203 return;
209 } 204 }
210 205
211 msg = NLMSG_DATA(nlh); 206 err = cn_call_callback(skb);
212 err = cn_call_callback(msg, (void (*)(void *))kfree_skb, skb);
213 if (err < 0) 207 if (err < 0)
214 kfree_skb(skb); 208 kfree_skb(skb);
215 } 209 }
@@ -270,7 +264,7 @@ static void cn_notify(struct cb_id *id, u32 notify_event)
270 * May sleep. 264 * May sleep.
271 */ 265 */
272int cn_add_callback(struct cb_id *id, char *name, 266int cn_add_callback(struct cb_id *id, char *name,
273 void (*callback)(struct cn_msg *)) 267 void (*callback)(struct cn_msg *, struct netlink_skb_parms *))
274{ 268{
275 int err; 269 int err;
276 struct cn_dev *dev = &cdev; 270 struct cn_dev *dev = &cdev;
@@ -352,7 +346,7 @@ static int cn_ctl_msg_equals(struct cn_ctl_msg *m1, struct cn_ctl_msg *m2)
352 * 346 *
353 * Used for notification of a request's processing. 347 * Used for notification of a request's processing.
354 */ 348 */
355static void cn_callback(struct cn_msg *msg) 349static void cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
356{ 350{
357 struct cn_ctl_msg *ctl; 351 struct cn_ctl_msg *ctl;
358 struct cn_ctl_entry *ent; 352 struct cn_ctl_entry *ent;
diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig
index 02127e59fe8e..55c9c59b3f71 100644
--- a/drivers/edac/Kconfig
+++ b/drivers/edac/Kconfig
@@ -47,6 +47,18 @@ config EDAC_DEBUG_VERBOSE
47 Source file name and line number where debugging message 47 Source file name and line number where debugging message
48 printed will be added to debugging message. 48 printed will be added to debugging message.
49 49
50 config EDAC_DECODE_MCE
51 tristate "Decode MCEs in human-readable form (only on AMD for now)"
52 depends on CPU_SUP_AMD && X86_MCE
53 default y
54 ---help---
55 Enable this option if you want to decode Machine Check Exceptions
56 occuring on your machine in human-readable form.
57
58 You should definitely say Y here in case you want to decode MCEs
59 which occur really early upon boot, before the module infrastructure
60 has been initialized.
61
50config EDAC_MM_EDAC 62config EDAC_MM_EDAC
51 tristate "Main Memory EDAC (Error Detection And Correction) reporting" 63 tristate "Main Memory EDAC (Error Detection And Correction) reporting"
52 help 64 help
@@ -59,7 +71,7 @@ config EDAC_MM_EDAC
59 71
60config EDAC_AMD64 72config EDAC_AMD64
61 tristate "AMD64 (Opteron, Athlon64) K8, F10h, F11h" 73 tristate "AMD64 (Opteron, Athlon64) K8, F10h, F11h"
62 depends on EDAC_MM_EDAC && K8_NB && X86_64 && PCI && CPU_SUP_AMD 74 depends on EDAC_MM_EDAC && K8_NB && X86_64 && PCI && EDAC_DECODE_MCE
63 help 75 help
64 Support for error detection and correction on the AMD 64 76 Support for error detection and correction on the AMD 64
65 Families of Memory Controllers (K8, F10h and F11h) 77 Families of Memory Controllers (K8, F10h and F11h)
diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile
index 7a473bbe8abd..bc5dc232a0fb 100644
--- a/drivers/edac/Makefile
+++ b/drivers/edac/Makefile
@@ -6,7 +6,6 @@
6# GNU General Public License. 6# GNU General Public License.
7# 7#
8 8
9
10obj-$(CONFIG_EDAC) := edac_stub.o 9obj-$(CONFIG_EDAC) := edac_stub.o
11obj-$(CONFIG_EDAC_MM_EDAC) += edac_core.o 10obj-$(CONFIG_EDAC_MM_EDAC) += edac_core.o
12 11
@@ -17,9 +16,7 @@ ifdef CONFIG_PCI
17edac_core-objs += edac_pci.o edac_pci_sysfs.o 16edac_core-objs += edac_pci.o edac_pci_sysfs.o
18endif 17endif
19 18
20ifdef CONFIG_CPU_SUP_AMD 19obj-$(CONFIG_EDAC_DECODE_MCE) += edac_mce_amd.o
21edac_core-objs += edac_mce_amd.o
22endif
23 20
24obj-$(CONFIG_EDAC_AMD76X) += amd76x_edac.o 21obj-$(CONFIG_EDAC_AMD76X) += amd76x_edac.o
25obj-$(CONFIG_EDAC_CPC925) += cpc925_edac.o 22obj-$(CONFIG_EDAC_CPC925) += cpc925_edac.o
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index 4e551e63b6dc..4f4ac82382f7 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -15,8 +15,8 @@ module_param(ecc_enable_override, int, 0644);
15 15
16/* Lookup table for all possible MC control instances */ 16/* Lookup table for all possible MC control instances */
17struct amd64_pvt; 17struct amd64_pvt;
18static struct mem_ctl_info *mci_lookup[MAX_NUMNODES]; 18static struct mem_ctl_info *mci_lookup[EDAC_MAX_NUMNODES];
19static struct amd64_pvt *pvt_lookup[MAX_NUMNODES]; 19static struct amd64_pvt *pvt_lookup[EDAC_MAX_NUMNODES];
20 20
21/* 21/*
22 * See F2x80 for K8 and F2x[1,0]80 for Fam10 and later. The table below is only 22 * See F2x80 for K8 and F2x[1,0]80 for Fam10 and later. The table below is only
@@ -189,7 +189,10 @@ static int amd64_get_scrub_rate(struct mem_ctl_info *mci, u32 *bw)
189/* Map from a CSROW entry to the mask entry that operates on it */ 189/* Map from a CSROW entry to the mask entry that operates on it */
190static inline u32 amd64_map_to_dcs_mask(struct amd64_pvt *pvt, int csrow) 190static inline u32 amd64_map_to_dcs_mask(struct amd64_pvt *pvt, int csrow)
191{ 191{
192 return csrow >> (pvt->num_dcsm >> 3); 192 if (boot_cpu_data.x86 == 0xf && pvt->ext_model < OPTERON_CPU_REV_F)
193 return csrow;
194 else
195 return csrow >> 1;
193} 196}
194 197
195/* return the 'base' address the i'th CS entry of the 'dct' DRAM controller */ 198/* return the 'base' address the i'th CS entry of the 'dct' DRAM controller */
@@ -279,29 +282,26 @@ static struct mem_ctl_info *find_mc_by_sys_addr(struct mem_ctl_info *mci,
279 intlv_en = pvt->dram_IntlvEn[0]; 282 intlv_en = pvt->dram_IntlvEn[0];
280 283
281 if (intlv_en == 0) { 284 if (intlv_en == 0) {
282 for (node_id = 0; ; ) { 285 for (node_id = 0; node_id < DRAM_REG_COUNT; node_id++) {
283 if (amd64_base_limit_match(pvt, sys_addr, node_id)) 286 if (amd64_base_limit_match(pvt, sys_addr, node_id))
284 break; 287 goto found;
285
286 if (++node_id >= DRAM_REG_COUNT)
287 goto err_no_match;
288 } 288 }
289 goto found; 289 goto err_no_match;
290 } 290 }
291 291
292 if (unlikely((intlv_en != (0x01 << 8)) && 292 if (unlikely((intlv_en != 0x01) &&
293 (intlv_en != (0x03 << 8)) && 293 (intlv_en != 0x03) &&
294 (intlv_en != (0x07 << 8)))) { 294 (intlv_en != 0x07))) {
295 amd64_printk(KERN_WARNING, "junk value of 0x%x extracted from " 295 amd64_printk(KERN_WARNING, "junk value of 0x%x extracted from "
296 "IntlvEn field of DRAM Base Register for node 0: " 296 "IntlvEn field of DRAM Base Register for node 0: "
297 "This probably indicates a BIOS bug.\n", intlv_en); 297 "this probably indicates a BIOS bug.\n", intlv_en);
298 return NULL; 298 return NULL;
299 } 299 }
300 300
301 bits = (((u32) sys_addr) >> 12) & intlv_en; 301 bits = (((u32) sys_addr) >> 12) & intlv_en;
302 302
303 for (node_id = 0; ; ) { 303 for (node_id = 0; ; ) {
304 if ((pvt->dram_limit[node_id] & intlv_en) == bits) 304 if ((pvt->dram_IntlvSel[node_id] & intlv_en) == bits)
305 break; /* intlv_sel field matches */ 305 break; /* intlv_sel field matches */
306 306
307 if (++node_id >= DRAM_REG_COUNT) 307 if (++node_id >= DRAM_REG_COUNT)
@@ -311,10 +311,10 @@ static struct mem_ctl_info *find_mc_by_sys_addr(struct mem_ctl_info *mci,
311 /* sanity test for sys_addr */ 311 /* sanity test for sys_addr */
312 if (unlikely(!amd64_base_limit_match(pvt, sys_addr, node_id))) { 312 if (unlikely(!amd64_base_limit_match(pvt, sys_addr, node_id))) {
313 amd64_printk(KERN_WARNING, 313 amd64_printk(KERN_WARNING,
314 "%s(): sys_addr 0x%lx falls outside base/limit " 314 "%s(): sys_addr 0x%llx falls outside base/limit "
315 "address range for node %d with node interleaving " 315 "address range for node %d with node interleaving "
316 "enabled.\n", __func__, (unsigned long)sys_addr, 316 "enabled.\n",
317 node_id); 317 __func__, sys_addr, node_id);
318 return NULL; 318 return NULL;
319 } 319 }
320 320
@@ -377,7 +377,7 @@ static int input_addr_to_csrow(struct mem_ctl_info *mci, u64 input_addr)
377 * base/mask register pair, test the condition shown near the start of 377 * base/mask register pair, test the condition shown near the start of
378 * section 3.5.4 (p. 84, BKDG #26094, K8, revA-E). 378 * section 3.5.4 (p. 84, BKDG #26094, K8, revA-E).
379 */ 379 */
380 for (csrow = 0; csrow < CHIPSELECT_COUNT; csrow++) { 380 for (csrow = 0; csrow < pvt->cs_count; csrow++) {
381 381
382 /* This DRAM chip select is disabled on this node */ 382 /* This DRAM chip select is disabled on this node */
383 if ((pvt->dcsb0[csrow] & K8_DCSB_CS_ENABLE) == 0) 383 if ((pvt->dcsb0[csrow] & K8_DCSB_CS_ENABLE) == 0)
@@ -734,7 +734,7 @@ static void find_csrow_limits(struct mem_ctl_info *mci, int csrow,
734 u64 base, mask; 734 u64 base, mask;
735 735
736 pvt = mci->pvt_info; 736 pvt = mci->pvt_info;
737 BUG_ON((csrow < 0) || (csrow >= CHIPSELECT_COUNT)); 737 BUG_ON((csrow < 0) || (csrow >= pvt->cs_count));
738 738
739 base = base_from_dct_base(pvt, csrow); 739 base = base_from_dct_base(pvt, csrow);
740 mask = mask_from_dct_mask(pvt, csrow); 740 mask = mask_from_dct_mask(pvt, csrow);
@@ -962,35 +962,27 @@ err_reg:
962 */ 962 */
963static void amd64_set_dct_base_and_mask(struct amd64_pvt *pvt) 963static void amd64_set_dct_base_and_mask(struct amd64_pvt *pvt)
964{ 964{
965 if (pvt->ext_model >= OPTERON_CPU_REV_F) { 965
966 if (boot_cpu_data.x86 == 0xf && pvt->ext_model < OPTERON_CPU_REV_F) {
967 pvt->dcsb_base = REV_E_DCSB_BASE_BITS;
968 pvt->dcsm_mask = REV_E_DCSM_MASK_BITS;
969 pvt->dcs_mask_notused = REV_E_DCS_NOTUSED_BITS;
970 pvt->dcs_shift = REV_E_DCS_SHIFT;
971 pvt->cs_count = 8;
972 pvt->num_dcsm = 8;
973 } else {
966 pvt->dcsb_base = REV_F_F1Xh_DCSB_BASE_BITS; 974 pvt->dcsb_base = REV_F_F1Xh_DCSB_BASE_BITS;
967 pvt->dcsm_mask = REV_F_F1Xh_DCSM_MASK_BITS; 975 pvt->dcsm_mask = REV_F_F1Xh_DCSM_MASK_BITS;
968 pvt->dcs_mask_notused = REV_F_F1Xh_DCS_NOTUSED_BITS; 976 pvt->dcs_mask_notused = REV_F_F1Xh_DCS_NOTUSED_BITS;
969 pvt->dcs_shift = REV_F_F1Xh_DCS_SHIFT; 977 pvt->dcs_shift = REV_F_F1Xh_DCS_SHIFT;
970 978
971 switch (boot_cpu_data.x86) { 979 if (boot_cpu_data.x86 == 0x11) {
972 case 0xf: 980 pvt->cs_count = 4;
973 pvt->num_dcsm = REV_F_DCSM_COUNT; 981 pvt->num_dcsm = 2;
974 break; 982 } else {
975 983 pvt->cs_count = 8;
976 case 0x10: 984 pvt->num_dcsm = 4;
977 pvt->num_dcsm = F10_DCSM_COUNT;
978 break;
979
980 case 0x11:
981 pvt->num_dcsm = F11_DCSM_COUNT;
982 break;
983
984 default:
985 amd64_printk(KERN_ERR, "Unsupported family!\n");
986 break;
987 } 985 }
988 } else {
989 pvt->dcsb_base = REV_E_DCSB_BASE_BITS;
990 pvt->dcsm_mask = REV_E_DCSM_MASK_BITS;
991 pvt->dcs_mask_notused = REV_E_DCS_NOTUSED_BITS;
992 pvt->dcs_shift = REV_E_DCS_SHIFT;
993 pvt->num_dcsm = REV_E_DCSM_COUNT;
994 } 986 }
995} 987}
996 988
@@ -1003,7 +995,7 @@ static void amd64_read_dct_base_mask(struct amd64_pvt *pvt)
1003 995
1004 amd64_set_dct_base_and_mask(pvt); 996 amd64_set_dct_base_and_mask(pvt);
1005 997
1006 for (cs = 0; cs < CHIPSELECT_COUNT; cs++) { 998 for (cs = 0; cs < pvt->cs_count; cs++) {
1007 reg = K8_DCSB0 + (cs * 4); 999 reg = K8_DCSB0 + (cs * 4);
1008 err = pci_read_config_dword(pvt->dram_f2_ctl, reg, 1000 err = pci_read_config_dword(pvt->dram_f2_ctl, reg,
1009 &pvt->dcsb0[cs]); 1001 &pvt->dcsb0[cs]);
@@ -1130,7 +1122,7 @@ static void k8_read_dram_base_limit(struct amd64_pvt *pvt, int dram)
1130 debugf0("Reading K8_DRAM_BASE_LOW failed\n"); 1122 debugf0("Reading K8_DRAM_BASE_LOW failed\n");
1131 1123
1132 /* Extract parts into separate data entries */ 1124 /* Extract parts into separate data entries */
1133 pvt->dram_base[dram] = ((u64) low & 0xFFFF0000) << 8; 1125 pvt->dram_base[dram] = ((u64) low & 0xFFFF0000) << 24;
1134 pvt->dram_IntlvEn[dram] = (low >> 8) & 0x7; 1126 pvt->dram_IntlvEn[dram] = (low >> 8) & 0x7;
1135 pvt->dram_rw_en[dram] = (low & 0x3); 1127 pvt->dram_rw_en[dram] = (low & 0x3);
1136 1128
@@ -1143,7 +1135,7 @@ static void k8_read_dram_base_limit(struct amd64_pvt *pvt, int dram)
1143 * Extract parts into separate data entries. Limit is the HIGHEST memory 1135 * Extract parts into separate data entries. Limit is the HIGHEST memory
1144 * location of the region, so lower 24 bits need to be all ones 1136 * location of the region, so lower 24 bits need to be all ones
1145 */ 1137 */
1146 pvt->dram_limit[dram] = (((u64) low & 0xFFFF0000) << 8) | 0x00FFFFFF; 1138 pvt->dram_limit[dram] = (((u64) low & 0xFFFF0000) << 24) | 0x00FFFFFF;
1147 pvt->dram_IntlvSel[dram] = (low >> 8) & 0x7; 1139 pvt->dram_IntlvSel[dram] = (low >> 8) & 0x7;
1148 pvt->dram_DstNode[dram] = (low & 0x7); 1140 pvt->dram_DstNode[dram] = (low & 0x7);
1149} 1141}
@@ -1193,7 +1185,7 @@ static void k8_map_sysaddr_to_csrow(struct mem_ctl_info *mci,
1193 * different from the node that detected the error. 1185 * different from the node that detected the error.
1194 */ 1186 */
1195 src_mci = find_mc_by_sys_addr(mci, SystemAddress); 1187 src_mci = find_mc_by_sys_addr(mci, SystemAddress);
1196 if (src_mci) { 1188 if (!src_mci) {
1197 amd64_mc_printk(mci, KERN_ERR, 1189 amd64_mc_printk(mci, KERN_ERR,
1198 "failed to map error address 0x%lx to a node\n", 1190 "failed to map error address 0x%lx to a node\n",
1199 (unsigned long)SystemAddress); 1191 (unsigned long)SystemAddress);
@@ -1376,8 +1368,8 @@ static void f10_read_dram_base_limit(struct amd64_pvt *pvt, int dram)
1376 1368
1377 pvt->dram_IntlvEn[dram] = (low_base >> 8) & 0x7; 1369 pvt->dram_IntlvEn[dram] = (low_base >> 8) & 0x7;
1378 1370
1379 pvt->dram_base[dram] = (((((u64) high_base & 0x000000FF) << 32) | 1371 pvt->dram_base[dram] = (((u64)high_base & 0x000000FF) << 40) |
1380 ((u64) low_base & 0xFFFF0000))) << 8; 1372 (((u64)low_base & 0xFFFF0000) << 24);
1381 1373
1382 low_offset = K8_DRAM_LIMIT_LOW + (dram << 3); 1374 low_offset = K8_DRAM_LIMIT_LOW + (dram << 3);
1383 high_offset = F10_DRAM_LIMIT_HIGH + (dram << 3); 1375 high_offset = F10_DRAM_LIMIT_HIGH + (dram << 3);
@@ -1398,9 +1390,9 @@ static void f10_read_dram_base_limit(struct amd64_pvt *pvt, int dram)
1398 * Extract address values and form a LIMIT address. Limit is the HIGHEST 1390 * Extract address values and form a LIMIT address. Limit is the HIGHEST
1399 * memory location of the region, so low 24 bits need to be all ones. 1391 * memory location of the region, so low 24 bits need to be all ones.
1400 */ 1392 */
1401 low_limit |= 0x0000FFFF; 1393 pvt->dram_limit[dram] = (((u64)high_limit & 0x000000FF) << 40) |
1402 pvt->dram_limit[dram] = 1394 (((u64) low_limit & 0xFFFF0000) << 24) |
1403 ((((u64) high_limit << 32) + (u64) low_limit) << 8) | (0xFF); 1395 0x00FFFFFF;
1404} 1396}
1405 1397
1406static void f10_read_dram_ctl_register(struct amd64_pvt *pvt) 1398static void f10_read_dram_ctl_register(struct amd64_pvt *pvt)
@@ -1566,7 +1558,7 @@ static int f10_lookup_addr_in_dct(u32 in_addr, u32 nid, u32 cs)
1566 1558
1567 debugf1("InputAddr=0x%x channelselect=%d\n", in_addr, cs); 1559 debugf1("InputAddr=0x%x channelselect=%d\n", in_addr, cs);
1568 1560
1569 for (csrow = 0; csrow < CHIPSELECT_COUNT; csrow++) { 1561 for (csrow = 0; csrow < pvt->cs_count; csrow++) {
1570 1562
1571 cs_base = amd64_get_dct_base(pvt, cs, csrow); 1563 cs_base = amd64_get_dct_base(pvt, cs, csrow);
1572 if (!(cs_base & K8_DCSB_CS_ENABLE)) 1564 if (!(cs_base & K8_DCSB_CS_ENABLE))
@@ -2497,7 +2489,7 @@ err_reg:
2497 * NOTE: CPU Revision Dependent code 2489 * NOTE: CPU Revision Dependent code
2498 * 2490 *
2499 * Input: 2491 * Input:
2500 * @csrow_nr ChipSelect Row Number (0..CHIPSELECT_COUNT-1) 2492 * @csrow_nr ChipSelect Row Number (0..pvt->cs_count-1)
2501 * k8 private pointer to --> 2493 * k8 private pointer to -->
2502 * DRAM Bank Address mapping register 2494 * DRAM Bank Address mapping register
2503 * node_id 2495 * node_id
@@ -2577,7 +2569,7 @@ static int amd64_init_csrows(struct mem_ctl_info *mci)
2577 (pvt->nbcfg & K8_NBCFG_ECC_ENABLE) ? "Enabled" : "Disabled" 2569 (pvt->nbcfg & K8_NBCFG_ECC_ENABLE) ? "Enabled" : "Disabled"
2578 ); 2570 );
2579 2571
2580 for (i = 0; i < CHIPSELECT_COUNT; i++) { 2572 for (i = 0; i < pvt->cs_count; i++) {
2581 csrow = &mci->csrows[i]; 2573 csrow = &mci->csrows[i];
2582 2574
2583 if ((pvt->dcsb0[i] & K8_DCSB_CS_ENABLE) == 0) { 2575 if ((pvt->dcsb0[i] & K8_DCSB_CS_ENABLE) == 0) {
@@ -2988,7 +2980,7 @@ static int amd64_init_2nd_stage(struct amd64_pvt *pvt)
2988 goto err_exit; 2980 goto err_exit;
2989 2981
2990 ret = -ENOMEM; 2982 ret = -ENOMEM;
2991 mci = edac_mc_alloc(0, CHIPSELECT_COUNT, pvt->channel_count, node_id); 2983 mci = edac_mc_alloc(0, pvt->cs_count, pvt->channel_count, node_id);
2992 if (!mci) 2984 if (!mci)
2993 goto err_exit; 2985 goto err_exit;
2994 2986
diff --git a/drivers/edac/amd64_edac.h b/drivers/edac/amd64_edac.h
index 8ea07e2715dc..c6f359a85207 100644
--- a/drivers/edac/amd64_edac.h
+++ b/drivers/edac/amd64_edac.h
@@ -132,6 +132,8 @@
132#define EDAC_AMD64_VERSION " Ver: 3.2.0 " __DATE__ 132#define EDAC_AMD64_VERSION " Ver: 3.2.0 " __DATE__
133#define EDAC_MOD_STR "amd64_edac" 133#define EDAC_MOD_STR "amd64_edac"
134 134
135#define EDAC_MAX_NUMNODES 8
136
135/* Extended Model from CPUID, for CPU Revision numbers */ 137/* Extended Model from CPUID, for CPU Revision numbers */
136#define OPTERON_CPU_LE_REV_C 0 138#define OPTERON_CPU_LE_REV_C 0
137#define OPTERON_CPU_REV_D 1 139#define OPTERON_CPU_REV_D 1
@@ -142,7 +144,7 @@
142#define OPTERON_CPU_REV_FA 5 144#define OPTERON_CPU_REV_FA 5
143 145
144/* Hardware limit on ChipSelect rows per MC and processors per system */ 146/* Hardware limit on ChipSelect rows per MC and processors per system */
145#define CHIPSELECT_COUNT 8 147#define MAX_CS_COUNT 8
146#define DRAM_REG_COUNT 8 148#define DRAM_REG_COUNT 8
147 149
148 150
@@ -193,7 +195,6 @@
193 */ 195 */
194#define REV_E_DCSB_BASE_BITS (0xFFE0FE00ULL) 196#define REV_E_DCSB_BASE_BITS (0xFFE0FE00ULL)
195#define REV_E_DCS_SHIFT 4 197#define REV_E_DCS_SHIFT 4
196#define REV_E_DCSM_COUNT 8
197 198
198#define REV_F_F1Xh_DCSB_BASE_BITS (0x1FF83FE0ULL) 199#define REV_F_F1Xh_DCSB_BASE_BITS (0x1FF83FE0ULL)
199#define REV_F_F1Xh_DCS_SHIFT 8 200#define REV_F_F1Xh_DCS_SHIFT 8
@@ -204,9 +205,6 @@
204 */ 205 */
205#define REV_F_DCSB_BASE_BITS (0x1FF83FE0ULL) 206#define REV_F_DCSB_BASE_BITS (0x1FF83FE0ULL)
206#define REV_F_DCS_SHIFT 8 207#define REV_F_DCS_SHIFT 8
207#define REV_F_DCSM_COUNT 4
208#define F10_DCSM_COUNT 4
209#define F11_DCSM_COUNT 2
210 208
211/* DRAM CS Mask Registers */ 209/* DRAM CS Mask Registers */
212#define K8_DCSM0 0x60 210#define K8_DCSM0 0x60
@@ -374,13 +372,11 @@ enum {
374 372
375#define SET_NB_DRAM_INJECTION_WRITE(word, bits) \ 373#define SET_NB_DRAM_INJECTION_WRITE(word, bits) \
376 (BIT(((word) & 0xF) + 20) | \ 374 (BIT(((word) & 0xF) + 20) | \
377 BIT(17) | \ 375 BIT(17) | bits)
378 ((bits) & 0xF))
379 376
380#define SET_NB_DRAM_INJECTION_READ(word, bits) \ 377#define SET_NB_DRAM_INJECTION_READ(word, bits) \
381 (BIT(((word) & 0xF) + 20) | \ 378 (BIT(((word) & 0xF) + 20) | \
382 BIT(16) | \ 379 BIT(16) | bits)
383 ((bits) & 0xF))
384 380
385#define K8_NBCAP 0xE8 381#define K8_NBCAP 0xE8
386#define K8_NBCAP_CORES (BIT(12)|BIT(13)) 382#define K8_NBCAP_CORES (BIT(12)|BIT(13))
@@ -445,12 +441,12 @@ struct amd64_pvt {
445 u32 dbam1; /* DRAM Base Address Mapping reg for DCT1 */ 441 u32 dbam1; /* DRAM Base Address Mapping reg for DCT1 */
446 442
447 /* DRAM CS Base Address Registers F2x[1,0][5C:40] */ 443 /* DRAM CS Base Address Registers F2x[1,0][5C:40] */
448 u32 dcsb0[CHIPSELECT_COUNT]; 444 u32 dcsb0[MAX_CS_COUNT];
449 u32 dcsb1[CHIPSELECT_COUNT]; 445 u32 dcsb1[MAX_CS_COUNT];
450 446
451 /* DRAM CS Mask Registers F2x[1,0][6C:60] */ 447 /* DRAM CS Mask Registers F2x[1,0][6C:60] */
452 u32 dcsm0[CHIPSELECT_COUNT]; 448 u32 dcsm0[MAX_CS_COUNT];
453 u32 dcsm1[CHIPSELECT_COUNT]; 449 u32 dcsm1[MAX_CS_COUNT];
454 450
455 /* 451 /*
456 * Decoded parts of DRAM BASE and LIMIT Registers 452 * Decoded parts of DRAM BASE and LIMIT Registers
@@ -470,6 +466,7 @@ struct amd64_pvt {
470 */ 466 */
471 u32 dcsb_base; /* DCSB base bits */ 467 u32 dcsb_base; /* DCSB base bits */
472 u32 dcsm_mask; /* DCSM mask bits */ 468 u32 dcsm_mask; /* DCSM mask bits */
469 u32 cs_count; /* num chip selects (== num DCSB registers) */
473 u32 num_dcsm; /* Number of DCSM registers */ 470 u32 num_dcsm; /* Number of DCSM registers */
474 u32 dcs_mask_notused; /* DCSM notused mask bits */ 471 u32 dcs_mask_notused; /* DCSM notused mask bits */
475 u32 dcs_shift; /* DCSB and DCSM shift value */ 472 u32 dcs_shift; /* DCSB and DCSM shift value */
diff --git a/drivers/edac/amd64_edac_inj.c b/drivers/edac/amd64_edac_inj.c
index d3675b76b3a7..29f1f7a612d9 100644
--- a/drivers/edac/amd64_edac_inj.c
+++ b/drivers/edac/amd64_edac_inj.c
@@ -1,5 +1,11 @@
1#include "amd64_edac.h" 1#include "amd64_edac.h"
2 2
3static ssize_t amd64_inject_section_show(struct mem_ctl_info *mci, char *buf)
4{
5 struct amd64_pvt *pvt = mci->pvt_info;
6 return sprintf(buf, "0x%x\n", pvt->injection.section);
7}
8
3/* 9/*
4 * store error injection section value which refers to one of 4 16-byte sections 10 * store error injection section value which refers to one of 4 16-byte sections
5 * within a 64-byte cacheline 11 * within a 64-byte cacheline
@@ -15,12 +21,26 @@ static ssize_t amd64_inject_section_store(struct mem_ctl_info *mci,
15 21
16 ret = strict_strtoul(data, 10, &value); 22 ret = strict_strtoul(data, 10, &value);
17 if (ret != -EINVAL) { 23 if (ret != -EINVAL) {
24
25 if (value > 3) {
26 amd64_printk(KERN_WARNING,
27 "%s: invalid section 0x%lx\n",
28 __func__, value);
29 return -EINVAL;
30 }
31
18 pvt->injection.section = (u32) value; 32 pvt->injection.section = (u32) value;
19 return count; 33 return count;
20 } 34 }
21 return ret; 35 return ret;
22} 36}
23 37
38static ssize_t amd64_inject_word_show(struct mem_ctl_info *mci, char *buf)
39{
40 struct amd64_pvt *pvt = mci->pvt_info;
41 return sprintf(buf, "0x%x\n", pvt->injection.word);
42}
43
24/* 44/*
25 * store error injection word value which refers to one of 9 16-bit word of the 45 * store error injection word value which refers to one of 9 16-bit word of the
26 * 16-byte (128-bit + ECC bits) section 46 * 16-byte (128-bit + ECC bits) section
@@ -37,14 +57,25 @@ static ssize_t amd64_inject_word_store(struct mem_ctl_info *mci,
37 ret = strict_strtoul(data, 10, &value); 57 ret = strict_strtoul(data, 10, &value);
38 if (ret != -EINVAL) { 58 if (ret != -EINVAL) {
39 59
40 value = (value <= 8) ? value : 0; 60 if (value > 8) {
41 pvt->injection.word = (u32) value; 61 amd64_printk(KERN_WARNING,
62 "%s: invalid word 0x%lx\n",
63 __func__, value);
64 return -EINVAL;
65 }
42 66
67 pvt->injection.word = (u32) value;
43 return count; 68 return count;
44 } 69 }
45 return ret; 70 return ret;
46} 71}
47 72
73static ssize_t amd64_inject_ecc_vector_show(struct mem_ctl_info *mci, char *buf)
74{
75 struct amd64_pvt *pvt = mci->pvt_info;
76 return sprintf(buf, "0x%x\n", pvt->injection.bit_map);
77}
78
48/* 79/*
49 * store 16 bit error injection vector which enables injecting errors to the 80 * store 16 bit error injection vector which enables injecting errors to the
50 * corresponding bit within the error injection word above. When used during a 81 * corresponding bit within the error injection word above. When used during a
@@ -60,8 +91,14 @@ static ssize_t amd64_inject_ecc_vector_store(struct mem_ctl_info *mci,
60 ret = strict_strtoul(data, 16, &value); 91 ret = strict_strtoul(data, 16, &value);
61 if (ret != -EINVAL) { 92 if (ret != -EINVAL) {
62 93
63 pvt->injection.bit_map = (u32) value & 0xFFFF; 94 if (value & 0xFFFF0000) {
95 amd64_printk(KERN_WARNING,
96 "%s: invalid EccVector: 0x%lx\n",
97 __func__, value);
98 return -EINVAL;
99 }
64 100
101 pvt->injection.bit_map = (u32) value;
65 return count; 102 return count;
66 } 103 }
67 return ret; 104 return ret;
@@ -147,7 +184,7 @@ struct mcidev_sysfs_attribute amd64_inj_attrs[] = {
147 .name = "inject_section", 184 .name = "inject_section",
148 .mode = (S_IRUGO | S_IWUSR) 185 .mode = (S_IRUGO | S_IWUSR)
149 }, 186 },
150 .show = NULL, 187 .show = amd64_inject_section_show,
151 .store = amd64_inject_section_store, 188 .store = amd64_inject_section_store,
152 }, 189 },
153 { 190 {
@@ -155,7 +192,7 @@ struct mcidev_sysfs_attribute amd64_inj_attrs[] = {
155 .name = "inject_word", 192 .name = "inject_word",
156 .mode = (S_IRUGO | S_IWUSR) 193 .mode = (S_IRUGO | S_IWUSR)
157 }, 194 },
158 .show = NULL, 195 .show = amd64_inject_word_show,
159 .store = amd64_inject_word_store, 196 .store = amd64_inject_word_store,
160 }, 197 },
161 { 198 {
@@ -163,7 +200,7 @@ struct mcidev_sysfs_attribute amd64_inj_attrs[] = {
163 .name = "inject_ecc_vector", 200 .name = "inject_ecc_vector",
164 .mode = (S_IRUGO | S_IWUSR) 201 .mode = (S_IRUGO | S_IWUSR)
165 }, 202 },
166 .show = NULL, 203 .show = amd64_inject_ecc_vector_show,
167 .store = amd64_inject_ecc_vector_store, 204 .store = amd64_inject_ecc_vector_store,
168 }, 205 },
169 { 206 {
diff --git a/drivers/edac/edac_mce_amd.c b/drivers/edac/edac_mce_amd.c
index 0c21c370c9dd..713ed7d37247 100644
--- a/drivers/edac/edac_mce_amd.c
+++ b/drivers/edac/edac_mce_amd.c
@@ -3,6 +3,7 @@
3 3
4static bool report_gart_errors; 4static bool report_gart_errors;
5static void (*nb_bus_decoder)(int node_id, struct err_regs *regs); 5static void (*nb_bus_decoder)(int node_id, struct err_regs *regs);
6static void (*orig_mce_callback)(struct mce *m);
6 7
7void amd_report_gart_errors(bool v) 8void amd_report_gart_errors(bool v)
8{ 9{
@@ -362,7 +363,7 @@ static inline void amd_decode_err_code(unsigned int ec)
362 pr_warning("Huh? Unknown MCE error 0x%x\n", ec); 363 pr_warning("Huh? Unknown MCE error 0x%x\n", ec);
363} 364}
364 365
365void decode_mce(struct mce *m) 366static void amd_decode_mce(struct mce *m)
366{ 367{
367 struct err_regs regs; 368 struct err_regs regs;
368 int node, ecc; 369 int node, ecc;
@@ -420,3 +421,32 @@ void decode_mce(struct mce *m)
420 421
421 amd_decode_err_code(m->status & 0xffff); 422 amd_decode_err_code(m->status & 0xffff);
422} 423}
424
425static int __init mce_amd_init(void)
426{
427 /*
428 * We can decode MCEs for Opteron and later CPUs:
429 */
430 if ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) &&
431 (boot_cpu_data.x86 >= 0xf)) {
432 /* safe the default decode mce callback */
433 orig_mce_callback = x86_mce_decode_callback;
434
435 x86_mce_decode_callback = amd_decode_mce;
436 }
437
438 return 0;
439}
440early_initcall(mce_amd_init);
441
442#ifdef MODULE
443static void __exit mce_amd_exit(void)
444{
445 x86_mce_decode_callback = orig_mce_callback;
446}
447
448MODULE_DESCRIPTION("AMD MCE decoder");
449MODULE_ALIAS("edac-mce-amd");
450MODULE_LICENSE("GPL");
451module_exit(mce_amd_exit);
452#endif
diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c
index ced186d7e9a9..5089331544ed 100644
--- a/drivers/firewire/core-cdev.c
+++ b/drivers/firewire/core-cdev.c
@@ -33,6 +33,7 @@
33#include <linux/mutex.h> 33#include <linux/mutex.h>
34#include <linux/poll.h> 34#include <linux/poll.h>
35#include <linux/preempt.h> 35#include <linux/preempt.h>
36#include <linux/sched.h>
36#include <linux/spinlock.h> 37#include <linux/spinlock.h>
37#include <linux/time.h> 38#include <linux/time.h>
38#include <linux/uaccess.h> 39#include <linux/uaccess.h>
diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c
index 50f0176de615..98dbbda3ad41 100644
--- a/drivers/firewire/sbp2.c
+++ b/drivers/firewire/sbp2.c
@@ -188,14 +188,7 @@ static struct fw_device *target_device(struct sbp2_target *tgt)
188/* Impossible login_id, to detect logout attempt before successful login */ 188/* Impossible login_id, to detect logout attempt before successful login */
189#define INVALID_LOGIN_ID 0x10000 189#define INVALID_LOGIN_ID 0x10000
190 190
191/* 191#define SBP2_ORB_TIMEOUT 2000U /* Timeout in ms */
192 * Per section 7.4.8 of the SBP-2 spec, a mgt_ORB_timeout value can be
193 * provided in the config rom. Most devices do provide a value, which
194 * we'll use for login management orbs, but with some sane limits.
195 */
196#define SBP2_MIN_LOGIN_ORB_TIMEOUT 5000U /* Timeout in ms */
197#define SBP2_MAX_LOGIN_ORB_TIMEOUT 40000U /* Timeout in ms */
198#define SBP2_ORB_TIMEOUT 2000U /* Timeout in ms */
199#define SBP2_ORB_NULL 0x80000000 192#define SBP2_ORB_NULL 0x80000000
200#define SBP2_RETRY_LIMIT 0xf /* 15 retries */ 193#define SBP2_RETRY_LIMIT 0xf /* 15 retries */
201#define SBP2_CYCLE_LIMIT (0xc8 << 12) /* 200 125us cycles */ 194#define SBP2_CYCLE_LIMIT (0xc8 << 12) /* 200 125us cycles */
@@ -1034,7 +1027,6 @@ static int sbp2_scan_unit_dir(struct sbp2_target *tgt, u32 *directory,
1034{ 1027{
1035 struct fw_csr_iterator ci; 1028 struct fw_csr_iterator ci;
1036 int key, value; 1029 int key, value;
1037 unsigned int timeout;
1038 1030
1039 fw_csr_iterator_init(&ci, directory); 1031 fw_csr_iterator_init(&ci, directory);
1040 while (fw_csr_iterator_next(&ci, &key, &value)) { 1032 while (fw_csr_iterator_next(&ci, &key, &value)) {
@@ -1059,17 +1051,7 @@ static int sbp2_scan_unit_dir(struct sbp2_target *tgt, u32 *directory,
1059 1051
1060 case SBP2_CSR_UNIT_CHARACTERISTICS: 1052 case SBP2_CSR_UNIT_CHARACTERISTICS:
1061 /* the timeout value is stored in 500ms units */ 1053 /* the timeout value is stored in 500ms units */
1062 timeout = ((unsigned int) value >> 8 & 0xff) * 500; 1054 tgt->mgt_orb_timeout = (value >> 8 & 0xff) * 500;
1063 timeout = max(timeout, SBP2_MIN_LOGIN_ORB_TIMEOUT);
1064 tgt->mgt_orb_timeout =
1065 min(timeout, SBP2_MAX_LOGIN_ORB_TIMEOUT);
1066
1067 if (timeout > tgt->mgt_orb_timeout)
1068 fw_notify("%s: config rom contains %ds "
1069 "management ORB timeout, limiting "
1070 "to %ds\n", tgt->bus_id,
1071 timeout / 1000,
1072 tgt->mgt_orb_timeout / 1000);
1073 break; 1055 break;
1074 1056
1075 case SBP2_CSR_LOGICAL_UNIT_NUMBER: 1057 case SBP2_CSR_LOGICAL_UNIT_NUMBER:
@@ -1087,6 +1069,22 @@ static int sbp2_scan_unit_dir(struct sbp2_target *tgt, u32 *directory,
1087 return 0; 1069 return 0;
1088} 1070}
1089 1071
1072/*
1073 * Per section 7.4.8 of the SBP-2 spec, a mgt_ORB_timeout value can be
1074 * provided in the config rom. Most devices do provide a value, which
1075 * we'll use for login management orbs, but with some sane limits.
1076 */
1077static void sbp2_clamp_management_orb_timeout(struct sbp2_target *tgt)
1078{
1079 unsigned int timeout = tgt->mgt_orb_timeout;
1080
1081 if (timeout > 40000)
1082 fw_notify("%s: %ds mgt_ORB_timeout limited to 40s\n",
1083 tgt->bus_id, timeout / 1000);
1084
1085 tgt->mgt_orb_timeout = clamp_val(timeout, 5000, 40000);
1086}
1087
1090static void sbp2_init_workarounds(struct sbp2_target *tgt, u32 model, 1088static void sbp2_init_workarounds(struct sbp2_target *tgt, u32 model,
1091 u32 firmware_revision) 1089 u32 firmware_revision)
1092{ 1090{
@@ -1171,6 +1169,7 @@ static int sbp2_probe(struct device *dev)
1171 &firmware_revision) < 0) 1169 &firmware_revision) < 0)
1172 goto fail_tgt_put; 1170 goto fail_tgt_put;
1173 1171
1172 sbp2_clamp_management_orb_timeout(tgt);
1174 sbp2_init_workarounds(tgt, model, firmware_revision); 1173 sbp2_init_workarounds(tgt, model, firmware_revision);
1175 1174
1176 /* 1175 /*
diff --git a/drivers/firmware/iscsi_ibft.c b/drivers/firmware/iscsi_ibft.c
index 420a96e7f2db..051d1ebbd287 100644
--- a/drivers/firmware/iscsi_ibft.c
+++ b/drivers/firmware/iscsi_ibft.c
@@ -939,7 +939,7 @@ static int __init ibft_init(void)
939 939
940 if (ibft_addr) { 940 if (ibft_addr) {
941 printk(KERN_INFO "iBFT detected at 0x%llx.\n", 941 printk(KERN_INFO "iBFT detected at 0x%llx.\n",
942 (u64)virt_to_phys((void *)ibft_addr)); 942 (u64)isa_virt_to_bus(ibft_addr));
943 943
944 rc = ibft_check_device(); 944 rc = ibft_check_device();
945 if (rc) 945 if (rc)
diff --git a/drivers/firmware/iscsi_ibft_find.c b/drivers/firmware/iscsi_ibft_find.c
index d53fbbfefa3e..dfb15c06c88f 100644
--- a/drivers/firmware/iscsi_ibft_find.c
+++ b/drivers/firmware/iscsi_ibft_find.c
@@ -65,10 +65,10 @@ void __init reserve_ibft_region(void)
65 * so skip that area */ 65 * so skip that area */
66 if (pos == VGA_MEM) 66 if (pos == VGA_MEM)
67 pos += VGA_SIZE; 67 pos += VGA_SIZE;
68 virt = phys_to_virt(pos); 68 virt = isa_bus_to_virt(pos);
69 if (memcmp(virt, IBFT_SIGN, IBFT_SIGN_LEN) == 0) { 69 if (memcmp(virt, IBFT_SIGN, IBFT_SIGN_LEN) == 0) {
70 unsigned long *addr = 70 unsigned long *addr =
71 (unsigned long *)phys_to_virt(pos + 4); 71 (unsigned long *)isa_bus_to_virt(pos + 4);
72 len = *addr; 72 len = *addr;
73 /* if the length of the table extends past 1M, 73 /* if the length of the table extends past 1M,
74 * the table cannot be valid. */ 74 * the table cannot be valid. */
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index bb11a429394a..662ed923d9eb 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -1487,7 +1487,7 @@ static int gpiolib_open(struct inode *inode, struct file *file)
1487 return single_open(file, gpiolib_show, NULL); 1487 return single_open(file, gpiolib_show, NULL);
1488} 1488}
1489 1489
1490static struct file_operations gpiolib_operations = { 1490static const struct file_operations gpiolib_operations = {
1491 .open = gpiolib_open, 1491 .open = gpiolib_open,
1492 .read = seq_read, 1492 .read = seq_read,
1493 .llseek = seq_lseek, 1493 .llseek = seq_lseek,
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 8e7b0ebece0c..5cae0b3eee9b 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -1556,8 +1556,6 @@ int drm_mode_cursor_ioctl(struct drm_device *dev,
1556 struct drm_crtc *crtc; 1556 struct drm_crtc *crtc;
1557 int ret = 0; 1557 int ret = 0;
1558 1558
1559 DRM_DEBUG_KMS("\n");
1560
1561 if (!req->flags) { 1559 if (!req->flags) {
1562 DRM_ERROR("no operation set\n"); 1560 DRM_ERROR("no operation set\n");
1563 return -EINVAL; 1561 return -EINVAL;
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 819ddcbfcce5..23dc9c115fd9 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -454,6 +454,96 @@ out_free:
454} 454}
455EXPORT_SYMBOL(drm_fb_helper_init_crtc_count); 455EXPORT_SYMBOL(drm_fb_helper_init_crtc_count);
456 456
457static void setcolreg(struct drm_crtc *crtc, u16 red, u16 green,
458 u16 blue, u16 regno, struct fb_info *info)
459{
460 struct drm_fb_helper *fb_helper = info->par;
461 struct drm_framebuffer *fb = fb_helper->fb;
462 int pindex;
463
464 pindex = regno;
465
466 if (fb->bits_per_pixel == 16) {
467 pindex = regno << 3;
468
469 if (fb->depth == 16 && regno > 63)
470 return;
471 if (fb->depth == 15 && regno > 31)
472 return;
473
474 if (fb->depth == 16) {
475 u16 r, g, b;
476 int i;
477 if (regno < 32) {
478 for (i = 0; i < 8; i++)
479 fb_helper->funcs->gamma_set(crtc, red,
480 green, blue, pindex + i);
481 }
482
483 fb_helper->funcs->gamma_get(crtc, &r,
484 &g, &b,
485 pindex >> 1);
486
487 for (i = 0; i < 4; i++)
488 fb_helper->funcs->gamma_set(crtc, r,
489 green, b,
490 (pindex >> 1) + i);
491 }
492 }
493
494 if (fb->depth != 16)
495 fb_helper->funcs->gamma_set(crtc, red, green, blue, pindex);
496
497 if (regno < 16 && info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
498 ((u32 *) fb->pseudo_palette)[regno] =
499 (regno << info->var.red.offset) |
500 (regno << info->var.green.offset) |
501 (regno << info->var.blue.offset);
502 }
503}
504
505int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info)
506{
507 struct drm_fb_helper *fb_helper = info->par;
508 struct drm_device *dev = fb_helper->dev;
509 u16 *red, *green, *blue, *transp;
510 struct drm_crtc *crtc;
511 int i, rc = 0;
512 int start;
513
514 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
515 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
516 for (i = 0; i < fb_helper->crtc_count; i++) {
517 if (crtc->base.id == fb_helper->crtc_info[i].crtc_id)
518 break;
519 }
520 if (i == fb_helper->crtc_count)
521 continue;
522
523 red = cmap->red;
524 green = cmap->green;
525 blue = cmap->blue;
526 transp = cmap->transp;
527 start = cmap->start;
528
529 for (i = 0; i < cmap->len; i++) {
530 u16 hred, hgreen, hblue, htransp = 0xffff;
531
532 hred = *red++;
533 hgreen = *green++;
534 hblue = *blue++;
535
536 if (transp)
537 htransp = *transp++;
538
539 setcolreg(crtc, hred, hgreen, hblue, start++, info);
540 }
541 crtc_funcs->load_lut(crtc);
542 }
543 return rc;
544}
545EXPORT_SYMBOL(drm_fb_helper_setcmap);
546
457int drm_fb_helper_setcolreg(unsigned regno, 547int drm_fb_helper_setcolreg(unsigned regno,
458 unsigned red, 548 unsigned red,
459 unsigned green, 549 unsigned green,
@@ -466,9 +556,11 @@ int drm_fb_helper_setcolreg(unsigned regno,
466 struct drm_crtc *crtc; 556 struct drm_crtc *crtc;
467 int i; 557 int i;
468 558
469 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 559 if (regno > 255)
470 struct drm_framebuffer *fb = fb_helper->fb; 560 return 1;
471 561
562 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
563 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
472 for (i = 0; i < fb_helper->crtc_count; i++) { 564 for (i = 0; i < fb_helper->crtc_count; i++) {
473 if (crtc->base.id == fb_helper->crtc_info[i].crtc_id) 565 if (crtc->base.id == fb_helper->crtc_info[i].crtc_id)
474 break; 566 break;
@@ -476,35 +568,9 @@ int drm_fb_helper_setcolreg(unsigned regno,
476 if (i == fb_helper->crtc_count) 568 if (i == fb_helper->crtc_count)
477 continue; 569 continue;
478 570
479 if (regno > 255)
480 return 1;
481
482 if (fb->depth == 8) {
483 fb_helper->funcs->gamma_set(crtc, red, green, blue, regno);
484 return 0;
485 }
486 571
487 if (regno < 16) { 572 setcolreg(crtc, red, green, blue, regno, info);
488 switch (fb->depth) { 573 crtc_funcs->load_lut(crtc);
489 case 15:
490 fb->pseudo_palette[regno] = ((red & 0xf800) >> 1) |
491 ((green & 0xf800) >> 6) |
492 ((blue & 0xf800) >> 11);
493 break;
494 case 16:
495 fb->pseudo_palette[regno] = (red & 0xf800) |
496 ((green & 0xfc00) >> 5) |
497 ((blue & 0xf800) >> 11);
498 break;
499 case 24:
500 case 32:
501 fb->pseudo_palette[regno] =
502 (((red >> 8) & 0xff) << info->var.red.offset) |
503 (((green >> 8) & 0xff) << info->var.green.offset) |
504 (((blue >> 8) & 0xff) << info->var.blue.offset);
505 break;
506 }
507 }
508 } 574 }
509 return 0; 575 return 0;
510} 576}
@@ -674,6 +740,7 @@ int drm_fb_helper_pan_display(struct fb_var_screeninfo *var,
674EXPORT_SYMBOL(drm_fb_helper_pan_display); 740EXPORT_SYMBOL(drm_fb_helper_pan_display);
675 741
676int drm_fb_helper_single_fb_probe(struct drm_device *dev, 742int drm_fb_helper_single_fb_probe(struct drm_device *dev,
743 int preferred_bpp,
677 int (*fb_create)(struct drm_device *dev, 744 int (*fb_create)(struct drm_device *dev,
678 uint32_t fb_width, 745 uint32_t fb_width,
679 uint32_t fb_height, 746 uint32_t fb_height,
@@ -696,6 +763,11 @@ int drm_fb_helper_single_fb_probe(struct drm_device *dev,
696 struct drm_fb_helper *fb_helper; 763 struct drm_fb_helper *fb_helper;
697 uint32_t surface_depth = 24, surface_bpp = 32; 764 uint32_t surface_depth = 24, surface_bpp = 32;
698 765
766 /* if driver picks 8 or 16 by default use that
767 for both depth/bpp */
768 if (preferred_bpp != surface_bpp) {
769 surface_depth = surface_bpp = preferred_bpp;
770 }
699 /* first up get a count of crtcs now in use and new min/maxes width/heights */ 771 /* first up get a count of crtcs now in use and new min/maxes width/heights */
700 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 772 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
701 struct drm_fb_helper_connector *fb_help_conn = connector->fb_helper_private; 773 struct drm_fb_helper_connector *fb_help_conn = connector->fb_helper_private;
@@ -851,10 +923,12 @@ void drm_fb_helper_free(struct drm_fb_helper *helper)
851} 923}
852EXPORT_SYMBOL(drm_fb_helper_free); 924EXPORT_SYMBOL(drm_fb_helper_free);
853 925
854void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch) 926void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch,
927 uint32_t depth)
855{ 928{
856 info->fix.type = FB_TYPE_PACKED_PIXELS; 929 info->fix.type = FB_TYPE_PACKED_PIXELS;
857 info->fix.visual = FB_VISUAL_TRUECOLOR; 930 info->fix.visual = depth == 8 ? FB_VISUAL_PSEUDOCOLOR :
931 FB_VISUAL_DIRECTCOLOR;
858 info->fix.type_aux = 0; 932 info->fix.type_aux = 0;
859 info->fix.xpanstep = 1; /* doing it in hw */ 933 info->fix.xpanstep = 1; /* doing it in hw */
860 info->fix.ypanstep = 1; /* doing it in hw */ 934 info->fix.ypanstep = 1; /* doing it in hw */
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 45d507ebd3ff..92aeb918e0c0 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1468,6 +1468,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
1468 spin_lock_init(&dev_priv->user_irq_lock); 1468 spin_lock_init(&dev_priv->user_irq_lock);
1469 spin_lock_init(&dev_priv->error_lock); 1469 spin_lock_init(&dev_priv->error_lock);
1470 dev_priv->user_irq_refcount = 0; 1470 dev_priv->user_irq_refcount = 0;
1471 dev_priv->trace_irq_seqno = 0;
1471 1472
1472 ret = drm_vblank_init(dev, I915_NUM_PIPE); 1473 ret = drm_vblank_init(dev, I915_NUM_PIPE);
1473 1474
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index b24b2d145b75..6035d3dae851 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -202,6 +202,7 @@ typedef struct drm_i915_private {
202 spinlock_t user_irq_lock; 202 spinlock_t user_irq_lock;
203 /** Refcount for i915_user_irq_get() versus i915_user_irq_put(). */ 203 /** Refcount for i915_user_irq_get() versus i915_user_irq_put(). */
204 int user_irq_refcount; 204 int user_irq_refcount;
205 u32 trace_irq_seqno;
205 /** Cached value of IMR to avoid reads in updating the bitfield */ 206 /** Cached value of IMR to avoid reads in updating the bitfield */
206 u32 irq_mask_reg; 207 u32 irq_mask_reg;
207 u32 pipestat[2]; 208 u32 pipestat[2];
@@ -665,6 +666,7 @@ extern int i915_irq_emit(struct drm_device *dev, void *data,
665extern int i915_irq_wait(struct drm_device *dev, void *data, 666extern int i915_irq_wait(struct drm_device *dev, void *data,
666 struct drm_file *file_priv); 667 struct drm_file *file_priv);
667void i915_user_irq_get(struct drm_device *dev); 668void i915_user_irq_get(struct drm_device *dev);
669void i915_trace_irq_get(struct drm_device *dev, u32 seqno);
668void i915_user_irq_put(struct drm_device *dev); 670void i915_user_irq_put(struct drm_device *dev);
669extern void i915_enable_interrupt (struct drm_device *dev); 671extern void i915_enable_interrupt (struct drm_device *dev);
670 672
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 40727d4c2919..abfc27b0c2ea 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1770,7 +1770,7 @@ i915_gem_retire_requests(struct drm_device *dev)
1770 drm_i915_private_t *dev_priv = dev->dev_private; 1770 drm_i915_private_t *dev_priv = dev->dev_private;
1771 uint32_t seqno; 1771 uint32_t seqno;
1772 1772
1773 if (!dev_priv->hw_status_page) 1773 if (!dev_priv->hw_status_page || list_empty(&dev_priv->mm.request_list))
1774 return; 1774 return;
1775 1775
1776 seqno = i915_get_gem_seqno(dev); 1776 seqno = i915_get_gem_seqno(dev);
@@ -1794,6 +1794,12 @@ i915_gem_retire_requests(struct drm_device *dev)
1794 } else 1794 } else
1795 break; 1795 break;
1796 } 1796 }
1797
1798 if (unlikely (dev_priv->trace_irq_seqno &&
1799 i915_seqno_passed(dev_priv->trace_irq_seqno, seqno))) {
1800 i915_user_irq_put(dev);
1801 dev_priv->trace_irq_seqno = 0;
1802 }
1797} 1803}
1798 1804
1799void 1805void
@@ -3352,7 +3358,7 @@ i915_dispatch_gem_execbuffer(struct drm_device *dev,
3352 exec_start = (uint32_t) exec_offset + exec->batch_start_offset; 3358 exec_start = (uint32_t) exec_offset + exec->batch_start_offset;
3353 exec_len = (uint32_t) exec->batch_len; 3359 exec_len = (uint32_t) exec->batch_len;
3354 3360
3355 trace_i915_gem_request_submit(dev, dev_priv->mm.next_gem_seqno); 3361 trace_i915_gem_request_submit(dev, dev_priv->mm.next_gem_seqno + 1);
3356 3362
3357 count = nbox ? nbox : 1; 3363 count = nbox ? nbox : 1;
3358 3364
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 4dfeec7cdd42..c3ceffa46ea0 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -725,6 +725,16 @@ void i915_user_irq_put(struct drm_device *dev)
725 spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); 725 spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags);
726} 726}
727 727
728void i915_trace_irq_get(struct drm_device *dev, u32 seqno)
729{
730 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
731
732 if (dev_priv->trace_irq_seqno == 0)
733 i915_user_irq_get(dev);
734
735 dev_priv->trace_irq_seqno = seqno;
736}
737
728static int i915_wait_irq(struct drm_device * dev, int irq_nr) 738static int i915_wait_irq(struct drm_device * dev, int irq_nr)
729{ 739{
730 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 740 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h
index 5567a40816f3..01840d9bc38f 100644
--- a/drivers/gpu/drm/i915/i915_trace.h
+++ b/drivers/gpu/drm/i915/i915_trace.h
@@ -158,16 +158,17 @@ TRACE_EVENT(i915_gem_request_submit,
158 TP_ARGS(dev, seqno), 158 TP_ARGS(dev, seqno),
159 159
160 TP_STRUCT__entry( 160 TP_STRUCT__entry(
161 __field(struct drm_device *, dev) 161 __field(u32, dev)
162 __field(u32, seqno) 162 __field(u32, seqno)
163 ), 163 ),
164 164
165 TP_fast_assign( 165 TP_fast_assign(
166 __entry->dev = dev; 166 __entry->dev = dev->primary->index;
167 __entry->seqno = seqno; 167 __entry->seqno = seqno;
168 i915_trace_irq_get(dev, seqno);
168 ), 169 ),
169 170
170 TP_printk("dev=%p, seqno=%u", __entry->dev, __entry->seqno) 171 TP_printk("dev=%u, seqno=%u", __entry->dev, __entry->seqno)
171); 172);
172 173
173TRACE_EVENT(i915_gem_request_flush, 174TRACE_EVENT(i915_gem_request_flush,
@@ -178,20 +179,20 @@ TRACE_EVENT(i915_gem_request_flush,
178 TP_ARGS(dev, seqno, flush_domains, invalidate_domains), 179 TP_ARGS(dev, seqno, flush_domains, invalidate_domains),
179 180
180 TP_STRUCT__entry( 181 TP_STRUCT__entry(
181 __field(struct drm_device *, dev) 182 __field(u32, dev)
182 __field(u32, seqno) 183 __field(u32, seqno)
183 __field(u32, flush_domains) 184 __field(u32, flush_domains)
184 __field(u32, invalidate_domains) 185 __field(u32, invalidate_domains)
185 ), 186 ),
186 187
187 TP_fast_assign( 188 TP_fast_assign(
188 __entry->dev = dev; 189 __entry->dev = dev->primary->index;
189 __entry->seqno = seqno; 190 __entry->seqno = seqno;
190 __entry->flush_domains = flush_domains; 191 __entry->flush_domains = flush_domains;
191 __entry->invalidate_domains = invalidate_domains; 192 __entry->invalidate_domains = invalidate_domains;
192 ), 193 ),
193 194
194 TP_printk("dev=%p, seqno=%u, flush=%04x, invalidate=%04x", 195 TP_printk("dev=%u, seqno=%u, flush=%04x, invalidate=%04x",
195 __entry->dev, __entry->seqno, 196 __entry->dev, __entry->seqno,
196 __entry->flush_domains, __entry->invalidate_domains) 197 __entry->flush_domains, __entry->invalidate_domains)
197); 198);
@@ -204,16 +205,16 @@ TRACE_EVENT(i915_gem_request_complete,
204 TP_ARGS(dev, seqno), 205 TP_ARGS(dev, seqno),
205 206
206 TP_STRUCT__entry( 207 TP_STRUCT__entry(
207 __field(struct drm_device *, dev) 208 __field(u32, dev)
208 __field(u32, seqno) 209 __field(u32, seqno)
209 ), 210 ),
210 211
211 TP_fast_assign( 212 TP_fast_assign(
212 __entry->dev = dev; 213 __entry->dev = dev->primary->index;
213 __entry->seqno = seqno; 214 __entry->seqno = seqno;
214 ), 215 ),
215 216
216 TP_printk("dev=%p, seqno=%u", __entry->dev, __entry->seqno) 217 TP_printk("dev=%u, seqno=%u", __entry->dev, __entry->seqno)
217); 218);
218 219
219TRACE_EVENT(i915_gem_request_retire, 220TRACE_EVENT(i915_gem_request_retire,
@@ -223,16 +224,16 @@ TRACE_EVENT(i915_gem_request_retire,
223 TP_ARGS(dev, seqno), 224 TP_ARGS(dev, seqno),
224 225
225 TP_STRUCT__entry( 226 TP_STRUCT__entry(
226 __field(struct drm_device *, dev) 227 __field(u32, dev)
227 __field(u32, seqno) 228 __field(u32, seqno)
228 ), 229 ),
229 230
230 TP_fast_assign( 231 TP_fast_assign(
231 __entry->dev = dev; 232 __entry->dev = dev->primary->index;
232 __entry->seqno = seqno; 233 __entry->seqno = seqno;
233 ), 234 ),
234 235
235 TP_printk("dev=%p, seqno=%u", __entry->dev, __entry->seqno) 236 TP_printk("dev=%u, seqno=%u", __entry->dev, __entry->seqno)
236); 237);
237 238
238TRACE_EVENT(i915_gem_request_wait_begin, 239TRACE_EVENT(i915_gem_request_wait_begin,
@@ -242,16 +243,16 @@ TRACE_EVENT(i915_gem_request_wait_begin,
242 TP_ARGS(dev, seqno), 243 TP_ARGS(dev, seqno),
243 244
244 TP_STRUCT__entry( 245 TP_STRUCT__entry(
245 __field(struct drm_device *, dev) 246 __field(u32, dev)
246 __field(u32, seqno) 247 __field(u32, seqno)
247 ), 248 ),
248 249
249 TP_fast_assign( 250 TP_fast_assign(
250 __entry->dev = dev; 251 __entry->dev = dev->primary->index;
251 __entry->seqno = seqno; 252 __entry->seqno = seqno;
252 ), 253 ),
253 254
254 TP_printk("dev=%p, seqno=%u", __entry->dev, __entry->seqno) 255 TP_printk("dev=%u, seqno=%u", __entry->dev, __entry->seqno)
255); 256);
256 257
257TRACE_EVENT(i915_gem_request_wait_end, 258TRACE_EVENT(i915_gem_request_wait_end,
@@ -261,16 +262,16 @@ TRACE_EVENT(i915_gem_request_wait_end,
261 TP_ARGS(dev, seqno), 262 TP_ARGS(dev, seqno),
262 263
263 TP_STRUCT__entry( 264 TP_STRUCT__entry(
264 __field(struct drm_device *, dev) 265 __field(u32, dev)
265 __field(u32, seqno) 266 __field(u32, seqno)
266 ), 267 ),
267 268
268 TP_fast_assign( 269 TP_fast_assign(
269 __entry->dev = dev; 270 __entry->dev = dev->primary->index;
270 __entry->seqno = seqno; 271 __entry->seqno = seqno;
271 ), 272 ),
272 273
273 TP_printk("dev=%p, seqno=%u", __entry->dev, __entry->seqno) 274 TP_printk("dev=%u, seqno=%u", __entry->dev, __entry->seqno)
274); 275);
275 276
276TRACE_EVENT(i915_ring_wait_begin, 277TRACE_EVENT(i915_ring_wait_begin,
@@ -280,14 +281,14 @@ TRACE_EVENT(i915_ring_wait_begin,
280 TP_ARGS(dev), 281 TP_ARGS(dev),
281 282
282 TP_STRUCT__entry( 283 TP_STRUCT__entry(
283 __field(struct drm_device *, dev) 284 __field(u32, dev)
284 ), 285 ),
285 286
286 TP_fast_assign( 287 TP_fast_assign(
287 __entry->dev = dev; 288 __entry->dev = dev->primary->index;
288 ), 289 ),
289 290
290 TP_printk("dev=%p", __entry->dev) 291 TP_printk("dev=%u", __entry->dev)
291); 292);
292 293
293TRACE_EVENT(i915_ring_wait_end, 294TRACE_EVENT(i915_ring_wait_end,
@@ -297,14 +298,14 @@ TRACE_EVENT(i915_ring_wait_end,
297 TP_ARGS(dev), 298 TP_ARGS(dev),
298 299
299 TP_STRUCT__entry( 300 TP_STRUCT__entry(
300 __field(struct drm_device *, dev) 301 __field(u32, dev)
301 ), 302 ),
302 303
303 TP_fast_assign( 304 TP_fast_assign(
304 __entry->dev = dev; 305 __entry->dev = dev->primary->index;
305 ), 306 ),
306 307
307 TP_printk("dev=%p", __entry->dev) 308 TP_printk("dev=%u", __entry->dev)
308); 309);
309 310
310#endif /* _I915_TRACE_H_ */ 311#endif /* _I915_TRACE_H_ */
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 93ff6c03733e..3c14240cc002 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3095,7 +3095,6 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
3095 struct drm_gem_object *bo; 3095 struct drm_gem_object *bo;
3096 struct drm_i915_gem_object *obj_priv; 3096 struct drm_i915_gem_object *obj_priv;
3097 int pipe = intel_crtc->pipe; 3097 int pipe = intel_crtc->pipe;
3098 int plane = intel_crtc->plane;
3099 uint32_t control = (pipe == 0) ? CURACNTR : CURBCNTR; 3098 uint32_t control = (pipe == 0) ? CURACNTR : CURBCNTR;
3100 uint32_t base = (pipe == 0) ? CURABASE : CURBBASE; 3099 uint32_t base = (pipe == 0) ? CURABASE : CURBBASE;
3101 uint32_t temp = I915_READ(control); 3100 uint32_t temp = I915_READ(control);
@@ -3182,9 +3181,6 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
3182 drm_gem_object_unreference(intel_crtc->cursor_bo); 3181 drm_gem_object_unreference(intel_crtc->cursor_bo);
3183 } 3182 }
3184 3183
3185 if ((IS_I965G(dev) || plane == 0))
3186 intel_update_fbc(crtc, &crtc->mode);
3187
3188 mutex_unlock(&dev->struct_mutex); 3184 mutex_unlock(&dev->struct_mutex);
3189 3185
3190 intel_crtc->cursor_addr = addr; 3186 intel_crtc->cursor_addr = addr;
@@ -3244,6 +3240,16 @@ void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
3244 intel_crtc->lut_b[regno] = blue >> 8; 3240 intel_crtc->lut_b[regno] = blue >> 8;
3245} 3241}
3246 3242
3243void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
3244 u16 *blue, int regno)
3245{
3246 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
3247
3248 *red = intel_crtc->lut_r[regno] << 8;
3249 *green = intel_crtc->lut_g[regno] << 8;
3250 *blue = intel_crtc->lut_b[regno] << 8;
3251}
3252
3247static void intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, 3253static void intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
3248 u16 *blue, uint32_t size) 3254 u16 *blue, uint32_t size)
3249{ 3255{
@@ -3835,6 +3841,7 @@ static const struct drm_crtc_helper_funcs intel_helper_funcs = {
3835 .mode_set_base = intel_pipe_set_base, 3841 .mode_set_base = intel_pipe_set_base,
3836 .prepare = intel_crtc_prepare, 3842 .prepare = intel_crtc_prepare,
3837 .commit = intel_crtc_commit, 3843 .commit = intel_crtc_commit,
3844 .load_lut = intel_crtc_load_lut,
3838}; 3845};
3839 3846
3840static const struct drm_crtc_funcs intel_crtc_funcs = { 3847static const struct drm_crtc_funcs intel_crtc_funcs = {
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 8aa4b7f30daa..ef61fe9507e2 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -175,6 +175,8 @@ extern int intelfb_resize(struct drm_device *dev, struct drm_crtc *crtc);
175extern void intelfb_restore(void); 175extern void intelfb_restore(void);
176extern void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, 176extern void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
177 u16 blue, int regno); 177 u16 blue, int regno);
178extern void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
179 u16 *blue, int regno);
178 180
179extern int intel_framebuffer_create(struct drm_device *dev, 181extern int intel_framebuffer_create(struct drm_device *dev,
180 struct drm_mode_fb_cmd *mode_cmd, 182 struct drm_mode_fb_cmd *mode_cmd,
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c
index e85d7e9eed7d..2b0fe54cd92c 100644
--- a/drivers/gpu/drm/i915/intel_fb.c
+++ b/drivers/gpu/drm/i915/intel_fb.c
@@ -60,10 +60,12 @@ static struct fb_ops intelfb_ops = {
60 .fb_imageblit = cfb_imageblit, 60 .fb_imageblit = cfb_imageblit,
61 .fb_pan_display = drm_fb_helper_pan_display, 61 .fb_pan_display = drm_fb_helper_pan_display,
62 .fb_blank = drm_fb_helper_blank, 62 .fb_blank = drm_fb_helper_blank,
63 .fb_setcmap = drm_fb_helper_setcmap,
63}; 64};
64 65
65static struct drm_fb_helper_funcs intel_fb_helper_funcs = { 66static struct drm_fb_helper_funcs intel_fb_helper_funcs = {
66 .gamma_set = intel_crtc_fb_gamma_set, 67 .gamma_set = intel_crtc_fb_gamma_set,
68 .gamma_get = intel_crtc_fb_gamma_get,
67}; 69};
68 70
69 71
@@ -123,6 +125,10 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width,
123 struct device *device = &dev->pdev->dev; 125 struct device *device = &dev->pdev->dev;
124 int size, ret, mmio_bar = IS_I9XX(dev) ? 0 : 1; 126 int size, ret, mmio_bar = IS_I9XX(dev) ? 0 : 1;
125 127
128 /* we don't do packed 24bpp */
129 if (surface_bpp == 24)
130 surface_bpp = 32;
131
126 mode_cmd.width = surface_width; 132 mode_cmd.width = surface_width;
127 mode_cmd.height = surface_height; 133 mode_cmd.height = surface_height;
128 134
@@ -206,7 +212,7 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width,
206 212
207// memset(info->screen_base, 0, size); 213// memset(info->screen_base, 0, size);
208 214
209 drm_fb_helper_fill_fix(info, fb->pitch); 215 drm_fb_helper_fill_fix(info, fb->pitch, fb->depth);
210 drm_fb_helper_fill_var(info, fb, fb_width, fb_height); 216 drm_fb_helper_fill_var(info, fb, fb_width, fb_height);
211 217
212 /* FIXME: we really shouldn't expose mmio space at all */ 218 /* FIXME: we really shouldn't expose mmio space at all */
@@ -244,7 +250,7 @@ int intelfb_probe(struct drm_device *dev)
244 int ret; 250 int ret;
245 251
246 DRM_DEBUG("\n"); 252 DRM_DEBUG("\n");
247 ret = drm_fb_helper_single_fb_probe(dev, intelfb_create); 253 ret = drm_fb_helper_single_fb_probe(dev, 32, intelfb_create);
248 return ret; 254 return ret;
249} 255}
250EXPORT_SYMBOL(intelfb_probe); 256EXPORT_SYMBOL(intelfb_probe);
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index fa304e136010..663ab6de0b58 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -223,7 +223,7 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
223 223
224 connector = &intel_output->base; 224 connector = &intel_output->base;
225 drm_connector_init(dev, connector, &intel_hdmi_connector_funcs, 225 drm_connector_init(dev, connector, &intel_hdmi_connector_funcs,
226 DRM_MODE_CONNECTOR_DVID); 226 DRM_MODE_CONNECTOR_HDMIA);
227 drm_connector_helper_add(connector, &intel_hdmi_connector_helper_funcs); 227 drm_connector_helper_add(connector, &intel_hdmi_connector_helper_funcs);
228 228
229 intel_output->type = INTEL_OUTPUT_HDMI; 229 intel_output->type = INTEL_OUTPUT_HDMI;
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
index c64eab493fb0..9ca917931afb 100644
--- a/drivers/gpu/drm/i915/intel_tv.c
+++ b/drivers/gpu/drm/i915/intel_tv.c
@@ -1082,7 +1082,8 @@ intel_tv_mode_valid(struct drm_connector *connector, struct drm_display_mode *mo
1082 const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output); 1082 const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output);
1083 1083
1084 /* Ensure TV refresh is close to desired refresh */ 1084 /* Ensure TV refresh is close to desired refresh */
1085 if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode)) < 10) 1085 if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode) * 1000)
1086 < 1000)
1086 return MODE_OK; 1087 return MODE_OK;
1087 return MODE_CLOCK_RANGE; 1088 return MODE_CLOCK_RANGE;
1088} 1089}
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index 6a015929deee..14fa9701aeb3 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -733,6 +733,7 @@ static const struct drm_crtc_helper_funcs atombios_helper_funcs = {
733 .mode_set_base = atombios_crtc_set_base, 733 .mode_set_base = atombios_crtc_set_base,
734 .prepare = atombios_crtc_prepare, 734 .prepare = atombios_crtc_prepare,
735 .commit = atombios_crtc_commit, 735 .commit = atombios_crtc_commit,
736 .load_lut = radeon_crtc_load_lut,
736}; 737};
737 738
738void radeon_atombios_init_crtc(struct drm_device *dev, 739void radeon_atombios_init_crtc(struct drm_device *dev,
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index e6cce24de802..161094c07d94 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -32,6 +32,9 @@
32#include "radeon_reg.h" 32#include "radeon_reg.h"
33#include "radeon.h" 33#include "radeon.h"
34#include "r100d.h" 34#include "r100d.h"
35#include "rs100d.h"
36#include "rv200d.h"
37#include "rv250d.h"
35 38
36#include <linux/firmware.h> 39#include <linux/firmware.h>
37#include <linux/platform_device.h> 40#include <linux/platform_device.h>
@@ -60,18 +63,7 @@ MODULE_FIRMWARE(FIRMWARE_R520);
60 63
61/* This files gather functions specifics to: 64/* This files gather functions specifics to:
62 * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 65 * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280
63 *
64 * Some of these functions might be used by newer ASICs.
65 */ 66 */
66int r200_init(struct radeon_device *rdev);
67void r100_hdp_reset(struct radeon_device *rdev);
68void r100_gpu_init(struct radeon_device *rdev);
69int r100_gui_wait_for_idle(struct radeon_device *rdev);
70int r100_mc_wait_for_idle(struct radeon_device *rdev);
71void r100_gpu_wait_for_vsync(struct radeon_device *rdev);
72void r100_gpu_wait_for_vsync2(struct radeon_device *rdev);
73int r100_debugfs_mc_info_init(struct radeon_device *rdev);
74
75 67
76/* 68/*
77 * PCI GART 69 * PCI GART
@@ -152,136 +144,6 @@ void r100_pci_gart_fini(struct radeon_device *rdev)
152 radeon_gart_fini(rdev); 144 radeon_gart_fini(rdev);
153} 145}
154 146
155
156/*
157 * MC
158 */
159void r100_mc_disable_clients(struct radeon_device *rdev)
160{
161 uint32_t ov0_scale_cntl, crtc_ext_cntl, crtc_gen_cntl, crtc2_gen_cntl;
162
163 /* FIXME: is this function correct for rs100,rs200,rs300 ? */
164 if (r100_gui_wait_for_idle(rdev)) {
165 printk(KERN_WARNING "Failed to wait GUI idle while "
166 "programming pipes. Bad things might happen.\n");
167 }
168
169 /* stop display and memory access */
170 ov0_scale_cntl = RREG32(RADEON_OV0_SCALE_CNTL);
171 WREG32(RADEON_OV0_SCALE_CNTL, ov0_scale_cntl & ~RADEON_SCALER_ENABLE);
172 crtc_ext_cntl = RREG32(RADEON_CRTC_EXT_CNTL);
173 WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl | RADEON_CRTC_DISPLAY_DIS);
174 crtc_gen_cntl = RREG32(RADEON_CRTC_GEN_CNTL);
175
176 r100_gpu_wait_for_vsync(rdev);
177
178 WREG32(RADEON_CRTC_GEN_CNTL,
179 (crtc_gen_cntl & ~(RADEON_CRTC_CUR_EN | RADEON_CRTC_ICON_EN)) |
180 RADEON_CRTC_DISP_REQ_EN_B | RADEON_CRTC_EXT_DISP_EN);
181
182 if (!(rdev->flags & RADEON_SINGLE_CRTC)) {
183 crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL);
184
185 r100_gpu_wait_for_vsync2(rdev);
186 WREG32(RADEON_CRTC2_GEN_CNTL,
187 (crtc2_gen_cntl &
188 ~(RADEON_CRTC2_CUR_EN | RADEON_CRTC2_ICON_EN)) |
189 RADEON_CRTC2_DISP_REQ_EN_B);
190 }
191
192 udelay(500);
193}
194
195void r100_mc_setup(struct radeon_device *rdev)
196{
197 uint32_t tmp;
198 int r;
199
200 r = r100_debugfs_mc_info_init(rdev);
201 if (r) {
202 DRM_ERROR("Failed to register debugfs file for R100 MC !\n");
203 }
204 /* Write VRAM size in case we are limiting it */
205 WREG32(RADEON_CONFIG_MEMSIZE, rdev->mc.real_vram_size);
206 /* Novell bug 204882 for RN50/M6/M7 with 8/16/32MB VRAM,
207 * if the aperture is 64MB but we have 32MB VRAM
208 * we report only 32MB VRAM but we have to set MC_FB_LOCATION
209 * to 64MB, otherwise the gpu accidentially dies */
210 tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1;
211 tmp = REG_SET(RADEON_MC_FB_TOP, tmp >> 16);
212 tmp |= REG_SET(RADEON_MC_FB_START, rdev->mc.vram_location >> 16);
213 WREG32(RADEON_MC_FB_LOCATION, tmp);
214
215 /* Enable bus mastering */
216 tmp = RREG32(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS;
217 WREG32(RADEON_BUS_CNTL, tmp);
218
219 if (rdev->flags & RADEON_IS_AGP) {
220 tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 1;
221 tmp = REG_SET(RADEON_MC_AGP_TOP, tmp >> 16);
222 tmp |= REG_SET(RADEON_MC_AGP_START, rdev->mc.gtt_location >> 16);
223 WREG32(RADEON_MC_AGP_LOCATION, tmp);
224 WREG32(RADEON_AGP_BASE, rdev->mc.agp_base);
225 } else {
226 WREG32(RADEON_MC_AGP_LOCATION, 0x0FFFFFFF);
227 WREG32(RADEON_AGP_BASE, 0);
228 }
229
230 tmp = RREG32(RADEON_HOST_PATH_CNTL) & RADEON_HDP_APER_CNTL;
231 tmp |= (7 << 28);
232 WREG32(RADEON_HOST_PATH_CNTL, tmp | RADEON_HDP_SOFT_RESET | RADEON_HDP_READ_BUFFER_INVALIDATE);
233 (void)RREG32(RADEON_HOST_PATH_CNTL);
234 WREG32(RADEON_HOST_PATH_CNTL, tmp);
235 (void)RREG32(RADEON_HOST_PATH_CNTL);
236}
237
238int r100_mc_init(struct radeon_device *rdev)
239{
240 int r;
241
242 if (r100_debugfs_rbbm_init(rdev)) {
243 DRM_ERROR("Failed to register debugfs file for RBBM !\n");
244 }
245
246 r100_gpu_init(rdev);
247 /* Disable gart which also disable out of gart access */
248 r100_pci_gart_disable(rdev);
249
250 /* Setup GPU memory space */
251 rdev->mc.gtt_location = 0xFFFFFFFFUL;
252 if (rdev->flags & RADEON_IS_AGP) {
253 r = radeon_agp_init(rdev);
254 if (r) {
255 printk(KERN_WARNING "[drm] Disabling AGP\n");
256 rdev->flags &= ~RADEON_IS_AGP;
257 rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
258 } else {
259 rdev->mc.gtt_location = rdev->mc.agp_base;
260 }
261 }
262 r = radeon_mc_setup(rdev);
263 if (r) {
264 return r;
265 }
266
267 r100_mc_disable_clients(rdev);
268 if (r100_mc_wait_for_idle(rdev)) {
269 printk(KERN_WARNING "Failed to wait MC idle while "
270 "programming pipes. Bad things might happen.\n");
271 }
272
273 r100_mc_setup(rdev);
274 return 0;
275}
276
277void r100_mc_fini(struct radeon_device *rdev)
278{
279}
280
281
282/*
283 * Interrupts
284 */
285int r100_irq_set(struct radeon_device *rdev) 147int r100_irq_set(struct radeon_device *rdev)
286{ 148{
287 uint32_t tmp = 0; 149 uint32_t tmp = 0;
@@ -358,10 +220,6 @@ u32 r100_get_vblank_counter(struct radeon_device *rdev, int crtc)
358 return RREG32(RADEON_CRTC2_CRNT_FRAME); 220 return RREG32(RADEON_CRTC2_CRNT_FRAME);
359} 221}
360 222
361
362/*
363 * Fence emission
364 */
365void r100_fence_ring_emit(struct radeon_device *rdev, 223void r100_fence_ring_emit(struct radeon_device *rdev,
366 struct radeon_fence *fence) 224 struct radeon_fence *fence)
367{ 225{
@@ -377,10 +235,6 @@ void r100_fence_ring_emit(struct radeon_device *rdev,
377 radeon_ring_write(rdev, RADEON_SW_INT_FIRE); 235 radeon_ring_write(rdev, RADEON_SW_INT_FIRE);
378} 236}
379 237
380
381/*
382 * Writeback
383 */
384int r100_wb_init(struct radeon_device *rdev) 238int r100_wb_init(struct radeon_device *rdev)
385{ 239{
386 int r; 240 int r;
@@ -504,10 +358,6 @@ int r100_copy_blit(struct radeon_device *rdev,
504 return r; 358 return r;
505} 359}
506 360
507
508/*
509 * CP
510 */
511static int r100_cp_wait_for_idle(struct radeon_device *rdev) 361static int r100_cp_wait_for_idle(struct radeon_device *rdev)
512{ 362{
513 unsigned i; 363 unsigned i;
@@ -612,6 +462,7 @@ static int r100_cp_init_microcode(struct radeon_device *rdev)
612 } 462 }
613 return err; 463 return err;
614} 464}
465
615static void r100_cp_load_microcode(struct radeon_device *rdev) 466static void r100_cp_load_microcode(struct radeon_device *rdev)
616{ 467{
617 const __be32 *fw_data; 468 const __be32 *fw_data;
@@ -978,7 +829,7 @@ int r100_cs_packet_parse_vline(struct radeon_cs_parser *p)
978 829
979 header = radeon_get_ib_value(p, h_idx); 830 header = radeon_get_ib_value(p, h_idx);
980 crtc_id = radeon_get_ib_value(p, h_idx + 5); 831 crtc_id = radeon_get_ib_value(p, h_idx + 5);
981 reg = header >> 2; 832 reg = CP_PACKET0_GET_REG(header);
982 mutex_lock(&p->rdev->ddev->mode_config.mutex); 833 mutex_lock(&p->rdev->ddev->mode_config.mutex);
983 obj = drm_mode_object_find(p->rdev->ddev, crtc_id, DRM_MODE_OBJECT_CRTC); 834 obj = drm_mode_object_find(p->rdev->ddev, crtc_id, DRM_MODE_OBJECT_CRTC);
984 if (!obj) { 835 if (!obj) {
@@ -1990,7 +1841,7 @@ void r100_pll_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
1990 r100_pll_errata_after_data(rdev); 1841 r100_pll_errata_after_data(rdev);
1991} 1842}
1992 1843
1993int r100_init(struct radeon_device *rdev) 1844void r100_set_safe_registers(struct radeon_device *rdev)
1994{ 1845{
1995 if (ASIC_IS_RN50(rdev)) { 1846 if (ASIC_IS_RN50(rdev)) {
1996 rdev->config.r100.reg_safe_bm = rn50_reg_safe_bm; 1847 rdev->config.r100.reg_safe_bm = rn50_reg_safe_bm;
@@ -1999,9 +1850,8 @@ int r100_init(struct radeon_device *rdev)
1999 rdev->config.r100.reg_safe_bm = r100_reg_safe_bm; 1850 rdev->config.r100.reg_safe_bm = r100_reg_safe_bm;
2000 rdev->config.r100.reg_safe_bm_size = ARRAY_SIZE(r100_reg_safe_bm); 1851 rdev->config.r100.reg_safe_bm_size = ARRAY_SIZE(r100_reg_safe_bm);
2001 } else { 1852 } else {
2002 return r200_init(rdev); 1853 r200_set_safe_registers(rdev);
2003 } 1854 }
2004 return 0;
2005} 1855}
2006 1856
2007/* 1857/*
@@ -2299,9 +2149,11 @@ void r100_bandwidth_update(struct radeon_device *rdev)
2299 mode1 = &rdev->mode_info.crtcs[0]->base.mode; 2149 mode1 = &rdev->mode_info.crtcs[0]->base.mode;
2300 pixel_bytes1 = rdev->mode_info.crtcs[0]->base.fb->bits_per_pixel / 8; 2150 pixel_bytes1 = rdev->mode_info.crtcs[0]->base.fb->bits_per_pixel / 8;
2301 } 2151 }
2302 if (rdev->mode_info.crtcs[1]->base.enabled) { 2152 if (!(rdev->flags & RADEON_SINGLE_CRTC)) {
2303 mode2 = &rdev->mode_info.crtcs[1]->base.mode; 2153 if (rdev->mode_info.crtcs[1]->base.enabled) {
2304 pixel_bytes2 = rdev->mode_info.crtcs[1]->base.fb->bits_per_pixel / 8; 2154 mode2 = &rdev->mode_info.crtcs[1]->base.mode;
2155 pixel_bytes2 = rdev->mode_info.crtcs[1]->base.fb->bits_per_pixel / 8;
2156 }
2305 } 2157 }
2306 2158
2307 min_mem_eff.full = rfixed_const_8(0); 2159 min_mem_eff.full = rfixed_const_8(0);
@@ -3114,7 +2966,7 @@ void r100_mc_stop(struct radeon_device *rdev, struct r100_mc_save *save)
3114 WREG32(R_000740_CP_CSQ_CNTL, 0); 2966 WREG32(R_000740_CP_CSQ_CNTL, 0);
3115 2967
3116 /* Save few CRTC registers */ 2968 /* Save few CRTC registers */
3117 save->GENMO_WT = RREG32(R_0003C0_GENMO_WT); 2969 save->GENMO_WT = RREG8(R_0003C2_GENMO_WT);
3118 save->CRTC_EXT_CNTL = RREG32(R_000054_CRTC_EXT_CNTL); 2970 save->CRTC_EXT_CNTL = RREG32(R_000054_CRTC_EXT_CNTL);
3119 save->CRTC_GEN_CNTL = RREG32(R_000050_CRTC_GEN_CNTL); 2971 save->CRTC_GEN_CNTL = RREG32(R_000050_CRTC_GEN_CNTL);
3120 save->CUR_OFFSET = RREG32(R_000260_CUR_OFFSET); 2972 save->CUR_OFFSET = RREG32(R_000260_CUR_OFFSET);
@@ -3124,7 +2976,7 @@ void r100_mc_stop(struct radeon_device *rdev, struct r100_mc_save *save)
3124 } 2976 }
3125 2977
3126 /* Disable VGA aperture access */ 2978 /* Disable VGA aperture access */
3127 WREG32(R_0003C0_GENMO_WT, C_0003C0_VGA_RAM_EN & save->GENMO_WT); 2979 WREG8(R_0003C2_GENMO_WT, C_0003C2_VGA_RAM_EN & save->GENMO_WT);
3128 /* Disable cursor, overlay, crtc */ 2980 /* Disable cursor, overlay, crtc */
3129 WREG32(R_000260_CUR_OFFSET, save->CUR_OFFSET | S_000260_CUR_LOCK(1)); 2981 WREG32(R_000260_CUR_OFFSET, save->CUR_OFFSET | S_000260_CUR_LOCK(1));
3130 WREG32(R_000054_CRTC_EXT_CNTL, save->CRTC_EXT_CNTL | 2982 WREG32(R_000054_CRTC_EXT_CNTL, save->CRTC_EXT_CNTL |
@@ -3156,10 +3008,264 @@ void r100_mc_resume(struct radeon_device *rdev, struct r100_mc_save *save)
3156 rdev->mc.vram_location); 3008 rdev->mc.vram_location);
3157 } 3009 }
3158 /* Restore CRTC registers */ 3010 /* Restore CRTC registers */
3159 WREG32(R_0003C0_GENMO_WT, save->GENMO_WT); 3011 WREG8(R_0003C2_GENMO_WT, save->GENMO_WT);
3160 WREG32(R_000054_CRTC_EXT_CNTL, save->CRTC_EXT_CNTL); 3012 WREG32(R_000054_CRTC_EXT_CNTL, save->CRTC_EXT_CNTL);
3161 WREG32(R_000050_CRTC_GEN_CNTL, save->CRTC_GEN_CNTL); 3013 WREG32(R_000050_CRTC_GEN_CNTL, save->CRTC_GEN_CNTL);
3162 if (!(rdev->flags & RADEON_SINGLE_CRTC)) { 3014 if (!(rdev->flags & RADEON_SINGLE_CRTC)) {
3163 WREG32(R_0003F8_CRTC2_GEN_CNTL, save->CRTC2_GEN_CNTL); 3015 WREG32(R_0003F8_CRTC2_GEN_CNTL, save->CRTC2_GEN_CNTL);
3164 } 3016 }
3165} 3017}
3018
3019void r100_vga_render_disable(struct radeon_device *rdev)
3020{
3021 u32 tmp;
3022
3023 tmp = RREG8(R_0003C2_GENMO_WT);
3024 WREG8(R_0003C2_GENMO_WT, C_0003C2_VGA_RAM_EN & tmp);
3025}
3026
3027static void r100_debugfs(struct radeon_device *rdev)
3028{
3029 int r;
3030
3031 r = r100_debugfs_mc_info_init(rdev);
3032 if (r)
3033 dev_warn(rdev->dev, "Failed to create r100_mc debugfs file.\n");
3034}
3035
3036static void r100_mc_program(struct radeon_device *rdev)
3037{
3038 struct r100_mc_save save;
3039
3040 /* Stops all mc clients */
3041 r100_mc_stop(rdev, &save);
3042 if (rdev->flags & RADEON_IS_AGP) {
3043 WREG32(R_00014C_MC_AGP_LOCATION,
3044 S_00014C_MC_AGP_START(rdev->mc.gtt_start >> 16) |
3045 S_00014C_MC_AGP_TOP(rdev->mc.gtt_end >> 16));
3046 WREG32(R_000170_AGP_BASE, lower_32_bits(rdev->mc.agp_base));
3047 if (rdev->family > CHIP_RV200)
3048 WREG32(R_00015C_AGP_BASE_2,
3049 upper_32_bits(rdev->mc.agp_base) & 0xff);
3050 } else {
3051 WREG32(R_00014C_MC_AGP_LOCATION, 0x0FFFFFFF);
3052 WREG32(R_000170_AGP_BASE, 0);
3053 if (rdev->family > CHIP_RV200)
3054 WREG32(R_00015C_AGP_BASE_2, 0);
3055 }
3056 /* Wait for mc idle */
3057 if (r100_mc_wait_for_idle(rdev))
3058 dev_warn(rdev->dev, "Wait for MC idle timeout.\n");
3059 /* Program MC, should be a 32bits limited address space */
3060 WREG32(R_000148_MC_FB_LOCATION,
3061 S_000148_MC_FB_START(rdev->mc.vram_start >> 16) |
3062 S_000148_MC_FB_TOP(rdev->mc.vram_end >> 16));
3063 r100_mc_resume(rdev, &save);
3064}
3065
3066void r100_clock_startup(struct radeon_device *rdev)
3067{
3068 u32 tmp;
3069
3070 if (radeon_dynclks != -1 && radeon_dynclks)
3071 radeon_legacy_set_clock_gating(rdev, 1);
3072 /* We need to force on some of the block */
3073 tmp = RREG32_PLL(R_00000D_SCLK_CNTL);
3074 tmp |= S_00000D_FORCE_CP(1) | S_00000D_FORCE_VIP(1);
3075 if ((rdev->family == CHIP_RV250) || (rdev->family == CHIP_RV280))
3076 tmp |= S_00000D_FORCE_DISP1(1) | S_00000D_FORCE_DISP2(1);
3077 WREG32_PLL(R_00000D_SCLK_CNTL, tmp);
3078}
3079
3080static int r100_startup(struct radeon_device *rdev)
3081{
3082 int r;
3083
3084 r100_mc_program(rdev);
3085 /* Resume clock */
3086 r100_clock_startup(rdev);
3087 /* Initialize GPU configuration (# pipes, ...) */
3088 r100_gpu_init(rdev);
3089 /* Initialize GART (initialize after TTM so we can allocate
3090 * memory through TTM but finalize after TTM) */
3091 if (rdev->flags & RADEON_IS_PCI) {
3092 r = r100_pci_gart_enable(rdev);
3093 if (r)
3094 return r;
3095 }
3096 /* Enable IRQ */
3097 rdev->irq.sw_int = true;
3098 r100_irq_set(rdev);
3099 /* 1M ring buffer */
3100 r = r100_cp_init(rdev, 1024 * 1024);
3101 if (r) {
3102 dev_err(rdev->dev, "failled initializing CP (%d).\n", r);
3103 return r;
3104 }
3105 r = r100_wb_init(rdev);
3106 if (r)
3107 dev_err(rdev->dev, "failled initializing WB (%d).\n", r);
3108 r = r100_ib_init(rdev);
3109 if (r) {
3110 dev_err(rdev->dev, "failled initializing IB (%d).\n", r);
3111 return r;
3112 }
3113 return 0;
3114}
3115
3116int r100_resume(struct radeon_device *rdev)
3117{
3118 /* Make sur GART are not working */
3119 if (rdev->flags & RADEON_IS_PCI)
3120 r100_pci_gart_disable(rdev);
3121 /* Resume clock before doing reset */
3122 r100_clock_startup(rdev);
3123 /* Reset gpu before posting otherwise ATOM will enter infinite loop */
3124 if (radeon_gpu_reset(rdev)) {
3125 dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
3126 RREG32(R_000E40_RBBM_STATUS),
3127 RREG32(R_0007C0_CP_STAT));
3128 }
3129 /* post */
3130 radeon_combios_asic_init(rdev->ddev);
3131 /* Resume clock after posting */
3132 r100_clock_startup(rdev);
3133 return r100_startup(rdev);
3134}
3135
3136int r100_suspend(struct radeon_device *rdev)
3137{
3138 r100_cp_disable(rdev);
3139 r100_wb_disable(rdev);
3140 r100_irq_disable(rdev);
3141 if (rdev->flags & RADEON_IS_PCI)
3142 r100_pci_gart_disable(rdev);
3143 return 0;
3144}
3145
3146void r100_fini(struct radeon_device *rdev)
3147{
3148 r100_suspend(rdev);
3149 r100_cp_fini(rdev);
3150 r100_wb_fini(rdev);
3151 r100_ib_fini(rdev);
3152 radeon_gem_fini(rdev);
3153 if (rdev->flags & RADEON_IS_PCI)
3154 r100_pci_gart_fini(rdev);
3155 radeon_irq_kms_fini(rdev);
3156 radeon_fence_driver_fini(rdev);
3157 radeon_object_fini(rdev);
3158 radeon_atombios_fini(rdev);
3159 kfree(rdev->bios);
3160 rdev->bios = NULL;
3161}
3162
3163int r100_mc_init(struct radeon_device *rdev)
3164{
3165 int r;
3166 u32 tmp;
3167
3168 /* Setup GPU memory space */
3169 rdev->mc.vram_location = 0xFFFFFFFFUL;
3170 rdev->mc.gtt_location = 0xFFFFFFFFUL;
3171 if (rdev->flags & RADEON_IS_IGP) {
3172 tmp = G_00015C_MC_FB_START(RREG32(R_00015C_NB_TOM));
3173 rdev->mc.vram_location = tmp << 16;
3174 }
3175 if (rdev->flags & RADEON_IS_AGP) {
3176 r = radeon_agp_init(rdev);
3177 if (r) {
3178 printk(KERN_WARNING "[drm] Disabling AGP\n");
3179 rdev->flags &= ~RADEON_IS_AGP;
3180 rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
3181 } else {
3182 rdev->mc.gtt_location = rdev->mc.agp_base;
3183 }
3184 }
3185 r = radeon_mc_setup(rdev);
3186 if (r)
3187 return r;
3188 return 0;
3189}
3190
3191int r100_init(struct radeon_device *rdev)
3192{
3193 int r;
3194
3195 /* Register debugfs file specific to this group of asics */
3196 r100_debugfs(rdev);
3197 /* Disable VGA */
3198 r100_vga_render_disable(rdev);
3199 /* Initialize scratch registers */
3200 radeon_scratch_init(rdev);
3201 /* Initialize surface registers */
3202 radeon_surface_init(rdev);
3203 /* TODO: disable VGA need to use VGA request */
3204 /* BIOS*/
3205 if (!radeon_get_bios(rdev)) {
3206 if (ASIC_IS_AVIVO(rdev))
3207 return -EINVAL;
3208 }
3209 if (rdev->is_atom_bios) {
3210 dev_err(rdev->dev, "Expecting combios for RS400/RS480 GPU\n");
3211 return -EINVAL;
3212 } else {
3213 r = radeon_combios_init(rdev);
3214 if (r)
3215 return r;
3216 }
3217 /* Reset gpu before posting otherwise ATOM will enter infinite loop */
3218 if (radeon_gpu_reset(rdev)) {
3219 dev_warn(rdev->dev,
3220 "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
3221 RREG32(R_000E40_RBBM_STATUS),
3222 RREG32(R_0007C0_CP_STAT));
3223 }
3224 /* check if cards are posted or not */
3225 if (!radeon_card_posted(rdev) && rdev->bios) {
3226 DRM_INFO("GPU not posted. posting now...\n");
3227 radeon_combios_asic_init(rdev->ddev);
3228 }
3229 /* Set asic errata */
3230 r100_errata(rdev);
3231 /* Initialize clocks */
3232 radeon_get_clock_info(rdev->ddev);
3233 /* Get vram informations */
3234 r100_vram_info(rdev);
3235 /* Initialize memory controller (also test AGP) */
3236 r = r100_mc_init(rdev);
3237 if (r)
3238 return r;
3239 /* Fence driver */
3240 r = radeon_fence_driver_init(rdev);
3241 if (r)
3242 return r;
3243 r = radeon_irq_kms_init(rdev);
3244 if (r)
3245 return r;
3246 /* Memory manager */
3247 r = radeon_object_init(rdev);
3248 if (r)
3249 return r;
3250 if (rdev->flags & RADEON_IS_PCI) {
3251 r = r100_pci_gart_init(rdev);
3252 if (r)
3253 return r;
3254 }
3255 r100_set_safe_registers(rdev);
3256 rdev->accel_working = true;
3257 r = r100_startup(rdev);
3258 if (r) {
3259 /* Somethings want wront with the accel init stop accel */
3260 dev_err(rdev->dev, "Disabling GPU acceleration\n");
3261 r100_suspend(rdev);
3262 r100_cp_fini(rdev);
3263 r100_wb_fini(rdev);
3264 r100_ib_fini(rdev);
3265 if (rdev->flags & RADEON_IS_PCI)
3266 r100_pci_gart_fini(rdev);
3267 radeon_irq_kms_fini(rdev);
3268 rdev->accel_working = false;
3269 }
3270 return 0;
3271}
diff --git a/drivers/gpu/drm/radeon/r100d.h b/drivers/gpu/drm/radeon/r100d.h
index c4b257ec920e..df29a630c466 100644
--- a/drivers/gpu/drm/radeon/r100d.h
+++ b/drivers/gpu/drm/radeon/r100d.h
@@ -381,6 +381,24 @@
381#define S_000054_VCRTC_IDX_MASTER(x) (((x) & 0x7F) << 24) 381#define S_000054_VCRTC_IDX_MASTER(x) (((x) & 0x7F) << 24)
382#define G_000054_VCRTC_IDX_MASTER(x) (((x) >> 24) & 0x7F) 382#define G_000054_VCRTC_IDX_MASTER(x) (((x) >> 24) & 0x7F)
383#define C_000054_VCRTC_IDX_MASTER 0x80FFFFFF 383#define C_000054_VCRTC_IDX_MASTER 0x80FFFFFF
384#define R_000148_MC_FB_LOCATION 0x000148
385#define S_000148_MC_FB_START(x) (((x) & 0xFFFF) << 0)
386#define G_000148_MC_FB_START(x) (((x) >> 0) & 0xFFFF)
387#define C_000148_MC_FB_START 0xFFFF0000
388#define S_000148_MC_FB_TOP(x) (((x) & 0xFFFF) << 16)
389#define G_000148_MC_FB_TOP(x) (((x) >> 16) & 0xFFFF)
390#define C_000148_MC_FB_TOP 0x0000FFFF
391#define R_00014C_MC_AGP_LOCATION 0x00014C
392#define S_00014C_MC_AGP_START(x) (((x) & 0xFFFF) << 0)
393#define G_00014C_MC_AGP_START(x) (((x) >> 0) & 0xFFFF)
394#define C_00014C_MC_AGP_START 0xFFFF0000
395#define S_00014C_MC_AGP_TOP(x) (((x) & 0xFFFF) << 16)
396#define G_00014C_MC_AGP_TOP(x) (((x) >> 16) & 0xFFFF)
397#define C_00014C_MC_AGP_TOP 0x0000FFFF
398#define R_000170_AGP_BASE 0x000170
399#define S_000170_AGP_BASE_ADDR(x) (((x) & 0xFFFFFFFF) << 0)
400#define G_000170_AGP_BASE_ADDR(x) (((x) >> 0) & 0xFFFFFFFF)
401#define C_000170_AGP_BASE_ADDR 0x00000000
384#define R_00023C_DISPLAY_BASE_ADDR 0x00023C 402#define R_00023C_DISPLAY_BASE_ADDR 0x00023C
385#define S_00023C_DISPLAY_BASE_ADDR(x) (((x) & 0xFFFFFFFF) << 0) 403#define S_00023C_DISPLAY_BASE_ADDR(x) (((x) & 0xFFFFFFFF) << 0)
386#define G_00023C_DISPLAY_BASE_ADDR(x) (((x) >> 0) & 0xFFFFFFFF) 404#define G_00023C_DISPLAY_BASE_ADDR(x) (((x) >> 0) & 0xFFFFFFFF)
@@ -403,25 +421,25 @@
403#define S_000360_CUR2_LOCK(x) (((x) & 0x1) << 31) 421#define S_000360_CUR2_LOCK(x) (((x) & 0x1) << 31)
404#define G_000360_CUR2_LOCK(x) (((x) >> 31) & 0x1) 422#define G_000360_CUR2_LOCK(x) (((x) >> 31) & 0x1)
405#define C_000360_CUR2_LOCK 0x7FFFFFFF 423#define C_000360_CUR2_LOCK 0x7FFFFFFF
406#define R_0003C0_GENMO_WT 0x0003C0 424#define R_0003C2_GENMO_WT 0x0003C0
407#define S_0003C0_GENMO_MONO_ADDRESS_B(x) (((x) & 0x1) << 0) 425#define S_0003C2_GENMO_MONO_ADDRESS_B(x) (((x) & 0x1) << 0)
408#define G_0003C0_GENMO_MONO_ADDRESS_B(x) (((x) >> 0) & 0x1) 426#define G_0003C2_GENMO_MONO_ADDRESS_B(x) (((x) >> 0) & 0x1)
409#define C_0003C0_GENMO_MONO_ADDRESS_B 0xFFFFFFFE 427#define C_0003C2_GENMO_MONO_ADDRESS_B 0xFE
410#define S_0003C0_VGA_RAM_EN(x) (((x) & 0x1) << 1) 428#define S_0003C2_VGA_RAM_EN(x) (((x) & 0x1) << 1)
411#define G_0003C0_VGA_RAM_EN(x) (((x) >> 1) & 0x1) 429#define G_0003C2_VGA_RAM_EN(x) (((x) >> 1) & 0x1)
412#define C_0003C0_VGA_RAM_EN 0xFFFFFFFD 430#define C_0003C2_VGA_RAM_EN 0xFD
413#define S_0003C0_VGA_CKSEL(x) (((x) & 0x3) << 2) 431#define S_0003C2_VGA_CKSEL(x) (((x) & 0x3) << 2)
414#define G_0003C0_VGA_CKSEL(x) (((x) >> 2) & 0x3) 432#define G_0003C2_VGA_CKSEL(x) (((x) >> 2) & 0x3)
415#define C_0003C0_VGA_CKSEL 0xFFFFFFF3 433#define C_0003C2_VGA_CKSEL 0xF3
416#define S_0003C0_ODD_EVEN_MD_PGSEL(x) (((x) & 0x1) << 5) 434#define S_0003C2_ODD_EVEN_MD_PGSEL(x) (((x) & 0x1) << 5)
417#define G_0003C0_ODD_EVEN_MD_PGSEL(x) (((x) >> 5) & 0x1) 435#define G_0003C2_ODD_EVEN_MD_PGSEL(x) (((x) >> 5) & 0x1)
418#define C_0003C0_ODD_EVEN_MD_PGSEL 0xFFFFFFDF 436#define C_0003C2_ODD_EVEN_MD_PGSEL 0xDF
419#define S_0003C0_VGA_HSYNC_POL(x) (((x) & 0x1) << 6) 437#define S_0003C2_VGA_HSYNC_POL(x) (((x) & 0x1) << 6)
420#define G_0003C0_VGA_HSYNC_POL(x) (((x) >> 6) & 0x1) 438#define G_0003C2_VGA_HSYNC_POL(x) (((x) >> 6) & 0x1)
421#define C_0003C0_VGA_HSYNC_POL 0xFFFFFFBF 439#define C_0003C2_VGA_HSYNC_POL 0xBF
422#define S_0003C0_VGA_VSYNC_POL(x) (((x) & 0x1) << 7) 440#define S_0003C2_VGA_VSYNC_POL(x) (((x) & 0x1) << 7)
423#define G_0003C0_VGA_VSYNC_POL(x) (((x) >> 7) & 0x1) 441#define G_0003C2_VGA_VSYNC_POL(x) (((x) >> 7) & 0x1)
424#define C_0003C0_VGA_VSYNC_POL 0xFFFFFF7F 442#define C_0003C2_VGA_VSYNC_POL 0x7F
425#define R_0003F8_CRTC2_GEN_CNTL 0x0003F8 443#define R_0003F8_CRTC2_GEN_CNTL 0x0003F8
426#define S_0003F8_CRTC2_DBL_SCAN_EN(x) (((x) & 0x1) << 0) 444#define S_0003F8_CRTC2_DBL_SCAN_EN(x) (((x) & 0x1) << 0)
427#define G_0003F8_CRTC2_DBL_SCAN_EN(x) (((x) >> 0) & 0x1) 445#define G_0003F8_CRTC2_DBL_SCAN_EN(x) (((x) >> 0) & 0x1)
@@ -545,6 +563,46 @@
545#define S_000774_SCRATCH_ADDR(x) (((x) & 0x7FFFFFF) << 5) 563#define S_000774_SCRATCH_ADDR(x) (((x) & 0x7FFFFFF) << 5)
546#define G_000774_SCRATCH_ADDR(x) (((x) >> 5) & 0x7FFFFFF) 564#define G_000774_SCRATCH_ADDR(x) (((x) >> 5) & 0x7FFFFFF)
547#define C_000774_SCRATCH_ADDR 0x0000001F 565#define C_000774_SCRATCH_ADDR 0x0000001F
566#define R_0007C0_CP_STAT 0x0007C0
567#define S_0007C0_MRU_BUSY(x) (((x) & 0x1) << 0)
568#define G_0007C0_MRU_BUSY(x) (((x) >> 0) & 0x1)
569#define C_0007C0_MRU_BUSY 0xFFFFFFFE
570#define S_0007C0_MWU_BUSY(x) (((x) & 0x1) << 1)
571#define G_0007C0_MWU_BUSY(x) (((x) >> 1) & 0x1)
572#define C_0007C0_MWU_BUSY 0xFFFFFFFD
573#define S_0007C0_RSIU_BUSY(x) (((x) & 0x1) << 2)
574#define G_0007C0_RSIU_BUSY(x) (((x) >> 2) & 0x1)
575#define C_0007C0_RSIU_BUSY 0xFFFFFFFB
576#define S_0007C0_RCIU_BUSY(x) (((x) & 0x1) << 3)
577#define G_0007C0_RCIU_BUSY(x) (((x) >> 3) & 0x1)
578#define C_0007C0_RCIU_BUSY 0xFFFFFFF7
579#define S_0007C0_CSF_PRIMARY_BUSY(x) (((x) & 0x1) << 9)
580#define G_0007C0_CSF_PRIMARY_BUSY(x) (((x) >> 9) & 0x1)
581#define C_0007C0_CSF_PRIMARY_BUSY 0xFFFFFDFF
582#define S_0007C0_CSF_INDIRECT_BUSY(x) (((x) & 0x1) << 10)
583#define G_0007C0_CSF_INDIRECT_BUSY(x) (((x) >> 10) & 0x1)
584#define C_0007C0_CSF_INDIRECT_BUSY 0xFFFFFBFF
585#define S_0007C0_CSQ_PRIMARY_BUSY(x) (((x) & 0x1) << 11)
586#define G_0007C0_CSQ_PRIMARY_BUSY(x) (((x) >> 11) & 0x1)
587#define C_0007C0_CSQ_PRIMARY_BUSY 0xFFFFF7FF
588#define S_0007C0_CSQ_INDIRECT_BUSY(x) (((x) & 0x1) << 12)
589#define G_0007C0_CSQ_INDIRECT_BUSY(x) (((x) >> 12) & 0x1)
590#define C_0007C0_CSQ_INDIRECT_BUSY 0xFFFFEFFF
591#define S_0007C0_CSI_BUSY(x) (((x) & 0x1) << 13)
592#define G_0007C0_CSI_BUSY(x) (((x) >> 13) & 0x1)
593#define C_0007C0_CSI_BUSY 0xFFFFDFFF
594#define S_0007C0_GUIDMA_BUSY(x) (((x) & 0x1) << 28)
595#define G_0007C0_GUIDMA_BUSY(x) (((x) >> 28) & 0x1)
596#define C_0007C0_GUIDMA_BUSY 0xEFFFFFFF
597#define S_0007C0_VIDDMA_BUSY(x) (((x) & 0x1) << 29)
598#define G_0007C0_VIDDMA_BUSY(x) (((x) >> 29) & 0x1)
599#define C_0007C0_VIDDMA_BUSY 0xDFFFFFFF
600#define S_0007C0_CMDSTRM_BUSY(x) (((x) & 0x1) << 30)
601#define G_0007C0_CMDSTRM_BUSY(x) (((x) >> 30) & 0x1)
602#define C_0007C0_CMDSTRM_BUSY 0xBFFFFFFF
603#define S_0007C0_CP_BUSY(x) (((x) & 0x1) << 31)
604#define G_0007C0_CP_BUSY(x) (((x) >> 31) & 0x1)
605#define C_0007C0_CP_BUSY 0x7FFFFFFF
548#define R_000E40_RBBM_STATUS 0x000E40 606#define R_000E40_RBBM_STATUS 0x000E40
549#define S_000E40_CMDFIFO_AVAIL(x) (((x) & 0x7F) << 0) 607#define S_000E40_CMDFIFO_AVAIL(x) (((x) & 0x7F) << 0)
550#define G_000E40_CMDFIFO_AVAIL(x) (((x) >> 0) & 0x7F) 608#define G_000E40_CMDFIFO_AVAIL(x) (((x) >> 0) & 0x7F)
@@ -604,4 +662,53 @@
604#define G_000E40_GUI_ACTIVE(x) (((x) >> 31) & 0x1) 662#define G_000E40_GUI_ACTIVE(x) (((x) >> 31) & 0x1)
605#define C_000E40_GUI_ACTIVE 0x7FFFFFFF 663#define C_000E40_GUI_ACTIVE 0x7FFFFFFF
606 664
665
666#define R_00000D_SCLK_CNTL 0x00000D
667#define S_00000D_SCLK_SRC_SEL(x) (((x) & 0x7) << 0)
668#define G_00000D_SCLK_SRC_SEL(x) (((x) >> 0) & 0x7)
669#define C_00000D_SCLK_SRC_SEL 0xFFFFFFF8
670#define S_00000D_TCLK_SRC_SEL(x) (((x) & 0x7) << 8)
671#define G_00000D_TCLK_SRC_SEL(x) (((x) >> 8) & 0x7)
672#define C_00000D_TCLK_SRC_SEL 0xFFFFF8FF
673#define S_00000D_FORCE_CP(x) (((x) & 0x1) << 16)
674#define G_00000D_FORCE_CP(x) (((x) >> 16) & 0x1)
675#define C_00000D_FORCE_CP 0xFFFEFFFF
676#define S_00000D_FORCE_HDP(x) (((x) & 0x1) << 17)
677#define G_00000D_FORCE_HDP(x) (((x) >> 17) & 0x1)
678#define C_00000D_FORCE_HDP 0xFFFDFFFF
679#define S_00000D_FORCE_DISP(x) (((x) & 0x1) << 18)
680#define G_00000D_FORCE_DISP(x) (((x) >> 18) & 0x1)
681#define C_00000D_FORCE_DISP 0xFFFBFFFF
682#define S_00000D_FORCE_TOP(x) (((x) & 0x1) << 19)
683#define G_00000D_FORCE_TOP(x) (((x) >> 19) & 0x1)
684#define C_00000D_FORCE_TOP 0xFFF7FFFF
685#define S_00000D_FORCE_E2(x) (((x) & 0x1) << 20)
686#define G_00000D_FORCE_E2(x) (((x) >> 20) & 0x1)
687#define C_00000D_FORCE_E2 0xFFEFFFFF
688#define S_00000D_FORCE_SE(x) (((x) & 0x1) << 21)
689#define G_00000D_FORCE_SE(x) (((x) >> 21) & 0x1)
690#define C_00000D_FORCE_SE 0xFFDFFFFF
691#define S_00000D_FORCE_IDCT(x) (((x) & 0x1) << 22)
692#define G_00000D_FORCE_IDCT(x) (((x) >> 22) & 0x1)
693#define C_00000D_FORCE_IDCT 0xFFBFFFFF
694#define S_00000D_FORCE_VIP(x) (((x) & 0x1) << 23)
695#define G_00000D_FORCE_VIP(x) (((x) >> 23) & 0x1)
696#define C_00000D_FORCE_VIP 0xFF7FFFFF
697#define S_00000D_FORCE_RE(x) (((x) & 0x1) << 24)
698#define G_00000D_FORCE_RE(x) (((x) >> 24) & 0x1)
699#define C_00000D_FORCE_RE 0xFEFFFFFF
700#define S_00000D_FORCE_PB(x) (((x) & 0x1) << 25)
701#define G_00000D_FORCE_PB(x) (((x) >> 25) & 0x1)
702#define C_00000D_FORCE_PB 0xFDFFFFFF
703#define S_00000D_FORCE_TAM(x) (((x) & 0x1) << 26)
704#define G_00000D_FORCE_TAM(x) (((x) >> 26) & 0x1)
705#define C_00000D_FORCE_TAM 0xFBFFFFFF
706#define S_00000D_FORCE_TDM(x) (((x) & 0x1) << 27)
707#define G_00000D_FORCE_TDM(x) (((x) >> 27) & 0x1)
708#define C_00000D_FORCE_TDM 0xF7FFFFFF
709#define S_00000D_FORCE_RB(x) (((x) & 0x1) << 28)
710#define G_00000D_FORCE_RB(x) (((x) >> 28) & 0x1)
711#define C_00000D_FORCE_RB 0xEFFFFFFF
712
713
607#endif 714#endif
diff --git a/drivers/gpu/drm/radeon/r200.c b/drivers/gpu/drm/radeon/r200.c
index cf7fea5ff2e5..eb740fc3549f 100644
--- a/drivers/gpu/drm/radeon/r200.c
+++ b/drivers/gpu/drm/radeon/r200.c
@@ -447,9 +447,8 @@ int r200_packet0_check(struct radeon_cs_parser *p,
447 return 0; 447 return 0;
448} 448}
449 449
450int r200_init(struct radeon_device *rdev) 450void r200_set_safe_registers(struct radeon_device *rdev)
451{ 451{
452 rdev->config.r100.reg_safe_bm = r200_reg_safe_bm; 452 rdev->config.r100.reg_safe_bm = r200_reg_safe_bm;
453 rdev->config.r100.reg_safe_bm_size = ARRAY_SIZE(r200_reg_safe_bm); 453 rdev->config.r100.reg_safe_bm_size = ARRAY_SIZE(r200_reg_safe_bm);
454 return 0;
455} 454}
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c
index 1ebea8cc8c93..e08c4a8974ca 100644
--- a/drivers/gpu/drm/radeon/r300.c
+++ b/drivers/gpu/drm/radeon/r300.c
@@ -33,43 +33,16 @@
33#include "radeon_drm.h" 33#include "radeon_drm.h"
34#include "r100_track.h" 34#include "r100_track.h"
35#include "r300d.h" 35#include "r300d.h"
36 36#include "rv350d.h"
37#include "r300_reg_safe.h" 37#include "r300_reg_safe.h"
38 38
39/* r300,r350,rv350,rv370,rv380 depends on : */ 39/* This files gather functions specifics to: r300,r350,rv350,rv370,rv380 */
40void r100_hdp_reset(struct radeon_device *rdev);
41int r100_cp_reset(struct radeon_device *rdev);
42int r100_rb2d_reset(struct radeon_device *rdev);
43int r100_cp_init(struct radeon_device *rdev, unsigned ring_size);
44int r100_pci_gart_enable(struct radeon_device *rdev);
45void r100_mc_setup(struct radeon_device *rdev);
46void r100_mc_disable_clients(struct radeon_device *rdev);
47int r100_gui_wait_for_idle(struct radeon_device *rdev);
48int r100_cs_packet_parse(struct radeon_cs_parser *p,
49 struct radeon_cs_packet *pkt,
50 unsigned idx);
51int r100_cs_packet_parse_vline(struct radeon_cs_parser *p);
52int r100_cs_parse_packet0(struct radeon_cs_parser *p,
53 struct radeon_cs_packet *pkt,
54 const unsigned *auth, unsigned n,
55 radeon_packet0_check_t check);
56int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p,
57 struct radeon_cs_packet *pkt,
58 struct radeon_object *robj);
59
60/* This files gather functions specifics to:
61 * r300,r350,rv350,rv370,rv380
62 *
63 * Some of these functions might be used by newer ASICs.
64 */
65void r300_gpu_init(struct radeon_device *rdev);
66int r300_mc_wait_for_idle(struct radeon_device *rdev);
67int rv370_debugfs_pcie_gart_info_init(struct radeon_device *rdev);
68
69 40
70/* 41/*
71 * rv370,rv380 PCIE GART 42 * rv370,rv380 PCIE GART
72 */ 43 */
44static int rv370_debugfs_pcie_gart_info_init(struct radeon_device *rdev);
45
73void rv370_pcie_gart_tlb_flush(struct radeon_device *rdev) 46void rv370_pcie_gart_tlb_flush(struct radeon_device *rdev)
74{ 47{
75 uint32_t tmp; 48 uint32_t tmp;
@@ -182,59 +155,6 @@ void rv370_pcie_gart_fini(struct radeon_device *rdev)
182 radeon_gart_fini(rdev); 155 radeon_gart_fini(rdev);
183} 156}
184 157
185/*
186 * MC
187 */
188int r300_mc_init(struct radeon_device *rdev)
189{
190 int r;
191
192 if (r100_debugfs_rbbm_init(rdev)) {
193 DRM_ERROR("Failed to register debugfs file for RBBM !\n");
194 }
195
196 r300_gpu_init(rdev);
197 r100_pci_gart_disable(rdev);
198 if (rdev->flags & RADEON_IS_PCIE) {
199 rv370_pcie_gart_disable(rdev);
200 }
201
202 /* Setup GPU memory space */
203 rdev->mc.vram_location = 0xFFFFFFFFUL;
204 rdev->mc.gtt_location = 0xFFFFFFFFUL;
205 if (rdev->flags & RADEON_IS_AGP) {
206 r = radeon_agp_init(rdev);
207 if (r) {
208 printk(KERN_WARNING "[drm] Disabling AGP\n");
209 rdev->flags &= ~RADEON_IS_AGP;
210 rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
211 } else {
212 rdev->mc.gtt_location = rdev->mc.agp_base;
213 }
214 }
215 r = radeon_mc_setup(rdev);
216 if (r) {
217 return r;
218 }
219
220 /* Program GPU memory space */
221 r100_mc_disable_clients(rdev);
222 if (r300_mc_wait_for_idle(rdev)) {
223 printk(KERN_WARNING "Failed to wait MC idle while "
224 "programming pipes. Bad things might happen.\n");
225 }
226 r100_mc_setup(rdev);
227 return 0;
228}
229
230void r300_mc_fini(struct radeon_device *rdev)
231{
232}
233
234
235/*
236 * Fence emission
237 */
238void r300_fence_ring_emit(struct radeon_device *rdev, 158void r300_fence_ring_emit(struct radeon_device *rdev,
239 struct radeon_fence *fence) 159 struct radeon_fence *fence)
240{ 160{
@@ -260,10 +180,6 @@ void r300_fence_ring_emit(struct radeon_device *rdev,
260 radeon_ring_write(rdev, RADEON_SW_INT_FIRE); 180 radeon_ring_write(rdev, RADEON_SW_INT_FIRE);
261} 181}
262 182
263
264/*
265 * Global GPU functions
266 */
267int r300_copy_dma(struct radeon_device *rdev, 183int r300_copy_dma(struct radeon_device *rdev,
268 uint64_t src_offset, 184 uint64_t src_offset,
269 uint64_t dst_offset, 185 uint64_t dst_offset,
@@ -582,11 +498,6 @@ void r300_vram_info(struct radeon_device *rdev)
582 r100_vram_init_sizes(rdev); 498 r100_vram_init_sizes(rdev);
583} 499}
584 500
585
586/*
587 * PCIE Lanes
588 */
589
590void rv370_set_pcie_lanes(struct radeon_device *rdev, int lanes) 501void rv370_set_pcie_lanes(struct radeon_device *rdev, int lanes)
591{ 502{
592 uint32_t link_width_cntl, mask; 503 uint32_t link_width_cntl, mask;
@@ -646,10 +557,6 @@ void rv370_set_pcie_lanes(struct radeon_device *rdev, int lanes)
646 557
647} 558}
648 559
649
650/*
651 * Debugfs info
652 */
653#if defined(CONFIG_DEBUG_FS) 560#if defined(CONFIG_DEBUG_FS)
654static int rv370_debugfs_pcie_gart_info(struct seq_file *m, void *data) 561static int rv370_debugfs_pcie_gart_info(struct seq_file *m, void *data)
655{ 562{
@@ -680,7 +587,7 @@ static struct drm_info_list rv370_pcie_gart_info_list[] = {
680}; 587};
681#endif 588#endif
682 589
683int rv370_debugfs_pcie_gart_info_init(struct radeon_device *rdev) 590static int rv370_debugfs_pcie_gart_info_init(struct radeon_device *rdev)
684{ 591{
685#if defined(CONFIG_DEBUG_FS) 592#if defined(CONFIG_DEBUG_FS)
686 return radeon_debugfs_add_files(rdev, rv370_pcie_gart_info_list, 1); 593 return radeon_debugfs_add_files(rdev, rv370_pcie_gart_info_list, 1);
@@ -689,10 +596,6 @@ int rv370_debugfs_pcie_gart_info_init(struct radeon_device *rdev)
689#endif 596#endif
690} 597}
691 598
692
693/*
694 * CS functions
695 */
696static int r300_packet0_check(struct radeon_cs_parser *p, 599static int r300_packet0_check(struct radeon_cs_parser *p,
697 struct radeon_cs_packet *pkt, 600 struct radeon_cs_packet *pkt,
698 unsigned idx, unsigned reg) 601 unsigned idx, unsigned reg)
@@ -1226,12 +1129,6 @@ void r300_set_reg_safe(struct radeon_device *rdev)
1226 rdev->config.r300.reg_safe_bm_size = ARRAY_SIZE(r300_reg_safe_bm); 1129 rdev->config.r300.reg_safe_bm_size = ARRAY_SIZE(r300_reg_safe_bm);
1227} 1130}
1228 1131
1229int r300_init(struct radeon_device *rdev)
1230{
1231 r300_set_reg_safe(rdev);
1232 return 0;
1233}
1234
1235void r300_mc_program(struct radeon_device *rdev) 1132void r300_mc_program(struct radeon_device *rdev)
1236{ 1133{
1237 struct r100_mc_save save; 1134 struct r100_mc_save save;
@@ -1265,3 +1162,198 @@ void r300_mc_program(struct radeon_device *rdev)
1265 S_000148_MC_FB_TOP(rdev->mc.vram_end >> 16)); 1162 S_000148_MC_FB_TOP(rdev->mc.vram_end >> 16));
1266 r100_mc_resume(rdev, &save); 1163 r100_mc_resume(rdev, &save);
1267} 1164}
1165
1166void r300_clock_startup(struct radeon_device *rdev)
1167{
1168 u32 tmp;
1169
1170 if (radeon_dynclks != -1 && radeon_dynclks)
1171 radeon_legacy_set_clock_gating(rdev, 1);
1172 /* We need to force on some of the block */
1173 tmp = RREG32_PLL(R_00000D_SCLK_CNTL);
1174 tmp |= S_00000D_FORCE_CP(1) | S_00000D_FORCE_VIP(1);
1175 if ((rdev->family == CHIP_RV350) || (rdev->family == CHIP_RV380))
1176 tmp |= S_00000D_FORCE_VAP(1);
1177 WREG32_PLL(R_00000D_SCLK_CNTL, tmp);
1178}
1179
1180static int r300_startup(struct radeon_device *rdev)
1181{
1182 int r;
1183
1184 r300_mc_program(rdev);
1185 /* Resume clock */
1186 r300_clock_startup(rdev);
1187 /* Initialize GPU configuration (# pipes, ...) */
1188 r300_gpu_init(rdev);
1189 /* Initialize GART (initialize after TTM so we can allocate
1190 * memory through TTM but finalize after TTM) */
1191 if (rdev->flags & RADEON_IS_PCIE) {
1192 r = rv370_pcie_gart_enable(rdev);
1193 if (r)
1194 return r;
1195 }
1196 if (rdev->flags & RADEON_IS_PCI) {
1197 r = r100_pci_gart_enable(rdev);
1198 if (r)
1199 return r;
1200 }
1201 /* Enable IRQ */
1202 rdev->irq.sw_int = true;
1203 r100_irq_set(rdev);
1204 /* 1M ring buffer */
1205 r = r100_cp_init(rdev, 1024 * 1024);
1206 if (r) {
1207 dev_err(rdev->dev, "failled initializing CP (%d).\n", r);
1208 return r;
1209 }
1210 r = r100_wb_init(rdev);
1211 if (r)
1212 dev_err(rdev->dev, "failled initializing WB (%d).\n", r);
1213 r = r100_ib_init(rdev);
1214 if (r) {
1215 dev_err(rdev->dev, "failled initializing IB (%d).\n", r);
1216 return r;
1217 }
1218 return 0;
1219}
1220
1221int r300_resume(struct radeon_device *rdev)
1222{
1223 /* Make sur GART are not working */
1224 if (rdev->flags & RADEON_IS_PCIE)
1225 rv370_pcie_gart_disable(rdev);
1226 if (rdev->flags & RADEON_IS_PCI)
1227 r100_pci_gart_disable(rdev);
1228 /* Resume clock before doing reset */
1229 r300_clock_startup(rdev);
1230 /* Reset gpu before posting otherwise ATOM will enter infinite loop */
1231 if (radeon_gpu_reset(rdev)) {
1232 dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
1233 RREG32(R_000E40_RBBM_STATUS),
1234 RREG32(R_0007C0_CP_STAT));
1235 }
1236 /* post */
1237 radeon_combios_asic_init(rdev->ddev);
1238 /* Resume clock after posting */
1239 r300_clock_startup(rdev);
1240 return r300_startup(rdev);
1241}
1242
1243int r300_suspend(struct radeon_device *rdev)
1244{
1245 r100_cp_disable(rdev);
1246 r100_wb_disable(rdev);
1247 r100_irq_disable(rdev);
1248 if (rdev->flags & RADEON_IS_PCIE)
1249 rv370_pcie_gart_disable(rdev);
1250 if (rdev->flags & RADEON_IS_PCI)
1251 r100_pci_gart_disable(rdev);
1252 return 0;
1253}
1254
1255void r300_fini(struct radeon_device *rdev)
1256{
1257 r300_suspend(rdev);
1258 r100_cp_fini(rdev);
1259 r100_wb_fini(rdev);
1260 r100_ib_fini(rdev);
1261 radeon_gem_fini(rdev);
1262 if (rdev->flags & RADEON_IS_PCIE)
1263 rv370_pcie_gart_fini(rdev);
1264 if (rdev->flags & RADEON_IS_PCI)
1265 r100_pci_gart_fini(rdev);
1266 radeon_irq_kms_fini(rdev);
1267 radeon_fence_driver_fini(rdev);
1268 radeon_object_fini(rdev);
1269 radeon_atombios_fini(rdev);
1270 kfree(rdev->bios);
1271 rdev->bios = NULL;
1272}
1273
1274int r300_init(struct radeon_device *rdev)
1275{
1276 int r;
1277
1278 /* Disable VGA */
1279 r100_vga_render_disable(rdev);
1280 /* Initialize scratch registers */
1281 radeon_scratch_init(rdev);
1282 /* Initialize surface registers */
1283 radeon_surface_init(rdev);
1284 /* TODO: disable VGA need to use VGA request */
1285 /* BIOS*/
1286 if (!radeon_get_bios(rdev)) {
1287 if (ASIC_IS_AVIVO(rdev))
1288 return -EINVAL;
1289 }
1290 if (rdev->is_atom_bios) {
1291 dev_err(rdev->dev, "Expecting combios for RS400/RS480 GPU\n");
1292 return -EINVAL;
1293 } else {
1294 r = radeon_combios_init(rdev);
1295 if (r)
1296 return r;
1297 }
1298 /* Reset gpu before posting otherwise ATOM will enter infinite loop */
1299 if (radeon_gpu_reset(rdev)) {
1300 dev_warn(rdev->dev,
1301 "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
1302 RREG32(R_000E40_RBBM_STATUS),
1303 RREG32(R_0007C0_CP_STAT));
1304 }
1305 /* check if cards are posted or not */
1306 if (!radeon_card_posted(rdev) && rdev->bios) {
1307 DRM_INFO("GPU not posted. posting now...\n");
1308 radeon_combios_asic_init(rdev->ddev);
1309 }
1310 /* Set asic errata */
1311 r300_errata(rdev);
1312 /* Initialize clocks */
1313 radeon_get_clock_info(rdev->ddev);
1314 /* Get vram informations */
1315 r300_vram_info(rdev);
1316 /* Initialize memory controller (also test AGP) */
1317 r = r420_mc_init(rdev);
1318 if (r)
1319 return r;
1320 /* Fence driver */
1321 r = radeon_fence_driver_init(rdev);
1322 if (r)
1323 return r;
1324 r = radeon_irq_kms_init(rdev);
1325 if (r)
1326 return r;
1327 /* Memory manager */
1328 r = radeon_object_init(rdev);
1329 if (r)
1330 return r;
1331 if (rdev->flags & RADEON_IS_PCIE) {
1332 r = rv370_pcie_gart_init(rdev);
1333 if (r)
1334 return r;
1335 }
1336 if (rdev->flags & RADEON_IS_PCI) {
1337 r = r100_pci_gart_init(rdev);
1338 if (r)
1339 return r;
1340 }
1341 r300_set_reg_safe(rdev);
1342 rdev->accel_working = true;
1343 r = r300_startup(rdev);
1344 if (r) {
1345 /* Somethings want wront with the accel init stop accel */
1346 dev_err(rdev->dev, "Disabling GPU acceleration\n");
1347 r300_suspend(rdev);
1348 r100_cp_fini(rdev);
1349 r100_wb_fini(rdev);
1350 r100_ib_fini(rdev);
1351 if (rdev->flags & RADEON_IS_PCIE)
1352 rv370_pcie_gart_fini(rdev);
1353 if (rdev->flags & RADEON_IS_PCI)
1354 r100_pci_gart_fini(rdev);
1355 radeon_irq_kms_fini(rdev);
1356 rdev->accel_working = false;
1357 }
1358 return 0;
1359}
diff --git a/drivers/gpu/drm/radeon/r300d.h b/drivers/gpu/drm/radeon/r300d.h
index d4fa3eb1074f..4c73114f0de9 100644
--- a/drivers/gpu/drm/radeon/r300d.h
+++ b/drivers/gpu/drm/radeon/r300d.h
@@ -96,6 +96,211 @@
96#define S_000170_AGP_BASE_ADDR(x) (((x) & 0xFFFFFFFF) << 0) 96#define S_000170_AGP_BASE_ADDR(x) (((x) & 0xFFFFFFFF) << 0)
97#define G_000170_AGP_BASE_ADDR(x) (((x) >> 0) & 0xFFFFFFFF) 97#define G_000170_AGP_BASE_ADDR(x) (((x) >> 0) & 0xFFFFFFFF)
98#define C_000170_AGP_BASE_ADDR 0x00000000 98#define C_000170_AGP_BASE_ADDR 0x00000000
99#define R_0007C0_CP_STAT 0x0007C0
100#define S_0007C0_MRU_BUSY(x) (((x) & 0x1) << 0)
101#define G_0007C0_MRU_BUSY(x) (((x) >> 0) & 0x1)
102#define C_0007C0_MRU_BUSY 0xFFFFFFFE
103#define S_0007C0_MWU_BUSY(x) (((x) & 0x1) << 1)
104#define G_0007C0_MWU_BUSY(x) (((x) >> 1) & 0x1)
105#define C_0007C0_MWU_BUSY 0xFFFFFFFD
106#define S_0007C0_RSIU_BUSY(x) (((x) & 0x1) << 2)
107#define G_0007C0_RSIU_BUSY(x) (((x) >> 2) & 0x1)
108#define C_0007C0_RSIU_BUSY 0xFFFFFFFB
109#define S_0007C0_RCIU_BUSY(x) (((x) & 0x1) << 3)
110#define G_0007C0_RCIU_BUSY(x) (((x) >> 3) & 0x1)
111#define C_0007C0_RCIU_BUSY 0xFFFFFFF7
112#define S_0007C0_CSF_PRIMARY_BUSY(x) (((x) & 0x1) << 9)
113#define G_0007C0_CSF_PRIMARY_BUSY(x) (((x) >> 9) & 0x1)
114#define C_0007C0_CSF_PRIMARY_BUSY 0xFFFFFDFF
115#define S_0007C0_CSF_INDIRECT_BUSY(x) (((x) & 0x1) << 10)
116#define G_0007C0_CSF_INDIRECT_BUSY(x) (((x) >> 10) & 0x1)
117#define C_0007C0_CSF_INDIRECT_BUSY 0xFFFFFBFF
118#define S_0007C0_CSQ_PRIMARY_BUSY(x) (((x) & 0x1) << 11)
119#define G_0007C0_CSQ_PRIMARY_BUSY(x) (((x) >> 11) & 0x1)
120#define C_0007C0_CSQ_PRIMARY_BUSY 0xFFFFF7FF
121#define S_0007C0_CSQ_INDIRECT_BUSY(x) (((x) & 0x1) << 12)
122#define G_0007C0_CSQ_INDIRECT_BUSY(x) (((x) >> 12) & 0x1)
123#define C_0007C0_CSQ_INDIRECT_BUSY 0xFFFFEFFF
124#define S_0007C0_CSI_BUSY(x) (((x) & 0x1) << 13)
125#define G_0007C0_CSI_BUSY(x) (((x) >> 13) & 0x1)
126#define C_0007C0_CSI_BUSY 0xFFFFDFFF
127#define S_0007C0_CSF_INDIRECT2_BUSY(x) (((x) & 0x1) << 14)
128#define G_0007C0_CSF_INDIRECT2_BUSY(x) (((x) >> 14) & 0x1)
129#define C_0007C0_CSF_INDIRECT2_BUSY 0xFFFFBFFF
130#define S_0007C0_CSQ_INDIRECT2_BUSY(x) (((x) & 0x1) << 15)
131#define G_0007C0_CSQ_INDIRECT2_BUSY(x) (((x) >> 15) & 0x1)
132#define C_0007C0_CSQ_INDIRECT2_BUSY 0xFFFF7FFF
133#define S_0007C0_GUIDMA_BUSY(x) (((x) & 0x1) << 28)
134#define G_0007C0_GUIDMA_BUSY(x) (((x) >> 28) & 0x1)
135#define C_0007C0_GUIDMA_BUSY 0xEFFFFFFF
136#define S_0007C0_VIDDMA_BUSY(x) (((x) & 0x1) << 29)
137#define G_0007C0_VIDDMA_BUSY(x) (((x) >> 29) & 0x1)
138#define C_0007C0_VIDDMA_BUSY 0xDFFFFFFF
139#define S_0007C0_CMDSTRM_BUSY(x) (((x) & 0x1) << 30)
140#define G_0007C0_CMDSTRM_BUSY(x) (((x) >> 30) & 0x1)
141#define C_0007C0_CMDSTRM_BUSY 0xBFFFFFFF
142#define S_0007C0_CP_BUSY(x) (((x) & 0x1) << 31)
143#define G_0007C0_CP_BUSY(x) (((x) >> 31) & 0x1)
144#define C_0007C0_CP_BUSY 0x7FFFFFFF
145#define R_000E40_RBBM_STATUS 0x000E40
146#define S_000E40_CMDFIFO_AVAIL(x) (((x) & 0x7F) << 0)
147#define G_000E40_CMDFIFO_AVAIL(x) (((x) >> 0) & 0x7F)
148#define C_000E40_CMDFIFO_AVAIL 0xFFFFFF80
149#define S_000E40_HIRQ_ON_RBB(x) (((x) & 0x1) << 8)
150#define G_000E40_HIRQ_ON_RBB(x) (((x) >> 8) & 0x1)
151#define C_000E40_HIRQ_ON_RBB 0xFFFFFEFF
152#define S_000E40_CPRQ_ON_RBB(x) (((x) & 0x1) << 9)
153#define G_000E40_CPRQ_ON_RBB(x) (((x) >> 9) & 0x1)
154#define C_000E40_CPRQ_ON_RBB 0xFFFFFDFF
155#define S_000E40_CFRQ_ON_RBB(x) (((x) & 0x1) << 10)
156#define G_000E40_CFRQ_ON_RBB(x) (((x) >> 10) & 0x1)
157#define C_000E40_CFRQ_ON_RBB 0xFFFFFBFF
158#define S_000E40_HIRQ_IN_RTBUF(x) (((x) & 0x1) << 11)
159#define G_000E40_HIRQ_IN_RTBUF(x) (((x) >> 11) & 0x1)
160#define C_000E40_HIRQ_IN_RTBUF 0xFFFFF7FF
161#define S_000E40_CPRQ_IN_RTBUF(x) (((x) & 0x1) << 12)
162#define G_000E40_CPRQ_IN_RTBUF(x) (((x) >> 12) & 0x1)
163#define C_000E40_CPRQ_IN_RTBUF 0xFFFFEFFF
164#define S_000E40_CFRQ_IN_RTBUF(x) (((x) & 0x1) << 13)
165#define G_000E40_CFRQ_IN_RTBUF(x) (((x) >> 13) & 0x1)
166#define C_000E40_CFRQ_IN_RTBUF 0xFFFFDFFF
167#define S_000E40_CF_PIPE_BUSY(x) (((x) & 0x1) << 14)
168#define G_000E40_CF_PIPE_BUSY(x) (((x) >> 14) & 0x1)
169#define C_000E40_CF_PIPE_BUSY 0xFFFFBFFF
170#define S_000E40_ENG_EV_BUSY(x) (((x) & 0x1) << 15)
171#define G_000E40_ENG_EV_BUSY(x) (((x) >> 15) & 0x1)
172#define C_000E40_ENG_EV_BUSY 0xFFFF7FFF
173#define S_000E40_CP_CMDSTRM_BUSY(x) (((x) & 0x1) << 16)
174#define G_000E40_CP_CMDSTRM_BUSY(x) (((x) >> 16) & 0x1)
175#define C_000E40_CP_CMDSTRM_BUSY 0xFFFEFFFF
176#define S_000E40_E2_BUSY(x) (((x) & 0x1) << 17)
177#define G_000E40_E2_BUSY(x) (((x) >> 17) & 0x1)
178#define C_000E40_E2_BUSY 0xFFFDFFFF
179#define S_000E40_RB2D_BUSY(x) (((x) & 0x1) << 18)
180#define G_000E40_RB2D_BUSY(x) (((x) >> 18) & 0x1)
181#define C_000E40_RB2D_BUSY 0xFFFBFFFF
182#define S_000E40_RB3D_BUSY(x) (((x) & 0x1) << 19)
183#define G_000E40_RB3D_BUSY(x) (((x) >> 19) & 0x1)
184#define C_000E40_RB3D_BUSY 0xFFF7FFFF
185#define S_000E40_VAP_BUSY(x) (((x) & 0x1) << 20)
186#define G_000E40_VAP_BUSY(x) (((x) >> 20) & 0x1)
187#define C_000E40_VAP_BUSY 0xFFEFFFFF
188#define S_000E40_RE_BUSY(x) (((x) & 0x1) << 21)
189#define G_000E40_RE_BUSY(x) (((x) >> 21) & 0x1)
190#define C_000E40_RE_BUSY 0xFFDFFFFF
191#define S_000E40_TAM_BUSY(x) (((x) & 0x1) << 22)
192#define G_000E40_TAM_BUSY(x) (((x) >> 22) & 0x1)
193#define C_000E40_TAM_BUSY 0xFFBFFFFF
194#define S_000E40_TDM_BUSY(x) (((x) & 0x1) << 23)
195#define G_000E40_TDM_BUSY(x) (((x) >> 23) & 0x1)
196#define C_000E40_TDM_BUSY 0xFF7FFFFF
197#define S_000E40_PB_BUSY(x) (((x) & 0x1) << 24)
198#define G_000E40_PB_BUSY(x) (((x) >> 24) & 0x1)
199#define C_000E40_PB_BUSY 0xFEFFFFFF
200#define S_000E40_TIM_BUSY(x) (((x) & 0x1) << 25)
201#define G_000E40_TIM_BUSY(x) (((x) >> 25) & 0x1)
202#define C_000E40_TIM_BUSY 0xFDFFFFFF
203#define S_000E40_GA_BUSY(x) (((x) & 0x1) << 26)
204#define G_000E40_GA_BUSY(x) (((x) >> 26) & 0x1)
205#define C_000E40_GA_BUSY 0xFBFFFFFF
206#define S_000E40_CBA2D_BUSY(x) (((x) & 0x1) << 27)
207#define G_000E40_CBA2D_BUSY(x) (((x) >> 27) & 0x1)
208#define C_000E40_CBA2D_BUSY 0xF7FFFFFF
209#define S_000E40_GUI_ACTIVE(x) (((x) & 0x1) << 31)
210#define G_000E40_GUI_ACTIVE(x) (((x) >> 31) & 0x1)
211#define C_000E40_GUI_ACTIVE 0x7FFFFFFF
99 212
100 213
214#define R_00000D_SCLK_CNTL 0x00000D
215#define S_00000D_SCLK_SRC_SEL(x) (((x) & 0x7) << 0)
216#define G_00000D_SCLK_SRC_SEL(x) (((x) >> 0) & 0x7)
217#define C_00000D_SCLK_SRC_SEL 0xFFFFFFF8
218#define S_00000D_CP_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 3)
219#define G_00000D_CP_MAX_DYN_STOP_LAT(x) (((x) >> 3) & 0x1)
220#define C_00000D_CP_MAX_DYN_STOP_LAT 0xFFFFFFF7
221#define S_00000D_HDP_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 4)
222#define G_00000D_HDP_MAX_DYN_STOP_LAT(x) (((x) >> 4) & 0x1)
223#define C_00000D_HDP_MAX_DYN_STOP_LAT 0xFFFFFFEF
224#define S_00000D_TV_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 5)
225#define G_00000D_TV_MAX_DYN_STOP_LAT(x) (((x) >> 5) & 0x1)
226#define C_00000D_TV_MAX_DYN_STOP_LAT 0xFFFFFFDF
227#define S_00000D_E2_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 6)
228#define G_00000D_E2_MAX_DYN_STOP_LAT(x) (((x) >> 6) & 0x1)
229#define C_00000D_E2_MAX_DYN_STOP_LAT 0xFFFFFFBF
230#define S_00000D_SE_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 7)
231#define G_00000D_SE_MAX_DYN_STOP_LAT(x) (((x) >> 7) & 0x1)
232#define C_00000D_SE_MAX_DYN_STOP_LAT 0xFFFFFF7F
233#define S_00000D_IDCT_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 8)
234#define G_00000D_IDCT_MAX_DYN_STOP_LAT(x) (((x) >> 8) & 0x1)
235#define C_00000D_IDCT_MAX_DYN_STOP_LAT 0xFFFFFEFF
236#define S_00000D_VIP_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 9)
237#define G_00000D_VIP_MAX_DYN_STOP_LAT(x) (((x) >> 9) & 0x1)
238#define C_00000D_VIP_MAX_DYN_STOP_LAT 0xFFFFFDFF
239#define S_00000D_RE_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 10)
240#define G_00000D_RE_MAX_DYN_STOP_LAT(x) (((x) >> 10) & 0x1)
241#define C_00000D_RE_MAX_DYN_STOP_LAT 0xFFFFFBFF
242#define S_00000D_PB_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 11)
243#define G_00000D_PB_MAX_DYN_STOP_LAT(x) (((x) >> 11) & 0x1)
244#define C_00000D_PB_MAX_DYN_STOP_LAT 0xFFFFF7FF
245#define S_00000D_TAM_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 12)
246#define G_00000D_TAM_MAX_DYN_STOP_LAT(x) (((x) >> 12) & 0x1)
247#define C_00000D_TAM_MAX_DYN_STOP_LAT 0xFFFFEFFF
248#define S_00000D_TDM_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 13)
249#define G_00000D_TDM_MAX_DYN_STOP_LAT(x) (((x) >> 13) & 0x1)
250#define C_00000D_TDM_MAX_DYN_STOP_LAT 0xFFFFDFFF
251#define S_00000D_RB_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 14)
252#define G_00000D_RB_MAX_DYN_STOP_LAT(x) (((x) >> 14) & 0x1)
253#define C_00000D_RB_MAX_DYN_STOP_LAT 0xFFFFBFFF
254#define S_00000D_FORCE_DISP2(x) (((x) & 0x1) << 15)
255#define G_00000D_FORCE_DISP2(x) (((x) >> 15) & 0x1)
256#define C_00000D_FORCE_DISP2 0xFFFF7FFF
257#define S_00000D_FORCE_CP(x) (((x) & 0x1) << 16)
258#define G_00000D_FORCE_CP(x) (((x) >> 16) & 0x1)
259#define C_00000D_FORCE_CP 0xFFFEFFFF
260#define S_00000D_FORCE_HDP(x) (((x) & 0x1) << 17)
261#define G_00000D_FORCE_HDP(x) (((x) >> 17) & 0x1)
262#define C_00000D_FORCE_HDP 0xFFFDFFFF
263#define S_00000D_FORCE_DISP1(x) (((x) & 0x1) << 18)
264#define G_00000D_FORCE_DISP1(x) (((x) >> 18) & 0x1)
265#define C_00000D_FORCE_DISP1 0xFFFBFFFF
266#define S_00000D_FORCE_TOP(x) (((x) & 0x1) << 19)
267#define G_00000D_FORCE_TOP(x) (((x) >> 19) & 0x1)
268#define C_00000D_FORCE_TOP 0xFFF7FFFF
269#define S_00000D_FORCE_E2(x) (((x) & 0x1) << 20)
270#define G_00000D_FORCE_E2(x) (((x) >> 20) & 0x1)
271#define C_00000D_FORCE_E2 0xFFEFFFFF
272#define S_00000D_FORCE_SE(x) (((x) & 0x1) << 21)
273#define G_00000D_FORCE_SE(x) (((x) >> 21) & 0x1)
274#define C_00000D_FORCE_SE 0xFFDFFFFF
275#define S_00000D_FORCE_IDCT(x) (((x) & 0x1) << 22)
276#define G_00000D_FORCE_IDCT(x) (((x) >> 22) & 0x1)
277#define C_00000D_FORCE_IDCT 0xFFBFFFFF
278#define S_00000D_FORCE_VIP(x) (((x) & 0x1) << 23)
279#define G_00000D_FORCE_VIP(x) (((x) >> 23) & 0x1)
280#define C_00000D_FORCE_VIP 0xFF7FFFFF
281#define S_00000D_FORCE_RE(x) (((x) & 0x1) << 24)
282#define G_00000D_FORCE_RE(x) (((x) >> 24) & 0x1)
283#define C_00000D_FORCE_RE 0xFEFFFFFF
284#define S_00000D_FORCE_PB(x) (((x) & 0x1) << 25)
285#define G_00000D_FORCE_PB(x) (((x) >> 25) & 0x1)
286#define C_00000D_FORCE_PB 0xFDFFFFFF
287#define S_00000D_FORCE_TAM(x) (((x) & 0x1) << 26)
288#define G_00000D_FORCE_TAM(x) (((x) >> 26) & 0x1)
289#define C_00000D_FORCE_TAM 0xFBFFFFFF
290#define S_00000D_FORCE_TDM(x) (((x) & 0x1) << 27)
291#define G_00000D_FORCE_TDM(x) (((x) >> 27) & 0x1)
292#define C_00000D_FORCE_TDM 0xF7FFFFFF
293#define S_00000D_FORCE_RB(x) (((x) & 0x1) << 28)
294#define G_00000D_FORCE_RB(x) (((x) >> 28) & 0x1)
295#define C_00000D_FORCE_RB 0xEFFFFFFF
296#define S_00000D_FORCE_TV_SCLK(x) (((x) & 0x1) << 29)
297#define G_00000D_FORCE_TV_SCLK(x) (((x) >> 29) & 0x1)
298#define C_00000D_FORCE_TV_SCLK 0xDFFFFFFF
299#define S_00000D_FORCE_SUBPIC(x) (((x) & 0x1) << 30)
300#define G_00000D_FORCE_SUBPIC(x) (((x) >> 30) & 0x1)
301#define C_00000D_FORCE_SUBPIC 0xBFFFFFFF
302#define S_00000D_FORCE_OV0(x) (((x) & 0x1) << 31)
303#define G_00000D_FORCE_OV0(x) (((x) >> 31) & 0x1)
304#define C_00000D_FORCE_OV0 0x7FFFFFFF
305
101#endif 306#endif
diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c
index 49a2fdc57d27..5c7fe52de30e 100644
--- a/drivers/gpu/drm/radeon/r420.c
+++ b/drivers/gpu/drm/radeon/r420.c
@@ -155,6 +155,9 @@ static void r420_debugfs(struct radeon_device *rdev)
155static void r420_clock_resume(struct radeon_device *rdev) 155static void r420_clock_resume(struct radeon_device *rdev)
156{ 156{
157 u32 sclk_cntl; 157 u32 sclk_cntl;
158
159 if (radeon_dynclks != -1 && radeon_dynclks)
160 radeon_atom_set_clock_gating(rdev, 1);
158 sclk_cntl = RREG32_PLL(R_00000D_SCLK_CNTL); 161 sclk_cntl = RREG32_PLL(R_00000D_SCLK_CNTL);
159 sclk_cntl |= S_00000D_FORCE_CP(1) | S_00000D_FORCE_VIP(1); 162 sclk_cntl |= S_00000D_FORCE_CP(1) | S_00000D_FORCE_VIP(1);
160 if (rdev->family == CHIP_R420) 163 if (rdev->family == CHIP_R420)
@@ -167,6 +170,8 @@ static int r420_startup(struct radeon_device *rdev)
167 int r; 170 int r;
168 171
169 r300_mc_program(rdev); 172 r300_mc_program(rdev);
173 /* Resume clock */
174 r420_clock_resume(rdev);
170 /* Initialize GART (initialize after TTM so we can allocate 175 /* Initialize GART (initialize after TTM so we can allocate
171 * memory through TTM but finalize after TTM) */ 176 * memory through TTM but finalize after TTM) */
172 if (rdev->flags & RADEON_IS_PCIE) { 177 if (rdev->flags & RADEON_IS_PCIE) {
@@ -267,7 +272,6 @@ int r420_init(struct radeon_device *rdev)
267{ 272{
268 int r; 273 int r;
269 274
270 rdev->new_init_path = true;
271 /* Initialize scratch registers */ 275 /* Initialize scratch registers */
272 radeon_scratch_init(rdev); 276 radeon_scratch_init(rdev);
273 /* Initialize surface registers */ 277 /* Initialize surface registers */
diff --git a/drivers/gpu/drm/radeon/r420d.h b/drivers/gpu/drm/radeon/r420d.h
index a48a7db1e2aa..fc78d31a0b4a 100644
--- a/drivers/gpu/drm/radeon/r420d.h
+++ b/drivers/gpu/drm/radeon/r420d.h
@@ -212,9 +212,9 @@
212#define S_00000D_FORCE_E2(x) (((x) & 0x1) << 20) 212#define S_00000D_FORCE_E2(x) (((x) & 0x1) << 20)
213#define G_00000D_FORCE_E2(x) (((x) >> 20) & 0x1) 213#define G_00000D_FORCE_E2(x) (((x) >> 20) & 0x1)
214#define C_00000D_FORCE_E2 0xFFEFFFFF 214#define C_00000D_FORCE_E2 0xFFEFFFFF
215#define S_00000D_FORCE_SE(x) (((x) & 0x1) << 21) 215#define S_00000D_FORCE_VAP(x) (((x) & 0x1) << 21)
216#define G_00000D_FORCE_SE(x) (((x) >> 21) & 0x1) 216#define G_00000D_FORCE_VAP(x) (((x) >> 21) & 0x1)
217#define C_00000D_FORCE_SE 0xFFDFFFFF 217#define C_00000D_FORCE_VAP 0xFFDFFFFF
218#define S_00000D_FORCE_IDCT(x) (((x) & 0x1) << 22) 218#define S_00000D_FORCE_IDCT(x) (((x) & 0x1) << 22)
219#define G_00000D_FORCE_IDCT(x) (((x) >> 22) & 0x1) 219#define G_00000D_FORCE_IDCT(x) (((x) >> 22) & 0x1)
220#define C_00000D_FORCE_IDCT 0xFFBFFFFF 220#define C_00000D_FORCE_IDCT 0xFFBFFFFF
@@ -224,24 +224,24 @@
224#define S_00000D_FORCE_RE(x) (((x) & 0x1) << 24) 224#define S_00000D_FORCE_RE(x) (((x) & 0x1) << 24)
225#define G_00000D_FORCE_RE(x) (((x) >> 24) & 0x1) 225#define G_00000D_FORCE_RE(x) (((x) >> 24) & 0x1)
226#define C_00000D_FORCE_RE 0xFEFFFFFF 226#define C_00000D_FORCE_RE 0xFEFFFFFF
227#define S_00000D_FORCE_PB(x) (((x) & 0x1) << 25) 227#define S_00000D_FORCE_SR(x) (((x) & 0x1) << 25)
228#define G_00000D_FORCE_PB(x) (((x) >> 25) & 0x1) 228#define G_00000D_FORCE_SR(x) (((x) >> 25) & 0x1)
229#define C_00000D_FORCE_PB 0xFDFFFFFF 229#define C_00000D_FORCE_SR 0xFDFFFFFF
230#define S_00000D_FORCE_PX(x) (((x) & 0x1) << 26) 230#define S_00000D_FORCE_PX(x) (((x) & 0x1) << 26)
231#define G_00000D_FORCE_PX(x) (((x) >> 26) & 0x1) 231#define G_00000D_FORCE_PX(x) (((x) >> 26) & 0x1)
232#define C_00000D_FORCE_PX 0xFBFFFFFF 232#define C_00000D_FORCE_PX 0xFBFFFFFF
233#define S_00000D_FORCE_TX(x) (((x) & 0x1) << 27) 233#define S_00000D_FORCE_TX(x) (((x) & 0x1) << 27)
234#define G_00000D_FORCE_TX(x) (((x) >> 27) & 0x1) 234#define G_00000D_FORCE_TX(x) (((x) >> 27) & 0x1)
235#define C_00000D_FORCE_TX 0xF7FFFFFF 235#define C_00000D_FORCE_TX 0xF7FFFFFF
236#define S_00000D_FORCE_RB(x) (((x) & 0x1) << 28) 236#define S_00000D_FORCE_US(x) (((x) & 0x1) << 28)
237#define G_00000D_FORCE_RB(x) (((x) >> 28) & 0x1) 237#define G_00000D_FORCE_US(x) (((x) >> 28) & 0x1)
238#define C_00000D_FORCE_RB 0xEFFFFFFF 238#define C_00000D_FORCE_US 0xEFFFFFFF
239#define S_00000D_FORCE_TV_SCLK(x) (((x) & 0x1) << 29) 239#define S_00000D_FORCE_TV_SCLK(x) (((x) & 0x1) << 29)
240#define G_00000D_FORCE_TV_SCLK(x) (((x) >> 29) & 0x1) 240#define G_00000D_FORCE_TV_SCLK(x) (((x) >> 29) & 0x1)
241#define C_00000D_FORCE_TV_SCLK 0xDFFFFFFF 241#define C_00000D_FORCE_TV_SCLK 0xDFFFFFFF
242#define S_00000D_FORCE_SUBPIC(x) (((x) & 0x1) << 30) 242#define S_00000D_FORCE_SU(x) (((x) & 0x1) << 30)
243#define G_00000D_FORCE_SUBPIC(x) (((x) >> 30) & 0x1) 243#define G_00000D_FORCE_SU(x) (((x) >> 30) & 0x1)
244#define C_00000D_FORCE_SUBPIC 0xBFFFFFFF 244#define C_00000D_FORCE_SU 0xBFFFFFFF
245#define S_00000D_FORCE_OV0(x) (((x) & 0x1) << 31) 245#define S_00000D_FORCE_OV0(x) (((x) & 0x1) << 31)
246#define G_00000D_FORCE_OV0(x) (((x) >> 31) & 0x1) 246#define G_00000D_FORCE_OV0(x) (((x) >> 31) & 0x1)
247#define C_00000D_FORCE_OV0 0x7FFFFFFF 247#define C_00000D_FORCE_OV0 0x7FFFFFFF
diff --git a/drivers/gpu/drm/radeon/r520.c b/drivers/gpu/drm/radeon/r520.c
index 0bf13fccdaf2..a555b7b19b48 100644
--- a/drivers/gpu/drm/radeon/r520.c
+++ b/drivers/gpu/drm/radeon/r520.c
@@ -186,7 +186,7 @@ static int r520_startup(struct radeon_device *rdev)
186 } 186 }
187 /* Enable IRQ */ 187 /* Enable IRQ */
188 rdev->irq.sw_int = true; 188 rdev->irq.sw_int = true;
189 r100_irq_set(rdev); 189 rs600_irq_set(rdev);
190 /* 1M ring buffer */ 190 /* 1M ring buffer */
191 r = r100_cp_init(rdev, 1024 * 1024); 191 r = r100_cp_init(rdev, 1024 * 1024);
192 if (r) { 192 if (r) {
@@ -228,7 +228,6 @@ int r520_init(struct radeon_device *rdev)
228{ 228{
229 int r; 229 int r;
230 230
231 rdev->new_init_path = true;
232 /* Initialize scratch registers */ 231 /* Initialize scratch registers */
233 radeon_scratch_init(rdev); 232 radeon_scratch_init(rdev);
234 /* Initialize surface registers */ 233 /* Initialize surface registers */
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 2e4e60edbff4..609719490ec2 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -65,16 +65,11 @@ MODULE_FIRMWARE("radeon/RV710_me.bin");
65 65
66int r600_debugfs_mc_info_init(struct radeon_device *rdev); 66int r600_debugfs_mc_info_init(struct radeon_device *rdev);
67 67
68/* This files gather functions specifics to: 68/* r600,rv610,rv630,rv620,rv635,rv670 */
69 * r600,rv610,rv630,rv620,rv635,rv670
70 *
71 * Some of these functions might be used by newer ASICs.
72 */
73int r600_mc_wait_for_idle(struct radeon_device *rdev); 69int r600_mc_wait_for_idle(struct radeon_device *rdev);
74void r600_gpu_init(struct radeon_device *rdev); 70void r600_gpu_init(struct radeon_device *rdev);
75void r600_fini(struct radeon_device *rdev); 71void r600_fini(struct radeon_device *rdev);
76 72
77
78/* 73/*
79 * R600 PCIE GART 74 * R600 PCIE GART
80 */ 75 */
@@ -168,7 +163,7 @@ int r600_pcie_gart_enable(struct radeon_device *rdev)
168 WREG32(MC_VM_L1_TLB_MCB_RD_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE); 163 WREG32(MC_VM_L1_TLB_MCB_RD_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE);
169 WREG32(MC_VM_L1_TLB_MCB_WR_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE); 164 WREG32(MC_VM_L1_TLB_MCB_WR_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE);
170 WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12); 165 WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
171 WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, (rdev->mc.gtt_end - 1) >> 12); 166 WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12);
172 WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12); 167 WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
173 WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) | 168 WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) |
174 RANGE_PROTECTION_FAULT_ENABLE_DEFAULT); 169 RANGE_PROTECTION_FAULT_ENABLE_DEFAULT);
@@ -225,6 +220,40 @@ void r600_pcie_gart_fini(struct radeon_device *rdev)
225 radeon_gart_fini(rdev); 220 radeon_gart_fini(rdev);
226} 221}
227 222
223void r600_agp_enable(struct radeon_device *rdev)
224{
225 u32 tmp;
226 int i;
227
228 /* Setup L2 cache */
229 WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING |
230 ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
231 EFFECTIVE_L2_QUEUE_SIZE(7));
232 WREG32(VM_L2_CNTL2, 0);
233 WREG32(VM_L2_CNTL3, BANK_SELECT_0(0) | BANK_SELECT_1(1));
234 /* Setup TLB control */
235 tmp = ENABLE_L1_TLB | ENABLE_L1_FRAGMENT_PROCESSING |
236 SYSTEM_ACCESS_MODE_NOT_IN_SYS |
237 EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5) |
238 ENABLE_WAIT_L2_QUERY;
239 WREG32(MC_VM_L1_TLB_MCB_RD_SYS_CNTL, tmp);
240 WREG32(MC_VM_L1_TLB_MCB_WR_SYS_CNTL, tmp);
241 WREG32(MC_VM_L1_TLB_MCB_RD_HDP_CNTL, tmp | ENABLE_L1_STRICT_ORDERING);
242 WREG32(MC_VM_L1_TLB_MCB_WR_HDP_CNTL, tmp);
243 WREG32(MC_VM_L1_TLB_MCD_RD_A_CNTL, tmp);
244 WREG32(MC_VM_L1_TLB_MCD_WR_A_CNTL, tmp);
245 WREG32(MC_VM_L1_TLB_MCD_RD_B_CNTL, tmp);
246 WREG32(MC_VM_L1_TLB_MCD_WR_B_CNTL, tmp);
247 WREG32(MC_VM_L1_TLB_MCB_RD_GFX_CNTL, tmp);
248 WREG32(MC_VM_L1_TLB_MCB_WR_GFX_CNTL, tmp);
249 WREG32(MC_VM_L1_TLB_MCB_RD_PDMA_CNTL, tmp);
250 WREG32(MC_VM_L1_TLB_MCB_WR_PDMA_CNTL, tmp);
251 WREG32(MC_VM_L1_TLB_MCB_RD_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE);
252 WREG32(MC_VM_L1_TLB_MCB_WR_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE);
253 for (i = 0; i < 7; i++)
254 WREG32(VM_CONTEXT0_CNTL + (i * 4), 0);
255}
256
228int r600_mc_wait_for_idle(struct radeon_device *rdev) 257int r600_mc_wait_for_idle(struct radeon_device *rdev)
229{ 258{
230 unsigned i; 259 unsigned i;
@@ -240,14 +269,9 @@ int r600_mc_wait_for_idle(struct radeon_device *rdev)
240 return -1; 269 return -1;
241} 270}
242 271
243static void r600_mc_resume(struct radeon_device *rdev) 272static void r600_mc_program(struct radeon_device *rdev)
244{ 273{
245 u32 d1vga_control, d2vga_control; 274 struct rv515_mc_save save;
246 u32 vga_render_control, vga_hdp_control;
247 u32 d1crtc_control, d2crtc_control;
248 u32 new_d1grph_primary, new_d1grph_secondary;
249 u32 new_d2grph_primary, new_d2grph_secondary;
250 u64 old_vram_start;
251 u32 tmp; 275 u32 tmp;
252 int i, j; 276 int i, j;
253 277
@@ -261,85 +285,51 @@ static void r600_mc_resume(struct radeon_device *rdev)
261 } 285 }
262 WREG32(HDP_REG_COHERENCY_FLUSH_CNTL, 0); 286 WREG32(HDP_REG_COHERENCY_FLUSH_CNTL, 0);
263 287
264 d1vga_control = RREG32(D1VGA_CONTROL); 288 rv515_mc_stop(rdev, &save);
265 d2vga_control = RREG32(D2VGA_CONTROL);
266 vga_render_control = RREG32(VGA_RENDER_CONTROL);
267 vga_hdp_control = RREG32(VGA_HDP_CONTROL);
268 d1crtc_control = RREG32(D1CRTC_CONTROL);
269 d2crtc_control = RREG32(D2CRTC_CONTROL);
270 old_vram_start = (u64)(RREG32(MC_VM_FB_LOCATION) & 0xFFFF) << 24;
271 new_d1grph_primary = RREG32(D1GRPH_PRIMARY_SURFACE_ADDRESS);
272 new_d1grph_secondary = RREG32(D1GRPH_SECONDARY_SURFACE_ADDRESS);
273 new_d1grph_primary += rdev->mc.vram_start - old_vram_start;
274 new_d1grph_secondary += rdev->mc.vram_start - old_vram_start;
275 new_d2grph_primary = RREG32(D2GRPH_PRIMARY_SURFACE_ADDRESS);
276 new_d2grph_secondary = RREG32(D2GRPH_SECONDARY_SURFACE_ADDRESS);
277 new_d2grph_primary += rdev->mc.vram_start - old_vram_start;
278 new_d2grph_secondary += rdev->mc.vram_start - old_vram_start;
279
280 /* Stop all video */
281 WREG32(D1VGA_CONTROL, 0);
282 WREG32(D2VGA_CONTROL, 0);
283 WREG32(VGA_RENDER_CONTROL, 0);
284 WREG32(D1CRTC_UPDATE_LOCK, 1);
285 WREG32(D2CRTC_UPDATE_LOCK, 1);
286 WREG32(D1CRTC_CONTROL, 0);
287 WREG32(D2CRTC_CONTROL, 0);
288 WREG32(D1CRTC_UPDATE_LOCK, 0);
289 WREG32(D2CRTC_UPDATE_LOCK, 0);
290
291 mdelay(1);
292 if (r600_mc_wait_for_idle(rdev)) { 289 if (r600_mc_wait_for_idle(rdev)) {
293 printk(KERN_WARNING "[drm] MC not idle !\n"); 290 dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
294 } 291 }
295 292 /* Lockout access through VGA aperture (doesn't exist before R600) */
296 /* Lockout access through VGA aperture*/
297 WREG32(VGA_HDP_CONTROL, VGA_MEMORY_DISABLE); 293 WREG32(VGA_HDP_CONTROL, VGA_MEMORY_DISABLE);
298
299 /* Update configuration */ 294 /* Update configuration */
300 WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.vram_start >> 12); 295 if (rdev->flags & RADEON_IS_AGP) {
301 WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, (rdev->mc.vram_end - 1) >> 12); 296 if (rdev->mc.vram_start < rdev->mc.gtt_start) {
297 /* VRAM before AGP */
298 WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR,
299 rdev->mc.vram_start >> 12);
300 WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR,
301 rdev->mc.gtt_end >> 12);
302 } else {
303 /* VRAM after AGP */
304 WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR,
305 rdev->mc.gtt_start >> 12);
306 WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR,
307 rdev->mc.vram_end >> 12);
308 }
309 } else {
310 WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.vram_start >> 12);
311 WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, rdev->mc.vram_end >> 12);
312 }
302 WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0); 313 WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0);
303 tmp = (((rdev->mc.vram_end - 1) >> 24) & 0xFFFF) << 16; 314 tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16;
304 tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF); 315 tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF);
305 WREG32(MC_VM_FB_LOCATION, tmp); 316 WREG32(MC_VM_FB_LOCATION, tmp);
306 WREG32(HDP_NONSURFACE_BASE, (rdev->mc.vram_start >> 8)); 317 WREG32(HDP_NONSURFACE_BASE, (rdev->mc.vram_start >> 8));
307 WREG32(HDP_NONSURFACE_INFO, (2 << 7)); 318 WREG32(HDP_NONSURFACE_INFO, (2 << 7));
308 WREG32(HDP_NONSURFACE_SIZE, (rdev->mc.mc_vram_size - 1) | 0x3FF); 319 WREG32(HDP_NONSURFACE_SIZE, rdev->mc.mc_vram_size | 0x3FF);
309 if (rdev->flags & RADEON_IS_AGP) { 320 if (rdev->flags & RADEON_IS_AGP) {
310 WREG32(MC_VM_AGP_TOP, (rdev->mc.gtt_end - 1) >> 16); 321 WREG32(MC_VM_AGP_TOP, rdev->mc.gtt_end >> 22);
311 WREG32(MC_VM_AGP_BOT, rdev->mc.gtt_start >> 16); 322 WREG32(MC_VM_AGP_BOT, rdev->mc.gtt_start >> 22);
312 WREG32(MC_VM_AGP_BASE, rdev->mc.agp_base >> 22); 323 WREG32(MC_VM_AGP_BASE, rdev->mc.agp_base >> 22);
313 } else { 324 } else {
314 WREG32(MC_VM_AGP_BASE, 0); 325 WREG32(MC_VM_AGP_BASE, 0);
315 WREG32(MC_VM_AGP_TOP, 0x0FFFFFFF); 326 WREG32(MC_VM_AGP_TOP, 0x0FFFFFFF);
316 WREG32(MC_VM_AGP_BOT, 0x0FFFFFFF); 327 WREG32(MC_VM_AGP_BOT, 0x0FFFFFFF);
317 } 328 }
318 WREG32(D1GRPH_PRIMARY_SURFACE_ADDRESS, new_d1grph_primary);
319 WREG32(D1GRPH_SECONDARY_SURFACE_ADDRESS, new_d1grph_secondary);
320 WREG32(D2GRPH_PRIMARY_SURFACE_ADDRESS, new_d2grph_primary);
321 WREG32(D2GRPH_SECONDARY_SURFACE_ADDRESS, new_d2grph_secondary);
322 WREG32(VGA_MEMORY_BASE_ADDRESS, rdev->mc.vram_start);
323
324 /* Unlock host access */
325 WREG32(VGA_HDP_CONTROL, vga_hdp_control);
326
327 mdelay(1);
328 if (r600_mc_wait_for_idle(rdev)) { 329 if (r600_mc_wait_for_idle(rdev)) {
329 printk(KERN_WARNING "[drm] MC not idle !\n"); 330 dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
330 } 331 }
331 332 rv515_mc_resume(rdev, &save);
332 /* Restore video state */
333 WREG32(D1CRTC_UPDATE_LOCK, 1);
334 WREG32(D2CRTC_UPDATE_LOCK, 1);
335 WREG32(D1CRTC_CONTROL, d1crtc_control);
336 WREG32(D2CRTC_CONTROL, d2crtc_control);
337 WREG32(D1CRTC_UPDATE_LOCK, 0);
338 WREG32(D2CRTC_UPDATE_LOCK, 0);
339 WREG32(D1VGA_CONTROL, d1vga_control);
340 WREG32(D2VGA_CONTROL, d2vga_control);
341 WREG32(VGA_RENDER_CONTROL, vga_render_control);
342
343 /* we need to own VRAM, so turn off the VGA renderer here 333 /* we need to own VRAM, so turn off the VGA renderer here
344 * to stop it overwriting our objects */ 334 * to stop it overwriting our objects */
345 rv515_vga_render_disable(rdev); 335 rv515_vga_render_disable(rdev);
@@ -445,9 +435,9 @@ int r600_mc_init(struct radeon_device *rdev)
445 } 435 }
446 } 436 }
447 rdev->mc.vram_start = rdev->mc.vram_location; 437 rdev->mc.vram_start = rdev->mc.vram_location;
448 rdev->mc.vram_end = rdev->mc.vram_location + rdev->mc.mc_vram_size; 438 rdev->mc.vram_end = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1;
449 rdev->mc.gtt_start = rdev->mc.gtt_location; 439 rdev->mc.gtt_start = rdev->mc.gtt_location;
450 rdev->mc.gtt_end = rdev->mc.gtt_location + rdev->mc.gtt_size; 440 rdev->mc.gtt_end = rdev->mc.gtt_location + rdev->mc.gtt_size - 1;
451 /* FIXME: we should enforce default clock in case GPU is not in 441 /* FIXME: we should enforce default clock in case GPU is not in
452 * default setup 442 * default setup
453 */ 443 */
@@ -463,6 +453,7 @@ int r600_mc_init(struct radeon_device *rdev)
463 */ 453 */
464int r600_gpu_soft_reset(struct radeon_device *rdev) 454int r600_gpu_soft_reset(struct radeon_device *rdev)
465{ 455{
456 struct rv515_mc_save save;
466 u32 grbm_busy_mask = S_008010_VC_BUSY(1) | S_008010_VGT_BUSY_NO_DMA(1) | 457 u32 grbm_busy_mask = S_008010_VC_BUSY(1) | S_008010_VGT_BUSY_NO_DMA(1) |
467 S_008010_VGT_BUSY(1) | S_008010_TA03_BUSY(1) | 458 S_008010_VGT_BUSY(1) | S_008010_TA03_BUSY(1) |
468 S_008010_TC_BUSY(1) | S_008010_SX_BUSY(1) | 459 S_008010_TC_BUSY(1) | S_008010_SX_BUSY(1) |
@@ -480,13 +471,25 @@ int r600_gpu_soft_reset(struct radeon_device *rdev)
480 S_008014_CB0_BUSY(1) | S_008014_CB1_BUSY(1) | 471 S_008014_CB0_BUSY(1) | S_008014_CB1_BUSY(1) |
481 S_008014_CB2_BUSY(1) | S_008014_CB3_BUSY(1); 472 S_008014_CB2_BUSY(1) | S_008014_CB3_BUSY(1);
482 u32 srbm_reset = 0; 473 u32 srbm_reset = 0;
474 u32 tmp;
483 475
476 dev_info(rdev->dev, "GPU softreset \n");
477 dev_info(rdev->dev, " R_008010_GRBM_STATUS=0x%08X\n",
478 RREG32(R_008010_GRBM_STATUS));
479 dev_info(rdev->dev, " R_008014_GRBM_STATUS2=0x%08X\n",
480 RREG32(R_008014_GRBM_STATUS2));
481 dev_info(rdev->dev, " R_000E50_SRBM_STATUS=0x%08X\n",
482 RREG32(R_000E50_SRBM_STATUS));
483 rv515_mc_stop(rdev, &save);
484 if (r600_mc_wait_for_idle(rdev)) {
485 dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
486 }
484 /* Disable CP parsing/prefetching */ 487 /* Disable CP parsing/prefetching */
485 WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(0xff)); 488 WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(0xff));
486 /* Check if any of the rendering block is busy and reset it */ 489 /* Check if any of the rendering block is busy and reset it */
487 if ((RREG32(R_008010_GRBM_STATUS) & grbm_busy_mask) || 490 if ((RREG32(R_008010_GRBM_STATUS) & grbm_busy_mask) ||
488 (RREG32(R_008014_GRBM_STATUS2) & grbm2_busy_mask)) { 491 (RREG32(R_008014_GRBM_STATUS2) & grbm2_busy_mask)) {
489 WREG32(R_008020_GRBM_SOFT_RESET, S_008020_SOFT_RESET_CR(1) | 492 tmp = S_008020_SOFT_RESET_CR(1) |
490 S_008020_SOFT_RESET_DB(1) | 493 S_008020_SOFT_RESET_DB(1) |
491 S_008020_SOFT_RESET_CB(1) | 494 S_008020_SOFT_RESET_CB(1) |
492 S_008020_SOFT_RESET_PA(1) | 495 S_008020_SOFT_RESET_PA(1) |
@@ -498,14 +501,18 @@ int r600_gpu_soft_reset(struct radeon_device *rdev)
498 S_008020_SOFT_RESET_TC(1) | 501 S_008020_SOFT_RESET_TC(1) |
499 S_008020_SOFT_RESET_TA(1) | 502 S_008020_SOFT_RESET_TA(1) |
500 S_008020_SOFT_RESET_VC(1) | 503 S_008020_SOFT_RESET_VC(1) |
501 S_008020_SOFT_RESET_VGT(1)); 504 S_008020_SOFT_RESET_VGT(1);
505 dev_info(rdev->dev, " R_008020_GRBM_SOFT_RESET=0x%08X\n", tmp);
506 WREG32(R_008020_GRBM_SOFT_RESET, tmp);
502 (void)RREG32(R_008020_GRBM_SOFT_RESET); 507 (void)RREG32(R_008020_GRBM_SOFT_RESET);
503 udelay(50); 508 udelay(50);
504 WREG32(R_008020_GRBM_SOFT_RESET, 0); 509 WREG32(R_008020_GRBM_SOFT_RESET, 0);
505 (void)RREG32(R_008020_GRBM_SOFT_RESET); 510 (void)RREG32(R_008020_GRBM_SOFT_RESET);
506 } 511 }
507 /* Reset CP (we always reset CP) */ 512 /* Reset CP (we always reset CP) */
508 WREG32(R_008020_GRBM_SOFT_RESET, S_008020_SOFT_RESET_CP(1)); 513 tmp = S_008020_SOFT_RESET_CP(1);
514 dev_info(rdev->dev, "R_008020_GRBM_SOFT_RESET=0x%08X\n", tmp);
515 WREG32(R_008020_GRBM_SOFT_RESET, tmp);
509 (void)RREG32(R_008020_GRBM_SOFT_RESET); 516 (void)RREG32(R_008020_GRBM_SOFT_RESET);
510 udelay(50); 517 udelay(50);
511 WREG32(R_008020_GRBM_SOFT_RESET, 0); 518 WREG32(R_008020_GRBM_SOFT_RESET, 0);
@@ -533,6 +540,14 @@ int r600_gpu_soft_reset(struct radeon_device *rdev)
533 srbm_reset |= S_000E60_SOFT_RESET_RLC(1); 540 srbm_reset |= S_000E60_SOFT_RESET_RLC(1);
534 if (G_000E50_SEM_BUSY(RREG32(R_000E50_SRBM_STATUS))) 541 if (G_000E50_SEM_BUSY(RREG32(R_000E50_SRBM_STATUS)))
535 srbm_reset |= S_000E60_SOFT_RESET_SEM(1); 542 srbm_reset |= S_000E60_SOFT_RESET_SEM(1);
543 if (G_000E50_BIF_BUSY(RREG32(R_000E50_SRBM_STATUS)))
544 srbm_reset |= S_000E60_SOFT_RESET_BIF(1);
545 dev_info(rdev->dev, " R_000E60_SRBM_SOFT_RESET=0x%08X\n", srbm_reset);
546 WREG32(R_000E60_SRBM_SOFT_RESET, srbm_reset);
547 (void)RREG32(R_000E60_SRBM_SOFT_RESET);
548 udelay(50);
549 WREG32(R_000E60_SRBM_SOFT_RESET, 0);
550 (void)RREG32(R_000E60_SRBM_SOFT_RESET);
536 WREG32(R_000E60_SRBM_SOFT_RESET, srbm_reset); 551 WREG32(R_000E60_SRBM_SOFT_RESET, srbm_reset);
537 (void)RREG32(R_000E60_SRBM_SOFT_RESET); 552 (void)RREG32(R_000E60_SRBM_SOFT_RESET);
538 udelay(50); 553 udelay(50);
@@ -540,6 +555,17 @@ int r600_gpu_soft_reset(struct radeon_device *rdev)
540 (void)RREG32(R_000E60_SRBM_SOFT_RESET); 555 (void)RREG32(R_000E60_SRBM_SOFT_RESET);
541 /* Wait a little for things to settle down */ 556 /* Wait a little for things to settle down */
542 udelay(50); 557 udelay(50);
558 dev_info(rdev->dev, " R_008010_GRBM_STATUS=0x%08X\n",
559 RREG32(R_008010_GRBM_STATUS));
560 dev_info(rdev->dev, " R_008014_GRBM_STATUS2=0x%08X\n",
561 RREG32(R_008014_GRBM_STATUS2));
562 dev_info(rdev->dev, " R_000E50_SRBM_STATUS=0x%08X\n",
563 RREG32(R_000E50_SRBM_STATUS));
564 /* After reset we need to reinit the asic as GPU often endup in an
565 * incoherent state.
566 */
567 atom_asic_init(rdev->mode_info.atom_context);
568 rv515_mc_resume(rdev, &save);
543 return 0; 569 return 0;
544} 570}
545 571
@@ -1350,32 +1376,47 @@ int r600_ring_test(struct radeon_device *rdev)
1350 return r; 1376 return r;
1351} 1377}
1352 1378
1353/* 1379void r600_wb_disable(struct radeon_device *rdev)
1354 * Writeback 1380{
1355 */ 1381 WREG32(SCRATCH_UMSK, 0);
1356int r600_wb_init(struct radeon_device *rdev) 1382 if (rdev->wb.wb_obj) {
1383 radeon_object_kunmap(rdev->wb.wb_obj);
1384 radeon_object_unpin(rdev->wb.wb_obj);
1385 }
1386}
1387
1388void r600_wb_fini(struct radeon_device *rdev)
1389{
1390 r600_wb_disable(rdev);
1391 if (rdev->wb.wb_obj) {
1392 radeon_object_unref(&rdev->wb.wb_obj);
1393 rdev->wb.wb = NULL;
1394 rdev->wb.wb_obj = NULL;
1395 }
1396}
1397
1398int r600_wb_enable(struct radeon_device *rdev)
1357{ 1399{
1358 int r; 1400 int r;
1359 1401
1360 if (rdev->wb.wb_obj == NULL) { 1402 if (rdev->wb.wb_obj == NULL) {
1361 r = radeon_object_create(rdev, NULL, 4096, 1403 r = radeon_object_create(rdev, NULL, 4096, true,
1362 true, 1404 RADEON_GEM_DOMAIN_GTT, false, &rdev->wb.wb_obj);
1363 RADEON_GEM_DOMAIN_GTT,
1364 false, &rdev->wb.wb_obj);
1365 if (r) { 1405 if (r) {
1366 DRM_ERROR("radeon: failed to create WB buffer (%d).\n", r); 1406 dev_warn(rdev->dev, "failed to create WB buffer (%d).\n", r);
1367 return r; 1407 return r;
1368 } 1408 }
1369 r = radeon_object_pin(rdev->wb.wb_obj, 1409 r = radeon_object_pin(rdev->wb.wb_obj, RADEON_GEM_DOMAIN_GTT,
1370 RADEON_GEM_DOMAIN_GTT, 1410 &rdev->wb.gpu_addr);
1371 &rdev->wb.gpu_addr);
1372 if (r) { 1411 if (r) {
1373 DRM_ERROR("radeon: failed to pin WB buffer (%d).\n", r); 1412 dev_warn(rdev->dev, "failed to pin WB buffer (%d).\n", r);
1413 r600_wb_fini(rdev);
1374 return r; 1414 return r;
1375 } 1415 }
1376 r = radeon_object_kmap(rdev->wb.wb_obj, (void **)&rdev->wb.wb); 1416 r = radeon_object_kmap(rdev->wb.wb_obj, (void **)&rdev->wb.wb);
1377 if (r) { 1417 if (r) {
1378 DRM_ERROR("radeon: failed to map WB buffer (%d).\n", r); 1418 dev_warn(rdev->dev, "failed to map WB buffer (%d).\n", r);
1419 r600_wb_fini(rdev);
1379 return r; 1420 return r;
1380 } 1421 }
1381 } 1422 }
@@ -1386,21 +1427,6 @@ int r600_wb_init(struct radeon_device *rdev)
1386 return 0; 1427 return 0;
1387} 1428}
1388 1429
1389void r600_wb_fini(struct radeon_device *rdev)
1390{
1391 if (rdev->wb.wb_obj) {
1392 radeon_object_kunmap(rdev->wb.wb_obj);
1393 radeon_object_unpin(rdev->wb.wb_obj);
1394 radeon_object_unref(&rdev->wb.wb_obj);
1395 rdev->wb.wb = NULL;
1396 rdev->wb.wb_obj = NULL;
1397 }
1398}
1399
1400
1401/*
1402 * CS
1403 */
1404void r600_fence_ring_emit(struct radeon_device *rdev, 1430void r600_fence_ring_emit(struct radeon_device *rdev,
1405 struct radeon_fence *fence) 1431 struct radeon_fence *fence)
1406{ 1432{
@@ -1477,11 +1503,14 @@ int r600_startup(struct radeon_device *rdev)
1477{ 1503{
1478 int r; 1504 int r;
1479 1505
1480 r600_gpu_reset(rdev); 1506 r600_mc_program(rdev);
1481 r600_mc_resume(rdev); 1507 if (rdev->flags & RADEON_IS_AGP) {
1482 r = r600_pcie_gart_enable(rdev); 1508 r600_agp_enable(rdev);
1483 if (r) 1509 } else {
1484 return r; 1510 r = r600_pcie_gart_enable(rdev);
1511 if (r)
1512 return r;
1513 }
1485 r600_gpu_init(rdev); 1514 r600_gpu_init(rdev);
1486 1515
1487 r = radeon_object_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM, 1516 r = radeon_object_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM,
@@ -1500,9 +1529,8 @@ int r600_startup(struct radeon_device *rdev)
1500 r = r600_cp_resume(rdev); 1529 r = r600_cp_resume(rdev);
1501 if (r) 1530 if (r)
1502 return r; 1531 return r;
1503 r = r600_wb_init(rdev); 1532 /* write back buffer are not vital so don't worry about failure */
1504 if (r) 1533 r600_wb_enable(rdev);
1505 return r;
1506 return 0; 1534 return 0;
1507} 1535}
1508 1536
@@ -1524,15 +1552,12 @@ int r600_resume(struct radeon_device *rdev)
1524{ 1552{
1525 int r; 1553 int r;
1526 1554
1527 if (radeon_gpu_reset(rdev)) { 1555 /* Do not reset GPU before posting, on r600 hw unlike on r500 hw,
1528 /* FIXME: what do we want to do here ? */ 1556 * posting will perform necessary task to bring back GPU into good
1529 } 1557 * shape.
1558 */
1530 /* post card */ 1559 /* post card */
1531 if (rdev->is_atom_bios) { 1560 atom_asic_init(rdev->mode_info.atom_context);
1532 atom_asic_init(rdev->mode_info.atom_context);
1533 } else {
1534 radeon_combios_asic_init(rdev->ddev);
1535 }
1536 /* Initialize clocks */ 1561 /* Initialize clocks */
1537 r = radeon_clocks_init(rdev); 1562 r = radeon_clocks_init(rdev);
1538 if (r) { 1563 if (r) {
@@ -1545,7 +1570,7 @@ int r600_resume(struct radeon_device *rdev)
1545 return r; 1570 return r;
1546 } 1571 }
1547 1572
1548 r = radeon_ib_test(rdev); 1573 r = r600_ib_test(rdev);
1549 if (r) { 1574 if (r) {
1550 DRM_ERROR("radeon: failled testing IB (%d).\n", r); 1575 DRM_ERROR("radeon: failled testing IB (%d).\n", r);
1551 return r; 1576 return r;
@@ -1553,13 +1578,12 @@ int r600_resume(struct radeon_device *rdev)
1553 return r; 1578 return r;
1554} 1579}
1555 1580
1556
1557int r600_suspend(struct radeon_device *rdev) 1581int r600_suspend(struct radeon_device *rdev)
1558{ 1582{
1559 /* FIXME: we should wait for ring to be empty */ 1583 /* FIXME: we should wait for ring to be empty */
1560 r600_cp_stop(rdev); 1584 r600_cp_stop(rdev);
1561 rdev->cp.ready = false; 1585 rdev->cp.ready = false;
1562 1586 r600_wb_disable(rdev);
1563 r600_pcie_gart_disable(rdev); 1587 r600_pcie_gart_disable(rdev);
1564 /* unpin shaders bo */ 1588 /* unpin shaders bo */
1565 radeon_object_unpin(rdev->r600_blit.shader_obj); 1589 radeon_object_unpin(rdev->r600_blit.shader_obj);
@@ -1576,7 +1600,6 @@ int r600_init(struct radeon_device *rdev)
1576{ 1600{
1577 int r; 1601 int r;
1578 1602
1579 rdev->new_init_path = true;
1580 r = radeon_dummy_page_init(rdev); 1603 r = radeon_dummy_page_init(rdev);
1581 if (r) 1604 if (r)
1582 return r; 1605 return r;
@@ -1593,8 +1616,10 @@ int r600_init(struct radeon_device *rdev)
1593 return -EINVAL; 1616 return -EINVAL;
1594 } 1617 }
1595 /* Must be an ATOMBIOS */ 1618 /* Must be an ATOMBIOS */
1596 if (!rdev->is_atom_bios) 1619 if (!rdev->is_atom_bios) {
1620 dev_err(rdev->dev, "Expecting atombios for R600 GPU\n");
1597 return -EINVAL; 1621 return -EINVAL;
1622 }
1598 r = radeon_atombios_init(rdev); 1623 r = radeon_atombios_init(rdev);
1599 if (r) 1624 if (r)
1600 return r; 1625 return r;
@@ -1616,15 +1641,8 @@ int r600_init(struct radeon_device *rdev)
1616 if (r) 1641 if (r)
1617 return r; 1642 return r;
1618 r = r600_mc_init(rdev); 1643 r = r600_mc_init(rdev);
1619 if (r) { 1644 if (r)
1620 if (rdev->flags & RADEON_IS_AGP) {
1621 /* Retry with disabling AGP */
1622 r600_fini(rdev);
1623 rdev->flags &= ~RADEON_IS_AGP;
1624 return r600_init(rdev);
1625 }
1626 return r; 1645 return r;
1627 }
1628 /* Memory manager */ 1646 /* Memory manager */
1629 r = radeon_object_init(rdev); 1647 r = radeon_object_init(rdev);
1630 if (r) 1648 if (r)
@@ -1653,12 +1671,10 @@ int r600_init(struct radeon_device *rdev)
1653 1671
1654 r = r600_startup(rdev); 1672 r = r600_startup(rdev);
1655 if (r) { 1673 if (r) {
1656 if (rdev->flags & RADEON_IS_AGP) { 1674 r600_suspend(rdev);
1657 /* Retry with disabling AGP */ 1675 r600_wb_fini(rdev);
1658 r600_fini(rdev); 1676 radeon_ring_fini(rdev);
1659 rdev->flags &= ~RADEON_IS_AGP; 1677 r600_pcie_gart_fini(rdev);
1660 return r600_init(rdev);
1661 }
1662 rdev->accel_working = false; 1678 rdev->accel_working = false;
1663 } 1679 }
1664 if (rdev->accel_working) { 1680 if (rdev->accel_working) {
@@ -1667,7 +1683,7 @@ int r600_init(struct radeon_device *rdev)
1667 DRM_ERROR("radeon: failled initializing IB pool (%d).\n", r); 1683 DRM_ERROR("radeon: failled initializing IB pool (%d).\n", r);
1668 rdev->accel_working = false; 1684 rdev->accel_working = false;
1669 } 1685 }
1670 r = radeon_ib_test(rdev); 1686 r = r600_ib_test(rdev);
1671 if (r) { 1687 if (r) {
1672 DRM_ERROR("radeon: failled testing IB (%d).\n", r); 1688 DRM_ERROR("radeon: failled testing IB (%d).\n", r);
1673 rdev->accel_working = false; 1689 rdev->accel_working = false;
@@ -1683,19 +1699,15 @@ void r600_fini(struct radeon_device *rdev)
1683 1699
1684 r600_blit_fini(rdev); 1700 r600_blit_fini(rdev);
1685 radeon_ring_fini(rdev); 1701 radeon_ring_fini(rdev);
1702 r600_wb_fini(rdev);
1686 r600_pcie_gart_fini(rdev); 1703 r600_pcie_gart_fini(rdev);
1687 radeon_gem_fini(rdev); 1704 radeon_gem_fini(rdev);
1688 radeon_fence_driver_fini(rdev); 1705 radeon_fence_driver_fini(rdev);
1689 radeon_clocks_fini(rdev); 1706 radeon_clocks_fini(rdev);
1690#if __OS_HAS_AGP
1691 if (rdev->flags & RADEON_IS_AGP) 1707 if (rdev->flags & RADEON_IS_AGP)
1692 radeon_agp_fini(rdev); 1708 radeon_agp_fini(rdev);
1693#endif
1694 radeon_object_fini(rdev); 1709 radeon_object_fini(rdev);
1695 if (rdev->is_atom_bios) 1710 radeon_atombios_fini(rdev);
1696 radeon_atombios_fini(rdev);
1697 else
1698 radeon_combios_fini(rdev);
1699 kfree(rdev->bios); 1711 kfree(rdev->bios);
1700 rdev->bios = NULL; 1712 rdev->bios = NULL;
1701 radeon_dummy_page_fini(rdev); 1713 radeon_dummy_page_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/r600_blit.c b/drivers/gpu/drm/radeon/r600_blit.c
index d988eece0187..dec501081608 100644
--- a/drivers/gpu/drm/radeon/r600_blit.c
+++ b/drivers/gpu/drm/radeon/r600_blit.c
@@ -582,8 +582,6 @@ r600_blit_copy(struct drm_device *dev,
582 u64 vb_addr; 582 u64 vb_addr;
583 u32 *vb; 583 u32 *vb;
584 584
585 vb = r600_nomm_get_vb_ptr(dev);
586
587 if ((size_bytes & 3) || (src_gpu_addr & 3) || (dst_gpu_addr & 3)) { 585 if ((size_bytes & 3) || (src_gpu_addr & 3) || (dst_gpu_addr & 3)) {
588 max_bytes = 8192; 586 max_bytes = 8192;
589 587
@@ -619,8 +617,8 @@ r600_blit_copy(struct drm_device *dev,
619 if (!dev_priv->blit_vb) 617 if (!dev_priv->blit_vb)
620 return; 618 return;
621 set_shaders(dev); 619 set_shaders(dev);
622 vb = r600_nomm_get_vb_ptr(dev);
623 } 620 }
621 vb = r600_nomm_get_vb_ptr(dev);
624 622
625 vb[0] = i2f(dst_x); 623 vb[0] = i2f(dst_x);
626 vb[1] = 0; 624 vb[1] = 0;
@@ -708,8 +706,8 @@ r600_blit_copy(struct drm_device *dev,
708 return; 706 return;
709 707
710 set_shaders(dev); 708 set_shaders(dev);
711 vb = r600_nomm_get_vb_ptr(dev);
712 } 709 }
710 vb = r600_nomm_get_vb_ptr(dev);
713 711
714 vb[0] = i2f(dst_x / 4); 712 vb[0] = i2f(dst_x / 4);
715 vb[1] = 0; 713 vb[1] = 0;
@@ -777,8 +775,6 @@ r600_blit_swap(struct drm_device *dev,
777 u64 vb_addr; 775 u64 vb_addr;
778 u32 *vb; 776 u32 *vb;
779 777
780 vb = r600_nomm_get_vb_ptr(dev);
781
782 if ((dev_priv->blit_vb->used + 48) > dev_priv->blit_vb->total) { 778 if ((dev_priv->blit_vb->used + 48) > dev_priv->blit_vb->total) {
783 779
784 r600_nomm_put_vb(dev); 780 r600_nomm_put_vb(dev);
@@ -787,8 +783,8 @@ r600_blit_swap(struct drm_device *dev,
787 return; 783 return;
788 784
789 set_shaders(dev); 785 set_shaders(dev);
790 vb = r600_nomm_get_vb_ptr(dev);
791 } 786 }
787 vb = r600_nomm_get_vb_ptr(dev);
792 788
793 if (cpp == 4) { 789 if (cpp == 4) {
794 cb_format = COLOR_8_8_8_8; 790 cb_format = COLOR_8_8_8_8;
diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c
index acae33e2ad51..93108bb31d1d 100644
--- a/drivers/gpu/drm/radeon/r600_blit_kms.c
+++ b/drivers/gpu/drm/radeon/r600_blit_kms.c
@@ -610,7 +610,6 @@ void r600_kms_blit_copy(struct radeon_device *rdev,
610 610
611 DRM_DEBUG("emitting copy %16llx %16llx %d %d\n", src_gpu_addr, dst_gpu_addr, 611 DRM_DEBUG("emitting copy %16llx %16llx %d %d\n", src_gpu_addr, dst_gpu_addr,
612 size_bytes, rdev->r600_blit.vb_used); 612 size_bytes, rdev->r600_blit.vb_used);
613 vb = (u32 *)(rdev->r600_blit.vb_ib->ptr + rdev->r600_blit.vb_used);
614 if ((size_bytes & 3) || (src_gpu_addr & 3) || (dst_gpu_addr & 3)) { 613 if ((size_bytes & 3) || (src_gpu_addr & 3) || (dst_gpu_addr & 3)) {
615 max_bytes = 8192; 614 max_bytes = 8192;
616 615
@@ -653,6 +652,7 @@ void r600_kms_blit_copy(struct radeon_device *rdev,
653 vb = r600_nomm_get_vb_ptr(dev); 652 vb = r600_nomm_get_vb_ptr(dev);
654#endif 653#endif
655 } 654 }
655 vb = (u32 *)(rdev->r600_blit.vb_ib->ptr + rdev->r600_blit.vb_used);
656 656
657 vb[0] = i2f(dst_x); 657 vb[0] = i2f(dst_x);
658 vb[1] = 0; 658 vb[1] = 0;
@@ -747,6 +747,7 @@ void r600_kms_blit_copy(struct radeon_device *rdev,
747 vb = r600_nomm_get_vb_ptr(dev); 747 vb = r600_nomm_get_vb_ptr(dev);
748 } 748 }
749#endif 749#endif
750 vb = (u32 *)(rdev->r600_blit.vb_ib->ptr + rdev->r600_blit.vb_used);
750 751
751 vb[0] = i2f(dst_x / 4); 752 vb[0] = i2f(dst_x / 4);
752 vb[1] = 0; 753 vb[1] = 0;
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c
index d28970db6a2d..17e42195c632 100644
--- a/drivers/gpu/drm/radeon/r600_cs.c
+++ b/drivers/gpu/drm/radeon/r600_cs.c
@@ -252,7 +252,7 @@ static int r600_cs_packet_parse_vline(struct radeon_cs_parser *p)
252 252
253 header = radeon_get_ib_value(p, h_idx); 253 header = radeon_get_ib_value(p, h_idx);
254 crtc_id = radeon_get_ib_value(p, h_idx + 2 + 7 + 1); 254 crtc_id = radeon_get_ib_value(p, h_idx + 2 + 7 + 1);
255 reg = header >> 2; 255 reg = CP_PACKET0_GET_REG(header);
256 mutex_lock(&p->rdev->ddev->mode_config.mutex); 256 mutex_lock(&p->rdev->ddev->mode_config.mutex);
257 obj = drm_mode_object_find(p->rdev->ddev, crtc_id, DRM_MODE_OBJECT_CRTC); 257 obj = drm_mode_object_find(p->rdev->ddev, crtc_id, DRM_MODE_OBJECT_CRTC);
258 if (!obj) { 258 if (!obj) {
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h
index 4a9028a85c9b..9b64d47f1f82 100644
--- a/drivers/gpu/drm/radeon/r600d.h
+++ b/drivers/gpu/drm/radeon/r600d.h
@@ -643,6 +643,7 @@
643#define G_000E50_MCDW_BUSY(x) (((x) >> 13) & 1) 643#define G_000E50_MCDW_BUSY(x) (((x) >> 13) & 1)
644#define G_000E50_SEM_BUSY(x) (((x) >> 14) & 1) 644#define G_000E50_SEM_BUSY(x) (((x) >> 14) & 1)
645#define G_000E50_RLC_BUSY(x) (((x) >> 15) & 1) 645#define G_000E50_RLC_BUSY(x) (((x) >> 15) & 1)
646#define G_000E50_BIF_BUSY(x) (((x) >> 29) & 1)
646#define R_000E60_SRBM_SOFT_RESET 0x0E60 647#define R_000E60_SRBM_SOFT_RESET 0x0E60
647#define S_000E60_SOFT_RESET_BIF(x) (((x) & 1) << 1) 648#define S_000E60_SOFT_RESET_BIF(x) (((x) & 1) << 1)
648#define S_000E60_SOFT_RESET_CG(x) (((x) & 1) << 2) 649#define S_000E60_SOFT_RESET_CG(x) (((x) & 1) << 2)
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 950b346e343f..5ab35b81c86b 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -590,18 +590,8 @@ struct radeon_asic {
590 void (*fini)(struct radeon_device *rdev); 590 void (*fini)(struct radeon_device *rdev);
591 int (*resume)(struct radeon_device *rdev); 591 int (*resume)(struct radeon_device *rdev);
592 int (*suspend)(struct radeon_device *rdev); 592 int (*suspend)(struct radeon_device *rdev);
593 void (*errata)(struct radeon_device *rdev);
594 void (*vram_info)(struct radeon_device *rdev);
595 void (*vga_set_state)(struct radeon_device *rdev, bool state); 593 void (*vga_set_state)(struct radeon_device *rdev, bool state);
596 int (*gpu_reset)(struct radeon_device *rdev); 594 int (*gpu_reset)(struct radeon_device *rdev);
597 int (*mc_init)(struct radeon_device *rdev);
598 void (*mc_fini)(struct radeon_device *rdev);
599 int (*wb_init)(struct radeon_device *rdev);
600 void (*wb_fini)(struct radeon_device *rdev);
601 int (*gart_init)(struct radeon_device *rdev);
602 void (*gart_fini)(struct radeon_device *rdev);
603 int (*gart_enable)(struct radeon_device *rdev);
604 void (*gart_disable)(struct radeon_device *rdev);
605 void (*gart_tlb_flush)(struct radeon_device *rdev); 595 void (*gart_tlb_flush)(struct radeon_device *rdev);
606 int (*gart_set_page)(struct radeon_device *rdev, int i, uint64_t addr); 596 int (*gart_set_page)(struct radeon_device *rdev, int i, uint64_t addr);
607 int (*cp_init)(struct radeon_device *rdev, unsigned ring_size); 597 int (*cp_init)(struct radeon_device *rdev, unsigned ring_size);
@@ -611,7 +601,6 @@ struct radeon_asic {
611 void (*ring_start)(struct radeon_device *rdev); 601 void (*ring_start)(struct radeon_device *rdev);
612 int (*ring_test)(struct radeon_device *rdev); 602 int (*ring_test)(struct radeon_device *rdev);
613 void (*ring_ib_execute)(struct radeon_device *rdev, struct radeon_ib *ib); 603 void (*ring_ib_execute)(struct radeon_device *rdev, struct radeon_ib *ib);
614 int (*ib_test)(struct radeon_device *rdev);
615 int (*irq_set)(struct radeon_device *rdev); 604 int (*irq_set)(struct radeon_device *rdev);
616 int (*irq_process)(struct radeon_device *rdev); 605 int (*irq_process)(struct radeon_device *rdev);
617 u32 (*get_vblank_counter)(struct radeon_device *rdev, int crtc); 606 u32 (*get_vblank_counter)(struct radeon_device *rdev, int crtc);
@@ -789,7 +778,6 @@ struct radeon_device {
789 bool shutdown; 778 bool shutdown;
790 bool suspend; 779 bool suspend;
791 bool need_dma32; 780 bool need_dma32;
792 bool new_init_path;
793 bool accel_working; 781 bool accel_working;
794 struct radeon_surface_reg surface_regs[RADEON_GEM_MAX_SURFACES]; 782 struct radeon_surface_reg surface_regs[RADEON_GEM_MAX_SURFACES];
795 const struct firmware *me_fw; /* all family ME firmware */ 783 const struct firmware *me_fw; /* all family ME firmware */
@@ -949,28 +937,14 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v)
949#define radeon_resume(rdev) (rdev)->asic->resume((rdev)) 937#define radeon_resume(rdev) (rdev)->asic->resume((rdev))
950#define radeon_suspend(rdev) (rdev)->asic->suspend((rdev)) 938#define radeon_suspend(rdev) (rdev)->asic->suspend((rdev))
951#define radeon_cs_parse(p) rdev->asic->cs_parse((p)) 939#define radeon_cs_parse(p) rdev->asic->cs_parse((p))
952#define radeon_errata(rdev) (rdev)->asic->errata((rdev))
953#define radeon_vram_info(rdev) (rdev)->asic->vram_info((rdev))
954#define radeon_vga_set_state(rdev, state) (rdev)->asic->vga_set_state((rdev), (state)) 940#define radeon_vga_set_state(rdev, state) (rdev)->asic->vga_set_state((rdev), (state))
955#define radeon_gpu_reset(rdev) (rdev)->asic->gpu_reset((rdev)) 941#define radeon_gpu_reset(rdev) (rdev)->asic->gpu_reset((rdev))
956#define radeon_mc_init(rdev) (rdev)->asic->mc_init((rdev))
957#define radeon_mc_fini(rdev) (rdev)->asic->mc_fini((rdev))
958#define radeon_wb_init(rdev) (rdev)->asic->wb_init((rdev))
959#define radeon_wb_fini(rdev) (rdev)->asic->wb_fini((rdev))
960#define radeon_gpu_gart_init(rdev) (rdev)->asic->gart_init((rdev))
961#define radeon_gpu_gart_fini(rdev) (rdev)->asic->gart_fini((rdev))
962#define radeon_gart_enable(rdev) (rdev)->asic->gart_enable((rdev))
963#define radeon_gart_disable(rdev) (rdev)->asic->gart_disable((rdev))
964#define radeon_gart_tlb_flush(rdev) (rdev)->asic->gart_tlb_flush((rdev)) 942#define radeon_gart_tlb_flush(rdev) (rdev)->asic->gart_tlb_flush((rdev))
965#define radeon_gart_set_page(rdev, i, p) (rdev)->asic->gart_set_page((rdev), (i), (p)) 943#define radeon_gart_set_page(rdev, i, p) (rdev)->asic->gart_set_page((rdev), (i), (p))
966#define radeon_cp_init(rdev,rsize) (rdev)->asic->cp_init((rdev), (rsize))
967#define radeon_cp_fini(rdev) (rdev)->asic->cp_fini((rdev))
968#define radeon_cp_disable(rdev) (rdev)->asic->cp_disable((rdev))
969#define radeon_cp_commit(rdev) (rdev)->asic->cp_commit((rdev)) 944#define radeon_cp_commit(rdev) (rdev)->asic->cp_commit((rdev))
970#define radeon_ring_start(rdev) (rdev)->asic->ring_start((rdev)) 945#define radeon_ring_start(rdev) (rdev)->asic->ring_start((rdev))
971#define radeon_ring_test(rdev) (rdev)->asic->ring_test((rdev)) 946#define radeon_ring_test(rdev) (rdev)->asic->ring_test((rdev))
972#define radeon_ring_ib_execute(rdev, ib) (rdev)->asic->ring_ib_execute((rdev), (ib)) 947#define radeon_ring_ib_execute(rdev, ib) (rdev)->asic->ring_ib_execute((rdev), (ib))
973#define radeon_ib_test(rdev) (rdev)->asic->ib_test((rdev))
974#define radeon_irq_set(rdev) (rdev)->asic->irq_set((rdev)) 948#define radeon_irq_set(rdev) (rdev)->asic->irq_set((rdev))
975#define radeon_irq_process(rdev) (rdev)->asic->irq_process((rdev)) 949#define radeon_irq_process(rdev) (rdev)->asic->irq_process((rdev))
976#define radeon_get_vblank_counter(rdev, crtc) (rdev)->asic->get_vblank_counter((rdev), (crtc)) 950#define radeon_get_vblank_counter(rdev, crtc) (rdev)->asic->get_vblank_counter((rdev), (crtc))
@@ -996,6 +970,7 @@ extern void radeon_clocks_fini(struct radeon_device *rdev);
996extern void radeon_scratch_init(struct radeon_device *rdev); 970extern void radeon_scratch_init(struct radeon_device *rdev);
997extern void radeon_surface_init(struct radeon_device *rdev); 971extern void radeon_surface_init(struct radeon_device *rdev);
998extern int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data); 972extern int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data);
973extern void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable);
999extern void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable); 974extern void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable);
1000 975
1001/* r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 */ 976/* r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 */
@@ -1031,11 +1006,27 @@ extern int r100_wb_init(struct radeon_device *rdev);
1031extern void r100_hdp_reset(struct radeon_device *rdev); 1006extern void r100_hdp_reset(struct radeon_device *rdev);
1032extern int r100_rb2d_reset(struct radeon_device *rdev); 1007extern int r100_rb2d_reset(struct radeon_device *rdev);
1033extern int r100_cp_reset(struct radeon_device *rdev); 1008extern int r100_cp_reset(struct radeon_device *rdev);
1009extern void r100_vga_render_disable(struct radeon_device *rdev);
1010extern int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p,
1011 struct radeon_cs_packet *pkt,
1012 struct radeon_object *robj);
1013extern int r100_cs_parse_packet0(struct radeon_cs_parser *p,
1014 struct radeon_cs_packet *pkt,
1015 const unsigned *auth, unsigned n,
1016 radeon_packet0_check_t check);
1017extern int r100_cs_packet_parse(struct radeon_cs_parser *p,
1018 struct radeon_cs_packet *pkt,
1019 unsigned idx);
1020
1021/* rv200,rv250,rv280 */
1022extern void r200_set_safe_registers(struct radeon_device *rdev);
1034 1023
1035/* r300,r350,rv350,rv370,rv380 */ 1024/* r300,r350,rv350,rv370,rv380 */
1036extern void r300_set_reg_safe(struct radeon_device *rdev); 1025extern void r300_set_reg_safe(struct radeon_device *rdev);
1037extern void r300_mc_program(struct radeon_device *rdev); 1026extern void r300_mc_program(struct radeon_device *rdev);
1038extern void r300_vram_info(struct radeon_device *rdev); 1027extern void r300_vram_info(struct radeon_device *rdev);
1028extern void r300_clock_startup(struct radeon_device *rdev);
1029extern int r300_mc_wait_for_idle(struct radeon_device *rdev);
1039extern int rv370_pcie_gart_init(struct radeon_device *rdev); 1030extern int rv370_pcie_gart_init(struct radeon_device *rdev);
1040extern void rv370_pcie_gart_fini(struct radeon_device *rdev); 1031extern void rv370_pcie_gart_fini(struct radeon_device *rdev);
1041extern int rv370_pcie_gart_enable(struct radeon_device *rdev); 1032extern int rv370_pcie_gart_enable(struct radeon_device *rdev);
@@ -1066,6 +1057,18 @@ extern void rv515_clock_startup(struct radeon_device *rdev);
1066extern void rv515_debugfs(struct radeon_device *rdev); 1057extern void rv515_debugfs(struct radeon_device *rdev);
1067extern int rv515_suspend(struct radeon_device *rdev); 1058extern int rv515_suspend(struct radeon_device *rdev);
1068 1059
1060/* rs400 */
1061extern int rs400_gart_init(struct radeon_device *rdev);
1062extern int rs400_gart_enable(struct radeon_device *rdev);
1063extern void rs400_gart_adjust_size(struct radeon_device *rdev);
1064extern void rs400_gart_disable(struct radeon_device *rdev);
1065extern void rs400_gart_fini(struct radeon_device *rdev);
1066
1067/* rs600 */
1068extern void rs600_set_safe_registers(struct radeon_device *rdev);
1069extern int rs600_irq_set(struct radeon_device *rdev);
1070extern void rs600_irq_disable(struct radeon_device *rdev);
1071
1069/* rs690, rs740 */ 1072/* rs690, rs740 */
1070extern void rs690_line_buffer_adjust(struct radeon_device *rdev, 1073extern void rs690_line_buffer_adjust(struct radeon_device *rdev,
1071 struct drm_display_mode *mode1, 1074 struct drm_display_mode *mode1,
@@ -1083,8 +1086,9 @@ extern int r600_pcie_gart_init(struct radeon_device *rdev);
1083extern void r600_pcie_gart_tlb_flush(struct radeon_device *rdev); 1086extern void r600_pcie_gart_tlb_flush(struct radeon_device *rdev);
1084extern int r600_ib_test(struct radeon_device *rdev); 1087extern int r600_ib_test(struct radeon_device *rdev);
1085extern int r600_ring_test(struct radeon_device *rdev); 1088extern int r600_ring_test(struct radeon_device *rdev);
1086extern int r600_wb_init(struct radeon_device *rdev);
1087extern void r600_wb_fini(struct radeon_device *rdev); 1089extern void r600_wb_fini(struct radeon_device *rdev);
1090extern int r600_wb_enable(struct radeon_device *rdev);
1091extern void r600_wb_disable(struct radeon_device *rdev);
1088extern void r600_scratch_init(struct radeon_device *rdev); 1092extern void r600_scratch_init(struct radeon_device *rdev);
1089extern int r600_blit_init(struct radeon_device *rdev); 1093extern int r600_blit_init(struct radeon_device *rdev);
1090extern void r600_blit_fini(struct radeon_device *rdev); 1094extern void r600_blit_fini(struct radeon_device *rdev);
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
index c8a4e7b5663d..c3532c7a6f3f 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -41,28 +41,17 @@ void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable);
41/* 41/*
42 * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 42 * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280
43 */ 43 */
44int r100_init(struct radeon_device *rdev); 44extern int r100_init(struct radeon_device *rdev);
45int r200_init(struct radeon_device *rdev); 45extern void r100_fini(struct radeon_device *rdev);
46extern int r100_suspend(struct radeon_device *rdev);
47extern int r100_resume(struct radeon_device *rdev);
46uint32_t r100_mm_rreg(struct radeon_device *rdev, uint32_t reg); 48uint32_t r100_mm_rreg(struct radeon_device *rdev, uint32_t reg);
47void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); 49void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
48void r100_errata(struct radeon_device *rdev);
49void r100_vram_info(struct radeon_device *rdev);
50void r100_vga_set_state(struct radeon_device *rdev, bool state); 50void r100_vga_set_state(struct radeon_device *rdev, bool state);
51int r100_gpu_reset(struct radeon_device *rdev); 51int r100_gpu_reset(struct radeon_device *rdev);
52int r100_mc_init(struct radeon_device *rdev);
53void r100_mc_fini(struct radeon_device *rdev);
54u32 r100_get_vblank_counter(struct radeon_device *rdev, int crtc); 52u32 r100_get_vblank_counter(struct radeon_device *rdev, int crtc);
55int r100_wb_init(struct radeon_device *rdev);
56void r100_wb_fini(struct radeon_device *rdev);
57int r100_pci_gart_init(struct radeon_device *rdev);
58void r100_pci_gart_fini(struct radeon_device *rdev);
59int r100_pci_gart_enable(struct radeon_device *rdev);
60void r100_pci_gart_disable(struct radeon_device *rdev);
61void r100_pci_gart_tlb_flush(struct radeon_device *rdev); 53void r100_pci_gart_tlb_flush(struct radeon_device *rdev);
62int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr); 54int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr);
63int r100_cp_init(struct radeon_device *rdev, unsigned ring_size);
64void r100_cp_fini(struct radeon_device *rdev);
65void r100_cp_disable(struct radeon_device *rdev);
66void r100_cp_commit(struct radeon_device *rdev); 55void r100_cp_commit(struct radeon_device *rdev);
67void r100_ring_start(struct radeon_device *rdev); 56void r100_ring_start(struct radeon_device *rdev);
68int r100_irq_set(struct radeon_device *rdev); 57int r100_irq_set(struct radeon_device *rdev);
@@ -83,33 +72,21 @@ int r100_set_surface_reg(struct radeon_device *rdev, int reg,
83int r100_clear_surface_reg(struct radeon_device *rdev, int reg); 72int r100_clear_surface_reg(struct radeon_device *rdev, int reg);
84void r100_bandwidth_update(struct radeon_device *rdev); 73void r100_bandwidth_update(struct radeon_device *rdev);
85void r100_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); 74void r100_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
86int r100_ib_test(struct radeon_device *rdev);
87int r100_ring_test(struct radeon_device *rdev); 75int r100_ring_test(struct radeon_device *rdev);
88 76
89static struct radeon_asic r100_asic = { 77static struct radeon_asic r100_asic = {
90 .init = &r100_init, 78 .init = &r100_init,
91 .errata = &r100_errata, 79 .fini = &r100_fini,
92 .vram_info = &r100_vram_info, 80 .suspend = &r100_suspend,
81 .resume = &r100_resume,
93 .vga_set_state = &r100_vga_set_state, 82 .vga_set_state = &r100_vga_set_state,
94 .gpu_reset = &r100_gpu_reset, 83 .gpu_reset = &r100_gpu_reset,
95 .mc_init = &r100_mc_init,
96 .mc_fini = &r100_mc_fini,
97 .wb_init = &r100_wb_init,
98 .wb_fini = &r100_wb_fini,
99 .gart_init = &r100_pci_gart_init,
100 .gart_fini = &r100_pci_gart_fini,
101 .gart_enable = &r100_pci_gart_enable,
102 .gart_disable = &r100_pci_gart_disable,
103 .gart_tlb_flush = &r100_pci_gart_tlb_flush, 84 .gart_tlb_flush = &r100_pci_gart_tlb_flush,
104 .gart_set_page = &r100_pci_gart_set_page, 85 .gart_set_page = &r100_pci_gart_set_page,
105 .cp_init = &r100_cp_init,
106 .cp_fini = &r100_cp_fini,
107 .cp_disable = &r100_cp_disable,
108 .cp_commit = &r100_cp_commit, 86 .cp_commit = &r100_cp_commit,
109 .ring_start = &r100_ring_start, 87 .ring_start = &r100_ring_start,
110 .ring_test = &r100_ring_test, 88 .ring_test = &r100_ring_test,
111 .ring_ib_execute = &r100_ring_ib_execute, 89 .ring_ib_execute = &r100_ring_ib_execute,
112 .ib_test = &r100_ib_test,
113 .irq_set = &r100_irq_set, 90 .irq_set = &r100_irq_set,
114 .irq_process = &r100_irq_process, 91 .irq_process = &r100_irq_process,
115 .get_vblank_counter = &r100_get_vblank_counter, 92 .get_vblank_counter = &r100_get_vblank_counter,
@@ -131,55 +108,38 @@ static struct radeon_asic r100_asic = {
131/* 108/*
132 * r300,r350,rv350,rv380 109 * r300,r350,rv350,rv380
133 */ 110 */
134int r300_init(struct radeon_device *rdev); 111extern int r300_init(struct radeon_device *rdev);
135void r300_errata(struct radeon_device *rdev); 112extern void r300_fini(struct radeon_device *rdev);
136void r300_vram_info(struct radeon_device *rdev); 113extern int r300_suspend(struct radeon_device *rdev);
137int r300_gpu_reset(struct radeon_device *rdev); 114extern int r300_resume(struct radeon_device *rdev);
138int r300_mc_init(struct radeon_device *rdev); 115extern int r300_gpu_reset(struct radeon_device *rdev);
139void r300_mc_fini(struct radeon_device *rdev); 116extern void r300_ring_start(struct radeon_device *rdev);
140void r300_ring_start(struct radeon_device *rdev); 117extern void r300_fence_ring_emit(struct radeon_device *rdev,
141void r300_fence_ring_emit(struct radeon_device *rdev, 118 struct radeon_fence *fence);
142 struct radeon_fence *fence); 119extern int r300_cs_parse(struct radeon_cs_parser *p);
143int r300_cs_parse(struct radeon_cs_parser *p); 120extern void rv370_pcie_gart_tlb_flush(struct radeon_device *rdev);
144int rv370_pcie_gart_init(struct radeon_device *rdev); 121extern int rv370_pcie_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr);
145void rv370_pcie_gart_fini(struct radeon_device *rdev); 122extern uint32_t rv370_pcie_rreg(struct radeon_device *rdev, uint32_t reg);
146int rv370_pcie_gart_enable(struct radeon_device *rdev); 123extern void rv370_pcie_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
147void rv370_pcie_gart_disable(struct radeon_device *rdev); 124extern void rv370_set_pcie_lanes(struct radeon_device *rdev, int lanes);
148void rv370_pcie_gart_tlb_flush(struct radeon_device *rdev); 125extern int r300_copy_dma(struct radeon_device *rdev,
149int rv370_pcie_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr); 126 uint64_t src_offset,
150uint32_t rv370_pcie_rreg(struct radeon_device *rdev, uint32_t reg); 127 uint64_t dst_offset,
151void rv370_pcie_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); 128 unsigned num_pages,
152void rv370_set_pcie_lanes(struct radeon_device *rdev, int lanes); 129 struct radeon_fence *fence);
153int r300_copy_dma(struct radeon_device *rdev,
154 uint64_t src_offset,
155 uint64_t dst_offset,
156 unsigned num_pages,
157 struct radeon_fence *fence);
158
159static struct radeon_asic r300_asic = { 130static struct radeon_asic r300_asic = {
160 .init = &r300_init, 131 .init = &r300_init,
161 .errata = &r300_errata, 132 .fini = &r300_fini,
162 .vram_info = &r300_vram_info, 133 .suspend = &r300_suspend,
134 .resume = &r300_resume,
163 .vga_set_state = &r100_vga_set_state, 135 .vga_set_state = &r100_vga_set_state,
164 .gpu_reset = &r300_gpu_reset, 136 .gpu_reset = &r300_gpu_reset,
165 .mc_init = &r300_mc_init,
166 .mc_fini = &r300_mc_fini,
167 .wb_init = &r100_wb_init,
168 .wb_fini = &r100_wb_fini,
169 .gart_init = &r100_pci_gart_init,
170 .gart_fini = &r100_pci_gart_fini,
171 .gart_enable = &r100_pci_gart_enable,
172 .gart_disable = &r100_pci_gart_disable,
173 .gart_tlb_flush = &r100_pci_gart_tlb_flush, 137 .gart_tlb_flush = &r100_pci_gart_tlb_flush,
174 .gart_set_page = &r100_pci_gart_set_page, 138 .gart_set_page = &r100_pci_gart_set_page,
175 .cp_init = &r100_cp_init,
176 .cp_fini = &r100_cp_fini,
177 .cp_disable = &r100_cp_disable,
178 .cp_commit = &r100_cp_commit, 139 .cp_commit = &r100_cp_commit,
179 .ring_start = &r300_ring_start, 140 .ring_start = &r300_ring_start,
180 .ring_test = &r100_ring_test, 141 .ring_test = &r100_ring_test,
181 .ring_ib_execute = &r100_ring_ib_execute, 142 .ring_ib_execute = &r100_ring_ib_execute,
182 .ib_test = &r100_ib_test,
183 .irq_set = &r100_irq_set, 143 .irq_set = &r100_irq_set,
184 .irq_process = &r100_irq_process, 144 .irq_process = &r100_irq_process,
185 .get_vblank_counter = &r100_get_vblank_counter, 145 .get_vblank_counter = &r100_get_vblank_counter,
@@ -209,26 +169,14 @@ static struct radeon_asic r420_asic = {
209 .fini = &r420_fini, 169 .fini = &r420_fini,
210 .suspend = &r420_suspend, 170 .suspend = &r420_suspend,
211 .resume = &r420_resume, 171 .resume = &r420_resume,
212 .errata = NULL,
213 .vram_info = NULL,
214 .vga_set_state = &r100_vga_set_state, 172 .vga_set_state = &r100_vga_set_state,
215 .gpu_reset = &r300_gpu_reset, 173 .gpu_reset = &r300_gpu_reset,
216 .mc_init = NULL,
217 .mc_fini = NULL,
218 .wb_init = NULL,
219 .wb_fini = NULL,
220 .gart_enable = NULL,
221 .gart_disable = NULL,
222 .gart_tlb_flush = &rv370_pcie_gart_tlb_flush, 174 .gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
223 .gart_set_page = &rv370_pcie_gart_set_page, 175 .gart_set_page = &rv370_pcie_gart_set_page,
224 .cp_init = NULL,
225 .cp_fini = NULL,
226 .cp_disable = NULL,
227 .cp_commit = &r100_cp_commit, 176 .cp_commit = &r100_cp_commit,
228 .ring_start = &r300_ring_start, 177 .ring_start = &r300_ring_start,
229 .ring_test = &r100_ring_test, 178 .ring_test = &r100_ring_test,
230 .ring_ib_execute = &r100_ring_ib_execute, 179 .ring_ib_execute = &r100_ring_ib_execute,
231 .ib_test = NULL,
232 .irq_set = &r100_irq_set, 180 .irq_set = &r100_irq_set,
233 .irq_process = &r100_irq_process, 181 .irq_process = &r100_irq_process,
234 .get_vblank_counter = &r100_get_vblank_counter, 182 .get_vblank_counter = &r100_get_vblank_counter,
@@ -250,42 +198,27 @@ static struct radeon_asic r420_asic = {
250/* 198/*
251 * rs400,rs480 199 * rs400,rs480
252 */ 200 */
253void rs400_errata(struct radeon_device *rdev); 201extern int rs400_init(struct radeon_device *rdev);
254void rs400_vram_info(struct radeon_device *rdev); 202extern void rs400_fini(struct radeon_device *rdev);
255int rs400_mc_init(struct radeon_device *rdev); 203extern int rs400_suspend(struct radeon_device *rdev);
256void rs400_mc_fini(struct radeon_device *rdev); 204extern int rs400_resume(struct radeon_device *rdev);
257int rs400_gart_init(struct radeon_device *rdev);
258void rs400_gart_fini(struct radeon_device *rdev);
259int rs400_gart_enable(struct radeon_device *rdev);
260void rs400_gart_disable(struct radeon_device *rdev);
261void rs400_gart_tlb_flush(struct radeon_device *rdev); 205void rs400_gart_tlb_flush(struct radeon_device *rdev);
262int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr); 206int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr);
263uint32_t rs400_mc_rreg(struct radeon_device *rdev, uint32_t reg); 207uint32_t rs400_mc_rreg(struct radeon_device *rdev, uint32_t reg);
264void rs400_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); 208void rs400_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
265static struct radeon_asic rs400_asic = { 209static struct radeon_asic rs400_asic = {
266 .init = &r300_init, 210 .init = &rs400_init,
267 .errata = &rs400_errata, 211 .fini = &rs400_fini,
268 .vram_info = &rs400_vram_info, 212 .suspend = &rs400_suspend,
213 .resume = &rs400_resume,
269 .vga_set_state = &r100_vga_set_state, 214 .vga_set_state = &r100_vga_set_state,
270 .gpu_reset = &r300_gpu_reset, 215 .gpu_reset = &r300_gpu_reset,
271 .mc_init = &rs400_mc_init,
272 .mc_fini = &rs400_mc_fini,
273 .wb_init = &r100_wb_init,
274 .wb_fini = &r100_wb_fini,
275 .gart_init = &rs400_gart_init,
276 .gart_fini = &rs400_gart_fini,
277 .gart_enable = &rs400_gart_enable,
278 .gart_disable = &rs400_gart_disable,
279 .gart_tlb_flush = &rs400_gart_tlb_flush, 216 .gart_tlb_flush = &rs400_gart_tlb_flush,
280 .gart_set_page = &rs400_gart_set_page, 217 .gart_set_page = &rs400_gart_set_page,
281 .cp_init = &r100_cp_init,
282 .cp_fini = &r100_cp_fini,
283 .cp_disable = &r100_cp_disable,
284 .cp_commit = &r100_cp_commit, 218 .cp_commit = &r100_cp_commit,
285 .ring_start = &r300_ring_start, 219 .ring_start = &r300_ring_start,
286 .ring_test = &r100_ring_test, 220 .ring_test = &r100_ring_test,
287 .ring_ib_execute = &r100_ring_ib_execute, 221 .ring_ib_execute = &r100_ring_ib_execute,
288 .ib_test = &r100_ib_test,
289 .irq_set = &r100_irq_set, 222 .irq_set = &r100_irq_set,
290 .irq_process = &r100_irq_process, 223 .irq_process = &r100_irq_process,
291 .get_vblank_counter = &r100_get_vblank_counter, 224 .get_vblank_counter = &r100_get_vblank_counter,
@@ -307,18 +240,13 @@ static struct radeon_asic rs400_asic = {
307/* 240/*
308 * rs600. 241 * rs600.
309 */ 242 */
310int rs600_init(struct radeon_device *rdev); 243extern int rs600_init(struct radeon_device *rdev);
311void rs600_errata(struct radeon_device *rdev); 244extern void rs600_fini(struct radeon_device *rdev);
312void rs600_vram_info(struct radeon_device *rdev); 245extern int rs600_suspend(struct radeon_device *rdev);
313int rs600_mc_init(struct radeon_device *rdev); 246extern int rs600_resume(struct radeon_device *rdev);
314void rs600_mc_fini(struct radeon_device *rdev);
315int rs600_irq_set(struct radeon_device *rdev); 247int rs600_irq_set(struct radeon_device *rdev);
316int rs600_irq_process(struct radeon_device *rdev); 248int rs600_irq_process(struct radeon_device *rdev);
317u32 rs600_get_vblank_counter(struct radeon_device *rdev, int crtc); 249u32 rs600_get_vblank_counter(struct radeon_device *rdev, int crtc);
318int rs600_gart_init(struct radeon_device *rdev);
319void rs600_gart_fini(struct radeon_device *rdev);
320int rs600_gart_enable(struct radeon_device *rdev);
321void rs600_gart_disable(struct radeon_device *rdev);
322void rs600_gart_tlb_flush(struct radeon_device *rdev); 250void rs600_gart_tlb_flush(struct radeon_device *rdev);
323int rs600_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr); 251int rs600_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr);
324uint32_t rs600_mc_rreg(struct radeon_device *rdev, uint32_t reg); 252uint32_t rs600_mc_rreg(struct radeon_device *rdev, uint32_t reg);
@@ -326,28 +254,17 @@ void rs600_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
326void rs600_bandwidth_update(struct radeon_device *rdev); 254void rs600_bandwidth_update(struct radeon_device *rdev);
327static struct radeon_asic rs600_asic = { 255static struct radeon_asic rs600_asic = {
328 .init = &rs600_init, 256 .init = &rs600_init,
329 .errata = &rs600_errata, 257 .fini = &rs600_fini,
330 .vram_info = &rs600_vram_info, 258 .suspend = &rs600_suspend,
259 .resume = &rs600_resume,
331 .vga_set_state = &r100_vga_set_state, 260 .vga_set_state = &r100_vga_set_state,
332 .gpu_reset = &r300_gpu_reset, 261 .gpu_reset = &r300_gpu_reset,
333 .mc_init = &rs600_mc_init,
334 .mc_fini = &rs600_mc_fini,
335 .wb_init = &r100_wb_init,
336 .wb_fini = &r100_wb_fini,
337 .gart_init = &rs600_gart_init,
338 .gart_fini = &rs600_gart_fini,
339 .gart_enable = &rs600_gart_enable,
340 .gart_disable = &rs600_gart_disable,
341 .gart_tlb_flush = &rs600_gart_tlb_flush, 262 .gart_tlb_flush = &rs600_gart_tlb_flush,
342 .gart_set_page = &rs600_gart_set_page, 263 .gart_set_page = &rs600_gart_set_page,
343 .cp_init = &r100_cp_init,
344 .cp_fini = &r100_cp_fini,
345 .cp_disable = &r100_cp_disable,
346 .cp_commit = &r100_cp_commit, 264 .cp_commit = &r100_cp_commit,
347 .ring_start = &r300_ring_start, 265 .ring_start = &r300_ring_start,
348 .ring_test = &r100_ring_test, 266 .ring_test = &r100_ring_test,
349 .ring_ib_execute = &r100_ring_ib_execute, 267 .ring_ib_execute = &r100_ring_ib_execute,
350 .ib_test = &r100_ib_test,
351 .irq_set = &rs600_irq_set, 268 .irq_set = &rs600_irq_set,
352 .irq_process = &rs600_irq_process, 269 .irq_process = &rs600_irq_process,
353 .get_vblank_counter = &rs600_get_vblank_counter, 270 .get_vblank_counter = &rs600_get_vblank_counter,
@@ -367,37 +284,26 @@ static struct radeon_asic rs600_asic = {
367/* 284/*
368 * rs690,rs740 285 * rs690,rs740
369 */ 286 */
370void rs690_errata(struct radeon_device *rdev); 287int rs690_init(struct radeon_device *rdev);
371void rs690_vram_info(struct radeon_device *rdev); 288void rs690_fini(struct radeon_device *rdev);
372int rs690_mc_init(struct radeon_device *rdev); 289int rs690_resume(struct radeon_device *rdev);
373void rs690_mc_fini(struct radeon_device *rdev); 290int rs690_suspend(struct radeon_device *rdev);
374uint32_t rs690_mc_rreg(struct radeon_device *rdev, uint32_t reg); 291uint32_t rs690_mc_rreg(struct radeon_device *rdev, uint32_t reg);
375void rs690_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); 292void rs690_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
376void rs690_bandwidth_update(struct radeon_device *rdev); 293void rs690_bandwidth_update(struct radeon_device *rdev);
377static struct radeon_asic rs690_asic = { 294static struct radeon_asic rs690_asic = {
378 .init = &rs600_init, 295 .init = &rs690_init,
379 .errata = &rs690_errata, 296 .fini = &rs690_fini,
380 .vram_info = &rs690_vram_info, 297 .suspend = &rs690_suspend,
298 .resume = &rs690_resume,
381 .vga_set_state = &r100_vga_set_state, 299 .vga_set_state = &r100_vga_set_state,
382 .gpu_reset = &r300_gpu_reset, 300 .gpu_reset = &r300_gpu_reset,
383 .mc_init = &rs690_mc_init,
384 .mc_fini = &rs690_mc_fini,
385 .wb_init = &r100_wb_init,
386 .wb_fini = &r100_wb_fini,
387 .gart_init = &rs400_gart_init,
388 .gart_fini = &rs400_gart_fini,
389 .gart_enable = &rs400_gart_enable,
390 .gart_disable = &rs400_gart_disable,
391 .gart_tlb_flush = &rs400_gart_tlb_flush, 301 .gart_tlb_flush = &rs400_gart_tlb_flush,
392 .gart_set_page = &rs400_gart_set_page, 302 .gart_set_page = &rs400_gart_set_page,
393 .cp_init = &r100_cp_init,
394 .cp_fini = &r100_cp_fini,
395 .cp_disable = &r100_cp_disable,
396 .cp_commit = &r100_cp_commit, 303 .cp_commit = &r100_cp_commit,
397 .ring_start = &r300_ring_start, 304 .ring_start = &r300_ring_start,
398 .ring_test = &r100_ring_test, 305 .ring_test = &r100_ring_test,
399 .ring_ib_execute = &r100_ring_ib_execute, 306 .ring_ib_execute = &r100_ring_ib_execute,
400 .ib_test = &r100_ib_test,
401 .irq_set = &rs600_irq_set, 307 .irq_set = &rs600_irq_set,
402 .irq_process = &rs600_irq_process, 308 .irq_process = &rs600_irq_process,
403 .get_vblank_counter = &rs600_get_vblank_counter, 309 .get_vblank_counter = &rs600_get_vblank_counter,
@@ -435,28 +341,14 @@ static struct radeon_asic rv515_asic = {
435 .fini = &rv515_fini, 341 .fini = &rv515_fini,
436 .suspend = &rv515_suspend, 342 .suspend = &rv515_suspend,
437 .resume = &rv515_resume, 343 .resume = &rv515_resume,
438 .errata = NULL,
439 .vram_info = NULL,
440 .vga_set_state = &r100_vga_set_state, 344 .vga_set_state = &r100_vga_set_state,
441 .gpu_reset = &rv515_gpu_reset, 345 .gpu_reset = &rv515_gpu_reset,
442 .mc_init = NULL,
443 .mc_fini = NULL,
444 .wb_init = NULL,
445 .wb_fini = NULL,
446 .gart_init = &rv370_pcie_gart_init,
447 .gart_fini = &rv370_pcie_gart_fini,
448 .gart_enable = NULL,
449 .gart_disable = NULL,
450 .gart_tlb_flush = &rv370_pcie_gart_tlb_flush, 346 .gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
451 .gart_set_page = &rv370_pcie_gart_set_page, 347 .gart_set_page = &rv370_pcie_gart_set_page,
452 .cp_init = NULL,
453 .cp_fini = NULL,
454 .cp_disable = NULL,
455 .cp_commit = &r100_cp_commit, 348 .cp_commit = &r100_cp_commit,
456 .ring_start = &rv515_ring_start, 349 .ring_start = &rv515_ring_start,
457 .ring_test = &r100_ring_test, 350 .ring_test = &r100_ring_test,
458 .ring_ib_execute = &r100_ring_ib_execute, 351 .ring_ib_execute = &r100_ring_ib_execute,
459 .ib_test = NULL,
460 .irq_set = &rs600_irq_set, 352 .irq_set = &rs600_irq_set,
461 .irq_process = &rs600_irq_process, 353 .irq_process = &rs600_irq_process,
462 .get_vblank_counter = &rs600_get_vblank_counter, 354 .get_vblank_counter = &rs600_get_vblank_counter,
@@ -485,28 +377,14 @@ static struct radeon_asic r520_asic = {
485 .fini = &rv515_fini, 377 .fini = &rv515_fini,
486 .suspend = &rv515_suspend, 378 .suspend = &rv515_suspend,
487 .resume = &r520_resume, 379 .resume = &r520_resume,
488 .errata = NULL,
489 .vram_info = NULL,
490 .vga_set_state = &r100_vga_set_state, 380 .vga_set_state = &r100_vga_set_state,
491 .gpu_reset = &rv515_gpu_reset, 381 .gpu_reset = &rv515_gpu_reset,
492 .mc_init = NULL,
493 .mc_fini = NULL,
494 .wb_init = NULL,
495 .wb_fini = NULL,
496 .gart_init = NULL,
497 .gart_fini = NULL,
498 .gart_enable = NULL,
499 .gart_disable = NULL,
500 .gart_tlb_flush = &rv370_pcie_gart_tlb_flush, 382 .gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
501 .gart_set_page = &rv370_pcie_gart_set_page, 383 .gart_set_page = &rv370_pcie_gart_set_page,
502 .cp_init = NULL,
503 .cp_fini = NULL,
504 .cp_disable = NULL,
505 .cp_commit = &r100_cp_commit, 384 .cp_commit = &r100_cp_commit,
506 .ring_start = &rv515_ring_start, 385 .ring_start = &rv515_ring_start,
507 .ring_test = &r100_ring_test, 386 .ring_test = &r100_ring_test,
508 .ring_ib_execute = &r100_ring_ib_execute, 387 .ring_ib_execute = &r100_ring_ib_execute,
509 .ib_test = NULL,
510 .irq_set = &rs600_irq_set, 388 .irq_set = &rs600_irq_set,
511 .irq_process = &rs600_irq_process, 389 .irq_process = &rs600_irq_process,
512 .get_vblank_counter = &rs600_get_vblank_counter, 390 .get_vblank_counter = &rs600_get_vblank_counter,
@@ -554,37 +432,23 @@ int r600_set_surface_reg(struct radeon_device *rdev, int reg,
554 uint32_t offset, uint32_t obj_size); 432 uint32_t offset, uint32_t obj_size);
555int r600_clear_surface_reg(struct radeon_device *rdev, int reg); 433int r600_clear_surface_reg(struct radeon_device *rdev, int reg);
556void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); 434void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib);
557int r600_ib_test(struct radeon_device *rdev);
558int r600_ring_test(struct radeon_device *rdev); 435int r600_ring_test(struct radeon_device *rdev);
559int r600_copy_blit(struct radeon_device *rdev, 436int r600_copy_blit(struct radeon_device *rdev,
560 uint64_t src_offset, uint64_t dst_offset, 437 uint64_t src_offset, uint64_t dst_offset,
561 unsigned num_pages, struct radeon_fence *fence); 438 unsigned num_pages, struct radeon_fence *fence);
562 439
563static struct radeon_asic r600_asic = { 440static struct radeon_asic r600_asic = {
564 .errata = NULL,
565 .init = &r600_init, 441 .init = &r600_init,
566 .fini = &r600_fini, 442 .fini = &r600_fini,
567 .suspend = &r600_suspend, 443 .suspend = &r600_suspend,
568 .resume = &r600_resume, 444 .resume = &r600_resume,
569 .cp_commit = &r600_cp_commit, 445 .cp_commit = &r600_cp_commit,
570 .vram_info = NULL,
571 .vga_set_state = &r600_vga_set_state, 446 .vga_set_state = &r600_vga_set_state,
572 .gpu_reset = &r600_gpu_reset, 447 .gpu_reset = &r600_gpu_reset,
573 .mc_init = NULL,
574 .mc_fini = NULL,
575 .wb_init = &r600_wb_init,
576 .wb_fini = &r600_wb_fini,
577 .gart_enable = NULL,
578 .gart_disable = NULL,
579 .gart_tlb_flush = &r600_pcie_gart_tlb_flush, 448 .gart_tlb_flush = &r600_pcie_gart_tlb_flush,
580 .gart_set_page = &rs600_gart_set_page, 449 .gart_set_page = &rs600_gart_set_page,
581 .cp_init = NULL,
582 .cp_fini = NULL,
583 .cp_disable = NULL,
584 .ring_start = NULL,
585 .ring_test = &r600_ring_test, 450 .ring_test = &r600_ring_test,
586 .ring_ib_execute = &r600_ring_ib_execute, 451 .ring_ib_execute = &r600_ring_ib_execute,
587 .ib_test = &r600_ib_test,
588 .irq_set = &r600_irq_set, 452 .irq_set = &r600_irq_set,
589 .irq_process = &r600_irq_process, 453 .irq_process = &r600_irq_process,
590 .fence_ring_emit = &r600_fence_ring_emit, 454 .fence_ring_emit = &r600_fence_ring_emit,
@@ -611,30 +475,17 @@ int rv770_resume(struct radeon_device *rdev);
611int rv770_gpu_reset(struct radeon_device *rdev); 475int rv770_gpu_reset(struct radeon_device *rdev);
612 476
613static struct radeon_asic rv770_asic = { 477static struct radeon_asic rv770_asic = {
614 .errata = NULL,
615 .init = &rv770_init, 478 .init = &rv770_init,
616 .fini = &rv770_fini, 479 .fini = &rv770_fini,
617 .suspend = &rv770_suspend, 480 .suspend = &rv770_suspend,
618 .resume = &rv770_resume, 481 .resume = &rv770_resume,
619 .cp_commit = &r600_cp_commit, 482 .cp_commit = &r600_cp_commit,
620 .vram_info = NULL,
621 .gpu_reset = &rv770_gpu_reset, 483 .gpu_reset = &rv770_gpu_reset,
622 .vga_set_state = &r600_vga_set_state, 484 .vga_set_state = &r600_vga_set_state,
623 .mc_init = NULL,
624 .mc_fini = NULL,
625 .wb_init = &r600_wb_init,
626 .wb_fini = &r600_wb_fini,
627 .gart_enable = NULL,
628 .gart_disable = NULL,
629 .gart_tlb_flush = &r600_pcie_gart_tlb_flush, 485 .gart_tlb_flush = &r600_pcie_gart_tlb_flush,
630 .gart_set_page = &rs600_gart_set_page, 486 .gart_set_page = &rs600_gart_set_page,
631 .cp_init = NULL,
632 .cp_fini = NULL,
633 .cp_disable = NULL,
634 .ring_start = NULL,
635 .ring_test = &r600_ring_test, 487 .ring_test = &r600_ring_test,
636 .ring_ib_execute = &r600_ring_ib_execute, 488 .ring_ib_execute = &r600_ring_ib_execute,
637 .ib_test = &r600_ib_test,
638 .irq_set = &r600_irq_set, 489 .irq_set = &r600_irq_set,
639 .irq_process = &r600_irq_process, 490 .irq_process = &r600_irq_process,
640 .fence_ring_emit = &r600_fence_ring_emit, 491 .fence_ring_emit = &r600_fence_ring_emit,
diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c
index 96e37a6e7ce4..34a9b9119518 100644
--- a/drivers/gpu/drm/radeon/radeon_bios.c
+++ b/drivers/gpu/drm/radeon/radeon_bios.c
@@ -33,12 +33,50 @@
33/* 33/*
34 * BIOS. 34 * BIOS.
35 */ 35 */
36
37/* If you boot an IGP board with a discrete card as the primary,
38 * the IGP rom is not accessible via the rom bar as the IGP rom is
39 * part of the system bios. On boot, the system bios puts a
40 * copy of the igp rom at the start of vram if a discrete card is
41 * present.
42 */
43static bool igp_read_bios_from_vram(struct radeon_device *rdev)
44{
45 uint8_t __iomem *bios;
46 resource_size_t vram_base;
47 resource_size_t size = 256 * 1024; /* ??? */
48
49 rdev->bios = NULL;
50 vram_base = drm_get_resource_start(rdev->ddev, 0);
51 bios = ioremap(vram_base, size);
52 if (!bios) {
53 DRM_ERROR("Unable to mmap vram\n");
54 return false;
55 }
56
57 if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) {
58 iounmap(bios);
59 DRM_ERROR("bad rom signature\n");
60 return false;
61 }
62 rdev->bios = kmalloc(size, GFP_KERNEL);
63 if (rdev->bios == NULL) {
64 iounmap(bios);
65 DRM_ERROR("kmalloc failed\n");
66 return false;
67 }
68 memcpy(rdev->bios, bios, size);
69 iounmap(bios);
70 return true;
71}
72
36static bool radeon_read_bios(struct radeon_device *rdev) 73static bool radeon_read_bios(struct radeon_device *rdev)
37{ 74{
38 uint8_t __iomem *bios; 75 uint8_t __iomem *bios;
39 size_t size; 76 size_t size;
40 77
41 rdev->bios = NULL; 78 rdev->bios = NULL;
79 /* XXX: some cards may return 0 for rom size? ddx has a workaround */
42 bios = pci_map_rom(rdev->pdev, &size); 80 bios = pci_map_rom(rdev->pdev, &size);
43 if (!bios) { 81 if (!bios) {
44 return false; 82 return false;
@@ -341,7 +379,9 @@ static bool legacy_read_disabled_bios(struct radeon_device *rdev)
341 379
342static bool radeon_read_disabled_bios(struct radeon_device *rdev) 380static bool radeon_read_disabled_bios(struct radeon_device *rdev)
343{ 381{
344 if (rdev->family >= CHIP_RV770) 382 if (rdev->flags & RADEON_IS_IGP)
383 return igp_read_bios_from_vram(rdev);
384 else if (rdev->family >= CHIP_RV770)
345 return r700_read_disabled_bios(rdev); 385 return r700_read_disabled_bios(rdev);
346 else if (rdev->family >= CHIP_R600) 386 else if (rdev->family >= CHIP_R600)
347 return r600_read_disabled_bios(rdev); 387 return r600_read_disabled_bios(rdev);
@@ -356,7 +396,12 @@ bool radeon_get_bios(struct radeon_device *rdev)
356 bool r; 396 bool r;
357 uint16_t tmp; 397 uint16_t tmp;
358 398
359 r = radeon_read_bios(rdev); 399 if (rdev->flags & RADEON_IS_IGP) {
400 r = igp_read_bios_from_vram(rdev);
401 if (r == false)
402 r = radeon_read_bios(rdev);
403 } else
404 r = radeon_read_bios(rdev);
360 if (r == false) { 405 if (r == false) {
361 r = radeon_read_disabled_bios(rdev); 406 r = radeon_read_disabled_bios(rdev);
362 } 407 }
diff --git a/drivers/gpu/drm/radeon/radeon_clocks.c b/drivers/gpu/drm/radeon/radeon_clocks.c
index 152eef13197a..f5c32a766b10 100644
--- a/drivers/gpu/drm/radeon/radeon_clocks.c
+++ b/drivers/gpu/drm/radeon/radeon_clocks.c
@@ -411,7 +411,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
411 R300_PIXCLK_TRANS_ALWAYS_ONb | 411 R300_PIXCLK_TRANS_ALWAYS_ONb |
412 R300_PIXCLK_TVO_ALWAYS_ONb | 412 R300_PIXCLK_TVO_ALWAYS_ONb |
413 R300_P2G2CLK_ALWAYS_ONb | 413 R300_P2G2CLK_ALWAYS_ONb |
414 R300_P2G2CLK_ALWAYS_ONb); 414 R300_P2G2CLK_DAC_ALWAYS_ONb);
415 WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp); 415 WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);
416 } else if (rdev->family >= CHIP_RV350) { 416 } else if (rdev->family >= CHIP_RV350) {
417 tmp = RREG32_PLL(R300_SCLK_CNTL2); 417 tmp = RREG32_PLL(R300_SCLK_CNTL2);
@@ -464,7 +464,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
464 R300_PIXCLK_TRANS_ALWAYS_ONb | 464 R300_PIXCLK_TRANS_ALWAYS_ONb |
465 R300_PIXCLK_TVO_ALWAYS_ONb | 465 R300_PIXCLK_TVO_ALWAYS_ONb |
466 R300_P2G2CLK_ALWAYS_ONb | 466 R300_P2G2CLK_ALWAYS_ONb |
467 R300_P2G2CLK_ALWAYS_ONb); 467 R300_P2G2CLK_DAC_ALWAYS_ONb);
468 WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp); 468 WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);
469 469
470 tmp = RREG32_PLL(RADEON_MCLK_MISC); 470 tmp = RREG32_PLL(RADEON_MCLK_MISC);
@@ -654,7 +654,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
654 R300_PIXCLK_TRANS_ALWAYS_ONb | 654 R300_PIXCLK_TRANS_ALWAYS_ONb |
655 R300_PIXCLK_TVO_ALWAYS_ONb | 655 R300_PIXCLK_TVO_ALWAYS_ONb |
656 R300_P2G2CLK_ALWAYS_ONb | 656 R300_P2G2CLK_ALWAYS_ONb |
657 R300_P2G2CLK_ALWAYS_ONb | 657 R300_P2G2CLK_DAC_ALWAYS_ONb |
658 R300_DISP_DAC_PIXCLK_DAC2_BLANK_OFF); 658 R300_DISP_DAC_PIXCLK_DAC2_BLANK_OFF);
659 WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp); 659 WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);
660 } else if (rdev->family >= CHIP_RV350) { 660 } else if (rdev->family >= CHIP_RV350) {
@@ -705,7 +705,7 @@ void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable)
705 R300_PIXCLK_TRANS_ALWAYS_ONb | 705 R300_PIXCLK_TRANS_ALWAYS_ONb |
706 R300_PIXCLK_TVO_ALWAYS_ONb | 706 R300_PIXCLK_TVO_ALWAYS_ONb |
707 R300_P2G2CLK_ALWAYS_ONb | 707 R300_P2G2CLK_ALWAYS_ONb |
708 R300_P2G2CLK_ALWAYS_ONb | 708 R300_P2G2CLK_DAC_ALWAYS_ONb |
709 R300_DISP_DAC_PIXCLK_DAC2_BLANK_OFF); 709 R300_DISP_DAC_PIXCLK_DAC2_BLANK_OFF);
710 WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp); 710 WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);
711 } else { 711 } else {
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index ec835d56d30a..3d667031de6e 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -322,10 +322,6 @@ int radeon_asic_init(struct radeon_device *rdev)
322 case CHIP_RV380: 322 case CHIP_RV380:
323 rdev->asic = &r300_asic; 323 rdev->asic = &r300_asic;
324 if (rdev->flags & RADEON_IS_PCIE) { 324 if (rdev->flags & RADEON_IS_PCIE) {
325 rdev->asic->gart_init = &rv370_pcie_gart_init;
326 rdev->asic->gart_fini = &rv370_pcie_gart_fini;
327 rdev->asic->gart_enable = &rv370_pcie_gart_enable;
328 rdev->asic->gart_disable = &rv370_pcie_gart_disable;
329 rdev->asic->gart_tlb_flush = &rv370_pcie_gart_tlb_flush; 325 rdev->asic->gart_tlb_flush = &rv370_pcie_gart_tlb_flush;
330 rdev->asic->gart_set_page = &rv370_pcie_gart_set_page; 326 rdev->asic->gart_set_page = &rv370_pcie_gart_set_page;
331 } 327 }
@@ -485,7 +481,6 @@ void radeon_combios_fini(struct radeon_device *rdev)
485static unsigned int radeon_vga_set_decode(void *cookie, bool state) 481static unsigned int radeon_vga_set_decode(void *cookie, bool state)
486{ 482{
487 struct radeon_device *rdev = cookie; 483 struct radeon_device *rdev = cookie;
488
489 radeon_vga_set_state(rdev, state); 484 radeon_vga_set_state(rdev, state);
490 if (state) 485 if (state)
491 return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM | 486 return VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM |
@@ -493,6 +488,29 @@ static unsigned int radeon_vga_set_decode(void *cookie, bool state)
493 else 488 else
494 return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM; 489 return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
495} 490}
491
492void radeon_agp_disable(struct radeon_device *rdev)
493{
494 rdev->flags &= ~RADEON_IS_AGP;
495 if (rdev->family >= CHIP_R600) {
496 DRM_INFO("Forcing AGP to PCIE mode\n");
497 rdev->flags |= RADEON_IS_PCIE;
498 } else if (rdev->family >= CHIP_RV515 ||
499 rdev->family == CHIP_RV380 ||
500 rdev->family == CHIP_RV410 ||
501 rdev->family == CHIP_R423) {
502 DRM_INFO("Forcing AGP to PCIE mode\n");
503 rdev->flags |= RADEON_IS_PCIE;
504 rdev->asic->gart_tlb_flush = &rv370_pcie_gart_tlb_flush;
505 rdev->asic->gart_set_page = &rv370_pcie_gart_set_page;
506 } else {
507 DRM_INFO("Forcing AGP to PCI mode\n");
508 rdev->flags |= RADEON_IS_PCI;
509 rdev->asic->gart_tlb_flush = &r100_pci_gart_tlb_flush;
510 rdev->asic->gart_set_page = &r100_pci_gart_set_page;
511 }
512}
513
496/* 514/*
497 * Radeon device. 515 * Radeon device.
498 */ 516 */
@@ -531,32 +549,7 @@ int radeon_device_init(struct radeon_device *rdev,
531 } 549 }
532 550
533 if (radeon_agpmode == -1) { 551 if (radeon_agpmode == -1) {
534 rdev->flags &= ~RADEON_IS_AGP; 552 radeon_agp_disable(rdev);
535 if (rdev->family >= CHIP_R600) {
536 DRM_INFO("Forcing AGP to PCIE mode\n");
537 rdev->flags |= RADEON_IS_PCIE;
538 } else if (rdev->family >= CHIP_RV515 ||
539 rdev->family == CHIP_RV380 ||
540 rdev->family == CHIP_RV410 ||
541 rdev->family == CHIP_R423) {
542 DRM_INFO("Forcing AGP to PCIE mode\n");
543 rdev->flags |= RADEON_IS_PCIE;
544 rdev->asic->gart_init = &rv370_pcie_gart_init;
545 rdev->asic->gart_fini = &rv370_pcie_gart_fini;
546 rdev->asic->gart_enable = &rv370_pcie_gart_enable;
547 rdev->asic->gart_disable = &rv370_pcie_gart_disable;
548 rdev->asic->gart_tlb_flush = &rv370_pcie_gart_tlb_flush;
549 rdev->asic->gart_set_page = &rv370_pcie_gart_set_page;
550 } else {
551 DRM_INFO("Forcing AGP to PCI mode\n");
552 rdev->flags |= RADEON_IS_PCI;
553 rdev->asic->gart_init = &r100_pci_gart_init;
554 rdev->asic->gart_fini = &r100_pci_gart_fini;
555 rdev->asic->gart_enable = &r100_pci_gart_enable;
556 rdev->asic->gart_disable = &r100_pci_gart_disable;
557 rdev->asic->gart_tlb_flush = &r100_pci_gart_tlb_flush;
558 rdev->asic->gart_set_page = &r100_pci_gart_set_page;
559 }
560 } 553 }
561 554
562 /* set DMA mask + need_dma32 flags. 555 /* set DMA mask + need_dma32 flags.
@@ -588,111 +581,27 @@ int radeon_device_init(struct radeon_device *rdev,
588 DRM_INFO("register mmio base: 0x%08X\n", (uint32_t)rdev->rmmio_base); 581 DRM_INFO("register mmio base: 0x%08X\n", (uint32_t)rdev->rmmio_base);
589 DRM_INFO("register mmio size: %u\n", (unsigned)rdev->rmmio_size); 582 DRM_INFO("register mmio size: %u\n", (unsigned)rdev->rmmio_size);
590 583
591 rdev->new_init_path = false;
592 r = radeon_init(rdev);
593 if (r) {
594 return r;
595 }
596
597 /* if we have > 1 VGA cards, then disable the radeon VGA resources */ 584 /* if we have > 1 VGA cards, then disable the radeon VGA resources */
598 r = vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode); 585 r = vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode);
599 if (r) { 586 if (r) {
600 return -EINVAL; 587 return -EINVAL;
601 } 588 }
602 589
603 if (!rdev->new_init_path) { 590 r = radeon_init(rdev);
604 /* Setup errata flags */ 591 if (r)
605 radeon_errata(rdev); 592 return r;
606 /* Initialize scratch registers */
607 radeon_scratch_init(rdev);
608 /* Initialize surface registers */
609 radeon_surface_init(rdev);
610
611 /* BIOS*/
612 if (!radeon_get_bios(rdev)) {
613 if (ASIC_IS_AVIVO(rdev))
614 return -EINVAL;
615 }
616 if (rdev->is_atom_bios) {
617 r = radeon_atombios_init(rdev);
618 if (r) {
619 return r;
620 }
621 } else {
622 r = radeon_combios_init(rdev);
623 if (r) {
624 return r;
625 }
626 }
627 /* Reset gpu before posting otherwise ATOM will enter infinite loop */
628 if (radeon_gpu_reset(rdev)) {
629 /* FIXME: what do we want to do here ? */
630 }
631 /* check if cards are posted or not */
632 if (!radeon_card_posted(rdev) && rdev->bios) {
633 DRM_INFO("GPU not posted. posting now...\n");
634 if (rdev->is_atom_bios) {
635 atom_asic_init(rdev->mode_info.atom_context);
636 } else {
637 radeon_combios_asic_init(rdev->ddev);
638 }
639 }
640 /* Get clock & vram information */
641 radeon_get_clock_info(rdev->ddev);
642 radeon_vram_info(rdev);
643 /* Initialize clocks */
644 r = radeon_clocks_init(rdev);
645 if (r) {
646 return r;
647 }
648 593
649 /* Initialize memory controller (also test AGP) */ 594 if (rdev->flags & RADEON_IS_AGP && !rdev->accel_working) {
650 r = radeon_mc_init(rdev); 595 /* Acceleration not working on AGP card try again
651 if (r) { 596 * with fallback to PCI or PCIE GART
652 return r; 597 */
653 } 598 radeon_gpu_reset(rdev);
654 /* Fence driver */ 599 radeon_fini(rdev);
655 r = radeon_fence_driver_init(rdev); 600 radeon_agp_disable(rdev);
656 if (r) { 601 r = radeon_init(rdev);
657 return r;
658 }
659 r = radeon_irq_kms_init(rdev);
660 if (r) {
661 return r;
662 }
663 /* Memory manager */
664 r = radeon_object_init(rdev);
665 if (r) {
666 return r;
667 }
668 r = radeon_gpu_gart_init(rdev);
669 if (r) 602 if (r)
670 return r; 603 return r;
671 /* Initialize GART (initialize after TTM so we can allocate
672 * memory through TTM but finalize after TTM) */
673 r = radeon_gart_enable(rdev);
674 if (r)
675 return 0;
676 r = radeon_gem_init(rdev);
677 if (r)
678 return 0;
679
680 /* 1M ring buffer */
681 r = radeon_cp_init(rdev, 1024 * 1024);
682 if (r)
683 return 0;
684 r = radeon_wb_init(rdev);
685 if (r)
686 DRM_ERROR("radeon: failled initializing WB (%d).\n", r);
687 r = radeon_ib_pool_init(rdev);
688 if (r)
689 return 0;
690 r = radeon_ib_test(rdev);
691 if (r)
692 return 0;
693 rdev->accel_working = true;
694 } 604 }
695 DRM_INFO("radeon: kernel modesetting successfully initialized.\n");
696 if (radeon_testing) { 605 if (radeon_testing) {
697 radeon_test_moves(rdev); 606 radeon_test_moves(rdev);
698 } 607 }
@@ -706,32 +615,8 @@ void radeon_device_fini(struct radeon_device *rdev)
706{ 615{
707 DRM_INFO("radeon: finishing device.\n"); 616 DRM_INFO("radeon: finishing device.\n");
708 rdev->shutdown = true; 617 rdev->shutdown = true;
709 /* Order matter so becarefull if you rearrange anythings */ 618 radeon_fini(rdev);
710 if (!rdev->new_init_path) { 619 vga_client_register(rdev->pdev, NULL, NULL, NULL);
711 radeon_ib_pool_fini(rdev);
712 radeon_cp_fini(rdev);
713 radeon_wb_fini(rdev);
714 radeon_gpu_gart_fini(rdev);
715 radeon_gem_fini(rdev);
716 radeon_mc_fini(rdev);
717#if __OS_HAS_AGP
718 radeon_agp_fini(rdev);
719#endif
720 radeon_irq_kms_fini(rdev);
721 vga_client_register(rdev->pdev, NULL, NULL, NULL);
722 radeon_fence_driver_fini(rdev);
723 radeon_clocks_fini(rdev);
724 radeon_object_fini(rdev);
725 if (rdev->is_atom_bios) {
726 radeon_atombios_fini(rdev);
727 } else {
728 radeon_combios_fini(rdev);
729 }
730 kfree(rdev->bios);
731 rdev->bios = NULL;
732 } else {
733 radeon_fini(rdev);
734 }
735 iounmap(rdev->rmmio); 620 iounmap(rdev->rmmio);
736 rdev->rmmio = NULL; 621 rdev->rmmio = NULL;
737} 622}
@@ -771,14 +656,7 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state)
771 656
772 radeon_save_bios_scratch_regs(rdev); 657 radeon_save_bios_scratch_regs(rdev);
773 658
774 if (!rdev->new_init_path) { 659 radeon_suspend(rdev);
775 radeon_cp_disable(rdev);
776 radeon_gart_disable(rdev);
777 rdev->irq.sw_int = false;
778 radeon_irq_set(rdev);
779 } else {
780 radeon_suspend(rdev);
781 }
782 /* evict remaining vram memory */ 660 /* evict remaining vram memory */
783 radeon_object_evict_vram(rdev); 661 radeon_object_evict_vram(rdev);
784 662
@@ -797,7 +675,6 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state)
797int radeon_resume_kms(struct drm_device *dev) 675int radeon_resume_kms(struct drm_device *dev)
798{ 676{
799 struct radeon_device *rdev = dev->dev_private; 677 struct radeon_device *rdev = dev->dev_private;
800 int r;
801 678
802 acquire_console_sem(); 679 acquire_console_sem();
803 pci_set_power_state(dev->pdev, PCI_D0); 680 pci_set_power_state(dev->pdev, PCI_D0);
@@ -807,43 +684,7 @@ int radeon_resume_kms(struct drm_device *dev)
807 return -1; 684 return -1;
808 } 685 }
809 pci_set_master(dev->pdev); 686 pci_set_master(dev->pdev);
810 /* Reset gpu before posting otherwise ATOM will enter infinite loop */ 687 radeon_resume(rdev);
811 if (!rdev->new_init_path) {
812 if (radeon_gpu_reset(rdev)) {
813 /* FIXME: what do we want to do here ? */
814 }
815 /* post card */
816 if (rdev->is_atom_bios) {
817 atom_asic_init(rdev->mode_info.atom_context);
818 } else {
819 radeon_combios_asic_init(rdev->ddev);
820 }
821 /* Initialize clocks */
822 r = radeon_clocks_init(rdev);
823 if (r) {
824 release_console_sem();
825 return r;
826 }
827 /* Enable IRQ */
828 rdev->irq.sw_int = true;
829 radeon_irq_set(rdev);
830 /* Initialize GPU Memory Controller */
831 r = radeon_mc_init(rdev);
832 if (r) {
833 goto out;
834 }
835 r = radeon_gart_enable(rdev);
836 if (r) {
837 goto out;
838 }
839 r = radeon_cp_init(rdev, rdev->cp.ring_size);
840 if (r) {
841 goto out;
842 }
843 } else {
844 radeon_resume(rdev);
845 }
846out:
847 radeon_restore_bios_scratch_regs(rdev); 688 radeon_restore_bios_scratch_regs(rdev);
848 fb_set_suspend(rdev->fbdev_info, 0); 689 fb_set_suspend(rdev->fbdev_info, 0);
849 release_console_sem(); 690 release_console_sem();
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index 5d8141b13765..3655d91993a6 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -106,24 +106,33 @@ void radeon_crtc_load_lut(struct drm_crtc *crtc)
106 legacy_crtc_load_lut(crtc); 106 legacy_crtc_load_lut(crtc);
107} 107}
108 108
109/** Sets the color ramps on behalf of RandR */ 109/** Sets the color ramps on behalf of fbcon */
110void radeon_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, 110void radeon_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
111 u16 blue, int regno) 111 u16 blue, int regno)
112{ 112{
113 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); 113 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
114 114
115 if (regno == 0)
116 DRM_DEBUG("gamma set %d\n", radeon_crtc->crtc_id);
117 radeon_crtc->lut_r[regno] = red >> 6; 115 radeon_crtc->lut_r[regno] = red >> 6;
118 radeon_crtc->lut_g[regno] = green >> 6; 116 radeon_crtc->lut_g[regno] = green >> 6;
119 radeon_crtc->lut_b[regno] = blue >> 6; 117 radeon_crtc->lut_b[regno] = blue >> 6;
120} 118}
121 119
120/** Gets the color ramps on behalf of fbcon */
121void radeon_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
122 u16 *blue, int regno)
123{
124 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
125
126 *red = radeon_crtc->lut_r[regno] << 6;
127 *green = radeon_crtc->lut_g[regno] << 6;
128 *blue = radeon_crtc->lut_b[regno] << 6;
129}
130
122static void radeon_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, 131static void radeon_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
123 u16 *blue, uint32_t size) 132 u16 *blue, uint32_t size)
124{ 133{
125 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); 134 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
126 int i, j; 135 int i;
127 136
128 if (size != 256) { 137 if (size != 256) {
129 return; 138 return;
@@ -132,23 +141,11 @@ static void radeon_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
132 return; 141 return;
133 } 142 }
134 143
135 if (crtc->fb->depth == 16) { 144 /* userspace palettes are always correct as is */
136 for (i = 0; i < 64; i++) { 145 for (i = 0; i < 256; i++) {
137 if (i <= 31) { 146 radeon_crtc->lut_r[i] = red[i] >> 6;
138 for (j = 0; j < 8; j++) { 147 radeon_crtc->lut_g[i] = green[i] >> 6;
139 radeon_crtc->lut_r[i * 8 + j] = red[i] >> 6; 148 radeon_crtc->lut_b[i] = blue[i] >> 6;
140 radeon_crtc->lut_b[i * 8 + j] = blue[i] >> 6;
141 }
142 }
143 for (j = 0; j < 4; j++)
144 radeon_crtc->lut_g[i * 4 + j] = green[i] >> 6;
145 }
146 } else {
147 for (i = 0; i < 256; i++) {
148 radeon_crtc->lut_r[i] = red[i] >> 6;
149 radeon_crtc->lut_g[i] = green[i] >> 6;
150 radeon_crtc->lut_b[i] = blue[i] >> 6;
151 }
152 } 149 }
153 150
154 radeon_crtc_load_lut(crtc); 151 radeon_crtc_load_lut(crtc);
@@ -724,7 +721,11 @@ int radeon_modeset_init(struct radeon_device *rdev)
724 if (ret) { 721 if (ret) {
725 return ret; 722 return ret;
726 } 723 }
727 /* allocate crtcs - TODO single crtc */ 724
725 if (rdev->flags & RADEON_SINGLE_CRTC)
726 num_crtc = 1;
727
728 /* allocate crtcs */
728 for (i = 0; i < num_crtc; i++) { 729 for (i = 0; i < num_crtc; i++) {
729 radeon_crtc_init(rdev->ddev, i); 730 radeon_crtc_init(rdev->ddev, i);
730 } 731 }
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c
index 621646752cd2..a65ab1a0dad2 100644
--- a/drivers/gpu/drm/radeon/radeon_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_encoders.c
@@ -1345,6 +1345,7 @@ radeon_atombios_set_dig_info(struct radeon_encoder *radeon_encoder)
1345void 1345void
1346radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t supported_device) 1346radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t supported_device)
1347{ 1347{
1348 struct radeon_device *rdev = dev->dev_private;
1348 struct drm_encoder *encoder; 1349 struct drm_encoder *encoder;
1349 struct radeon_encoder *radeon_encoder; 1350 struct radeon_encoder *radeon_encoder;
1350 1351
@@ -1364,7 +1365,10 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su
1364 return; 1365 return;
1365 1366
1366 encoder = &radeon_encoder->base; 1367 encoder = &radeon_encoder->base;
1367 encoder->possible_crtcs = 0x3; 1368 if (rdev->flags & RADEON_SINGLE_CRTC)
1369 encoder->possible_crtcs = 0x1;
1370 else
1371 encoder->possible_crtcs = 0x3;
1368 encoder->possible_clones = 0; 1372 encoder->possible_clones = 0;
1369 1373
1370 radeon_encoder->enc_priv = NULL; 1374 radeon_encoder->enc_priv = NULL;
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c
index 1ba704eedefb..b38c4c8e2c61 100644
--- a/drivers/gpu/drm/radeon/radeon_fb.c
+++ b/drivers/gpu/drm/radeon/radeon_fb.c
@@ -55,6 +55,7 @@ static struct fb_ops radeonfb_ops = {
55 .fb_imageblit = cfb_imageblit, 55 .fb_imageblit = cfb_imageblit,
56 .fb_pan_display = drm_fb_helper_pan_display, 56 .fb_pan_display = drm_fb_helper_pan_display,
57 .fb_blank = drm_fb_helper_blank, 57 .fb_blank = drm_fb_helper_blank,
58 .fb_setcmap = drm_fb_helper_setcmap,
58}; 59};
59 60
60/** 61/**
@@ -123,6 +124,7 @@ static int radeon_align_pitch(struct radeon_device *rdev, int width, int bpp, bo
123 124
124static struct drm_fb_helper_funcs radeon_fb_helper_funcs = { 125static struct drm_fb_helper_funcs radeon_fb_helper_funcs = {
125 .gamma_set = radeon_crtc_fb_gamma_set, 126 .gamma_set = radeon_crtc_fb_gamma_set,
127 .gamma_get = radeon_crtc_fb_gamma_get,
126}; 128};
127 129
128int radeonfb_create(struct drm_device *dev, 130int radeonfb_create(struct drm_device *dev,
@@ -146,9 +148,15 @@ int radeonfb_create(struct drm_device *dev,
146 unsigned long tmp; 148 unsigned long tmp;
147 bool fb_tiled = false; /* useful for testing */ 149 bool fb_tiled = false; /* useful for testing */
148 u32 tiling_flags = 0; 150 u32 tiling_flags = 0;
151 int crtc_count;
149 152
150 mode_cmd.width = surface_width; 153 mode_cmd.width = surface_width;
151 mode_cmd.height = surface_height; 154 mode_cmd.height = surface_height;
155
156 /* avivo can't scanout real 24bpp */
157 if ((surface_bpp == 24) && ASIC_IS_AVIVO(rdev))
158 surface_bpp = 32;
159
152 mode_cmd.bpp = surface_bpp; 160 mode_cmd.bpp = surface_bpp;
153 /* need to align pitch with crtc limits */ 161 /* need to align pitch with crtc limits */
154 mode_cmd.pitch = radeon_align_pitch(rdev, mode_cmd.width, mode_cmd.bpp, fb_tiled) * ((mode_cmd.bpp + 1) / 8); 162 mode_cmd.pitch = radeon_align_pitch(rdev, mode_cmd.width, mode_cmd.bpp, fb_tiled) * ((mode_cmd.bpp + 1) / 8);
@@ -217,7 +225,11 @@ int radeonfb_create(struct drm_device *dev,
217 rfbdev = info->par; 225 rfbdev = info->par;
218 rfbdev->helper.funcs = &radeon_fb_helper_funcs; 226 rfbdev->helper.funcs = &radeon_fb_helper_funcs;
219 rfbdev->helper.dev = dev; 227 rfbdev->helper.dev = dev;
220 ret = drm_fb_helper_init_crtc_count(&rfbdev->helper, 2, 228 if (rdev->flags & RADEON_SINGLE_CRTC)
229 crtc_count = 1;
230 else
231 crtc_count = 2;
232 ret = drm_fb_helper_init_crtc_count(&rfbdev->helper, crtc_count,
221 RADEONFB_CONN_LIMIT); 233 RADEONFB_CONN_LIMIT);
222 if (ret) 234 if (ret)
223 goto out_unref; 235 goto out_unref;
@@ -234,7 +246,7 @@ int radeonfb_create(struct drm_device *dev,
234 246
235 strcpy(info->fix.id, "radeondrmfb"); 247 strcpy(info->fix.id, "radeondrmfb");
236 248
237 drm_fb_helper_fill_fix(info, fb->pitch); 249 drm_fb_helper_fill_fix(info, fb->pitch, fb->depth);
238 250
239 info->flags = FBINFO_DEFAULT; 251 info->flags = FBINFO_DEFAULT;
240 info->fbops = &radeonfb_ops; 252 info->fbops = &radeonfb_ops;
@@ -309,7 +321,7 @@ int radeon_parse_options(char *options)
309 321
310int radeonfb_probe(struct drm_device *dev) 322int radeonfb_probe(struct drm_device *dev)
311{ 323{
312 return drm_fb_helper_single_fb_probe(dev, &radeonfb_create); 324 return drm_fb_helper_single_fb_probe(dev, 32, &radeonfb_create);
313} 325}
314 326
315int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *fb) 327int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *fb)
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c
index 1841145a7c4f..8e0a8759e428 100644
--- a/drivers/gpu/drm/radeon/radeon_irq_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c
@@ -83,8 +83,12 @@ void radeon_driver_irq_uninstall_kms(struct drm_device *dev)
83int radeon_irq_kms_init(struct radeon_device *rdev) 83int radeon_irq_kms_init(struct radeon_device *rdev)
84{ 84{
85 int r = 0; 85 int r = 0;
86 int num_crtc = 2;
86 87
87 r = drm_vblank_init(rdev->ddev, 2); 88 if (rdev->flags & RADEON_SINGLE_CRTC)
89 num_crtc = 1;
90
91 r = drm_vblank_init(rdev->ddev, num_crtc);
88 if (r) { 92 if (r) {
89 return r; 93 return r;
90 } 94 }
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
index 2b997a15fb1f..36410f85d705 100644
--- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
+++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
@@ -1053,6 +1053,7 @@ static const struct drm_crtc_helper_funcs legacy_helper_funcs = {
1053 .mode_set_base = radeon_crtc_set_base, 1053 .mode_set_base = radeon_crtc_set_base,
1054 .prepare = radeon_crtc_prepare, 1054 .prepare = radeon_crtc_prepare,
1055 .commit = radeon_crtc_commit, 1055 .commit = radeon_crtc_commit,
1056 .load_lut = radeon_crtc_load_lut,
1056}; 1057};
1057 1058
1058 1059
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
index b1547f700d73..6ceb958fd194 100644
--- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
@@ -881,7 +881,7 @@ static void radeon_legacy_tv_dac_mode_set(struct drm_encoder *encoder,
881 R420_TV_DAC_DACADJ_MASK | 881 R420_TV_DAC_DACADJ_MASK |
882 R420_TV_DAC_RDACPD | 882 R420_TV_DAC_RDACPD |
883 R420_TV_DAC_GDACPD | 883 R420_TV_DAC_GDACPD |
884 R420_TV_DAC_GDACPD | 884 R420_TV_DAC_BDACPD |
885 R420_TV_DAC_TVENABLE); 885 R420_TV_DAC_TVENABLE);
886 } else { 886 } else {
887 tv_dac_cntl &= ~(RADEON_TV_DAC_STD_MASK | 887 tv_dac_cntl &= ~(RADEON_TV_DAC_STD_MASK |
@@ -889,7 +889,7 @@ static void radeon_legacy_tv_dac_mode_set(struct drm_encoder *encoder,
889 RADEON_TV_DAC_DACADJ_MASK | 889 RADEON_TV_DAC_DACADJ_MASK |
890 RADEON_TV_DAC_RDACPD | 890 RADEON_TV_DAC_RDACPD |
891 RADEON_TV_DAC_GDACPD | 891 RADEON_TV_DAC_GDACPD |
892 RADEON_TV_DAC_GDACPD); 892 RADEON_TV_DAC_BDACPD);
893 } 893 }
894 894
895 /* FIXME TV */ 895 /* FIXME TV */
@@ -1318,7 +1318,10 @@ radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t
1318 return; 1318 return;
1319 1319
1320 encoder = &radeon_encoder->base; 1320 encoder = &radeon_encoder->base;
1321 encoder->possible_crtcs = 0x3; 1321 if (rdev->flags & RADEON_SINGLE_CRTC)
1322 encoder->possible_crtcs = 0x1;
1323 else
1324 encoder->possible_crtcs = 0x3;
1322 encoder->possible_clones = 0; 1325 encoder->possible_clones = 0;
1323 1326
1324 radeon_encoder->enc_priv = NULL; 1327 radeon_encoder->enc_priv = NULL;
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index 570a58729daf..e61226817ccf 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -407,6 +407,8 @@ extern void
407radeon_combios_encoder_dpms_scratch_regs(struct drm_encoder *encoder, bool on); 407radeon_combios_encoder_dpms_scratch_regs(struct drm_encoder *encoder, bool on);
408extern void radeon_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, 408extern void radeon_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
409 u16 blue, int regno); 409 u16 blue, int regno);
410extern void radeon_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
411 u16 *blue, int regno);
410struct drm_framebuffer *radeon_framebuffer_create(struct drm_device *dev, 412struct drm_framebuffer *radeon_framebuffer_create(struct drm_device *dev,
411 struct drm_mode_fb_cmd *mode_cmd, 413 struct drm_mode_fb_cmd *mode_cmd,
412 struct drm_gem_object *obj); 414 struct drm_gem_object *obj);
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c
index 73af463b7a59..1f056dadc5c2 100644
--- a/drivers/gpu/drm/radeon/radeon_object.c
+++ b/drivers/gpu/drm/radeon/radeon_object.c
@@ -400,11 +400,9 @@ void radeon_object_list_add_object(struct radeon_object_list *lobj,
400int radeon_object_list_reserve(struct list_head *head) 400int radeon_object_list_reserve(struct list_head *head)
401{ 401{
402 struct radeon_object_list *lobj; 402 struct radeon_object_list *lobj;
403 struct list_head *i;
404 int r; 403 int r;
405 404
406 list_for_each(i, head) { 405 list_for_each_entry(lobj, head, list){
407 lobj = list_entry(i, struct radeon_object_list, list);
408 if (!lobj->robj->pin_count) { 406 if (!lobj->robj->pin_count) {
409 r = radeon_object_reserve(lobj->robj, true); 407 r = radeon_object_reserve(lobj->robj, true);
410 if (unlikely(r != 0)) { 408 if (unlikely(r != 0)) {
@@ -420,13 +418,10 @@ int radeon_object_list_reserve(struct list_head *head)
420void radeon_object_list_unreserve(struct list_head *head) 418void radeon_object_list_unreserve(struct list_head *head)
421{ 419{
422 struct radeon_object_list *lobj; 420 struct radeon_object_list *lobj;
423 struct list_head *i;
424 421
425 list_for_each(i, head) { 422 list_for_each_entry(lobj, head, list) {
426 lobj = list_entry(i, struct radeon_object_list, list);
427 if (!lobj->robj->pin_count) { 423 if (!lobj->robj->pin_count) {
428 radeon_object_unreserve(lobj->robj); 424 radeon_object_unreserve(lobj->robj);
429 } else {
430 } 425 }
431 } 426 }
432} 427}
@@ -436,7 +431,6 @@ int radeon_object_list_validate(struct list_head *head, void *fence)
436 struct radeon_object_list *lobj; 431 struct radeon_object_list *lobj;
437 struct radeon_object *robj; 432 struct radeon_object *robj;
438 struct radeon_fence *old_fence = NULL; 433 struct radeon_fence *old_fence = NULL;
439 struct list_head *i;
440 int r; 434 int r;
441 435
442 r = radeon_object_list_reserve(head); 436 r = radeon_object_list_reserve(head);
@@ -444,8 +438,7 @@ int radeon_object_list_validate(struct list_head *head, void *fence)
444 radeon_object_list_unreserve(head); 438 radeon_object_list_unreserve(head);
445 return r; 439 return r;
446 } 440 }
447 list_for_each(i, head) { 441 list_for_each_entry(lobj, head, list) {
448 lobj = list_entry(i, struct radeon_object_list, list);
449 robj = lobj->robj; 442 robj = lobj->robj;
450 if (!robj->pin_count) { 443 if (!robj->pin_count) {
451 if (lobj->wdomain) { 444 if (lobj->wdomain) {
@@ -482,10 +475,8 @@ void radeon_object_list_unvalidate(struct list_head *head)
482{ 475{
483 struct radeon_object_list *lobj; 476 struct radeon_object_list *lobj;
484 struct radeon_fence *old_fence = NULL; 477 struct radeon_fence *old_fence = NULL;
485 struct list_head *i;
486 478
487 list_for_each(i, head) { 479 list_for_each_entry(lobj, head, list) {
488 lobj = list_entry(i, struct radeon_object_list, list);
489 old_fence = (struct radeon_fence *)lobj->robj->tobj.sync_obj; 480 old_fence = (struct radeon_fence *)lobj->robj->tobj.sync_obj;
490 lobj->robj->tobj.sync_obj = NULL; 481 lobj->robj->tobj.sync_obj = NULL;
491 if (old_fence) { 482 if (old_fence) {
diff --git a/drivers/gpu/drm/radeon/rs100d.h b/drivers/gpu/drm/radeon/rs100d.h
new file mode 100644
index 000000000000..48a913a06cfd
--- /dev/null
+++ b/drivers/gpu/drm/radeon/rs100d.h
@@ -0,0 +1,40 @@
1/*
2 * Copyright 2008 Advanced Micro Devices, Inc.
3 * Copyright 2008 Red Hat Inc.
4 * Copyright 2009 Jerome Glisse.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors: Dave Airlie
25 * Alex Deucher
26 * Jerome Glisse
27 */
28#ifndef __RS100D_H__
29#define __RS100D_H__
30
31/* Registers */
32#define R_00015C_NB_TOM 0x00015C
33#define S_00015C_MC_FB_START(x) (((x) & 0xFFFF) << 0)
34#define G_00015C_MC_FB_START(x) (((x) >> 0) & 0xFFFF)
35#define C_00015C_MC_FB_START 0xFFFF0000
36#define S_00015C_MC_FB_TOP(x) (((x) & 0xFFFF) << 16)
37#define G_00015C_MC_FB_TOP(x) (((x) >> 16) & 0xFFFF)
38#define C_00015C_MC_FB_TOP 0x0000FFFF
39
40#endif
diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c
index a3fbdad938c7..a769c296f6a6 100644
--- a/drivers/gpu/drm/radeon/rs400.c
+++ b/drivers/gpu/drm/radeon/rs400.c
@@ -27,27 +27,12 @@
27 */ 27 */
28#include <linux/seq_file.h> 28#include <linux/seq_file.h>
29#include <drm/drmP.h> 29#include <drm/drmP.h>
30#include "radeon_reg.h"
31#include "radeon.h" 30#include "radeon.h"
31#include "rs400d.h"
32 32
33/* rs400,rs480 depends on : */ 33/* This files gather functions specifics to : rs400,rs480 */
34void r100_hdp_reset(struct radeon_device *rdev); 34static int rs400_debugfs_pcie_gart_info_init(struct radeon_device *rdev);
35void r100_mc_disable_clients(struct radeon_device *rdev);
36int r300_mc_wait_for_idle(struct radeon_device *rdev);
37void r420_pipes_init(struct radeon_device *rdev);
38 35
39/* This files gather functions specifics to :
40 * rs400,rs480
41 *
42 * Some of these functions might be used by newer ASICs.
43 */
44void rs400_gpu_init(struct radeon_device *rdev);
45int rs400_debugfs_pcie_gart_info_init(struct radeon_device *rdev);
46
47
48/*
49 * GART functions.
50 */
51void rs400_gart_adjust_size(struct radeon_device *rdev) 36void rs400_gart_adjust_size(struct radeon_device *rdev)
52{ 37{
53 /* Check gart size */ 38 /* Check gart size */
@@ -238,61 +223,6 @@ int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)
238 return 0; 223 return 0;
239} 224}
240 225
241
242/*
243 * MC functions.
244 */
245int rs400_mc_init(struct radeon_device *rdev)
246{
247 uint32_t tmp;
248 int r;
249
250 if (r100_debugfs_rbbm_init(rdev)) {
251 DRM_ERROR("Failed to register debugfs file for RBBM !\n");
252 }
253
254 rs400_gpu_init(rdev);
255 rs400_gart_disable(rdev);
256 rdev->mc.gtt_location = rdev->mc.mc_vram_size;
257 rdev->mc.gtt_location += (rdev->mc.gtt_size - 1);
258 rdev->mc.gtt_location &= ~(rdev->mc.gtt_size - 1);
259 r = radeon_mc_setup(rdev);
260 if (r) {
261 return r;
262 }
263
264 r100_mc_disable_clients(rdev);
265 if (r300_mc_wait_for_idle(rdev)) {
266 printk(KERN_WARNING "Failed to wait MC idle while "
267 "programming pipes. Bad things might happen.\n");
268 }
269
270 tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1;
271 tmp = REG_SET(RADEON_MC_FB_TOP, tmp >> 16);
272 tmp |= REG_SET(RADEON_MC_FB_START, rdev->mc.vram_location >> 16);
273 WREG32(RADEON_MC_FB_LOCATION, tmp);
274 tmp = RREG32(RADEON_HOST_PATH_CNTL) | RADEON_HP_LIN_RD_CACHE_DIS;
275 WREG32(RADEON_HOST_PATH_CNTL, tmp | RADEON_HDP_SOFT_RESET | RADEON_HDP_READ_BUFFER_INVALIDATE);
276 (void)RREG32(RADEON_HOST_PATH_CNTL);
277 WREG32(RADEON_HOST_PATH_CNTL, tmp);
278 (void)RREG32(RADEON_HOST_PATH_CNTL);
279
280 return 0;
281}
282
283void rs400_mc_fini(struct radeon_device *rdev)
284{
285}
286
287
288/*
289 * Global GPU functions
290 */
291void rs400_errata(struct radeon_device *rdev)
292{
293 rdev->pll_errata = 0;
294}
295
296void rs400_gpu_init(struct radeon_device *rdev) 226void rs400_gpu_init(struct radeon_device *rdev)
297{ 227{
298 /* FIXME: HDP same place on rs400 ? */ 228 /* FIXME: HDP same place on rs400 ? */
@@ -305,10 +235,6 @@ void rs400_gpu_init(struct radeon_device *rdev)
305 } 235 }
306} 236}
307 237
308
309/*
310 * VRAM info.
311 */
312void rs400_vram_info(struct radeon_device *rdev) 238void rs400_vram_info(struct radeon_device *rdev)
313{ 239{
314 rs400_gart_adjust_size(rdev); 240 rs400_gart_adjust_size(rdev);
@@ -319,10 +245,6 @@ void rs400_vram_info(struct radeon_device *rdev)
319 r100_vram_init_sizes(rdev); 245 r100_vram_init_sizes(rdev);
320} 246}
321 247
322
323/*
324 * Indirect registers accessor
325 */
326uint32_t rs400_mc_rreg(struct radeon_device *rdev, uint32_t reg) 248uint32_t rs400_mc_rreg(struct radeon_device *rdev, uint32_t reg)
327{ 249{
328 uint32_t r; 250 uint32_t r;
@@ -340,10 +262,6 @@ void rs400_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
340 WREG32(RS480_NB_MC_INDEX, 0xff); 262 WREG32(RS480_NB_MC_INDEX, 0xff);
341} 263}
342 264
343
344/*
345 * Debugfs info
346 */
347#if defined(CONFIG_DEBUG_FS) 265#if defined(CONFIG_DEBUG_FS)
348static int rs400_debugfs_gart_info(struct seq_file *m, void *data) 266static int rs400_debugfs_gart_info(struct seq_file *m, void *data)
349{ 267{
@@ -419,7 +337,7 @@ static struct drm_info_list rs400_gart_info_list[] = {
419}; 337};
420#endif 338#endif
421 339
422int rs400_debugfs_pcie_gart_info_init(struct radeon_device *rdev) 340static int rs400_debugfs_pcie_gart_info_init(struct radeon_device *rdev)
423{ 341{
424#if defined(CONFIG_DEBUG_FS) 342#if defined(CONFIG_DEBUG_FS)
425 return radeon_debugfs_add_files(rdev, rs400_gart_info_list, 1); 343 return radeon_debugfs_add_files(rdev, rs400_gart_info_list, 1);
@@ -427,3 +345,188 @@ int rs400_debugfs_pcie_gart_info_init(struct radeon_device *rdev)
427 return 0; 345 return 0;
428#endif 346#endif
429} 347}
348
349static int rs400_mc_init(struct radeon_device *rdev)
350{
351 int r;
352 u32 tmp;
353
354 /* Setup GPU memory space */
355 tmp = G_00015C_MC_FB_START(RREG32(R_00015C_NB_TOM));
356 rdev->mc.vram_location = G_00015C_MC_FB_START(tmp) << 16;
357 rdev->mc.gtt_location = 0xFFFFFFFFUL;
358 r = radeon_mc_setup(rdev);
359 if (r)
360 return r;
361 return 0;
362}
363
364void rs400_mc_program(struct radeon_device *rdev)
365{
366 struct r100_mc_save save;
367
368 /* Stops all mc clients */
369 r100_mc_stop(rdev, &save);
370
371 /* Wait for mc idle */
372 if (r300_mc_wait_for_idle(rdev))
373 dev_warn(rdev->dev, "Wait MC idle timeout before updating MC.\n");
374 WREG32(R_000148_MC_FB_LOCATION,
375 S_000148_MC_FB_START(rdev->mc.vram_start >> 16) |
376 S_000148_MC_FB_TOP(rdev->mc.vram_end >> 16));
377
378 r100_mc_resume(rdev, &save);
379}
380
381static int rs400_startup(struct radeon_device *rdev)
382{
383 int r;
384
385 rs400_mc_program(rdev);
386 /* Resume clock */
387 r300_clock_startup(rdev);
388 /* Initialize GPU configuration (# pipes, ...) */
389 rs400_gpu_init(rdev);
390 /* Initialize GART (initialize after TTM so we can allocate
391 * memory through TTM but finalize after TTM) */
392 r = rs400_gart_enable(rdev);
393 if (r)
394 return r;
395 /* Enable IRQ */
396 rdev->irq.sw_int = true;
397 r100_irq_set(rdev);
398 /* 1M ring buffer */
399 r = r100_cp_init(rdev, 1024 * 1024);
400 if (r) {
401 dev_err(rdev->dev, "failled initializing CP (%d).\n", r);
402 return r;
403 }
404 r = r100_wb_init(rdev);
405 if (r)
406 dev_err(rdev->dev, "failled initializing WB (%d).\n", r);
407 r = r100_ib_init(rdev);
408 if (r) {
409 dev_err(rdev->dev, "failled initializing IB (%d).\n", r);
410 return r;
411 }
412 return 0;
413}
414
415int rs400_resume(struct radeon_device *rdev)
416{
417 /* Make sur GART are not working */
418 rs400_gart_disable(rdev);
419 /* Resume clock before doing reset */
420 r300_clock_startup(rdev);
421 /* Reset gpu before posting otherwise ATOM will enter infinite loop */
422 if (radeon_gpu_reset(rdev)) {
423 dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
424 RREG32(R_000E40_RBBM_STATUS),
425 RREG32(R_0007C0_CP_STAT));
426 }
427 /* post */
428 radeon_combios_asic_init(rdev->ddev);
429 /* Resume clock after posting */
430 r300_clock_startup(rdev);
431 return rs400_startup(rdev);
432}
433
434int rs400_suspend(struct radeon_device *rdev)
435{
436 r100_cp_disable(rdev);
437 r100_wb_disable(rdev);
438 r100_irq_disable(rdev);
439 rs400_gart_disable(rdev);
440 return 0;
441}
442
443void rs400_fini(struct radeon_device *rdev)
444{
445 rs400_suspend(rdev);
446 r100_cp_fini(rdev);
447 r100_wb_fini(rdev);
448 r100_ib_fini(rdev);
449 radeon_gem_fini(rdev);
450 rs400_gart_fini(rdev);
451 radeon_irq_kms_fini(rdev);
452 radeon_fence_driver_fini(rdev);
453 radeon_object_fini(rdev);
454 radeon_atombios_fini(rdev);
455 kfree(rdev->bios);
456 rdev->bios = NULL;
457}
458
459int rs400_init(struct radeon_device *rdev)
460{
461 int r;
462
463 /* Disable VGA */
464 r100_vga_render_disable(rdev);
465 /* Initialize scratch registers */
466 radeon_scratch_init(rdev);
467 /* Initialize surface registers */
468 radeon_surface_init(rdev);
469 /* TODO: disable VGA need to use VGA request */
470 /* BIOS*/
471 if (!radeon_get_bios(rdev)) {
472 if (ASIC_IS_AVIVO(rdev))
473 return -EINVAL;
474 }
475 if (rdev->is_atom_bios) {
476 dev_err(rdev->dev, "Expecting combios for RS400/RS480 GPU\n");
477 return -EINVAL;
478 } else {
479 r = radeon_combios_init(rdev);
480 if (r)
481 return r;
482 }
483 /* Reset gpu before posting otherwise ATOM will enter infinite loop */
484 if (radeon_gpu_reset(rdev)) {
485 dev_warn(rdev->dev,
486 "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
487 RREG32(R_000E40_RBBM_STATUS),
488 RREG32(R_0007C0_CP_STAT));
489 }
490 /* check if cards are posted or not */
491 if (!radeon_card_posted(rdev) && rdev->bios) {
492 DRM_INFO("GPU not posted. posting now...\n");
493 radeon_combios_asic_init(rdev->ddev);
494 }
495 /* Initialize clocks */
496 radeon_get_clock_info(rdev->ddev);
497 /* Get vram informations */
498 rs400_vram_info(rdev);
499 /* Initialize memory controller (also test AGP) */
500 r = rs400_mc_init(rdev);
501 if (r)
502 return r;
503 /* Fence driver */
504 r = radeon_fence_driver_init(rdev);
505 if (r)
506 return r;
507 r = radeon_irq_kms_init(rdev);
508 if (r)
509 return r;
510 /* Memory manager */
511 r = radeon_object_init(rdev);
512 if (r)
513 return r;
514 r = rs400_gart_init(rdev);
515 if (r)
516 return r;
517 r300_set_reg_safe(rdev);
518 rdev->accel_working = true;
519 r = rs400_startup(rdev);
520 if (r) {
521 /* Somethings want wront with the accel init stop accel */
522 dev_err(rdev->dev, "Disabling GPU acceleration\n");
523 rs400_suspend(rdev);
524 r100_cp_fini(rdev);
525 r100_wb_fini(rdev);
526 r100_ib_fini(rdev);
527 rs400_gart_fini(rdev);
528 radeon_irq_kms_fini(rdev);
529 rdev->accel_working = false;
530 }
531 return 0;
532}
diff --git a/drivers/gpu/drm/radeon/rs400d.h b/drivers/gpu/drm/radeon/rs400d.h
new file mode 100644
index 000000000000..6d8bac58ced9
--- /dev/null
+++ b/drivers/gpu/drm/radeon/rs400d.h
@@ -0,0 +1,160 @@
1/*
2 * Copyright 2008 Advanced Micro Devices, Inc.
3 * Copyright 2008 Red Hat Inc.
4 * Copyright 2009 Jerome Glisse.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors: Dave Airlie
25 * Alex Deucher
26 * Jerome Glisse
27 */
28#ifndef __RS400D_H__
29#define __RS400D_H__
30
31/* Registers */
32#define R_000148_MC_FB_LOCATION 0x000148
33#define S_000148_MC_FB_START(x) (((x) & 0xFFFF) << 0)
34#define G_000148_MC_FB_START(x) (((x) >> 0) & 0xFFFF)
35#define C_000148_MC_FB_START 0xFFFF0000
36#define S_000148_MC_FB_TOP(x) (((x) & 0xFFFF) << 16)
37#define G_000148_MC_FB_TOP(x) (((x) >> 16) & 0xFFFF)
38#define C_000148_MC_FB_TOP 0x0000FFFF
39#define R_00015C_NB_TOM 0x00015C
40#define S_00015C_MC_FB_START(x) (((x) & 0xFFFF) << 0)
41#define G_00015C_MC_FB_START(x) (((x) >> 0) & 0xFFFF)
42#define C_00015C_MC_FB_START 0xFFFF0000
43#define S_00015C_MC_FB_TOP(x) (((x) & 0xFFFF) << 16)
44#define G_00015C_MC_FB_TOP(x) (((x) >> 16) & 0xFFFF)
45#define C_00015C_MC_FB_TOP 0x0000FFFF
46#define R_0007C0_CP_STAT 0x0007C0
47#define S_0007C0_MRU_BUSY(x) (((x) & 0x1) << 0)
48#define G_0007C0_MRU_BUSY(x) (((x) >> 0) & 0x1)
49#define C_0007C0_MRU_BUSY 0xFFFFFFFE
50#define S_0007C0_MWU_BUSY(x) (((x) & 0x1) << 1)
51#define G_0007C0_MWU_BUSY(x) (((x) >> 1) & 0x1)
52#define C_0007C0_MWU_BUSY 0xFFFFFFFD
53#define S_0007C0_RSIU_BUSY(x) (((x) & 0x1) << 2)
54#define G_0007C0_RSIU_BUSY(x) (((x) >> 2) & 0x1)
55#define C_0007C0_RSIU_BUSY 0xFFFFFFFB
56#define S_0007C0_RCIU_BUSY(x) (((x) & 0x1) << 3)
57#define G_0007C0_RCIU_BUSY(x) (((x) >> 3) & 0x1)
58#define C_0007C0_RCIU_BUSY 0xFFFFFFF7
59#define S_0007C0_CSF_PRIMARY_BUSY(x) (((x) & 0x1) << 9)
60#define G_0007C0_CSF_PRIMARY_BUSY(x) (((x) >> 9) & 0x1)
61#define C_0007C0_CSF_PRIMARY_BUSY 0xFFFFFDFF
62#define S_0007C0_CSF_INDIRECT_BUSY(x) (((x) & 0x1) << 10)
63#define G_0007C0_CSF_INDIRECT_BUSY(x) (((x) >> 10) & 0x1)
64#define C_0007C0_CSF_INDIRECT_BUSY 0xFFFFFBFF
65#define S_0007C0_CSQ_PRIMARY_BUSY(x) (((x) & 0x1) << 11)
66#define G_0007C0_CSQ_PRIMARY_BUSY(x) (((x) >> 11) & 0x1)
67#define C_0007C0_CSQ_PRIMARY_BUSY 0xFFFFF7FF
68#define S_0007C0_CSQ_INDIRECT_BUSY(x) (((x) & 0x1) << 12)
69#define G_0007C0_CSQ_INDIRECT_BUSY(x) (((x) >> 12) & 0x1)
70#define C_0007C0_CSQ_INDIRECT_BUSY 0xFFFFEFFF
71#define S_0007C0_CSI_BUSY(x) (((x) & 0x1) << 13)
72#define G_0007C0_CSI_BUSY(x) (((x) >> 13) & 0x1)
73#define C_0007C0_CSI_BUSY 0xFFFFDFFF
74#define S_0007C0_CSF_INDIRECT2_BUSY(x) (((x) & 0x1) << 14)
75#define G_0007C0_CSF_INDIRECT2_BUSY(x) (((x) >> 14) & 0x1)
76#define C_0007C0_CSF_INDIRECT2_BUSY 0xFFFFBFFF
77#define S_0007C0_CSQ_INDIRECT2_BUSY(x) (((x) & 0x1) << 15)
78#define G_0007C0_CSQ_INDIRECT2_BUSY(x) (((x) >> 15) & 0x1)
79#define C_0007C0_CSQ_INDIRECT2_BUSY 0xFFFF7FFF
80#define S_0007C0_GUIDMA_BUSY(x) (((x) & 0x1) << 28)
81#define G_0007C0_GUIDMA_BUSY(x) (((x) >> 28) & 0x1)
82#define C_0007C0_GUIDMA_BUSY 0xEFFFFFFF
83#define S_0007C0_VIDDMA_BUSY(x) (((x) & 0x1) << 29)
84#define G_0007C0_VIDDMA_BUSY(x) (((x) >> 29) & 0x1)
85#define C_0007C0_VIDDMA_BUSY 0xDFFFFFFF
86#define S_0007C0_CMDSTRM_BUSY(x) (((x) & 0x1) << 30)
87#define G_0007C0_CMDSTRM_BUSY(x) (((x) >> 30) & 0x1)
88#define C_0007C0_CMDSTRM_BUSY 0xBFFFFFFF
89#define S_0007C0_CP_BUSY(x) (((x) & 0x1) << 31)
90#define G_0007C0_CP_BUSY(x) (((x) >> 31) & 0x1)
91#define C_0007C0_CP_BUSY 0x7FFFFFFF
92#define R_000E40_RBBM_STATUS 0x000E40
93#define S_000E40_CMDFIFO_AVAIL(x) (((x) & 0x7F) << 0)
94#define G_000E40_CMDFIFO_AVAIL(x) (((x) >> 0) & 0x7F)
95#define C_000E40_CMDFIFO_AVAIL 0xFFFFFF80
96#define S_000E40_HIRQ_ON_RBB(x) (((x) & 0x1) << 8)
97#define G_000E40_HIRQ_ON_RBB(x) (((x) >> 8) & 0x1)
98#define C_000E40_HIRQ_ON_RBB 0xFFFFFEFF
99#define S_000E40_CPRQ_ON_RBB(x) (((x) & 0x1) << 9)
100#define G_000E40_CPRQ_ON_RBB(x) (((x) >> 9) & 0x1)
101#define C_000E40_CPRQ_ON_RBB 0xFFFFFDFF
102#define S_000E40_CFRQ_ON_RBB(x) (((x) & 0x1) << 10)
103#define G_000E40_CFRQ_ON_RBB(x) (((x) >> 10) & 0x1)
104#define C_000E40_CFRQ_ON_RBB 0xFFFFFBFF
105#define S_000E40_HIRQ_IN_RTBUF(x) (((x) & 0x1) << 11)
106#define G_000E40_HIRQ_IN_RTBUF(x) (((x) >> 11) & 0x1)
107#define C_000E40_HIRQ_IN_RTBUF 0xFFFFF7FF
108#define S_000E40_CPRQ_IN_RTBUF(x) (((x) & 0x1) << 12)
109#define G_000E40_CPRQ_IN_RTBUF(x) (((x) >> 12) & 0x1)
110#define C_000E40_CPRQ_IN_RTBUF 0xFFFFEFFF
111#define S_000E40_CFRQ_IN_RTBUF(x) (((x) & 0x1) << 13)
112#define G_000E40_CFRQ_IN_RTBUF(x) (((x) >> 13) & 0x1)
113#define C_000E40_CFRQ_IN_RTBUF 0xFFFFDFFF
114#define S_000E40_CF_PIPE_BUSY(x) (((x) & 0x1) << 14)
115#define G_000E40_CF_PIPE_BUSY(x) (((x) >> 14) & 0x1)
116#define C_000E40_CF_PIPE_BUSY 0xFFFFBFFF
117#define S_000E40_ENG_EV_BUSY(x) (((x) & 0x1) << 15)
118#define G_000E40_ENG_EV_BUSY(x) (((x) >> 15) & 0x1)
119#define C_000E40_ENG_EV_BUSY 0xFFFF7FFF
120#define S_000E40_CP_CMDSTRM_BUSY(x) (((x) & 0x1) << 16)
121#define G_000E40_CP_CMDSTRM_BUSY(x) (((x) >> 16) & 0x1)
122#define C_000E40_CP_CMDSTRM_BUSY 0xFFFEFFFF
123#define S_000E40_E2_BUSY(x) (((x) & 0x1) << 17)
124#define G_000E40_E2_BUSY(x) (((x) >> 17) & 0x1)
125#define C_000E40_E2_BUSY 0xFFFDFFFF
126#define S_000E40_RB2D_BUSY(x) (((x) & 0x1) << 18)
127#define G_000E40_RB2D_BUSY(x) (((x) >> 18) & 0x1)
128#define C_000E40_RB2D_BUSY 0xFFFBFFFF
129#define S_000E40_RB3D_BUSY(x) (((x) & 0x1) << 19)
130#define G_000E40_RB3D_BUSY(x) (((x) >> 19) & 0x1)
131#define C_000E40_RB3D_BUSY 0xFFF7FFFF
132#define S_000E40_VAP_BUSY(x) (((x) & 0x1) << 20)
133#define G_000E40_VAP_BUSY(x) (((x) >> 20) & 0x1)
134#define C_000E40_VAP_BUSY 0xFFEFFFFF
135#define S_000E40_RE_BUSY(x) (((x) & 0x1) << 21)
136#define G_000E40_RE_BUSY(x) (((x) >> 21) & 0x1)
137#define C_000E40_RE_BUSY 0xFFDFFFFF
138#define S_000E40_TAM_BUSY(x) (((x) & 0x1) << 22)
139#define G_000E40_TAM_BUSY(x) (((x) >> 22) & 0x1)
140#define C_000E40_TAM_BUSY 0xFFBFFFFF
141#define S_000E40_TDM_BUSY(x) (((x) & 0x1) << 23)
142#define G_000E40_TDM_BUSY(x) (((x) >> 23) & 0x1)
143#define C_000E40_TDM_BUSY 0xFF7FFFFF
144#define S_000E40_PB_BUSY(x) (((x) & 0x1) << 24)
145#define G_000E40_PB_BUSY(x) (((x) >> 24) & 0x1)
146#define C_000E40_PB_BUSY 0xFEFFFFFF
147#define S_000E40_TIM_BUSY(x) (((x) & 0x1) << 25)
148#define G_000E40_TIM_BUSY(x) (((x) >> 25) & 0x1)
149#define C_000E40_TIM_BUSY 0xFDFFFFFF
150#define S_000E40_GA_BUSY(x) (((x) & 0x1) << 26)
151#define G_000E40_GA_BUSY(x) (((x) >> 26) & 0x1)
152#define C_000E40_GA_BUSY 0xFBFFFFFF
153#define S_000E40_CBA2D_BUSY(x) (((x) & 0x1) << 27)
154#define G_000E40_CBA2D_BUSY(x) (((x) >> 27) & 0x1)
155#define C_000E40_CBA2D_BUSY 0xF7FFFFFF
156#define S_000E40_GUI_ACTIVE(x) (((x) & 0x1) << 31)
157#define G_000E40_GUI_ACTIVE(x) (((x) >> 31) & 0x1)
158#define C_000E40_GUI_ACTIVE 0x7FFFFFFF
159
160#endif
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c
index 4a4fe1cb131c..10dfa78762da 100644
--- a/drivers/gpu/drm/radeon/rs600.c
+++ b/drivers/gpu/drm/radeon/rs600.c
@@ -25,27 +25,26 @@
25 * Alex Deucher 25 * Alex Deucher
26 * Jerome Glisse 26 * Jerome Glisse
27 */ 27 */
28/* RS600 / Radeon X1250/X1270 integrated GPU
29 *
30 * This file gather function specific to RS600 which is the IGP of
31 * the X1250/X1270 family supporting intel CPU (while RS690/RS740
32 * is the X1250/X1270 supporting AMD CPU). The display engine are
33 * the avivo one, bios is an atombios, 3D block are the one of the
34 * R4XX family. The GART is different from the RS400 one and is very
35 * close to the one of the R600 family (R600 likely being an evolution
36 * of the RS600 GART block).
37 */
28#include "drmP.h" 38#include "drmP.h"
29#include "radeon_reg.h"
30#include "radeon.h" 39#include "radeon.h"
40#include "atom.h"
41#include "rs600d.h"
31 42
32#include "rs600_reg_safe.h" 43#include "rs600_reg_safe.h"
33 44
34/* rs600 depends on : */
35void r100_hdp_reset(struct radeon_device *rdev);
36int r100_gui_wait_for_idle(struct radeon_device *rdev);
37int r300_mc_wait_for_idle(struct radeon_device *rdev);
38void r420_pipes_init(struct radeon_device *rdev);
39
40/* This files gather functions specifics to :
41 * rs600
42 *
43 * Some of these functions might be used by newer ASICs.
44 */
45void rs600_gpu_init(struct radeon_device *rdev); 45void rs600_gpu_init(struct radeon_device *rdev);
46int rs600_mc_wait_for_idle(struct radeon_device *rdev); 46int rs600_mc_wait_for_idle(struct radeon_device *rdev);
47 47
48
49/* 48/*
50 * GART. 49 * GART.
51 */ 50 */
@@ -53,18 +52,18 @@ void rs600_gart_tlb_flush(struct radeon_device *rdev)
53{ 52{
54 uint32_t tmp; 53 uint32_t tmp;
55 54
56 tmp = RREG32_MC(RS600_MC_PT0_CNTL); 55 tmp = RREG32_MC(R_000100_MC_PT0_CNTL);
57 tmp &= ~(RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE); 56 tmp &= C_000100_INVALIDATE_ALL_L1_TLBS & C_000100_INVALIDATE_L2_CACHE;
58 WREG32_MC(RS600_MC_PT0_CNTL, tmp); 57 WREG32_MC(R_000100_MC_PT0_CNTL, tmp);
59 58
60 tmp = RREG32_MC(RS600_MC_PT0_CNTL); 59 tmp = RREG32_MC(R_000100_MC_PT0_CNTL);
61 tmp |= RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE; 60 tmp |= S_000100_INVALIDATE_ALL_L1_TLBS(1) & S_000100_INVALIDATE_L2_CACHE(1);
62 WREG32_MC(RS600_MC_PT0_CNTL, tmp); 61 WREG32_MC(R_000100_MC_PT0_CNTL, tmp);
63 62
64 tmp = RREG32_MC(RS600_MC_PT0_CNTL); 63 tmp = RREG32_MC(R_000100_MC_PT0_CNTL);
65 tmp &= ~(RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE); 64 tmp &= C_000100_INVALIDATE_ALL_L1_TLBS & C_000100_INVALIDATE_L2_CACHE;
66 WREG32_MC(RS600_MC_PT0_CNTL, tmp); 65 WREG32_MC(R_000100_MC_PT0_CNTL, tmp);
67 tmp = RREG32_MC(RS600_MC_PT0_CNTL); 66 tmp = RREG32_MC(R_000100_MC_PT0_CNTL);
68} 67}
69 68
70int rs600_gart_init(struct radeon_device *rdev) 69int rs600_gart_init(struct radeon_device *rdev)
@@ -86,7 +85,7 @@ int rs600_gart_init(struct radeon_device *rdev)
86 85
87int rs600_gart_enable(struct radeon_device *rdev) 86int rs600_gart_enable(struct radeon_device *rdev)
88{ 87{
89 uint32_t tmp; 88 u32 tmp;
90 int r, i; 89 int r, i;
91 90
92 if (rdev->gart.table.vram.robj == NULL) { 91 if (rdev->gart.table.vram.robj == NULL) {
@@ -96,46 +95,50 @@ int rs600_gart_enable(struct radeon_device *rdev)
96 r = radeon_gart_table_vram_pin(rdev); 95 r = radeon_gart_table_vram_pin(rdev);
97 if (r) 96 if (r)
98 return r; 97 return r;
98 /* Enable bus master */
99 tmp = RREG32(R_00004C_BUS_CNTL) & C_00004C_BUS_MASTER_DIS;
100 WREG32(R_00004C_BUS_CNTL, tmp);
99 /* FIXME: setup default page */ 101 /* FIXME: setup default page */
100 WREG32_MC(RS600_MC_PT0_CNTL, 102 WREG32_MC(R_000100_MC_PT0_CNTL,
101 (RS600_EFFECTIVE_L2_CACHE_SIZE(6) | 103 (S_000100_EFFECTIVE_L2_CACHE_SIZE(6) |
102 RS600_EFFECTIVE_L2_QUEUE_SIZE(6))); 104 S_000100_EFFECTIVE_L2_QUEUE_SIZE(6)));
103 for (i = 0; i < 19; i++) { 105 for (i = 0; i < 19; i++) {
104 WREG32_MC(RS600_MC_PT0_CLIENT0_CNTL + i, 106 WREG32_MC(R_00016C_MC_PT0_CLIENT0_CNTL + i,
105 (RS600_ENABLE_TRANSLATION_MODE_OVERRIDE | 107 S_00016C_ENABLE_TRANSLATION_MODE_OVERRIDE(1) |
106 RS600_SYSTEM_ACCESS_MODE_IN_SYS | 108 S_00016C_SYSTEM_ACCESS_MODE_MASK(
107 RS600_SYSTEM_APERTURE_UNMAPPED_ACCESS_DEFAULT_PAGE | 109 V_00016C_SYSTEM_ACCESS_MODE_IN_SYS) |
108 RS600_EFFECTIVE_L1_CACHE_SIZE(3) | 110 S_00016C_SYSTEM_APERTURE_UNMAPPED_ACCESS(
109 RS600_ENABLE_FRAGMENT_PROCESSING | 111 V_00016C_SYSTEM_APERTURE_UNMAPPED_DEFAULT_PAGE) |
110 RS600_EFFECTIVE_L1_QUEUE_SIZE(3))); 112 S_00016C_EFFECTIVE_L1_CACHE_SIZE(1) |
113 S_00016C_ENABLE_FRAGMENT_PROCESSING(1) |
114 S_00016C_EFFECTIVE_L1_QUEUE_SIZE(1));
111 } 115 }
112 116
113 /* System context map to GART space */ 117 /* System context map to GART space */
114 WREG32_MC(RS600_MC_PT0_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.gtt_location); 118 WREG32_MC(R_000112_MC_PT0_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.gtt_start);
115 tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 1; 119 WREG32_MC(R_000114_MC_PT0_SYSTEM_APERTURE_HIGH_ADDR, rdev->mc.gtt_end);
116 WREG32_MC(RS600_MC_PT0_SYSTEM_APERTURE_HIGH_ADDR, tmp);
117 120
118 /* enable first context */ 121 /* enable first context */
119 WREG32_MC(RS600_MC_PT0_CONTEXT0_FLAT_START_ADDR, rdev->mc.gtt_location); 122 WREG32_MC(R_00013C_MC_PT0_CONTEXT0_FLAT_START_ADDR, rdev->mc.gtt_start);
120 tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 1; 123 WREG32_MC(R_00014C_MC_PT0_CONTEXT0_FLAT_END_ADDR, rdev->mc.gtt_end);
121 WREG32_MC(RS600_MC_PT0_CONTEXT0_FLAT_END_ADDR, tmp); 124 WREG32_MC(R_000102_MC_PT0_CONTEXT0_CNTL,
122 WREG32_MC(RS600_MC_PT0_CONTEXT0_CNTL, 125 S_000102_ENABLE_PAGE_TABLE(1) |
123 (RS600_ENABLE_PAGE_TABLE | RS600_PAGE_TABLE_TYPE_FLAT)); 126 S_000102_PAGE_TABLE_DEPTH(V_000102_PAGE_TABLE_FLAT));
124 /* disable all other contexts */ 127 /* disable all other contexts */
125 for (i = 1; i < 8; i++) { 128 for (i = 1; i < 8; i++) {
126 WREG32_MC(RS600_MC_PT0_CONTEXT0_CNTL + i, 0); 129 WREG32_MC(R_000102_MC_PT0_CONTEXT0_CNTL + i, 0);
127 } 130 }
128 131
129 /* setup the page table */ 132 /* setup the page table */
130 WREG32_MC(RS600_MC_PT0_CONTEXT0_FLAT_BASE_ADDR, 133 WREG32_MC(R_00012C_MC_PT0_CONTEXT0_FLAT_BASE_ADDR,
131 rdev->gart.table_addr); 134 rdev->gart.table_addr);
132 WREG32_MC(RS600_MC_PT0_CONTEXT0_DEFAULT_READ_ADDR, 0); 135 WREG32_MC(R_00011C_MC_PT0_CONTEXT0_DEFAULT_READ_ADDR, 0);
133 136
134 /* enable page tables */ 137 /* enable page tables */
135 tmp = RREG32_MC(RS600_MC_PT0_CNTL); 138 tmp = RREG32_MC(R_000100_MC_PT0_CNTL);
136 WREG32_MC(RS600_MC_PT0_CNTL, (tmp | RS600_ENABLE_PT)); 139 WREG32_MC(R_000100_MC_PT0_CNTL, (tmp | S_000100_ENABLE_PT(1)));
137 tmp = RREG32_MC(RS600_MC_CNTL1); 140 tmp = RREG32_MC(R_000009_MC_CNTL1);
138 WREG32_MC(RS600_MC_CNTL1, (tmp | RS600_ENABLE_PAGE_TABLES)); 141 WREG32_MC(R_000009_MC_CNTL1, (tmp | S_000009_ENABLE_PAGE_TABLES(1)));
139 rs600_gart_tlb_flush(rdev); 142 rs600_gart_tlb_flush(rdev);
140 rdev->gart.ready = true; 143 rdev->gart.ready = true;
141 return 0; 144 return 0;
@@ -146,10 +149,9 @@ void rs600_gart_disable(struct radeon_device *rdev)
146 uint32_t tmp; 149 uint32_t tmp;
147 150
148 /* FIXME: disable out of gart access */ 151 /* FIXME: disable out of gart access */
149 WREG32_MC(RS600_MC_PT0_CNTL, 0); 152 WREG32_MC(R_000100_MC_PT0_CNTL, 0);
150 tmp = RREG32_MC(RS600_MC_CNTL1); 153 tmp = RREG32_MC(R_000009_MC_CNTL1);
151 tmp &= ~RS600_ENABLE_PAGE_TABLES; 154 WREG32_MC(R_000009_MC_CNTL1, tmp & C_000009_ENABLE_PAGE_TABLES);
152 WREG32_MC(RS600_MC_CNTL1, tmp);
153 if (rdev->gart.table.vram.robj) { 155 if (rdev->gart.table.vram.robj) {
154 radeon_object_kunmap(rdev->gart.table.vram.robj); 156 radeon_object_kunmap(rdev->gart.table.vram.robj);
155 radeon_object_unpin(rdev->gart.table.vram.robj); 157 radeon_object_unpin(rdev->gart.table.vram.robj);
@@ -183,129 +185,61 @@ int rs600_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)
183 return 0; 185 return 0;
184} 186}
185 187
186
187/*
188 * MC.
189 */
190void rs600_mc_disable_clients(struct radeon_device *rdev)
191{
192 unsigned tmp;
193
194 if (r100_gui_wait_for_idle(rdev)) {
195 printk(KERN_WARNING "Failed to wait GUI idle while "
196 "programming pipes. Bad things might happen.\n");
197 }
198
199 rv515_vga_render_disable(rdev);
200
201 tmp = RREG32(AVIVO_D1VGA_CONTROL);
202 WREG32(AVIVO_D1VGA_CONTROL, tmp & ~AVIVO_DVGA_CONTROL_MODE_ENABLE);
203 tmp = RREG32(AVIVO_D2VGA_CONTROL);
204 WREG32(AVIVO_D2VGA_CONTROL, tmp & ~AVIVO_DVGA_CONTROL_MODE_ENABLE);
205
206 tmp = RREG32(AVIVO_D1CRTC_CONTROL);
207 WREG32(AVIVO_D1CRTC_CONTROL, tmp & ~AVIVO_CRTC_EN);
208 tmp = RREG32(AVIVO_D2CRTC_CONTROL);
209 WREG32(AVIVO_D2CRTC_CONTROL, tmp & ~AVIVO_CRTC_EN);
210
211 /* make sure all previous write got through */
212 tmp = RREG32(AVIVO_D2CRTC_CONTROL);
213
214 mdelay(1);
215}
216
217int rs600_mc_init(struct radeon_device *rdev)
218{
219 uint32_t tmp;
220 int r;
221
222 if (r100_debugfs_rbbm_init(rdev)) {
223 DRM_ERROR("Failed to register debugfs file for RBBM !\n");
224 }
225
226 rs600_gpu_init(rdev);
227 rs600_gart_disable(rdev);
228
229 /* Setup GPU memory space */
230 rdev->mc.vram_location = 0xFFFFFFFFUL;
231 rdev->mc.gtt_location = 0xFFFFFFFFUL;
232 r = radeon_mc_setup(rdev);
233 if (r) {
234 return r;
235 }
236
237 /* Program GPU memory space */
238 /* Enable bus master */
239 tmp = RREG32(RADEON_BUS_CNTL) & ~RS600_BUS_MASTER_DIS;
240 WREG32(RADEON_BUS_CNTL, tmp);
241 /* FIXME: What does AGP means for such chipset ? */
242 WREG32_MC(RS600_MC_AGP_LOCATION, 0x0FFFFFFF);
243 /* FIXME: are this AGP reg in indirect MC range ? */
244 WREG32_MC(RS600_MC_AGP_BASE, 0);
245 WREG32_MC(RS600_MC_AGP_BASE_2, 0);
246 rs600_mc_disable_clients(rdev);
247 if (rs600_mc_wait_for_idle(rdev)) {
248 printk(KERN_WARNING "Failed to wait MC idle while "
249 "programming pipes. Bad things might happen.\n");
250 }
251 tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1;
252 tmp = REG_SET(RS600_MC_FB_TOP, tmp >> 16);
253 tmp |= REG_SET(RS600_MC_FB_START, rdev->mc.vram_location >> 16);
254 WREG32_MC(RS600_MC_FB_LOCATION, tmp);
255 WREG32(RS690_HDP_FB_LOCATION, rdev->mc.vram_location >> 16);
256 return 0;
257}
258
259void rs600_mc_fini(struct radeon_device *rdev)
260{
261}
262
263
264/*
265 * Interrupts
266 */
267int rs600_irq_set(struct radeon_device *rdev) 188int rs600_irq_set(struct radeon_device *rdev)
268{ 189{
269 uint32_t tmp = 0; 190 uint32_t tmp = 0;
270 uint32_t mode_int = 0; 191 uint32_t mode_int = 0;
271 192
272 if (rdev->irq.sw_int) { 193 if (rdev->irq.sw_int) {
273 tmp |= RADEON_SW_INT_ENABLE; 194 tmp |= S_000040_SW_INT_EN(1);
274 } 195 }
275 if (rdev->irq.crtc_vblank_int[0]) { 196 if (rdev->irq.crtc_vblank_int[0]) {
276 mode_int |= AVIVO_D1MODE_INT_MASK; 197 mode_int |= S_006540_D1MODE_VBLANK_INT_MASK(1);
277 } 198 }
278 if (rdev->irq.crtc_vblank_int[1]) { 199 if (rdev->irq.crtc_vblank_int[1]) {
279 mode_int |= AVIVO_D2MODE_INT_MASK; 200 mode_int |= S_006540_D2MODE_VBLANK_INT_MASK(1);
280 } 201 }
281 WREG32(RADEON_GEN_INT_CNTL, tmp); 202 WREG32(R_000040_GEN_INT_CNTL, tmp);
282 WREG32(AVIVO_DxMODE_INT_MASK, mode_int); 203 WREG32(R_006540_DxMODE_INT_MASK, mode_int);
283 return 0; 204 return 0;
284} 205}
285 206
286static inline uint32_t rs600_irq_ack(struct radeon_device *rdev, u32 *r500_disp_int) 207static inline uint32_t rs600_irq_ack(struct radeon_device *rdev, u32 *r500_disp_int)
287{ 208{
288 uint32_t irqs = RREG32(RADEON_GEN_INT_STATUS); 209 uint32_t irqs = RREG32(R_000044_GEN_INT_STATUS);
289 uint32_t irq_mask = RADEON_SW_INT_TEST; 210 uint32_t irq_mask = ~C_000044_SW_INT;
290 211
291 if (irqs & AVIVO_DISPLAY_INT_STATUS) { 212 if (G_000044_DISPLAY_INT_STAT(irqs)) {
292 *r500_disp_int = RREG32(AVIVO_DISP_INTERRUPT_STATUS); 213 *r500_disp_int = RREG32(R_007EDC_DISP_INTERRUPT_STATUS);
293 if (*r500_disp_int & AVIVO_D1_VBLANK_INTERRUPT) { 214 if (G_007EDC_LB_D1_VBLANK_INTERRUPT(*r500_disp_int)) {
294 WREG32(AVIVO_D1MODE_VBLANK_STATUS, AVIVO_VBLANK_ACK); 215 WREG32(R_006534_D1MODE_VBLANK_STATUS,
216 S_006534_D1MODE_VBLANK_ACK(1));
295 } 217 }
296 if (*r500_disp_int & AVIVO_D2_VBLANK_INTERRUPT) { 218 if (G_007EDC_LB_D2_VBLANK_INTERRUPT(*r500_disp_int)) {
297 WREG32(AVIVO_D2MODE_VBLANK_STATUS, AVIVO_VBLANK_ACK); 219 WREG32(R_006D34_D2MODE_VBLANK_STATUS,
220 S_006D34_D2MODE_VBLANK_ACK(1));
298 } 221 }
299 } else { 222 } else {
300 *r500_disp_int = 0; 223 *r500_disp_int = 0;
301 } 224 }
302 225
303 if (irqs) { 226 if (irqs) {
304 WREG32(RADEON_GEN_INT_STATUS, irqs); 227 WREG32(R_000044_GEN_INT_STATUS, irqs);
305 } 228 }
306 return irqs & irq_mask; 229 return irqs & irq_mask;
307} 230}
308 231
232void rs600_irq_disable(struct radeon_device *rdev)
233{
234 u32 tmp;
235
236 WREG32(R_000040_GEN_INT_CNTL, 0);
237 WREG32(R_006540_DxMODE_INT_MASK, 0);
238 /* Wait and acknowledge irq */
239 mdelay(1);
240 rs600_irq_ack(rdev, &tmp);
241}
242
309int rs600_irq_process(struct radeon_device *rdev) 243int rs600_irq_process(struct radeon_device *rdev)
310{ 244{
311 uint32_t status; 245 uint32_t status;
@@ -317,16 +251,13 @@ int rs600_irq_process(struct radeon_device *rdev)
317 } 251 }
318 while (status || r500_disp_int) { 252 while (status || r500_disp_int) {
319 /* SW interrupt */ 253 /* SW interrupt */
320 if (status & RADEON_SW_INT_TEST) { 254 if (G_000040_SW_INT_EN(status))
321 radeon_fence_process(rdev); 255 radeon_fence_process(rdev);
322 }
323 /* Vertical blank interrupts */ 256 /* Vertical blank interrupts */
324 if (r500_disp_int & AVIVO_D1_VBLANK_INTERRUPT) { 257 if (G_007EDC_LB_D1_VBLANK_INTERRUPT(r500_disp_int))
325 drm_handle_vblank(rdev->ddev, 0); 258 drm_handle_vblank(rdev->ddev, 0);
326 } 259 if (G_007EDC_LB_D2_VBLANK_INTERRUPT(r500_disp_int))
327 if (r500_disp_int & AVIVO_D2_VBLANK_INTERRUPT) {
328 drm_handle_vblank(rdev->ddev, 1); 260 drm_handle_vblank(rdev->ddev, 1);
329 }
330 status = rs600_irq_ack(rdev, &r500_disp_int); 261 status = rs600_irq_ack(rdev, &r500_disp_int);
331 } 262 }
332 return IRQ_HANDLED; 263 return IRQ_HANDLED;
@@ -335,53 +266,34 @@ int rs600_irq_process(struct radeon_device *rdev)
335u32 rs600_get_vblank_counter(struct radeon_device *rdev, int crtc) 266u32 rs600_get_vblank_counter(struct radeon_device *rdev, int crtc)
336{ 267{
337 if (crtc == 0) 268 if (crtc == 0)
338 return RREG32(AVIVO_D1CRTC_FRAME_COUNT); 269 return RREG32(R_0060A4_D1CRTC_STATUS_FRAME_COUNT);
339 else 270 else
340 return RREG32(AVIVO_D2CRTC_FRAME_COUNT); 271 return RREG32(R_0068A4_D2CRTC_STATUS_FRAME_COUNT);
341} 272}
342 273
343
344/*
345 * Global GPU functions
346 */
347int rs600_mc_wait_for_idle(struct radeon_device *rdev) 274int rs600_mc_wait_for_idle(struct radeon_device *rdev)
348{ 275{
349 unsigned i; 276 unsigned i;
350 uint32_t tmp;
351 277
352 for (i = 0; i < rdev->usec_timeout; i++) { 278 for (i = 0; i < rdev->usec_timeout; i++) {
353 /* read MC_STATUS */ 279 if (G_000000_MC_IDLE(RREG32_MC(R_000000_MC_STATUS)))
354 tmp = RREG32_MC(RS600_MC_STATUS);
355 if (tmp & RS600_MC_STATUS_IDLE) {
356 return 0; 280 return 0;
357 } 281 udelay(1);
358 DRM_UDELAY(1);
359 } 282 }
360 return -1; 283 return -1;
361} 284}
362 285
363void rs600_errata(struct radeon_device *rdev)
364{
365 rdev->pll_errata = 0;
366}
367
368void rs600_gpu_init(struct radeon_device *rdev) 286void rs600_gpu_init(struct radeon_device *rdev)
369{ 287{
370 /* FIXME: HDP same place on rs600 ? */ 288 /* FIXME: HDP same place on rs600 ? */
371 r100_hdp_reset(rdev); 289 r100_hdp_reset(rdev);
372 rv515_vga_render_disable(rdev);
373 /* FIXME: is this correct ? */ 290 /* FIXME: is this correct ? */
374 r420_pipes_init(rdev); 291 r420_pipes_init(rdev);
375 if (rs600_mc_wait_for_idle(rdev)) { 292 /* Wait for mc idle */
376 printk(KERN_WARNING "Failed to wait MC idle while " 293 if (rs600_mc_wait_for_idle(rdev))
377 "programming pipes. Bad things might happen.\n"); 294 dev_warn(rdev->dev, "Wait MC idle timeout before updating MC.\n");
378 }
379} 295}
380 296
381
382/*
383 * VRAM info.
384 */
385void rs600_vram_info(struct radeon_device *rdev) 297void rs600_vram_info(struct radeon_device *rdev)
386{ 298{
387 /* FIXME: to do or is these values sane ? */ 299 /* FIXME: to do or is these values sane ? */
@@ -394,31 +306,206 @@ void rs600_bandwidth_update(struct radeon_device *rdev)
394 /* FIXME: implement, should this be like rs690 ? */ 306 /* FIXME: implement, should this be like rs690 ? */
395} 307}
396 308
397
398/*
399 * Indirect registers accessor
400 */
401uint32_t rs600_mc_rreg(struct radeon_device *rdev, uint32_t reg) 309uint32_t rs600_mc_rreg(struct radeon_device *rdev, uint32_t reg)
402{ 310{
403 uint32_t r; 311 WREG32(R_000070_MC_IND_INDEX, S_000070_MC_IND_ADDR(reg) |
404 312 S_000070_MC_IND_CITF_ARB0(1));
405 WREG32(RS600_MC_INDEX, 313 return RREG32(R_000074_MC_IND_DATA);
406 ((reg & RS600_MC_ADDR_MASK) | RS600_MC_IND_CITF_ARB0));
407 r = RREG32(RS600_MC_DATA);
408 return r;
409} 314}
410 315
411void rs600_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) 316void rs600_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
412{ 317{
413 WREG32(RS600_MC_INDEX, 318 WREG32(R_000070_MC_IND_INDEX, S_000070_MC_IND_ADDR(reg) |
414 RS600_MC_IND_WR_EN | RS600_MC_IND_CITF_ARB0 | 319 S_000070_MC_IND_CITF_ARB0(1) | S_000070_MC_IND_WR_EN(1));
415 ((reg) & RS600_MC_ADDR_MASK)); 320 WREG32(R_000074_MC_IND_DATA, v);
416 WREG32(RS600_MC_DATA, v);
417} 321}
418 322
419int rs600_init(struct radeon_device *rdev) 323void rs600_debugfs(struct radeon_device *rdev)
324{
325 if (r100_debugfs_rbbm_init(rdev))
326 DRM_ERROR("Failed to register debugfs file for RBBM !\n");
327}
328
329void rs600_set_safe_registers(struct radeon_device *rdev)
420{ 330{
421 rdev->config.r300.reg_safe_bm = rs600_reg_safe_bm; 331 rdev->config.r300.reg_safe_bm = rs600_reg_safe_bm;
422 rdev->config.r300.reg_safe_bm_size = ARRAY_SIZE(rs600_reg_safe_bm); 332 rdev->config.r300.reg_safe_bm_size = ARRAY_SIZE(rs600_reg_safe_bm);
333}
334
335static void rs600_mc_program(struct radeon_device *rdev)
336{
337 struct rv515_mc_save save;
338
339 /* Stops all mc clients */
340 rv515_mc_stop(rdev, &save);
341
342 /* Wait for mc idle */
343 if (rs600_mc_wait_for_idle(rdev))
344 dev_warn(rdev->dev, "Wait MC idle timeout before updating MC.\n");
345
346 /* FIXME: What does AGP means for such chipset ? */
347 WREG32_MC(R_000005_MC_AGP_LOCATION, 0x0FFFFFFF);
348 WREG32_MC(R_000006_AGP_BASE, 0);
349 WREG32_MC(R_000007_AGP_BASE_2, 0);
350 /* Program MC */
351 WREG32_MC(R_000004_MC_FB_LOCATION,
352 S_000004_MC_FB_START(rdev->mc.vram_start >> 16) |
353 S_000004_MC_FB_TOP(rdev->mc.vram_end >> 16));
354 WREG32(R_000134_HDP_FB_LOCATION,
355 S_000134_HDP_FB_START(rdev->mc.vram_start >> 16));
356
357 rv515_mc_resume(rdev, &save);
358}
359
360static int rs600_startup(struct radeon_device *rdev)
361{
362 int r;
363
364 rs600_mc_program(rdev);
365 /* Resume clock */
366 rv515_clock_startup(rdev);
367 /* Initialize GPU configuration (# pipes, ...) */
368 rs600_gpu_init(rdev);
369 /* Initialize GART (initialize after TTM so we can allocate
370 * memory through TTM but finalize after TTM) */
371 r = rs600_gart_enable(rdev);
372 if (r)
373 return r;
374 /* Enable IRQ */
375 rdev->irq.sw_int = true;
376 rs600_irq_set(rdev);
377 /* 1M ring buffer */
378 r = r100_cp_init(rdev, 1024 * 1024);
379 if (r) {
380 dev_err(rdev->dev, "failled initializing CP (%d).\n", r);
381 return r;
382 }
383 r = r100_wb_init(rdev);
384 if (r)
385 dev_err(rdev->dev, "failled initializing WB (%d).\n", r);
386 r = r100_ib_init(rdev);
387 if (r) {
388 dev_err(rdev->dev, "failled initializing IB (%d).\n", r);
389 return r;
390 }
391 return 0;
392}
393
394int rs600_resume(struct radeon_device *rdev)
395{
396 /* Make sur GART are not working */
397 rs600_gart_disable(rdev);
398 /* Resume clock before doing reset */
399 rv515_clock_startup(rdev);
400 /* Reset gpu before posting otherwise ATOM will enter infinite loop */
401 if (radeon_gpu_reset(rdev)) {
402 dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
403 RREG32(R_000E40_RBBM_STATUS),
404 RREG32(R_0007C0_CP_STAT));
405 }
406 /* post */
407 atom_asic_init(rdev->mode_info.atom_context);
408 /* Resume clock after posting */
409 rv515_clock_startup(rdev);
410 return rs600_startup(rdev);
411}
412
413int rs600_suspend(struct radeon_device *rdev)
414{
415 r100_cp_disable(rdev);
416 r100_wb_disable(rdev);
417 rs600_irq_disable(rdev);
418 rs600_gart_disable(rdev);
419 return 0;
420}
421
422void rs600_fini(struct radeon_device *rdev)
423{
424 rs600_suspend(rdev);
425 r100_cp_fini(rdev);
426 r100_wb_fini(rdev);
427 r100_ib_fini(rdev);
428 radeon_gem_fini(rdev);
429 rs600_gart_fini(rdev);
430 radeon_irq_kms_fini(rdev);
431 radeon_fence_driver_fini(rdev);
432 radeon_object_fini(rdev);
433 radeon_atombios_fini(rdev);
434 kfree(rdev->bios);
435 rdev->bios = NULL;
436}
437
438int rs600_init(struct radeon_device *rdev)
439{
440 int r;
441
442 /* Disable VGA */
443 rv515_vga_render_disable(rdev);
444 /* Initialize scratch registers */
445 radeon_scratch_init(rdev);
446 /* Initialize surface registers */
447 radeon_surface_init(rdev);
448 /* BIOS */
449 if (!radeon_get_bios(rdev)) {
450 if (ASIC_IS_AVIVO(rdev))
451 return -EINVAL;
452 }
453 if (rdev->is_atom_bios) {
454 r = radeon_atombios_init(rdev);
455 if (r)
456 return r;
457 } else {
458 dev_err(rdev->dev, "Expecting atombios for RS600 GPU\n");
459 return -EINVAL;
460 }
461 /* Reset gpu before posting otherwise ATOM will enter infinite loop */
462 if (radeon_gpu_reset(rdev)) {
463 dev_warn(rdev->dev,
464 "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
465 RREG32(R_000E40_RBBM_STATUS),
466 RREG32(R_0007C0_CP_STAT));
467 }
468 /* check if cards are posted or not */
469 if (!radeon_card_posted(rdev) && rdev->bios) {
470 DRM_INFO("GPU not posted. posting now...\n");
471 atom_asic_init(rdev->mode_info.atom_context);
472 }
473 /* Initialize clocks */
474 radeon_get_clock_info(rdev->ddev);
475 /* Get vram informations */
476 rs600_vram_info(rdev);
477 /* Initialize memory controller (also test AGP) */
478 r = r420_mc_init(rdev);
479 if (r)
480 return r;
481 rs600_debugfs(rdev);
482 /* Fence driver */
483 r = radeon_fence_driver_init(rdev);
484 if (r)
485 return r;
486 r = radeon_irq_kms_init(rdev);
487 if (r)
488 return r;
489 /* Memory manager */
490 r = radeon_object_init(rdev);
491 if (r)
492 return r;
493 r = rs600_gart_init(rdev);
494 if (r)
495 return r;
496 rs600_set_safe_registers(rdev);
497 rdev->accel_working = true;
498 r = rs600_startup(rdev);
499 if (r) {
500 /* Somethings want wront with the accel init stop accel */
501 dev_err(rdev->dev, "Disabling GPU acceleration\n");
502 rs600_suspend(rdev);
503 r100_cp_fini(rdev);
504 r100_wb_fini(rdev);
505 r100_ib_fini(rdev);
506 rs600_gart_fini(rdev);
507 radeon_irq_kms_fini(rdev);
508 rdev->accel_working = false;
509 }
423 return 0; 510 return 0;
424} 511}
diff --git a/drivers/gpu/drm/radeon/rs600d.h b/drivers/gpu/drm/radeon/rs600d.h
new file mode 100644
index 000000000000..81308924859a
--- /dev/null
+++ b/drivers/gpu/drm/radeon/rs600d.h
@@ -0,0 +1,470 @@
1/*
2 * Copyright 2008 Advanced Micro Devices, Inc.
3 * Copyright 2008 Red Hat Inc.
4 * Copyright 2009 Jerome Glisse.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors: Dave Airlie
25 * Alex Deucher
26 * Jerome Glisse
27 */
28#ifndef __RS600D_H__
29#define __RS600D_H__
30
31/* Registers */
32#define R_000040_GEN_INT_CNTL 0x000040
33#define S_000040_DISPLAY_INT_STATUS(x) (((x) & 0x1) << 0)
34#define G_000040_DISPLAY_INT_STATUS(x) (((x) >> 0) & 0x1)
35#define C_000040_DISPLAY_INT_STATUS 0xFFFFFFFE
36#define S_000040_DMA_VIPH0_INT_EN(x) (((x) & 0x1) << 12)
37#define G_000040_DMA_VIPH0_INT_EN(x) (((x) >> 12) & 0x1)
38#define C_000040_DMA_VIPH0_INT_EN 0xFFFFEFFF
39#define S_000040_CRTC2_VSYNC(x) (((x) & 0x1) << 6)
40#define G_000040_CRTC2_VSYNC(x) (((x) >> 6) & 0x1)
41#define C_000040_CRTC2_VSYNC 0xFFFFFFBF
42#define S_000040_SNAPSHOT2(x) (((x) & 0x1) << 7)
43#define G_000040_SNAPSHOT2(x) (((x) >> 7) & 0x1)
44#define C_000040_SNAPSHOT2 0xFFFFFF7F
45#define S_000040_CRTC2_VBLANK(x) (((x) & 0x1) << 9)
46#define G_000040_CRTC2_VBLANK(x) (((x) >> 9) & 0x1)
47#define C_000040_CRTC2_VBLANK 0xFFFFFDFF
48#define S_000040_FP2_DETECT(x) (((x) & 0x1) << 10)
49#define G_000040_FP2_DETECT(x) (((x) >> 10) & 0x1)
50#define C_000040_FP2_DETECT 0xFFFFFBFF
51#define S_000040_VSYNC_DIFF_OVER_LIMIT(x) (((x) & 0x1) << 11)
52#define G_000040_VSYNC_DIFF_OVER_LIMIT(x) (((x) >> 11) & 0x1)
53#define C_000040_VSYNC_DIFF_OVER_LIMIT 0xFFFFF7FF
54#define S_000040_DMA_VIPH1_INT_EN(x) (((x) & 0x1) << 13)
55#define G_000040_DMA_VIPH1_INT_EN(x) (((x) >> 13) & 0x1)
56#define C_000040_DMA_VIPH1_INT_EN 0xFFFFDFFF
57#define S_000040_DMA_VIPH2_INT_EN(x) (((x) & 0x1) << 14)
58#define G_000040_DMA_VIPH2_INT_EN(x) (((x) >> 14) & 0x1)
59#define C_000040_DMA_VIPH2_INT_EN 0xFFFFBFFF
60#define S_000040_DMA_VIPH3_INT_EN(x) (((x) & 0x1) << 15)
61#define G_000040_DMA_VIPH3_INT_EN(x) (((x) >> 15) & 0x1)
62#define C_000040_DMA_VIPH3_INT_EN 0xFFFF7FFF
63#define S_000040_I2C_INT_EN(x) (((x) & 0x1) << 17)
64#define G_000040_I2C_INT_EN(x) (((x) >> 17) & 0x1)
65#define C_000040_I2C_INT_EN 0xFFFDFFFF
66#define S_000040_GUI_IDLE(x) (((x) & 0x1) << 19)
67#define G_000040_GUI_IDLE(x) (((x) >> 19) & 0x1)
68#define C_000040_GUI_IDLE 0xFFF7FFFF
69#define S_000040_VIPH_INT_EN(x) (((x) & 0x1) << 24)
70#define G_000040_VIPH_INT_EN(x) (((x) >> 24) & 0x1)
71#define C_000040_VIPH_INT_EN 0xFEFFFFFF
72#define S_000040_SW_INT_EN(x) (((x) & 0x1) << 25)
73#define G_000040_SW_INT_EN(x) (((x) >> 25) & 0x1)
74#define C_000040_SW_INT_EN 0xFDFFFFFF
75#define S_000040_GEYSERVILLE(x) (((x) & 0x1) << 27)
76#define G_000040_GEYSERVILLE(x) (((x) >> 27) & 0x1)
77#define C_000040_GEYSERVILLE 0xF7FFFFFF
78#define S_000040_HDCP_AUTHORIZED_INT(x) (((x) & 0x1) << 28)
79#define G_000040_HDCP_AUTHORIZED_INT(x) (((x) >> 28) & 0x1)
80#define C_000040_HDCP_AUTHORIZED_INT 0xEFFFFFFF
81#define S_000040_DVI_I2C_INT(x) (((x) & 0x1) << 29)
82#define G_000040_DVI_I2C_INT(x) (((x) >> 29) & 0x1)
83#define C_000040_DVI_I2C_INT 0xDFFFFFFF
84#define S_000040_GUIDMA(x) (((x) & 0x1) << 30)
85#define G_000040_GUIDMA(x) (((x) >> 30) & 0x1)
86#define C_000040_GUIDMA 0xBFFFFFFF
87#define S_000040_VIDDMA(x) (((x) & 0x1) << 31)
88#define G_000040_VIDDMA(x) (((x) >> 31) & 0x1)
89#define C_000040_VIDDMA 0x7FFFFFFF
90#define R_000044_GEN_INT_STATUS 0x000044
91#define S_000044_DISPLAY_INT_STAT(x) (((x) & 0x1) << 0)
92#define G_000044_DISPLAY_INT_STAT(x) (((x) >> 0) & 0x1)
93#define C_000044_DISPLAY_INT_STAT 0xFFFFFFFE
94#define S_000044_VGA_INT_STAT(x) (((x) & 0x1) << 1)
95#define G_000044_VGA_INT_STAT(x) (((x) >> 1) & 0x1)
96#define C_000044_VGA_INT_STAT 0xFFFFFFFD
97#define S_000044_CAP0_INT_ACTIVE(x) (((x) & 0x1) << 8)
98#define G_000044_CAP0_INT_ACTIVE(x) (((x) >> 8) & 0x1)
99#define C_000044_CAP0_INT_ACTIVE 0xFFFFFEFF
100#define S_000044_DMA_VIPH0_INT(x) (((x) & 0x1) << 12)
101#define G_000044_DMA_VIPH0_INT(x) (((x) >> 12) & 0x1)
102#define C_000044_DMA_VIPH0_INT 0xFFFFEFFF
103#define S_000044_DMA_VIPH1_INT(x) (((x) & 0x1) << 13)
104#define G_000044_DMA_VIPH1_INT(x) (((x) >> 13) & 0x1)
105#define C_000044_DMA_VIPH1_INT 0xFFFFDFFF
106#define S_000044_DMA_VIPH2_INT(x) (((x) & 0x1) << 14)
107#define G_000044_DMA_VIPH2_INT(x) (((x) >> 14) & 0x1)
108#define C_000044_DMA_VIPH2_INT 0xFFFFBFFF
109#define S_000044_DMA_VIPH3_INT(x) (((x) & 0x1) << 15)
110#define G_000044_DMA_VIPH3_INT(x) (((x) >> 15) & 0x1)
111#define C_000044_DMA_VIPH3_INT 0xFFFF7FFF
112#define S_000044_MC_PROBE_FAULT_STAT(x) (((x) & 0x1) << 16)
113#define G_000044_MC_PROBE_FAULT_STAT(x) (((x) >> 16) & 0x1)
114#define C_000044_MC_PROBE_FAULT_STAT 0xFFFEFFFF
115#define S_000044_I2C_INT(x) (((x) & 0x1) << 17)
116#define G_000044_I2C_INT(x) (((x) >> 17) & 0x1)
117#define C_000044_I2C_INT 0xFFFDFFFF
118#define S_000044_SCRATCH_INT_STAT(x) (((x) & 0x1) << 18)
119#define G_000044_SCRATCH_INT_STAT(x) (((x) >> 18) & 0x1)
120#define C_000044_SCRATCH_INT_STAT 0xFFFBFFFF
121#define S_000044_GUI_IDLE_STAT(x) (((x) & 0x1) << 19)
122#define G_000044_GUI_IDLE_STAT(x) (((x) >> 19) & 0x1)
123#define C_000044_GUI_IDLE_STAT 0xFFF7FFFF
124#define S_000044_ATI_OVERDRIVE_INT_STAT(x) (((x) & 0x1) << 20)
125#define G_000044_ATI_OVERDRIVE_INT_STAT(x) (((x) >> 20) & 0x1)
126#define C_000044_ATI_OVERDRIVE_INT_STAT 0xFFEFFFFF
127#define S_000044_MC_PROTECTION_FAULT_STAT(x) (((x) & 0x1) << 21)
128#define G_000044_MC_PROTECTION_FAULT_STAT(x) (((x) >> 21) & 0x1)
129#define C_000044_MC_PROTECTION_FAULT_STAT 0xFFDFFFFF
130#define S_000044_RBBM_READ_INT_STAT(x) (((x) & 0x1) << 22)
131#define G_000044_RBBM_READ_INT_STAT(x) (((x) >> 22) & 0x1)
132#define C_000044_RBBM_READ_INT_STAT 0xFFBFFFFF
133#define S_000044_CB_CONTEXT_SWITCH_STAT(x) (((x) & 0x1) << 23)
134#define G_000044_CB_CONTEXT_SWITCH_STAT(x) (((x) >> 23) & 0x1)
135#define C_000044_CB_CONTEXT_SWITCH_STAT 0xFF7FFFFF
136#define S_000044_VIPH_INT(x) (((x) & 0x1) << 24)
137#define G_000044_VIPH_INT(x) (((x) >> 24) & 0x1)
138#define C_000044_VIPH_INT 0xFEFFFFFF
139#define S_000044_SW_INT(x) (((x) & 0x1) << 25)
140#define G_000044_SW_INT(x) (((x) >> 25) & 0x1)
141#define C_000044_SW_INT 0xFDFFFFFF
142#define S_000044_SW_INT_SET(x) (((x) & 0x1) << 26)
143#define G_000044_SW_INT_SET(x) (((x) >> 26) & 0x1)
144#define C_000044_SW_INT_SET 0xFBFFFFFF
145#define S_000044_IDCT_INT_STAT(x) (((x) & 0x1) << 27)
146#define G_000044_IDCT_INT_STAT(x) (((x) >> 27) & 0x1)
147#define C_000044_IDCT_INT_STAT 0xF7FFFFFF
148#define S_000044_GUIDMA_STAT(x) (((x) & 0x1) << 30)
149#define G_000044_GUIDMA_STAT(x) (((x) >> 30) & 0x1)
150#define C_000044_GUIDMA_STAT 0xBFFFFFFF
151#define S_000044_VIDDMA_STAT(x) (((x) & 0x1) << 31)
152#define G_000044_VIDDMA_STAT(x) (((x) >> 31) & 0x1)
153#define C_000044_VIDDMA_STAT 0x7FFFFFFF
154#define R_00004C_BUS_CNTL 0x00004C
155#define S_00004C_BUS_MASTER_DIS(x) (((x) & 0x1) << 14)
156#define G_00004C_BUS_MASTER_DIS(x) (((x) >> 14) & 0x1)
157#define C_00004C_BUS_MASTER_DIS 0xFFFFBFFF
158#define S_00004C_BUS_MSI_REARM(x) (((x) & 0x1) << 20)
159#define G_00004C_BUS_MSI_REARM(x) (((x) >> 20) & 0x1)
160#define C_00004C_BUS_MSI_REARM 0xFFEFFFFF
161#define R_000070_MC_IND_INDEX 0x000070
162#define S_000070_MC_IND_ADDR(x) (((x) & 0xFFFF) << 0)
163#define G_000070_MC_IND_ADDR(x) (((x) >> 0) & 0xFFFF)
164#define C_000070_MC_IND_ADDR 0xFFFF0000
165#define S_000070_MC_IND_SEQ_RBS_0(x) (((x) & 0x1) << 16)
166#define G_000070_MC_IND_SEQ_RBS_0(x) (((x) >> 16) & 0x1)
167#define C_000070_MC_IND_SEQ_RBS_0 0xFFFEFFFF
168#define S_000070_MC_IND_SEQ_RBS_1(x) (((x) & 0x1) << 17)
169#define G_000070_MC_IND_SEQ_RBS_1(x) (((x) >> 17) & 0x1)
170#define C_000070_MC_IND_SEQ_RBS_1 0xFFFDFFFF
171#define S_000070_MC_IND_SEQ_RBS_2(x) (((x) & 0x1) << 18)
172#define G_000070_MC_IND_SEQ_RBS_2(x) (((x) >> 18) & 0x1)
173#define C_000070_MC_IND_SEQ_RBS_2 0xFFFBFFFF
174#define S_000070_MC_IND_SEQ_RBS_3(x) (((x) & 0x1) << 19)
175#define G_000070_MC_IND_SEQ_RBS_3(x) (((x) >> 19) & 0x1)
176#define C_000070_MC_IND_SEQ_RBS_3 0xFFF7FFFF
177#define S_000070_MC_IND_AIC_RBS(x) (((x) & 0x1) << 20)
178#define G_000070_MC_IND_AIC_RBS(x) (((x) >> 20) & 0x1)
179#define C_000070_MC_IND_AIC_RBS 0xFFEFFFFF
180#define S_000070_MC_IND_CITF_ARB0(x) (((x) & 0x1) << 21)
181#define G_000070_MC_IND_CITF_ARB0(x) (((x) >> 21) & 0x1)
182#define C_000070_MC_IND_CITF_ARB0 0xFFDFFFFF
183#define S_000070_MC_IND_CITF_ARB1(x) (((x) & 0x1) << 22)
184#define G_000070_MC_IND_CITF_ARB1(x) (((x) >> 22) & 0x1)
185#define C_000070_MC_IND_CITF_ARB1 0xFFBFFFFF
186#define S_000070_MC_IND_WR_EN(x) (((x) & 0x1) << 23)
187#define G_000070_MC_IND_WR_EN(x) (((x) >> 23) & 0x1)
188#define C_000070_MC_IND_WR_EN 0xFF7FFFFF
189#define S_000070_MC_IND_RD_INV(x) (((x) & 0x1) << 24)
190#define G_000070_MC_IND_RD_INV(x) (((x) >> 24) & 0x1)
191#define C_000070_MC_IND_RD_INV 0xFEFFFFFF
192#define R_000074_MC_IND_DATA 0x000074
193#define S_000074_MC_IND_DATA(x) (((x) & 0xFFFFFFFF) << 0)
194#define G_000074_MC_IND_DATA(x) (((x) >> 0) & 0xFFFFFFFF)
195#define C_000074_MC_IND_DATA 0x00000000
196#define R_000134_HDP_FB_LOCATION 0x000134
197#define S_000134_HDP_FB_START(x) (((x) & 0xFFFF) << 0)
198#define G_000134_HDP_FB_START(x) (((x) >> 0) & 0xFFFF)
199#define C_000134_HDP_FB_START 0xFFFF0000
200#define R_0007C0_CP_STAT 0x0007C0
201#define S_0007C0_MRU_BUSY(x) (((x) & 0x1) << 0)
202#define G_0007C0_MRU_BUSY(x) (((x) >> 0) & 0x1)
203#define C_0007C0_MRU_BUSY 0xFFFFFFFE
204#define S_0007C0_MWU_BUSY(x) (((x) & 0x1) << 1)
205#define G_0007C0_MWU_BUSY(x) (((x) >> 1) & 0x1)
206#define C_0007C0_MWU_BUSY 0xFFFFFFFD
207#define S_0007C0_RSIU_BUSY(x) (((x) & 0x1) << 2)
208#define G_0007C0_RSIU_BUSY(x) (((x) >> 2) & 0x1)
209#define C_0007C0_RSIU_BUSY 0xFFFFFFFB
210#define S_0007C0_RCIU_BUSY(x) (((x) & 0x1) << 3)
211#define G_0007C0_RCIU_BUSY(x) (((x) >> 3) & 0x1)
212#define C_0007C0_RCIU_BUSY 0xFFFFFFF7
213#define S_0007C0_CSF_PRIMARY_BUSY(x) (((x) & 0x1) << 9)
214#define G_0007C0_CSF_PRIMARY_BUSY(x) (((x) >> 9) & 0x1)
215#define C_0007C0_CSF_PRIMARY_BUSY 0xFFFFFDFF
216#define S_0007C0_CSF_INDIRECT_BUSY(x) (((x) & 0x1) << 10)
217#define G_0007C0_CSF_INDIRECT_BUSY(x) (((x) >> 10) & 0x1)
218#define C_0007C0_CSF_INDIRECT_BUSY 0xFFFFFBFF
219#define S_0007C0_CSQ_PRIMARY_BUSY(x) (((x) & 0x1) << 11)
220#define G_0007C0_CSQ_PRIMARY_BUSY(x) (((x) >> 11) & 0x1)
221#define C_0007C0_CSQ_PRIMARY_BUSY 0xFFFFF7FF
222#define S_0007C0_CSQ_INDIRECT_BUSY(x) (((x) & 0x1) << 12)
223#define G_0007C0_CSQ_INDIRECT_BUSY(x) (((x) >> 12) & 0x1)
224#define C_0007C0_CSQ_INDIRECT_BUSY 0xFFFFEFFF
225#define S_0007C0_CSI_BUSY(x) (((x) & 0x1) << 13)
226#define G_0007C0_CSI_BUSY(x) (((x) >> 13) & 0x1)
227#define C_0007C0_CSI_BUSY 0xFFFFDFFF
228#define S_0007C0_CSF_INDIRECT2_BUSY(x) (((x) & 0x1) << 14)
229#define G_0007C0_CSF_INDIRECT2_BUSY(x) (((x) >> 14) & 0x1)
230#define C_0007C0_CSF_INDIRECT2_BUSY 0xFFFFBFFF
231#define S_0007C0_CSQ_INDIRECT2_BUSY(x) (((x) & 0x1) << 15)
232#define G_0007C0_CSQ_INDIRECT2_BUSY(x) (((x) >> 15) & 0x1)
233#define C_0007C0_CSQ_INDIRECT2_BUSY 0xFFFF7FFF
234#define S_0007C0_GUIDMA_BUSY(x) (((x) & 0x1) << 28)
235#define G_0007C0_GUIDMA_BUSY(x) (((x) >> 28) & 0x1)
236#define C_0007C0_GUIDMA_BUSY 0xEFFFFFFF
237#define S_0007C0_VIDDMA_BUSY(x) (((x) & 0x1) << 29)
238#define G_0007C0_VIDDMA_BUSY(x) (((x) >> 29) & 0x1)
239#define C_0007C0_VIDDMA_BUSY 0xDFFFFFFF
240#define S_0007C0_CMDSTRM_BUSY(x) (((x) & 0x1) << 30)
241#define G_0007C0_CMDSTRM_BUSY(x) (((x) >> 30) & 0x1)
242#define C_0007C0_CMDSTRM_BUSY 0xBFFFFFFF
243#define S_0007C0_CP_BUSY(x) (((x) & 0x1) << 31)
244#define G_0007C0_CP_BUSY(x) (((x) >> 31) & 0x1)
245#define C_0007C0_CP_BUSY 0x7FFFFFFF
246#define R_000E40_RBBM_STATUS 0x000E40
247#define S_000E40_CMDFIFO_AVAIL(x) (((x) & 0x7F) << 0)
248#define G_000E40_CMDFIFO_AVAIL(x) (((x) >> 0) & 0x7F)
249#define C_000E40_CMDFIFO_AVAIL 0xFFFFFF80
250#define S_000E40_HIRQ_ON_RBB(x) (((x) & 0x1) << 8)
251#define G_000E40_HIRQ_ON_RBB(x) (((x) >> 8) & 0x1)
252#define C_000E40_HIRQ_ON_RBB 0xFFFFFEFF
253#define S_000E40_CPRQ_ON_RBB(x) (((x) & 0x1) << 9)
254#define G_000E40_CPRQ_ON_RBB(x) (((x) >> 9) & 0x1)
255#define C_000E40_CPRQ_ON_RBB 0xFFFFFDFF
256#define S_000E40_CFRQ_ON_RBB(x) (((x) & 0x1) << 10)
257#define G_000E40_CFRQ_ON_RBB(x) (((x) >> 10) & 0x1)
258#define C_000E40_CFRQ_ON_RBB 0xFFFFFBFF
259#define S_000E40_HIRQ_IN_RTBUF(x) (((x) & 0x1) << 11)
260#define G_000E40_HIRQ_IN_RTBUF(x) (((x) >> 11) & 0x1)
261#define C_000E40_HIRQ_IN_RTBUF 0xFFFFF7FF
262#define S_000E40_CPRQ_IN_RTBUF(x) (((x) & 0x1) << 12)
263#define G_000E40_CPRQ_IN_RTBUF(x) (((x) >> 12) & 0x1)
264#define C_000E40_CPRQ_IN_RTBUF 0xFFFFEFFF
265#define S_000E40_CFRQ_IN_RTBUF(x) (((x) & 0x1) << 13)
266#define G_000E40_CFRQ_IN_RTBUF(x) (((x) >> 13) & 0x1)
267#define C_000E40_CFRQ_IN_RTBUF 0xFFFFDFFF
268#define S_000E40_CF_PIPE_BUSY(x) (((x) & 0x1) << 14)
269#define G_000E40_CF_PIPE_BUSY(x) (((x) >> 14) & 0x1)
270#define C_000E40_CF_PIPE_BUSY 0xFFFFBFFF
271#define S_000E40_ENG_EV_BUSY(x) (((x) & 0x1) << 15)
272#define G_000E40_ENG_EV_BUSY(x) (((x) >> 15) & 0x1)
273#define C_000E40_ENG_EV_BUSY 0xFFFF7FFF
274#define S_000E40_CP_CMDSTRM_BUSY(x) (((x) & 0x1) << 16)
275#define G_000E40_CP_CMDSTRM_BUSY(x) (((x) >> 16) & 0x1)
276#define C_000E40_CP_CMDSTRM_BUSY 0xFFFEFFFF
277#define S_000E40_E2_BUSY(x) (((x) & 0x1) << 17)
278#define G_000E40_E2_BUSY(x) (((x) >> 17) & 0x1)
279#define C_000E40_E2_BUSY 0xFFFDFFFF
280#define S_000E40_RB2D_BUSY(x) (((x) & 0x1) << 18)
281#define G_000E40_RB2D_BUSY(x) (((x) >> 18) & 0x1)
282#define C_000E40_RB2D_BUSY 0xFFFBFFFF
283#define S_000E40_RB3D_BUSY(x) (((x) & 0x1) << 19)
284#define G_000E40_RB3D_BUSY(x) (((x) >> 19) & 0x1)
285#define C_000E40_RB3D_BUSY 0xFFF7FFFF
286#define S_000E40_VAP_BUSY(x) (((x) & 0x1) << 20)
287#define G_000E40_VAP_BUSY(x) (((x) >> 20) & 0x1)
288#define C_000E40_VAP_BUSY 0xFFEFFFFF
289#define S_000E40_RE_BUSY(x) (((x) & 0x1) << 21)
290#define G_000E40_RE_BUSY(x) (((x) >> 21) & 0x1)
291#define C_000E40_RE_BUSY 0xFFDFFFFF
292#define S_000E40_TAM_BUSY(x) (((x) & 0x1) << 22)
293#define G_000E40_TAM_BUSY(x) (((x) >> 22) & 0x1)
294#define C_000E40_TAM_BUSY 0xFFBFFFFF
295#define S_000E40_TDM_BUSY(x) (((x) & 0x1) << 23)
296#define G_000E40_TDM_BUSY(x) (((x) >> 23) & 0x1)
297#define C_000E40_TDM_BUSY 0xFF7FFFFF
298#define S_000E40_PB_BUSY(x) (((x) & 0x1) << 24)
299#define G_000E40_PB_BUSY(x) (((x) >> 24) & 0x1)
300#define C_000E40_PB_BUSY 0xFEFFFFFF
301#define S_000E40_TIM_BUSY(x) (((x) & 0x1) << 25)
302#define G_000E40_TIM_BUSY(x) (((x) >> 25) & 0x1)
303#define C_000E40_TIM_BUSY 0xFDFFFFFF
304#define S_000E40_GA_BUSY(x) (((x) & 0x1) << 26)
305#define G_000E40_GA_BUSY(x) (((x) >> 26) & 0x1)
306#define C_000E40_GA_BUSY 0xFBFFFFFF
307#define S_000E40_CBA2D_BUSY(x) (((x) & 0x1) << 27)
308#define G_000E40_CBA2D_BUSY(x) (((x) >> 27) & 0x1)
309#define C_000E40_CBA2D_BUSY 0xF7FFFFFF
310#define S_000E40_GUI_ACTIVE(x) (((x) & 0x1) << 31)
311#define G_000E40_GUI_ACTIVE(x) (((x) >> 31) & 0x1)
312#define C_000E40_GUI_ACTIVE 0x7FFFFFFF
313#define R_0060A4_D1CRTC_STATUS_FRAME_COUNT 0x0060A4
314#define S_0060A4_D1CRTC_FRAME_COUNT(x) (((x) & 0xFFFFFF) << 0)
315#define G_0060A4_D1CRTC_FRAME_COUNT(x) (((x) >> 0) & 0xFFFFFF)
316#define C_0060A4_D1CRTC_FRAME_COUNT 0xFF000000
317#define R_006534_D1MODE_VBLANK_STATUS 0x006534
318#define S_006534_D1MODE_VBLANK_OCCURRED(x) (((x) & 0x1) << 0)
319#define G_006534_D1MODE_VBLANK_OCCURRED(x) (((x) >> 0) & 0x1)
320#define C_006534_D1MODE_VBLANK_OCCURRED 0xFFFFFFFE
321#define S_006534_D1MODE_VBLANK_ACK(x) (((x) & 0x1) << 4)
322#define G_006534_D1MODE_VBLANK_ACK(x) (((x) >> 4) & 0x1)
323#define C_006534_D1MODE_VBLANK_ACK 0xFFFFFFEF
324#define S_006534_D1MODE_VBLANK_STAT(x) (((x) & 0x1) << 12)
325#define G_006534_D1MODE_VBLANK_STAT(x) (((x) >> 12) & 0x1)
326#define C_006534_D1MODE_VBLANK_STAT 0xFFFFEFFF
327#define S_006534_D1MODE_VBLANK_INTERRUPT(x) (((x) & 0x1) << 16)
328#define G_006534_D1MODE_VBLANK_INTERRUPT(x) (((x) >> 16) & 0x1)
329#define C_006534_D1MODE_VBLANK_INTERRUPT 0xFFFEFFFF
330#define R_006540_DxMODE_INT_MASK 0x006540
331#define S_006540_D1MODE_VBLANK_INT_MASK(x) (((x) & 0x1) << 0)
332#define G_006540_D1MODE_VBLANK_INT_MASK(x) (((x) >> 0) & 0x1)
333#define C_006540_D1MODE_VBLANK_INT_MASK 0xFFFFFFFE
334#define S_006540_D1MODE_VLINE_INT_MASK(x) (((x) & 0x1) << 4)
335#define G_006540_D1MODE_VLINE_INT_MASK(x) (((x) >> 4) & 0x1)
336#define C_006540_D1MODE_VLINE_INT_MASK 0xFFFFFFEF
337#define S_006540_D2MODE_VBLANK_INT_MASK(x) (((x) & 0x1) << 8)
338#define G_006540_D2MODE_VBLANK_INT_MASK(x) (((x) >> 8) & 0x1)
339#define C_006540_D2MODE_VBLANK_INT_MASK 0xFFFFFEFF
340#define S_006540_D2MODE_VLINE_INT_MASK(x) (((x) & 0x1) << 12)
341#define G_006540_D2MODE_VLINE_INT_MASK(x) (((x) >> 12) & 0x1)
342#define C_006540_D2MODE_VLINE_INT_MASK 0xFFFFEFFF
343#define S_006540_D1MODE_VBLANK_CP_SEL(x) (((x) & 0x1) << 30)
344#define G_006540_D1MODE_VBLANK_CP_SEL(x) (((x) >> 30) & 0x1)
345#define C_006540_D1MODE_VBLANK_CP_SEL 0xBFFFFFFF
346#define S_006540_D2MODE_VBLANK_CP_SEL(x) (((x) & 0x1) << 31)
347#define G_006540_D2MODE_VBLANK_CP_SEL(x) (((x) >> 31) & 0x1)
348#define C_006540_D2MODE_VBLANK_CP_SEL 0x7FFFFFFF
349#define R_0068A4_D2CRTC_STATUS_FRAME_COUNT 0x0068A4
350#define S_0068A4_D2CRTC_FRAME_COUNT(x) (((x) & 0xFFFFFF) << 0)
351#define G_0068A4_D2CRTC_FRAME_COUNT(x) (((x) >> 0) & 0xFFFFFF)
352#define C_0068A4_D2CRTC_FRAME_COUNT 0xFF000000
353#define R_006D34_D2MODE_VBLANK_STATUS 0x006D34
354#define S_006D34_D2MODE_VBLANK_OCCURRED(x) (((x) & 0x1) << 0)
355#define G_006D34_D2MODE_VBLANK_OCCURRED(x) (((x) >> 0) & 0x1)
356#define C_006D34_D2MODE_VBLANK_OCCURRED 0xFFFFFFFE
357#define S_006D34_D2MODE_VBLANK_ACK(x) (((x) & 0x1) << 4)
358#define G_006D34_D2MODE_VBLANK_ACK(x) (((x) >> 4) & 0x1)
359#define C_006D34_D2MODE_VBLANK_ACK 0xFFFFFFEF
360#define S_006D34_D2MODE_VBLANK_STAT(x) (((x) & 0x1) << 12)
361#define G_006D34_D2MODE_VBLANK_STAT(x) (((x) >> 12) & 0x1)
362#define C_006D34_D2MODE_VBLANK_STAT 0xFFFFEFFF
363#define S_006D34_D2MODE_VBLANK_INTERRUPT(x) (((x) & 0x1) << 16)
364#define G_006D34_D2MODE_VBLANK_INTERRUPT(x) (((x) >> 16) & 0x1)
365#define C_006D34_D2MODE_VBLANK_INTERRUPT 0xFFFEFFFF
366#define R_007EDC_DISP_INTERRUPT_STATUS 0x007EDC
367#define S_007EDC_LB_D1_VBLANK_INTERRUPT(x) (((x) & 0x1) << 4)
368#define G_007EDC_LB_D1_VBLANK_INTERRUPT(x) (((x) >> 4) & 0x1)
369#define C_007EDC_LB_D1_VBLANK_INTERRUPT 0xFFFFFFEF
370#define S_007EDC_LB_D2_VBLANK_INTERRUPT(x) (((x) & 0x1) << 5)
371#define G_007EDC_LB_D2_VBLANK_INTERRUPT(x) (((x) >> 5) & 0x1)
372#define C_007EDC_LB_D2_VBLANK_INTERRUPT 0xFFFFFFDF
373
374
375/* MC registers */
376#define R_000000_MC_STATUS 0x000000
377#define S_000000_MC_IDLE(x) (((x) & 0x1) << 0)
378#define G_000000_MC_IDLE(x) (((x) >> 0) & 0x1)
379#define C_000000_MC_IDLE 0xFFFFFFFE
380#define R_000004_MC_FB_LOCATION 0x000004
381#define S_000004_MC_FB_START(x) (((x) & 0xFFFF) << 0)
382#define G_000004_MC_FB_START(x) (((x) >> 0) & 0xFFFF)
383#define C_000004_MC_FB_START 0xFFFF0000
384#define S_000004_MC_FB_TOP(x) (((x) & 0xFFFF) << 16)
385#define G_000004_MC_FB_TOP(x) (((x) >> 16) & 0xFFFF)
386#define C_000004_MC_FB_TOP 0x0000FFFF
387#define R_000005_MC_AGP_LOCATION 0x000005
388#define S_000005_MC_AGP_START(x) (((x) & 0xFFFF) << 0)
389#define G_000005_MC_AGP_START(x) (((x) >> 0) & 0xFFFF)
390#define C_000005_MC_AGP_START 0xFFFF0000
391#define S_000005_MC_AGP_TOP(x) (((x) & 0xFFFF) << 16)
392#define G_000005_MC_AGP_TOP(x) (((x) >> 16) & 0xFFFF)
393#define C_000005_MC_AGP_TOP 0x0000FFFF
394#define R_000006_AGP_BASE 0x000006
395#define S_000006_AGP_BASE_ADDR(x) (((x) & 0xFFFFFFFF) << 0)
396#define G_000006_AGP_BASE_ADDR(x) (((x) >> 0) & 0xFFFFFFFF)
397#define C_000006_AGP_BASE_ADDR 0x00000000
398#define R_000007_AGP_BASE_2 0x000007
399#define S_000007_AGP_BASE_ADDR_2(x) (((x) & 0xF) << 0)
400#define G_000007_AGP_BASE_ADDR_2(x) (((x) >> 0) & 0xF)
401#define C_000007_AGP_BASE_ADDR_2 0xFFFFFFF0
402#define R_000009_MC_CNTL1 0x000009
403#define S_000009_ENABLE_PAGE_TABLES(x) (((x) & 0x1) << 26)
404#define G_000009_ENABLE_PAGE_TABLES(x) (((x) >> 26) & 0x1)
405#define C_000009_ENABLE_PAGE_TABLES 0xFBFFFFFF
406/* FIXME don't know the various field size need feedback from AMD */
407#define R_000100_MC_PT0_CNTL 0x000100
408#define S_000100_ENABLE_PT(x) (((x) & 0x1) << 0)
409#define G_000100_ENABLE_PT(x) (((x) >> 0) & 0x1)
410#define C_000100_ENABLE_PT 0xFFFFFFFE
411#define S_000100_EFFECTIVE_L2_CACHE_SIZE(x) (((x) & 0x7) << 15)
412#define G_000100_EFFECTIVE_L2_CACHE_SIZE(x) (((x) >> 15) & 0x7)
413#define C_000100_EFFECTIVE_L2_CACHE_SIZE 0xFFFC7FFF
414#define S_000100_EFFECTIVE_L2_QUEUE_SIZE(x) (((x) & 0x7) << 21)
415#define G_000100_EFFECTIVE_L2_QUEUE_SIZE(x) (((x) >> 21) & 0x7)
416#define C_000100_EFFECTIVE_L2_QUEUE_SIZE 0xFF1FFFFF
417#define S_000100_INVALIDATE_ALL_L1_TLBS(x) (((x) & 0x1) << 28)
418#define G_000100_INVALIDATE_ALL_L1_TLBS(x) (((x) >> 28) & 0x1)
419#define C_000100_INVALIDATE_ALL_L1_TLBS 0xEFFFFFFF
420#define S_000100_INVALIDATE_L2_CACHE(x) (((x) & 0x1) << 29)
421#define G_000100_INVALIDATE_L2_CACHE(x) (((x) >> 29) & 0x1)
422#define C_000100_INVALIDATE_L2_CACHE 0xDFFFFFFF
423#define R_000102_MC_PT0_CONTEXT0_CNTL 0x000102
424#define S_000102_ENABLE_PAGE_TABLE(x) (((x) & 0x1) << 0)
425#define G_000102_ENABLE_PAGE_TABLE(x) (((x) >> 0) & 0x1)
426#define C_000102_ENABLE_PAGE_TABLE 0xFFFFFFFE
427#define S_000102_PAGE_TABLE_DEPTH(x) (((x) & 0x3) << 1)
428#define G_000102_PAGE_TABLE_DEPTH(x) (((x) >> 1) & 0x3)
429#define C_000102_PAGE_TABLE_DEPTH 0xFFFFFFF9
430#define V_000102_PAGE_TABLE_FLAT 0
431/* R600 documentation suggest that this should be a number of pages */
432#define R_000112_MC_PT0_SYSTEM_APERTURE_LOW_ADDR 0x000112
433#define R_000114_MC_PT0_SYSTEM_APERTURE_HIGH_ADDR 0x000114
434#define R_00011C_MC_PT0_CONTEXT0_DEFAULT_READ_ADDR 0x00011C
435#define R_00012C_MC_PT0_CONTEXT0_FLAT_BASE_ADDR 0x00012C
436#define R_00013C_MC_PT0_CONTEXT0_FLAT_START_ADDR 0x00013C
437#define R_00014C_MC_PT0_CONTEXT0_FLAT_END_ADDR 0x00014C
438#define R_00016C_MC_PT0_CLIENT0_CNTL 0x00016C
439#define S_00016C_ENABLE_TRANSLATION_MODE_OVERRIDE(x) (((x) & 0x1) << 0)
440#define G_00016C_ENABLE_TRANSLATION_MODE_OVERRIDE(x) (((x) >> 0) & 0x1)
441#define C_00016C_ENABLE_TRANSLATION_MODE_OVERRIDE 0xFFFFFFFE
442#define S_00016C_TRANSLATION_MODE_OVERRIDE(x) (((x) & 0x1) << 1)
443#define G_00016C_TRANSLATION_MODE_OVERRIDE(x) (((x) >> 1) & 0x1)
444#define C_00016C_TRANSLATION_MODE_OVERRIDE 0xFFFFFFFD
445#define S_00016C_SYSTEM_ACCESS_MODE_MASK(x) (((x) & 0x3) << 8)
446#define G_00016C_SYSTEM_ACCESS_MODE_MASK(x) (((x) >> 8) & 0x3)
447#define C_00016C_SYSTEM_ACCESS_MODE_MASK 0xFFFFFCFF
448#define V_00016C_SYSTEM_ACCESS_MODE_PA_ONLY 0
449#define V_00016C_SYSTEM_ACCESS_MODE_USE_SYS_MAP 1
450#define V_00016C_SYSTEM_ACCESS_MODE_IN_SYS 2
451#define V_00016C_SYSTEM_ACCESS_MODE_NOT_IN_SYS 3
452#define S_00016C_SYSTEM_APERTURE_UNMAPPED_ACCESS(x) (((x) & 0x1) << 10)
453#define G_00016C_SYSTEM_APERTURE_UNMAPPED_ACCESS(x) (((x) >> 10) & 0x1)
454#define C_00016C_SYSTEM_APERTURE_UNMAPPED_ACCESS 0xFFFFFBFF
455#define V_00016C_SYSTEM_APERTURE_UNMAPPED_PASSTHROUGH 0
456#define V_00016C_SYSTEM_APERTURE_UNMAPPED_DEFAULT_PAGE 1
457#define S_00016C_EFFECTIVE_L1_CACHE_SIZE(x) (((x) & 0x7) << 11)
458#define G_00016C_EFFECTIVE_L1_CACHE_SIZE(x) (((x) >> 11) & 0x7)
459#define C_00016C_EFFECTIVE_L1_CACHE_SIZE 0xFFFFC7FF
460#define S_00016C_ENABLE_FRAGMENT_PROCESSING(x) (((x) & 0x1) << 14)
461#define G_00016C_ENABLE_FRAGMENT_PROCESSING(x) (((x) >> 14) & 0x1)
462#define C_00016C_ENABLE_FRAGMENT_PROCESSING 0xFFFFBFFF
463#define S_00016C_EFFECTIVE_L1_QUEUE_SIZE(x) (((x) & 0x7) << 15)
464#define G_00016C_EFFECTIVE_L1_QUEUE_SIZE(x) (((x) >> 15) & 0x7)
465#define C_00016C_EFFECTIVE_L1_QUEUE_SIZE 0xFFFC7FFF
466#define S_00016C_INVALIDATE_L1_TLB(x) (((x) & 0x1) << 20)
467#define G_00016C_INVALIDATE_L1_TLB(x) (((x) >> 20) & 0x1)
468#define C_00016C_INVALIDATE_L1_TLB 0xFFEFFFFF
469
470#endif
diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c
index 7a0098ddf977..025e3225346c 100644
--- a/drivers/gpu/drm/radeon/rs690.c
+++ b/drivers/gpu/drm/radeon/rs690.c
@@ -26,105 +26,29 @@
26 * Jerome Glisse 26 * Jerome Glisse
27 */ 27 */
28#include "drmP.h" 28#include "drmP.h"
29#include "radeon_reg.h"
30#include "radeon.h" 29#include "radeon.h"
31#include "rs690r.h"
32#include "atom.h" 30#include "atom.h"
33#include "atom-bits.h" 31#include "rs690d.h"
34
35/* rs690,rs740 depends on : */
36void r100_hdp_reset(struct radeon_device *rdev);
37int r300_mc_wait_for_idle(struct radeon_device *rdev);
38void r420_pipes_init(struct radeon_device *rdev);
39void rs400_gart_disable(struct radeon_device *rdev);
40int rs400_gart_enable(struct radeon_device *rdev);
41void rs400_gart_adjust_size(struct radeon_device *rdev);
42void rs600_mc_disable_clients(struct radeon_device *rdev);
43
44/* This files gather functions specifics to :
45 * rs690,rs740
46 *
47 * Some of these functions might be used by newer ASICs.
48 */
49void rs690_gpu_init(struct radeon_device *rdev);
50int rs690_mc_wait_for_idle(struct radeon_device *rdev);
51
52
53/*
54 * MC functions.
55 */
56int rs690_mc_init(struct radeon_device *rdev)
57{
58 uint32_t tmp;
59 int r;
60
61 if (r100_debugfs_rbbm_init(rdev)) {
62 DRM_ERROR("Failed to register debugfs file for RBBM !\n");
63 }
64
65 rs690_gpu_init(rdev);
66 rs400_gart_disable(rdev);
67
68 /* Setup GPU memory space */
69 rdev->mc.gtt_location = rdev->mc.mc_vram_size;
70 rdev->mc.gtt_location += (rdev->mc.gtt_size - 1);
71 rdev->mc.gtt_location &= ~(rdev->mc.gtt_size - 1);
72 rdev->mc.vram_location = 0xFFFFFFFFUL;
73 r = radeon_mc_setup(rdev);
74 if (r) {
75 return r;
76 }
77
78 /* Program GPU memory space */
79 rs600_mc_disable_clients(rdev);
80 if (rs690_mc_wait_for_idle(rdev)) {
81 printk(KERN_WARNING "Failed to wait MC idle while "
82 "programming pipes. Bad things might happen.\n");
83 }
84 tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1;
85 tmp = REG_SET(RS690_MC_FB_TOP, tmp >> 16);
86 tmp |= REG_SET(RS690_MC_FB_START, rdev->mc.vram_location >> 16);
87 WREG32_MC(RS690_MCCFG_FB_LOCATION, tmp);
88 /* FIXME: Does this reg exist on RS480,RS740 ? */
89 WREG32(0x310, rdev->mc.vram_location);
90 WREG32(RS690_HDP_FB_LOCATION, rdev->mc.vram_location >> 16);
91 return 0;
92}
93
94void rs690_mc_fini(struct radeon_device *rdev)
95{
96}
97
98 32
99/* 33static int rs690_mc_wait_for_idle(struct radeon_device *rdev)
100 * Global GPU functions
101 */
102int rs690_mc_wait_for_idle(struct radeon_device *rdev)
103{ 34{
104 unsigned i; 35 unsigned i;
105 uint32_t tmp; 36 uint32_t tmp;
106 37
107 for (i = 0; i < rdev->usec_timeout; i++) { 38 for (i = 0; i < rdev->usec_timeout; i++) {
108 /* read MC_STATUS */ 39 /* read MC_STATUS */
109 tmp = RREG32_MC(RS690_MC_STATUS); 40 tmp = RREG32_MC(R_000090_MC_SYSTEM_STATUS);
110 if (tmp & RS690_MC_STATUS_IDLE) { 41 if (G_000090_MC_SYSTEM_IDLE(tmp))
111 return 0; 42 return 0;
112 } 43 udelay(1);
113 DRM_UDELAY(1);
114 } 44 }
115 return -1; 45 return -1;
116} 46}
117 47
118void rs690_errata(struct radeon_device *rdev) 48static void rs690_gpu_init(struct radeon_device *rdev)
119{
120 rdev->pll_errata = 0;
121}
122
123void rs690_gpu_init(struct radeon_device *rdev)
124{ 49{
125 /* FIXME: HDP same place on rs690 ? */ 50 /* FIXME: HDP same place on rs690 ? */
126 r100_hdp_reset(rdev); 51 r100_hdp_reset(rdev);
127 rv515_vga_render_disable(rdev);
128 /* FIXME: is this correct ? */ 52 /* FIXME: is this correct ? */
129 r420_pipes_init(rdev); 53 r420_pipes_init(rdev);
130 if (rs690_mc_wait_for_idle(rdev)) { 54 if (rs690_mc_wait_for_idle(rdev)) {
@@ -133,10 +57,6 @@ void rs690_gpu_init(struct radeon_device *rdev)
133 } 57 }
134} 58}
135 59
136
137/*
138 * VRAM info.
139 */
140void rs690_pm_info(struct radeon_device *rdev) 60void rs690_pm_info(struct radeon_device *rdev)
141{ 61{
142 int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo); 62 int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo);
@@ -250,39 +170,39 @@ void rs690_line_buffer_adjust(struct radeon_device *rdev,
250 /* 170 /*
251 * Line Buffer Setup 171 * Line Buffer Setup
252 * There is a single line buffer shared by both display controllers. 172 * There is a single line buffer shared by both display controllers.
253 * DC_LB_MEMORY_SPLIT controls how that line buffer is shared between 173 * R_006520_DC_LB_MEMORY_SPLIT controls how that line buffer is shared between
254 * the display controllers. The paritioning can either be done 174 * the display controllers. The paritioning can either be done
255 * manually or via one of four preset allocations specified in bits 1:0: 175 * manually or via one of four preset allocations specified in bits 1:0:
256 * 0 - line buffer is divided in half and shared between crtc 176 * 0 - line buffer is divided in half and shared between crtc
257 * 1 - D1 gets 3/4 of the line buffer, D2 gets 1/4 177 * 1 - D1 gets 3/4 of the line buffer, D2 gets 1/4
258 * 2 - D1 gets the whole buffer 178 * 2 - D1 gets the whole buffer
259 * 3 - D1 gets 1/4 of the line buffer, D2 gets 3/4 179 * 3 - D1 gets 1/4 of the line buffer, D2 gets 3/4
260 * Setting bit 2 of DC_LB_MEMORY_SPLIT controls switches to manual 180 * Setting bit 2 of R_006520_DC_LB_MEMORY_SPLIT controls switches to manual
261 * allocation mode. In manual allocation mode, D1 always starts at 0, 181 * allocation mode. In manual allocation mode, D1 always starts at 0,
262 * D1 end/2 is specified in bits 14:4; D2 allocation follows D1. 182 * D1 end/2 is specified in bits 14:4; D2 allocation follows D1.
263 */ 183 */
264 tmp = RREG32(DC_LB_MEMORY_SPLIT) & ~DC_LB_MEMORY_SPLIT_MASK; 184 tmp = RREG32(R_006520_DC_LB_MEMORY_SPLIT) & C_006520_DC_LB_MEMORY_SPLIT;
265 tmp &= ~DC_LB_MEMORY_SPLIT_SHIFT_MODE; 185 tmp &= ~C_006520_DC_LB_MEMORY_SPLIT_MODE;
266 /* auto */ 186 /* auto */
267 if (mode1 && mode2) { 187 if (mode1 && mode2) {
268 if (mode1->hdisplay > mode2->hdisplay) { 188 if (mode1->hdisplay > mode2->hdisplay) {
269 if (mode1->hdisplay > 2560) 189 if (mode1->hdisplay > 2560)
270 tmp |= DC_LB_MEMORY_SPLIT_D1_3Q_D2_1Q; 190 tmp |= V_006520_DC_LB_MEMORY_SPLIT_D1_3Q_D2_1Q;
271 else 191 else
272 tmp |= DC_LB_MEMORY_SPLIT_D1HALF_D2HALF; 192 tmp |= V_006520_DC_LB_MEMORY_SPLIT_D1HALF_D2HALF;
273 } else if (mode2->hdisplay > mode1->hdisplay) { 193 } else if (mode2->hdisplay > mode1->hdisplay) {
274 if (mode2->hdisplay > 2560) 194 if (mode2->hdisplay > 2560)
275 tmp |= DC_LB_MEMORY_SPLIT_D1_1Q_D2_3Q; 195 tmp |= V_006520_DC_LB_MEMORY_SPLIT_D1_1Q_D2_3Q;
276 else 196 else
277 tmp |= DC_LB_MEMORY_SPLIT_D1HALF_D2HALF; 197 tmp |= V_006520_DC_LB_MEMORY_SPLIT_D1HALF_D2HALF;
278 } else 198 } else
279 tmp |= AVIVO_DC_LB_MEMORY_SPLIT_D1HALF_D2HALF; 199 tmp |= V_006520_DC_LB_MEMORY_SPLIT_D1HALF_D2HALF;
280 } else if (mode1) { 200 } else if (mode1) {
281 tmp |= DC_LB_MEMORY_SPLIT_D1_ONLY; 201 tmp |= V_006520_DC_LB_MEMORY_SPLIT_D1_ONLY;
282 } else if (mode2) { 202 } else if (mode2) {
283 tmp |= DC_LB_MEMORY_SPLIT_D1_1Q_D2_3Q; 203 tmp |= V_006520_DC_LB_MEMORY_SPLIT_D1_1Q_D2_3Q;
284 } 204 }
285 WREG32(DC_LB_MEMORY_SPLIT, tmp); 205 WREG32(R_006520_DC_LB_MEMORY_SPLIT, tmp);
286} 206}
287 207
288struct rs690_watermark { 208struct rs690_watermark {
@@ -487,28 +407,28 @@ void rs690_bandwidth_update(struct radeon_device *rdev)
487 * option. 407 * option.
488 */ 408 */
489 if (rdev->disp_priority == 2) { 409 if (rdev->disp_priority == 2) {
490 tmp = RREG32_MC(MC_INIT_MISC_LAT_TIMER); 410 tmp = RREG32_MC(R_000104_MC_INIT_MISC_LAT_TIMER);
491 tmp &= ~MC_DISP1R_INIT_LAT_MASK; 411 tmp &= C_000104_MC_DISP0R_INIT_LAT;
492 tmp &= ~MC_DISP0R_INIT_LAT_MASK; 412 tmp &= C_000104_MC_DISP1R_INIT_LAT;
493 if (mode1)
494 tmp |= (1 << MC_DISP1R_INIT_LAT_SHIFT);
495 if (mode0) 413 if (mode0)
496 tmp |= (1 << MC_DISP0R_INIT_LAT_SHIFT); 414 tmp |= S_000104_MC_DISP0R_INIT_LAT(1);
497 WREG32_MC(MC_INIT_MISC_LAT_TIMER, tmp); 415 if (mode1)
416 tmp |= S_000104_MC_DISP1R_INIT_LAT(1);
417 WREG32_MC(R_000104_MC_INIT_MISC_LAT_TIMER, tmp);
498 } 418 }
499 rs690_line_buffer_adjust(rdev, mode0, mode1); 419 rs690_line_buffer_adjust(rdev, mode0, mode1);
500 420
501 if ((rdev->family == CHIP_RS690) || (rdev->family == CHIP_RS740)) 421 if ((rdev->family == CHIP_RS690) || (rdev->family == CHIP_RS740))
502 WREG32(DCP_CONTROL, 0); 422 WREG32(R_006C9C_DCP_CONTROL, 0);
503 if ((rdev->family == CHIP_RS780) || (rdev->family == CHIP_RS880)) 423 if ((rdev->family == CHIP_RS780) || (rdev->family == CHIP_RS880))
504 WREG32(DCP_CONTROL, 2); 424 WREG32(R_006C9C_DCP_CONTROL, 2);
505 425
506 rs690_crtc_bandwidth_compute(rdev, rdev->mode_info.crtcs[0], &wm0); 426 rs690_crtc_bandwidth_compute(rdev, rdev->mode_info.crtcs[0], &wm0);
507 rs690_crtc_bandwidth_compute(rdev, rdev->mode_info.crtcs[1], &wm1); 427 rs690_crtc_bandwidth_compute(rdev, rdev->mode_info.crtcs[1], &wm1);
508 428
509 tmp = (wm0.lb_request_fifo_depth - 1); 429 tmp = (wm0.lb_request_fifo_depth - 1);
510 tmp |= (wm1.lb_request_fifo_depth - 1) << 16; 430 tmp |= (wm1.lb_request_fifo_depth - 1) << 16;
511 WREG32(LB_MAX_REQ_OUTSTANDING, tmp); 431 WREG32(R_006D58_LB_MAX_REQ_OUTSTANDING, tmp);
512 432
513 if (mode0 && mode1) { 433 if (mode0 && mode1) {
514 if (rfixed_trunc(wm0.dbpp) > 64) 434 if (rfixed_trunc(wm0.dbpp) > 64)
@@ -561,10 +481,10 @@ void rs690_bandwidth_update(struct radeon_device *rdev)
561 priority_mark12.full = 0; 481 priority_mark12.full = 0;
562 if (wm1.priority_mark_max.full > priority_mark12.full) 482 if (wm1.priority_mark_max.full > priority_mark12.full)
563 priority_mark12.full = wm1.priority_mark_max.full; 483 priority_mark12.full = wm1.priority_mark_max.full;
564 WREG32(D1MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark02)); 484 WREG32(R_006548_D1MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark02));
565 WREG32(D1MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark02)); 485 WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark02));
566 WREG32(D2MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark12)); 486 WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark12));
567 WREG32(D2MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark12)); 487 WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark12));
568 } else if (mode0) { 488 } else if (mode0) {
569 if (rfixed_trunc(wm0.dbpp) > 64) 489 if (rfixed_trunc(wm0.dbpp) > 64)
570 a.full = rfixed_mul(wm0.dbpp, wm0.num_line_pair); 490 a.full = rfixed_mul(wm0.dbpp, wm0.num_line_pair);
@@ -591,10 +511,12 @@ void rs690_bandwidth_update(struct radeon_device *rdev)
591 priority_mark02.full = 0; 511 priority_mark02.full = 0;
592 if (wm0.priority_mark_max.full > priority_mark02.full) 512 if (wm0.priority_mark_max.full > priority_mark02.full)
593 priority_mark02.full = wm0.priority_mark_max.full; 513 priority_mark02.full = wm0.priority_mark_max.full;
594 WREG32(D1MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark02)); 514 WREG32(R_006548_D1MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark02));
595 WREG32(D1MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark02)); 515 WREG32(R_00654C_D1MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark02));
596 WREG32(D2MODE_PRIORITY_A_CNT, MODE_PRIORITY_OFF); 516 WREG32(R_006D48_D2MODE_PRIORITY_A_CNT,
597 WREG32(D2MODE_PRIORITY_B_CNT, MODE_PRIORITY_OFF); 517 S_006D48_D2MODE_PRIORITY_A_OFF(1));
518 WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT,
519 S_006D4C_D2MODE_PRIORITY_B_OFF(1));
598 } else { 520 } else {
599 if (rfixed_trunc(wm1.dbpp) > 64) 521 if (rfixed_trunc(wm1.dbpp) > 64)
600 a.full = rfixed_mul(wm1.dbpp, wm1.num_line_pair); 522 a.full = rfixed_mul(wm1.dbpp, wm1.num_line_pair);
@@ -621,30 +543,203 @@ void rs690_bandwidth_update(struct radeon_device *rdev)
621 priority_mark12.full = 0; 543 priority_mark12.full = 0;
622 if (wm1.priority_mark_max.full > priority_mark12.full) 544 if (wm1.priority_mark_max.full > priority_mark12.full)
623 priority_mark12.full = wm1.priority_mark_max.full; 545 priority_mark12.full = wm1.priority_mark_max.full;
624 WREG32(D1MODE_PRIORITY_A_CNT, MODE_PRIORITY_OFF); 546 WREG32(R_006548_D1MODE_PRIORITY_A_CNT,
625 WREG32(D1MODE_PRIORITY_B_CNT, MODE_PRIORITY_OFF); 547 S_006548_D1MODE_PRIORITY_A_OFF(1));
626 WREG32(D2MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark12)); 548 WREG32(R_00654C_D1MODE_PRIORITY_B_CNT,
627 WREG32(D2MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark12)); 549 S_00654C_D1MODE_PRIORITY_B_OFF(1));
550 WREG32(R_006D48_D2MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark12));
551 WREG32(R_006D4C_D2MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark12));
628 } 552 }
629} 553}
630 554
631/*
632 * Indirect registers accessor
633 */
634uint32_t rs690_mc_rreg(struct radeon_device *rdev, uint32_t reg) 555uint32_t rs690_mc_rreg(struct radeon_device *rdev, uint32_t reg)
635{ 556{
636 uint32_t r; 557 uint32_t r;
637 558
638 WREG32(RS690_MC_INDEX, (reg & RS690_MC_INDEX_MASK)); 559 WREG32(R_000078_MC_INDEX, S_000078_MC_IND_ADDR(reg));
639 r = RREG32(RS690_MC_DATA); 560 r = RREG32(R_00007C_MC_DATA);
640 WREG32(RS690_MC_INDEX, RS690_MC_INDEX_MASK); 561 WREG32(R_000078_MC_INDEX, ~C_000078_MC_IND_ADDR);
641 return r; 562 return r;
642} 563}
643 564
644void rs690_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) 565void rs690_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
645{ 566{
646 WREG32(RS690_MC_INDEX, 567 WREG32(R_000078_MC_INDEX, S_000078_MC_IND_ADDR(reg) |
647 RS690_MC_INDEX_WR_EN | ((reg) & RS690_MC_INDEX_MASK)); 568 S_000078_MC_IND_WR_EN(1));
648 WREG32(RS690_MC_DATA, v); 569 WREG32(R_00007C_MC_DATA, v);
649 WREG32(RS690_MC_INDEX, RS690_MC_INDEX_WR_ACK); 570 WREG32(R_000078_MC_INDEX, 0x7F);
571}
572
573void rs690_mc_program(struct radeon_device *rdev)
574{
575 struct rv515_mc_save save;
576
577 /* Stops all mc clients */
578 rv515_mc_stop(rdev, &save);
579
580 /* Wait for mc idle */
581 if (rs690_mc_wait_for_idle(rdev))
582 dev_warn(rdev->dev, "Wait MC idle timeout before updating MC.\n");
583 /* Program MC, should be a 32bits limited address space */
584 WREG32_MC(R_000100_MCCFG_FB_LOCATION,
585 S_000100_MC_FB_START(rdev->mc.vram_start >> 16) |
586 S_000100_MC_FB_TOP(rdev->mc.vram_end >> 16));
587 WREG32(R_000134_HDP_FB_LOCATION,
588 S_000134_HDP_FB_START(rdev->mc.vram_start >> 16));
589
590 rv515_mc_resume(rdev, &save);
591}
592
593static int rs690_startup(struct radeon_device *rdev)
594{
595 int r;
596
597 rs690_mc_program(rdev);
598 /* Resume clock */
599 rv515_clock_startup(rdev);
600 /* Initialize GPU configuration (# pipes, ...) */
601 rs690_gpu_init(rdev);
602 /* Initialize GART (initialize after TTM so we can allocate
603 * memory through TTM but finalize after TTM) */
604 r = rs400_gart_enable(rdev);
605 if (r)
606 return r;
607 /* Enable IRQ */
608 rdev->irq.sw_int = true;
609 rs600_irq_set(rdev);
610 /* 1M ring buffer */
611 r = r100_cp_init(rdev, 1024 * 1024);
612 if (r) {
613 dev_err(rdev->dev, "failled initializing CP (%d).\n", r);
614 return r;
615 }
616 r = r100_wb_init(rdev);
617 if (r)
618 dev_err(rdev->dev, "failled initializing WB (%d).\n", r);
619 r = r100_ib_init(rdev);
620 if (r) {
621 dev_err(rdev->dev, "failled initializing IB (%d).\n", r);
622 return r;
623 }
624 return 0;
625}
626
627int rs690_resume(struct radeon_device *rdev)
628{
629 /* Make sur GART are not working */
630 rs400_gart_disable(rdev);
631 /* Resume clock before doing reset */
632 rv515_clock_startup(rdev);
633 /* Reset gpu before posting otherwise ATOM will enter infinite loop */
634 if (radeon_gpu_reset(rdev)) {
635 dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
636 RREG32(R_000E40_RBBM_STATUS),
637 RREG32(R_0007C0_CP_STAT));
638 }
639 /* post */
640 atom_asic_init(rdev->mode_info.atom_context);
641 /* Resume clock after posting */
642 rv515_clock_startup(rdev);
643 return rs690_startup(rdev);
644}
645
646int rs690_suspend(struct radeon_device *rdev)
647{
648 r100_cp_disable(rdev);
649 r100_wb_disable(rdev);
650 rs600_irq_disable(rdev);
651 rs400_gart_disable(rdev);
652 return 0;
653}
654
655void rs690_fini(struct radeon_device *rdev)
656{
657 rs690_suspend(rdev);
658 r100_cp_fini(rdev);
659 r100_wb_fini(rdev);
660 r100_ib_fini(rdev);
661 radeon_gem_fini(rdev);
662 rs400_gart_fini(rdev);
663 radeon_irq_kms_fini(rdev);
664 radeon_fence_driver_fini(rdev);
665 radeon_object_fini(rdev);
666 radeon_atombios_fini(rdev);
667 kfree(rdev->bios);
668 rdev->bios = NULL;
669}
670
671int rs690_init(struct radeon_device *rdev)
672{
673 int r;
674
675 /* Disable VGA */
676 rv515_vga_render_disable(rdev);
677 /* Initialize scratch registers */
678 radeon_scratch_init(rdev);
679 /* Initialize surface registers */
680 radeon_surface_init(rdev);
681 /* TODO: disable VGA need to use VGA request */
682 /* BIOS*/
683 if (!radeon_get_bios(rdev)) {
684 if (ASIC_IS_AVIVO(rdev))
685 return -EINVAL;
686 }
687 if (rdev->is_atom_bios) {
688 r = radeon_atombios_init(rdev);
689 if (r)
690 return r;
691 } else {
692 dev_err(rdev->dev, "Expecting atombios for RV515 GPU\n");
693 return -EINVAL;
694 }
695 /* Reset gpu before posting otherwise ATOM will enter infinite loop */
696 if (radeon_gpu_reset(rdev)) {
697 dev_warn(rdev->dev,
698 "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
699 RREG32(R_000E40_RBBM_STATUS),
700 RREG32(R_0007C0_CP_STAT));
701 }
702 /* check if cards are posted or not */
703 if (!radeon_card_posted(rdev) && rdev->bios) {
704 DRM_INFO("GPU not posted. posting now...\n");
705 atom_asic_init(rdev->mode_info.atom_context);
706 }
707 /* Initialize clocks */
708 radeon_get_clock_info(rdev->ddev);
709 /* Get vram informations */
710 rs690_vram_info(rdev);
711 /* Initialize memory controller (also test AGP) */
712 r = r420_mc_init(rdev);
713 if (r)
714 return r;
715 rv515_debugfs(rdev);
716 /* Fence driver */
717 r = radeon_fence_driver_init(rdev);
718 if (r)
719 return r;
720 r = radeon_irq_kms_init(rdev);
721 if (r)
722 return r;
723 /* Memory manager */
724 r = radeon_object_init(rdev);
725 if (r)
726 return r;
727 r = rs400_gart_init(rdev);
728 if (r)
729 return r;
730 rs600_set_safe_registers(rdev);
731 rdev->accel_working = true;
732 r = rs690_startup(rdev);
733 if (r) {
734 /* Somethings want wront with the accel init stop accel */
735 dev_err(rdev->dev, "Disabling GPU acceleration\n");
736 rs690_suspend(rdev);
737 r100_cp_fini(rdev);
738 r100_wb_fini(rdev);
739 r100_ib_fini(rdev);
740 rs400_gart_fini(rdev);
741 radeon_irq_kms_fini(rdev);
742 rdev->accel_working = false;
743 }
744 return 0;
650} 745}
diff --git a/drivers/gpu/drm/radeon/rs690d.h b/drivers/gpu/drm/radeon/rs690d.h
new file mode 100644
index 000000000000..62d31e7a897f
--- /dev/null
+++ b/drivers/gpu/drm/radeon/rs690d.h
@@ -0,0 +1,307 @@
1/*
2 * Copyright 2008 Advanced Micro Devices, Inc.
3 * Copyright 2008 Red Hat Inc.
4 * Copyright 2009 Jerome Glisse.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors: Dave Airlie
25 * Alex Deucher
26 * Jerome Glisse
27 */
28#ifndef __RS690D_H__
29#define __RS690D_H__
30
31/* Registers */
32#define R_000078_MC_INDEX 0x000078
33#define S_000078_MC_IND_ADDR(x) (((x) & 0x1FF) << 0)
34#define G_000078_MC_IND_ADDR(x) (((x) >> 0) & 0x1FF)
35#define C_000078_MC_IND_ADDR 0xFFFFFE00
36#define S_000078_MC_IND_WR_EN(x) (((x) & 0x1) << 9)
37#define G_000078_MC_IND_WR_EN(x) (((x) >> 9) & 0x1)
38#define C_000078_MC_IND_WR_EN 0xFFFFFDFF
39#define R_00007C_MC_DATA 0x00007C
40#define S_00007C_MC_DATA(x) (((x) & 0xFFFFFFFF) << 0)
41#define G_00007C_MC_DATA(x) (((x) >> 0) & 0xFFFFFFFF)
42#define C_00007C_MC_DATA 0x00000000
43#define R_0000F8_CONFIG_MEMSIZE 0x0000F8
44#define S_0000F8_CONFIG_MEMSIZE(x) (((x) & 0xFFFFFFFF) << 0)
45#define G_0000F8_CONFIG_MEMSIZE(x) (((x) >> 0) & 0xFFFFFFFF)
46#define C_0000F8_CONFIG_MEMSIZE 0x00000000
47#define R_000134_HDP_FB_LOCATION 0x000134
48#define S_000134_HDP_FB_START(x) (((x) & 0xFFFF) << 0)
49#define G_000134_HDP_FB_START(x) (((x) >> 0) & 0xFFFF)
50#define C_000134_HDP_FB_START 0xFFFF0000
51#define R_0007C0_CP_STAT 0x0007C0
52#define S_0007C0_MRU_BUSY(x) (((x) & 0x1) << 0)
53#define G_0007C0_MRU_BUSY(x) (((x) >> 0) & 0x1)
54#define C_0007C0_MRU_BUSY 0xFFFFFFFE
55#define S_0007C0_MWU_BUSY(x) (((x) & 0x1) << 1)
56#define G_0007C0_MWU_BUSY(x) (((x) >> 1) & 0x1)
57#define C_0007C0_MWU_BUSY 0xFFFFFFFD
58#define S_0007C0_RSIU_BUSY(x) (((x) & 0x1) << 2)
59#define G_0007C0_RSIU_BUSY(x) (((x) >> 2) & 0x1)
60#define C_0007C0_RSIU_BUSY 0xFFFFFFFB
61#define S_0007C0_RCIU_BUSY(x) (((x) & 0x1) << 3)
62#define G_0007C0_RCIU_BUSY(x) (((x) >> 3) & 0x1)
63#define C_0007C0_RCIU_BUSY 0xFFFFFFF7
64#define S_0007C0_CSF_PRIMARY_BUSY(x) (((x) & 0x1) << 9)
65#define G_0007C0_CSF_PRIMARY_BUSY(x) (((x) >> 9) & 0x1)
66#define C_0007C0_CSF_PRIMARY_BUSY 0xFFFFFDFF
67#define S_0007C0_CSF_INDIRECT_BUSY(x) (((x) & 0x1) << 10)
68#define G_0007C0_CSF_INDIRECT_BUSY(x) (((x) >> 10) & 0x1)
69#define C_0007C0_CSF_INDIRECT_BUSY 0xFFFFFBFF
70#define S_0007C0_CSQ_PRIMARY_BUSY(x) (((x) & 0x1) << 11)
71#define G_0007C0_CSQ_PRIMARY_BUSY(x) (((x) >> 11) & 0x1)
72#define C_0007C0_CSQ_PRIMARY_BUSY 0xFFFFF7FF
73#define S_0007C0_CSQ_INDIRECT_BUSY(x) (((x) & 0x1) << 12)
74#define G_0007C0_CSQ_INDIRECT_BUSY(x) (((x) >> 12) & 0x1)
75#define C_0007C0_CSQ_INDIRECT_BUSY 0xFFFFEFFF
76#define S_0007C0_CSI_BUSY(x) (((x) & 0x1) << 13)
77#define G_0007C0_CSI_BUSY(x) (((x) >> 13) & 0x1)
78#define C_0007C0_CSI_BUSY 0xFFFFDFFF
79#define S_0007C0_CSF_INDIRECT2_BUSY(x) (((x) & 0x1) << 14)
80#define G_0007C0_CSF_INDIRECT2_BUSY(x) (((x) >> 14) & 0x1)
81#define C_0007C0_CSF_INDIRECT2_BUSY 0xFFFFBFFF
82#define S_0007C0_CSQ_INDIRECT2_BUSY(x) (((x) & 0x1) << 15)
83#define G_0007C0_CSQ_INDIRECT2_BUSY(x) (((x) >> 15) & 0x1)
84#define C_0007C0_CSQ_INDIRECT2_BUSY 0xFFFF7FFF
85#define S_0007C0_GUIDMA_BUSY(x) (((x) & 0x1) << 28)
86#define G_0007C0_GUIDMA_BUSY(x) (((x) >> 28) & 0x1)
87#define C_0007C0_GUIDMA_BUSY 0xEFFFFFFF
88#define S_0007C0_VIDDMA_BUSY(x) (((x) & 0x1) << 29)
89#define G_0007C0_VIDDMA_BUSY(x) (((x) >> 29) & 0x1)
90#define C_0007C0_VIDDMA_BUSY 0xDFFFFFFF
91#define S_0007C0_CMDSTRM_BUSY(x) (((x) & 0x1) << 30)
92#define G_0007C0_CMDSTRM_BUSY(x) (((x) >> 30) & 0x1)
93#define C_0007C0_CMDSTRM_BUSY 0xBFFFFFFF
94#define S_0007C0_CP_BUSY(x) (((x) & 0x1) << 31)
95#define G_0007C0_CP_BUSY(x) (((x) >> 31) & 0x1)
96#define C_0007C0_CP_BUSY 0x7FFFFFFF
97#define R_000E40_RBBM_STATUS 0x000E40
98#define S_000E40_CMDFIFO_AVAIL(x) (((x) & 0x7F) << 0)
99#define G_000E40_CMDFIFO_AVAIL(x) (((x) >> 0) & 0x7F)
100#define C_000E40_CMDFIFO_AVAIL 0xFFFFFF80
101#define S_000E40_HIRQ_ON_RBB(x) (((x) & 0x1) << 8)
102#define G_000E40_HIRQ_ON_RBB(x) (((x) >> 8) & 0x1)
103#define C_000E40_HIRQ_ON_RBB 0xFFFFFEFF
104#define S_000E40_CPRQ_ON_RBB(x) (((x) & 0x1) << 9)
105#define G_000E40_CPRQ_ON_RBB(x) (((x) >> 9) & 0x1)
106#define C_000E40_CPRQ_ON_RBB 0xFFFFFDFF
107#define S_000E40_CFRQ_ON_RBB(x) (((x) & 0x1) << 10)
108#define G_000E40_CFRQ_ON_RBB(x) (((x) >> 10) & 0x1)
109#define C_000E40_CFRQ_ON_RBB 0xFFFFFBFF
110#define S_000E40_HIRQ_IN_RTBUF(x) (((x) & 0x1) << 11)
111#define G_000E40_HIRQ_IN_RTBUF(x) (((x) >> 11) & 0x1)
112#define C_000E40_HIRQ_IN_RTBUF 0xFFFFF7FF
113#define S_000E40_CPRQ_IN_RTBUF(x) (((x) & 0x1) << 12)
114#define G_000E40_CPRQ_IN_RTBUF(x) (((x) >> 12) & 0x1)
115#define C_000E40_CPRQ_IN_RTBUF 0xFFFFEFFF
116#define S_000E40_CFRQ_IN_RTBUF(x) (((x) & 0x1) << 13)
117#define G_000E40_CFRQ_IN_RTBUF(x) (((x) >> 13) & 0x1)
118#define C_000E40_CFRQ_IN_RTBUF 0xFFFFDFFF
119#define S_000E40_CF_PIPE_BUSY(x) (((x) & 0x1) << 14)
120#define G_000E40_CF_PIPE_BUSY(x) (((x) >> 14) & 0x1)
121#define C_000E40_CF_PIPE_BUSY 0xFFFFBFFF
122#define S_000E40_ENG_EV_BUSY(x) (((x) & 0x1) << 15)
123#define G_000E40_ENG_EV_BUSY(x) (((x) >> 15) & 0x1)
124#define C_000E40_ENG_EV_BUSY 0xFFFF7FFF
125#define S_000E40_CP_CMDSTRM_BUSY(x) (((x) & 0x1) << 16)
126#define G_000E40_CP_CMDSTRM_BUSY(x) (((x) >> 16) & 0x1)
127#define C_000E40_CP_CMDSTRM_BUSY 0xFFFEFFFF
128#define S_000E40_E2_BUSY(x) (((x) & 0x1) << 17)
129#define G_000E40_E2_BUSY(x) (((x) >> 17) & 0x1)
130#define C_000E40_E2_BUSY 0xFFFDFFFF
131#define S_000E40_RB2D_BUSY(x) (((x) & 0x1) << 18)
132#define G_000E40_RB2D_BUSY(x) (((x) >> 18) & 0x1)
133#define C_000E40_RB2D_BUSY 0xFFFBFFFF
134#define S_000E40_RB3D_BUSY(x) (((x) & 0x1) << 19)
135#define G_000E40_RB3D_BUSY(x) (((x) >> 19) & 0x1)
136#define C_000E40_RB3D_BUSY 0xFFF7FFFF
137#define S_000E40_VAP_BUSY(x) (((x) & 0x1) << 20)
138#define G_000E40_VAP_BUSY(x) (((x) >> 20) & 0x1)
139#define C_000E40_VAP_BUSY 0xFFEFFFFF
140#define S_000E40_RE_BUSY(x) (((x) & 0x1) << 21)
141#define G_000E40_RE_BUSY(x) (((x) >> 21) & 0x1)
142#define C_000E40_RE_BUSY 0xFFDFFFFF
143#define S_000E40_TAM_BUSY(x) (((x) & 0x1) << 22)
144#define G_000E40_TAM_BUSY(x) (((x) >> 22) & 0x1)
145#define C_000E40_TAM_BUSY 0xFFBFFFFF
146#define S_000E40_TDM_BUSY(x) (((x) & 0x1) << 23)
147#define G_000E40_TDM_BUSY(x) (((x) >> 23) & 0x1)
148#define C_000E40_TDM_BUSY 0xFF7FFFFF
149#define S_000E40_PB_BUSY(x) (((x) & 0x1) << 24)
150#define G_000E40_PB_BUSY(x) (((x) >> 24) & 0x1)
151#define C_000E40_PB_BUSY 0xFEFFFFFF
152#define S_000E40_TIM_BUSY(x) (((x) & 0x1) << 25)
153#define G_000E40_TIM_BUSY(x) (((x) >> 25) & 0x1)
154#define C_000E40_TIM_BUSY 0xFDFFFFFF
155#define S_000E40_GA_BUSY(x) (((x) & 0x1) << 26)
156#define G_000E40_GA_BUSY(x) (((x) >> 26) & 0x1)
157#define C_000E40_GA_BUSY 0xFBFFFFFF
158#define S_000E40_CBA2D_BUSY(x) (((x) & 0x1) << 27)
159#define G_000E40_CBA2D_BUSY(x) (((x) >> 27) & 0x1)
160#define C_000E40_CBA2D_BUSY 0xF7FFFFFF
161#define S_000E40_GUI_ACTIVE(x) (((x) & 0x1) << 31)
162#define G_000E40_GUI_ACTIVE(x) (((x) >> 31) & 0x1)
163#define C_000E40_GUI_ACTIVE 0x7FFFFFFF
164#define R_006520_DC_LB_MEMORY_SPLIT 0x006520
165#define S_006520_DC_LB_MEMORY_SPLIT(x) (((x) & 0x3) << 0)
166#define G_006520_DC_LB_MEMORY_SPLIT(x) (((x) >> 0) & 0x3)
167#define C_006520_DC_LB_MEMORY_SPLIT 0xFFFFFFFC
168#define S_006520_DC_LB_MEMORY_SPLIT_MODE(x) (((x) & 0x1) << 2)
169#define G_006520_DC_LB_MEMORY_SPLIT_MODE(x) (((x) >> 2) & 0x1)
170#define C_006520_DC_LB_MEMORY_SPLIT_MODE 0xFFFFFFFB
171#define V_006520_DC_LB_MEMORY_SPLIT_D1HALF_D2HALF 0
172#define V_006520_DC_LB_MEMORY_SPLIT_D1_3Q_D2_1Q 1
173#define V_006520_DC_LB_MEMORY_SPLIT_D1_ONLY 2
174#define V_006520_DC_LB_MEMORY_SPLIT_D1_1Q_D2_3Q 3
175#define S_006520_DC_LB_DISP1_END_ADR(x) (((x) & 0x7FF) << 4)
176#define G_006520_DC_LB_DISP1_END_ADR(x) (((x) >> 4) & 0x7FF)
177#define C_006520_DC_LB_DISP1_END_ADR 0xFFFF800F
178#define R_006548_D1MODE_PRIORITY_A_CNT 0x006548
179#define S_006548_D1MODE_PRIORITY_MARK_A(x) (((x) & 0x7FFF) << 0)
180#define G_006548_D1MODE_PRIORITY_MARK_A(x) (((x) >> 0) & 0x7FFF)
181#define C_006548_D1MODE_PRIORITY_MARK_A 0xFFFF8000
182#define S_006548_D1MODE_PRIORITY_A_OFF(x) (((x) & 0x1) << 16)
183#define G_006548_D1MODE_PRIORITY_A_OFF(x) (((x) >> 16) & 0x1)
184#define C_006548_D1MODE_PRIORITY_A_OFF 0xFFFEFFFF
185#define S_006548_D1MODE_PRIORITY_A_FORCE_MASK(x) (((x) & 0x1) << 24)
186#define G_006548_D1MODE_PRIORITY_A_FORCE_MASK(x) (((x) >> 24) & 0x1)
187#define C_006548_D1MODE_PRIORITY_A_FORCE_MASK 0xFEFFFFFF
188#define R_00654C_D1MODE_PRIORITY_B_CNT 0x00654C
189#define S_00654C_D1MODE_PRIORITY_MARK_B(x) (((x) & 0x7FFF) << 0)
190#define G_00654C_D1MODE_PRIORITY_MARK_B(x) (((x) >> 0) & 0x7FFF)
191#define C_00654C_D1MODE_PRIORITY_MARK_B 0xFFFF8000
192#define S_00654C_D1MODE_PRIORITY_B_OFF(x) (((x) & 0x1) << 16)
193#define G_00654C_D1MODE_PRIORITY_B_OFF(x) (((x) >> 16) & 0x1)
194#define C_00654C_D1MODE_PRIORITY_B_OFF 0xFFFEFFFF
195#define S_00654C_D1MODE_PRIORITY_B_ALWAYS_ON(x) (((x) & 0x1) << 20)
196#define G_00654C_D1MODE_PRIORITY_B_ALWAYS_ON(x) (((x) >> 20) & 0x1)
197#define C_00654C_D1MODE_PRIORITY_B_ALWAYS_ON 0xFFEFFFFF
198#define S_00654C_D1MODE_PRIORITY_B_FORCE_MASK(x) (((x) & 0x1) << 24)
199#define G_00654C_D1MODE_PRIORITY_B_FORCE_MASK(x) (((x) >> 24) & 0x1)
200#define C_00654C_D1MODE_PRIORITY_B_FORCE_MASK 0xFEFFFFFF
201#define R_006C9C_DCP_CONTROL 0x006C9C
202#define R_006D48_D2MODE_PRIORITY_A_CNT 0x006D48
203#define S_006D48_D2MODE_PRIORITY_MARK_A(x) (((x) & 0x7FFF) << 0)
204#define G_006D48_D2MODE_PRIORITY_MARK_A(x) (((x) >> 0) & 0x7FFF)
205#define C_006D48_D2MODE_PRIORITY_MARK_A 0xFFFF8000
206#define S_006D48_D2MODE_PRIORITY_A_OFF(x) (((x) & 0x1) << 16)
207#define G_006D48_D2MODE_PRIORITY_A_OFF(x) (((x) >> 16) & 0x1)
208#define C_006D48_D2MODE_PRIORITY_A_OFF 0xFFFEFFFF
209#define S_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(x) (((x) & 0x1) << 20)
210#define G_006D48_D2MODE_PRIORITY_A_ALWAYS_ON(x) (((x) >> 20) & 0x1)
211#define C_006D48_D2MODE_PRIORITY_A_ALWAYS_ON 0xFFEFFFFF
212#define S_006D48_D2MODE_PRIORITY_A_FORCE_MASK(x) (((x) & 0x1) << 24)
213#define G_006D48_D2MODE_PRIORITY_A_FORCE_MASK(x) (((x) >> 24) & 0x1)
214#define C_006D48_D2MODE_PRIORITY_A_FORCE_MASK 0xFEFFFFFF
215#define R_006D4C_D2MODE_PRIORITY_B_CNT 0x006D4C
216#define S_006D4C_D2MODE_PRIORITY_MARK_B(x) (((x) & 0x7FFF) << 0)
217#define G_006D4C_D2MODE_PRIORITY_MARK_B(x) (((x) >> 0) & 0x7FFF)
218#define C_006D4C_D2MODE_PRIORITY_MARK_B 0xFFFF8000
219#define S_006D4C_D2MODE_PRIORITY_B_OFF(x) (((x) & 0x1) << 16)
220#define G_006D4C_D2MODE_PRIORITY_B_OFF(x) (((x) >> 16) & 0x1)
221#define C_006D4C_D2MODE_PRIORITY_B_OFF 0xFFFEFFFF
222#define S_006D4C_D2MODE_PRIORITY_B_ALWAYS_ON(x) (((x) & 0x1) << 20)
223#define G_006D4C_D2MODE_PRIORITY_B_ALWAYS_ON(x) (((x) >> 20) & 0x1)
224#define C_006D4C_D2MODE_PRIORITY_B_ALWAYS_ON 0xFFEFFFFF
225#define S_006D4C_D2MODE_PRIORITY_B_FORCE_MASK(x) (((x) & 0x1) << 24)
226#define G_006D4C_D2MODE_PRIORITY_B_FORCE_MASK(x) (((x) >> 24) & 0x1)
227#define C_006D4C_D2MODE_PRIORITY_B_FORCE_MASK 0xFEFFFFFF
228#define R_006D58_LB_MAX_REQ_OUTSTANDING 0x006D58
229#define S_006D58_LB_D1_MAX_REQ_OUTSTANDING(x) (((x) & 0xF) << 0)
230#define G_006D58_LB_D1_MAX_REQ_OUTSTANDING(x) (((x) >> 0) & 0xF)
231#define C_006D58_LB_D1_MAX_REQ_OUTSTANDING 0xFFFFFFF0
232#define S_006D58_LB_D2_MAX_REQ_OUTSTANDING(x) (((x) & 0xF) << 16)
233#define G_006D58_LB_D2_MAX_REQ_OUTSTANDING(x) (((x) >> 16) & 0xF)
234#define C_006D58_LB_D2_MAX_REQ_OUTSTANDING 0xFFF0FFFF
235
236
237#define R_000090_MC_SYSTEM_STATUS 0x000090
238#define S_000090_MC_SYSTEM_IDLE(x) (((x) & 0x1) << 0)
239#define G_000090_MC_SYSTEM_IDLE(x) (((x) >> 0) & 0x1)
240#define C_000090_MC_SYSTEM_IDLE 0xFFFFFFFE
241#define S_000090_MC_SEQUENCER_IDLE(x) (((x) & 0x1) << 1)
242#define G_000090_MC_SEQUENCER_IDLE(x) (((x) >> 1) & 0x1)
243#define C_000090_MC_SEQUENCER_IDLE 0xFFFFFFFD
244#define S_000090_MC_ARBITER_IDLE(x) (((x) & 0x1) << 2)
245#define G_000090_MC_ARBITER_IDLE(x) (((x) >> 2) & 0x1)
246#define C_000090_MC_ARBITER_IDLE 0xFFFFFFFB
247#define S_000090_MC_SELECT_PM(x) (((x) & 0x1) << 3)
248#define G_000090_MC_SELECT_PM(x) (((x) >> 3) & 0x1)
249#define C_000090_MC_SELECT_PM 0xFFFFFFF7
250#define S_000090_RESERVED4(x) (((x) & 0xF) << 4)
251#define G_000090_RESERVED4(x) (((x) >> 4) & 0xF)
252#define C_000090_RESERVED4 0xFFFFFF0F
253#define S_000090_RESERVED8(x) (((x) & 0xF) << 8)
254#define G_000090_RESERVED8(x) (((x) >> 8) & 0xF)
255#define C_000090_RESERVED8 0xFFFFF0FF
256#define S_000090_RESERVED12(x) (((x) & 0xF) << 12)
257#define G_000090_RESERVED12(x) (((x) >> 12) & 0xF)
258#define C_000090_RESERVED12 0xFFFF0FFF
259#define S_000090_MCA_INIT_EXECUTED(x) (((x) & 0x1) << 16)
260#define G_000090_MCA_INIT_EXECUTED(x) (((x) >> 16) & 0x1)
261#define C_000090_MCA_INIT_EXECUTED 0xFFFEFFFF
262#define S_000090_MCA_IDLE(x) (((x) & 0x1) << 17)
263#define G_000090_MCA_IDLE(x) (((x) >> 17) & 0x1)
264#define C_000090_MCA_IDLE 0xFFFDFFFF
265#define S_000090_MCA_SEQ_IDLE(x) (((x) & 0x1) << 18)
266#define G_000090_MCA_SEQ_IDLE(x) (((x) >> 18) & 0x1)
267#define C_000090_MCA_SEQ_IDLE 0xFFFBFFFF
268#define S_000090_MCA_ARB_IDLE(x) (((x) & 0x1) << 19)
269#define G_000090_MCA_ARB_IDLE(x) (((x) >> 19) & 0x1)
270#define C_000090_MCA_ARB_IDLE 0xFFF7FFFF
271#define S_000090_RESERVED20(x) (((x) & 0xFFF) << 20)
272#define G_000090_RESERVED20(x) (((x) >> 20) & 0xFFF)
273#define C_000090_RESERVED20 0x000FFFFF
274#define R_000100_MCCFG_FB_LOCATION 0x000100
275#define S_000100_MC_FB_START(x) (((x) & 0xFFFF) << 0)
276#define G_000100_MC_FB_START(x) (((x) >> 0) & 0xFFFF)
277#define C_000100_MC_FB_START 0xFFFF0000
278#define S_000100_MC_FB_TOP(x) (((x) & 0xFFFF) << 16)
279#define G_000100_MC_FB_TOP(x) (((x) >> 16) & 0xFFFF)
280#define C_000100_MC_FB_TOP 0x0000FFFF
281#define R_000104_MC_INIT_MISC_LAT_TIMER 0x000104
282#define S_000104_MC_CPR_INIT_LAT(x) (((x) & 0xF) << 0)
283#define G_000104_MC_CPR_INIT_LAT(x) (((x) >> 0) & 0xF)
284#define C_000104_MC_CPR_INIT_LAT 0xFFFFFFF0
285#define S_000104_MC_VF_INIT_LAT(x) (((x) & 0xF) << 4)
286#define G_000104_MC_VF_INIT_LAT(x) (((x) >> 4) & 0xF)
287#define C_000104_MC_VF_INIT_LAT 0xFFFFFF0F
288#define S_000104_MC_DISP0R_INIT_LAT(x) (((x) & 0xF) << 8)
289#define G_000104_MC_DISP0R_INIT_LAT(x) (((x) >> 8) & 0xF)
290#define C_000104_MC_DISP0R_INIT_LAT 0xFFFFF0FF
291#define S_000104_MC_DISP1R_INIT_LAT(x) (((x) & 0xF) << 12)
292#define G_000104_MC_DISP1R_INIT_LAT(x) (((x) >> 12) & 0xF)
293#define C_000104_MC_DISP1R_INIT_LAT 0xFFFF0FFF
294#define S_000104_MC_FIXED_INIT_LAT(x) (((x) & 0xF) << 16)
295#define G_000104_MC_FIXED_INIT_LAT(x) (((x) >> 16) & 0xF)
296#define C_000104_MC_FIXED_INIT_LAT 0xFFF0FFFF
297#define S_000104_MC_E2R_INIT_LAT(x) (((x) & 0xF) << 20)
298#define G_000104_MC_E2R_INIT_LAT(x) (((x) >> 20) & 0xF)
299#define C_000104_MC_E2R_INIT_LAT 0xFF0FFFFF
300#define S_000104_SAME_PAGE_PRIO(x) (((x) & 0xF) << 24)
301#define G_000104_SAME_PAGE_PRIO(x) (((x) >> 24) & 0xF)
302#define C_000104_SAME_PAGE_PRIO 0xF0FFFFFF
303#define S_000104_MC_GLOBW_INIT_LAT(x) (((x) & 0xF) << 28)
304#define G_000104_MC_GLOBW_INIT_LAT(x) (((x) >> 28) & 0xF)
305#define C_000104_MC_GLOBW_INIT_LAT 0x0FFFFFFF
306
307#endif
diff --git a/drivers/gpu/drm/radeon/rs690r.h b/drivers/gpu/drm/radeon/rs690r.h
deleted file mode 100644
index c0d9faa2175b..000000000000
--- a/drivers/gpu/drm/radeon/rs690r.h
+++ /dev/null
@@ -1,99 +0,0 @@
1/*
2 * Copyright 2008 Advanced Micro Devices, Inc.
3 * Copyright 2008 Red Hat Inc.
4 * Copyright 2009 Jerome Glisse.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors: Dave Airlie
25 * Alex Deucher
26 * Jerome Glisse
27 */
28#ifndef RS690R_H
29#define RS690R_H
30
31/* RS690/RS740 registers */
32#define MC_INDEX 0x0078
33# define MC_INDEX_MASK 0x1FF
34# define MC_INDEX_WR_EN (1 << 9)
35# define MC_INDEX_WR_ACK 0x7F
36#define MC_DATA 0x007C
37#define HDP_FB_LOCATION 0x0134
38#define DC_LB_MEMORY_SPLIT 0x6520
39#define DC_LB_MEMORY_SPLIT_MASK 0x00000003
40#define DC_LB_MEMORY_SPLIT_SHIFT 0
41#define DC_LB_MEMORY_SPLIT_D1HALF_D2HALF 0
42#define DC_LB_MEMORY_SPLIT_D1_3Q_D2_1Q 1
43#define DC_LB_MEMORY_SPLIT_D1_ONLY 2
44#define DC_LB_MEMORY_SPLIT_D1_1Q_D2_3Q 3
45#define DC_LB_MEMORY_SPLIT_SHIFT_MODE (1 << 2)
46#define DC_LB_DISP1_END_ADR_SHIFT 4
47#define DC_LB_DISP1_END_ADR_MASK 0x00007FF0
48#define D1MODE_PRIORITY_A_CNT 0x6548
49#define MODE_PRIORITY_MARK_MASK 0x00007FFF
50#define MODE_PRIORITY_OFF (1 << 16)
51#define MODE_PRIORITY_ALWAYS_ON (1 << 20)
52#define MODE_PRIORITY_FORCE_MASK (1 << 24)
53#define D1MODE_PRIORITY_B_CNT 0x654C
54#define LB_MAX_REQ_OUTSTANDING 0x6D58
55#define LB_D1_MAX_REQ_OUTSTANDING_MASK 0x0000000F
56#define LB_D1_MAX_REQ_OUTSTANDING_SHIFT 0
57#define LB_D2_MAX_REQ_OUTSTANDING_MASK 0x000F0000
58#define LB_D2_MAX_REQ_OUTSTANDING_SHIFT 16
59#define DCP_CONTROL 0x6C9C
60#define D2MODE_PRIORITY_A_CNT 0x6D48
61#define D2MODE_PRIORITY_B_CNT 0x6D4C
62
63/* MC indirect registers */
64#define MC_STATUS_IDLE (1 << 0)
65#define MC_MISC_CNTL 0x18
66#define DISABLE_GTW (1 << 1)
67#define GART_INDEX_REG_EN (1 << 12)
68#define BLOCK_GFX_D3_EN (1 << 14)
69#define GART_FEATURE_ID 0x2B
70#define HANG_EN (1 << 11)
71#define TLB_ENABLE (1 << 18)
72#define P2P_ENABLE (1 << 19)
73#define GTW_LAC_EN (1 << 25)
74#define LEVEL2_GART (0 << 30)
75#define LEVEL1_GART (1 << 30)
76#define PDC_EN (1 << 31)
77#define GART_BASE 0x2C
78#define GART_CACHE_CNTRL 0x2E
79# define GART_CACHE_INVALIDATE (1 << 0)
80#define MC_STATUS 0x90
81#define MCCFG_FB_LOCATION 0x100
82#define MC_FB_START_MASK 0x0000FFFF
83#define MC_FB_START_SHIFT 0
84#define MC_FB_TOP_MASK 0xFFFF0000
85#define MC_FB_TOP_SHIFT 16
86#define MCCFG_AGP_LOCATION 0x101
87#define MC_AGP_START_MASK 0x0000FFFF
88#define MC_AGP_START_SHIFT 0
89#define MC_AGP_TOP_MASK 0xFFFF0000
90#define MC_AGP_TOP_SHIFT 16
91#define MCCFG_AGP_BASE 0x102
92#define MCCFG_AGP_BASE_2 0x103
93#define MC_INIT_MISC_LAT_TIMER 0x104
94#define MC_DISP0R_INIT_LAT_SHIFT 8
95#define MC_DISP0R_INIT_LAT_MASK 0x00000F00
96#define MC_DISP1R_INIT_LAT_SHIFT 12
97#define MC_DISP1R_INIT_LAT_MASK 0x0000F000
98
99#endif
diff --git a/drivers/gpu/drm/radeon/rv200d.h b/drivers/gpu/drm/radeon/rv200d.h
new file mode 100644
index 000000000000..c5b398330c26
--- /dev/null
+++ b/drivers/gpu/drm/radeon/rv200d.h
@@ -0,0 +1,36 @@
1/*
2 * Copyright 2008 Advanced Micro Devices, Inc.
3 * Copyright 2008 Red Hat Inc.
4 * Copyright 2009 Jerome Glisse.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors: Dave Airlie
25 * Alex Deucher
26 * Jerome Glisse
27 */
28#ifndef __RV200D_H__
29#define __RV200D_H__
30
31#define R_00015C_AGP_BASE_2 0x00015C
32#define S_00015C_AGP_BASE_ADDR_2(x) (((x) & 0xF) << 0)
33#define G_00015C_AGP_BASE_ADDR_2(x) (((x) >> 0) & 0xF)
34#define C_00015C_AGP_BASE_ADDR_2 0xFFFFFFF0
35
36#endif
diff --git a/drivers/gpu/drm/radeon/rv250d.h b/drivers/gpu/drm/radeon/rv250d.h
new file mode 100644
index 000000000000..e5a70b06fe1f
--- /dev/null
+++ b/drivers/gpu/drm/radeon/rv250d.h
@@ -0,0 +1,123 @@
1/*
2 * Copyright 2008 Advanced Micro Devices, Inc.
3 * Copyright 2008 Red Hat Inc.
4 * Copyright 2009 Jerome Glisse.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors: Dave Airlie
25 * Alex Deucher
26 * Jerome Glisse
27 */
28#ifndef __RV250D_H__
29#define __RV250D_H__
30
31#define R_00000D_SCLK_CNTL_M6 0x00000D
32#define S_00000D_SCLK_SRC_SEL(x) (((x) & 0x7) << 0)
33#define G_00000D_SCLK_SRC_SEL(x) (((x) >> 0) & 0x7)
34#define C_00000D_SCLK_SRC_SEL 0xFFFFFFF8
35#define S_00000D_CP_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 3)
36#define G_00000D_CP_MAX_DYN_STOP_LAT(x) (((x) >> 3) & 0x1)
37#define C_00000D_CP_MAX_DYN_STOP_LAT 0xFFFFFFF7
38#define S_00000D_HDP_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 4)
39#define G_00000D_HDP_MAX_DYN_STOP_LAT(x) (((x) >> 4) & 0x1)
40#define C_00000D_HDP_MAX_DYN_STOP_LAT 0xFFFFFFEF
41#define S_00000D_TV_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 5)
42#define G_00000D_TV_MAX_DYN_STOP_LAT(x) (((x) >> 5) & 0x1)
43#define C_00000D_TV_MAX_DYN_STOP_LAT 0xFFFFFFDF
44#define S_00000D_E2_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 6)
45#define G_00000D_E2_MAX_DYN_STOP_LAT(x) (((x) >> 6) & 0x1)
46#define C_00000D_E2_MAX_DYN_STOP_LAT 0xFFFFFFBF
47#define S_00000D_SE_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 7)
48#define G_00000D_SE_MAX_DYN_STOP_LAT(x) (((x) >> 7) & 0x1)
49#define C_00000D_SE_MAX_DYN_STOP_LAT 0xFFFFFF7F
50#define S_00000D_IDCT_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 8)
51#define G_00000D_IDCT_MAX_DYN_STOP_LAT(x) (((x) >> 8) & 0x1)
52#define C_00000D_IDCT_MAX_DYN_STOP_LAT 0xFFFFFEFF
53#define S_00000D_VIP_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 9)
54#define G_00000D_VIP_MAX_DYN_STOP_LAT(x) (((x) >> 9) & 0x1)
55#define C_00000D_VIP_MAX_DYN_STOP_LAT 0xFFFFFDFF
56#define S_00000D_RE_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 10)
57#define G_00000D_RE_MAX_DYN_STOP_LAT(x) (((x) >> 10) & 0x1)
58#define C_00000D_RE_MAX_DYN_STOP_LAT 0xFFFFFBFF
59#define S_00000D_PB_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 11)
60#define G_00000D_PB_MAX_DYN_STOP_LAT(x) (((x) >> 11) & 0x1)
61#define C_00000D_PB_MAX_DYN_STOP_LAT 0xFFFFF7FF
62#define S_00000D_TAM_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 12)
63#define G_00000D_TAM_MAX_DYN_STOP_LAT(x) (((x) >> 12) & 0x1)
64#define C_00000D_TAM_MAX_DYN_STOP_LAT 0xFFFFEFFF
65#define S_00000D_TDM_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 13)
66#define G_00000D_TDM_MAX_DYN_STOP_LAT(x) (((x) >> 13) & 0x1)
67#define C_00000D_TDM_MAX_DYN_STOP_LAT 0xFFFFDFFF
68#define S_00000D_RB_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 14)
69#define G_00000D_RB_MAX_DYN_STOP_LAT(x) (((x) >> 14) & 0x1)
70#define C_00000D_RB_MAX_DYN_STOP_LAT 0xFFFFBFFF
71#define S_00000D_FORCE_DISP2(x) (((x) & 0x1) << 15)
72#define G_00000D_FORCE_DISP2(x) (((x) >> 15) & 0x1)
73#define C_00000D_FORCE_DISP2 0xFFFF7FFF
74#define S_00000D_FORCE_CP(x) (((x) & 0x1) << 16)
75#define G_00000D_FORCE_CP(x) (((x) >> 16) & 0x1)
76#define C_00000D_FORCE_CP 0xFFFEFFFF
77#define S_00000D_FORCE_HDP(x) (((x) & 0x1) << 17)
78#define G_00000D_FORCE_HDP(x) (((x) >> 17) & 0x1)
79#define C_00000D_FORCE_HDP 0xFFFDFFFF
80#define S_00000D_FORCE_DISP1(x) (((x) & 0x1) << 18)
81#define G_00000D_FORCE_DISP1(x) (((x) >> 18) & 0x1)
82#define C_00000D_FORCE_DISP1 0xFFFBFFFF
83#define S_00000D_FORCE_TOP(x) (((x) & 0x1) << 19)
84#define G_00000D_FORCE_TOP(x) (((x) >> 19) & 0x1)
85#define C_00000D_FORCE_TOP 0xFFF7FFFF
86#define S_00000D_FORCE_E2(x) (((x) & 0x1) << 20)
87#define G_00000D_FORCE_E2(x) (((x) >> 20) & 0x1)
88#define C_00000D_FORCE_E2 0xFFEFFFFF
89#define S_00000D_FORCE_SE(x) (((x) & 0x1) << 21)
90#define G_00000D_FORCE_SE(x) (((x) >> 21) & 0x1)
91#define C_00000D_FORCE_SE 0xFFDFFFFF
92#define S_00000D_FORCE_IDCT(x) (((x) & 0x1) << 22)
93#define G_00000D_FORCE_IDCT(x) (((x) >> 22) & 0x1)
94#define C_00000D_FORCE_IDCT 0xFFBFFFFF
95#define S_00000D_FORCE_VIP(x) (((x) & 0x1) << 23)
96#define G_00000D_FORCE_VIP(x) (((x) >> 23) & 0x1)
97#define C_00000D_FORCE_VIP 0xFF7FFFFF
98#define S_00000D_FORCE_RE(x) (((x) & 0x1) << 24)
99#define G_00000D_FORCE_RE(x) (((x) >> 24) & 0x1)
100#define C_00000D_FORCE_RE 0xFEFFFFFF
101#define S_00000D_FORCE_PB(x) (((x) & 0x1) << 25)
102#define G_00000D_FORCE_PB(x) (((x) >> 25) & 0x1)
103#define C_00000D_FORCE_PB 0xFDFFFFFF
104#define S_00000D_FORCE_TAM(x) (((x) & 0x1) << 26)
105#define G_00000D_FORCE_TAM(x) (((x) >> 26) & 0x1)
106#define C_00000D_FORCE_TAM 0xFBFFFFFF
107#define S_00000D_FORCE_TDM(x) (((x) & 0x1) << 27)
108#define G_00000D_FORCE_TDM(x) (((x) >> 27) & 0x1)
109#define C_00000D_FORCE_TDM 0xF7FFFFFF
110#define S_00000D_FORCE_RB(x) (((x) & 0x1) << 28)
111#define G_00000D_FORCE_RB(x) (((x) >> 28) & 0x1)
112#define C_00000D_FORCE_RB 0xEFFFFFFF
113#define S_00000D_FORCE_TV_SCLK(x) (((x) & 0x1) << 29)
114#define G_00000D_FORCE_TV_SCLK(x) (((x) >> 29) & 0x1)
115#define C_00000D_FORCE_TV_SCLK 0xDFFFFFFF
116#define S_00000D_FORCE_SUBPIC(x) (((x) & 0x1) << 30)
117#define G_00000D_FORCE_SUBPIC(x) (((x) >> 30) & 0x1)
118#define C_00000D_FORCE_SUBPIC 0xBFFFFFFF
119#define S_00000D_FORCE_OV0(x) (((x) & 0x1) << 31)
120#define G_00000D_FORCE_OV0(x) (((x) >> 31) & 0x1)
121#define C_00000D_FORCE_OV0 0x7FFFFFFF
122
123#endif
diff --git a/drivers/gpu/drm/radeon/rv350d.h b/drivers/gpu/drm/radeon/rv350d.h
new file mode 100644
index 000000000000..c75c5ed9e654
--- /dev/null
+++ b/drivers/gpu/drm/radeon/rv350d.h
@@ -0,0 +1,52 @@
1/*
2 * Copyright 2008 Advanced Micro Devices, Inc.
3 * Copyright 2008 Red Hat Inc.
4 * Copyright 2009 Jerome Glisse.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors: Dave Airlie
25 * Alex Deucher
26 * Jerome Glisse
27 */
28#ifndef __RV350D_H__
29#define __RV350D_H__
30
31/* RV350, RV380 registers */
32/* #define R_00000D_SCLK_CNTL 0x00000D */
33#define S_00000D_FORCE_VAP(x) (((x) & 0x1) << 21)
34#define G_00000D_FORCE_VAP(x) (((x) >> 21) & 0x1)
35#define C_00000D_FORCE_VAP 0xFFDFFFFF
36#define S_00000D_FORCE_SR(x) (((x) & 0x1) << 25)
37#define G_00000D_FORCE_SR(x) (((x) >> 25) & 0x1)
38#define C_00000D_FORCE_SR 0xFDFFFFFF
39#define S_00000D_FORCE_PX(x) (((x) & 0x1) << 26)
40#define G_00000D_FORCE_PX(x) (((x) >> 26) & 0x1)
41#define C_00000D_FORCE_PX 0xFBFFFFFF
42#define S_00000D_FORCE_TX(x) (((x) & 0x1) << 27)
43#define G_00000D_FORCE_TX(x) (((x) >> 27) & 0x1)
44#define C_00000D_FORCE_TX 0xF7FFFFFF
45#define S_00000D_FORCE_US(x) (((x) & 0x1) << 28)
46#define G_00000D_FORCE_US(x) (((x) >> 28) & 0x1)
47#define C_00000D_FORCE_US 0xEFFFFFFF
48#define S_00000D_FORCE_SU(x) (((x) & 0x1) << 30)
49#define G_00000D_FORCE_SU(x) (((x) >> 30) & 0x1)
50#define C_00000D_FORCE_SU 0xBFFFFFFF
51
52#endif
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c
index e53b5ca7a253..41a34c23e6d8 100644
--- a/drivers/gpu/drm/radeon/rv515.c
+++ b/drivers/gpu/drm/radeon/rv515.c
@@ -478,7 +478,7 @@ static int rv515_startup(struct radeon_device *rdev)
478 } 478 }
479 /* Enable IRQ */ 479 /* Enable IRQ */
480 rdev->irq.sw_int = true; 480 rdev->irq.sw_int = true;
481 r100_irq_set(rdev); 481 rs600_irq_set(rdev);
482 /* 1M ring buffer */ 482 /* 1M ring buffer */
483 r = r100_cp_init(rdev, 1024 * 1024); 483 r = r100_cp_init(rdev, 1024 * 1024);
484 if (r) { 484 if (r) {
@@ -520,7 +520,7 @@ int rv515_suspend(struct radeon_device *rdev)
520{ 520{
521 r100_cp_disable(rdev); 521 r100_cp_disable(rdev);
522 r100_wb_disable(rdev); 522 r100_wb_disable(rdev);
523 r100_irq_disable(rdev); 523 rs600_irq_disable(rdev);
524 if (rdev->flags & RADEON_IS_PCIE) 524 if (rdev->flags & RADEON_IS_PCIE)
525 rv370_pcie_gart_disable(rdev); 525 rv370_pcie_gart_disable(rdev);
526 return 0; 526 return 0;
@@ -553,7 +553,6 @@ int rv515_init(struct radeon_device *rdev)
553{ 553{
554 int r; 554 int r;
555 555
556 rdev->new_init_path = true;
557 /* Initialize scratch registers */ 556 /* Initialize scratch registers */
558 radeon_scratch_init(rdev); 557 radeon_scratch_init(rdev);
559 /* Initialize surface registers */ 558 /* Initialize surface registers */
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
index e0b97d161397..595ac638039d 100644
--- a/drivers/gpu/drm/radeon/rv770.c
+++ b/drivers/gpu/drm/radeon/rv770.c
@@ -75,7 +75,7 @@ int rv770_pcie_gart_enable(struct radeon_device *rdev)
75 WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); 75 WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp);
76 WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp); 76 WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp);
77 WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12); 77 WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
78 WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, (rdev->mc.gtt_end - 1) >> 12); 78 WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12);
79 WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12); 79 WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
80 WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) | 80 WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) |
81 RANGE_PROTECTION_FAULT_ENABLE_DEFAULT); 81 RANGE_PROTECTION_FAULT_ENABLE_DEFAULT);
@@ -126,17 +126,36 @@ void rv770_pcie_gart_fini(struct radeon_device *rdev)
126} 126}
127 127
128 128
129/* 129void rv770_agp_enable(struct radeon_device *rdev)
130 * MC
131 */
132static void rv770_mc_resume(struct radeon_device *rdev)
133{ 130{
134 u32 d1vga_control, d2vga_control; 131 u32 tmp;
135 u32 vga_render_control, vga_hdp_control; 132 int i;
136 u32 d1crtc_control, d2crtc_control; 133
137 u32 new_d1grph_primary, new_d1grph_secondary; 134 /* Setup L2 cache */
138 u32 new_d2grph_primary, new_d2grph_secondary; 135 WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING |
139 u64 old_vram_start; 136 ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
137 EFFECTIVE_L2_QUEUE_SIZE(7));
138 WREG32(VM_L2_CNTL2, 0);
139 WREG32(VM_L2_CNTL3, BANK_SELECT(0) | CACHE_UPDATE_MODE(2));
140 /* Setup TLB control */
141 tmp = ENABLE_L1_TLB | ENABLE_L1_FRAGMENT_PROCESSING |
142 SYSTEM_ACCESS_MODE_NOT_IN_SYS |
143 SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU |
144 EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5);
145 WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp);
146 WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp);
147 WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp);
148 WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp);
149 WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp);
150 WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp);
151 WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp);
152 for (i = 0; i < 7; i++)
153 WREG32(VM_CONTEXT0_CNTL + (i * 4), 0);
154}
155
156static void rv770_mc_program(struct radeon_device *rdev)
157{
158 struct rv515_mc_save save;
140 u32 tmp; 159 u32 tmp;
141 int i, j; 160 int i, j;
142 161
@@ -150,53 +169,42 @@ static void rv770_mc_resume(struct radeon_device *rdev)
150 } 169 }
151 WREG32(HDP_REG_COHERENCY_FLUSH_CNTL, 0); 170 WREG32(HDP_REG_COHERENCY_FLUSH_CNTL, 0);
152 171
153 d1vga_control = RREG32(D1VGA_CONTROL); 172 rv515_mc_stop(rdev, &save);
154 d2vga_control = RREG32(D2VGA_CONTROL);
155 vga_render_control = RREG32(VGA_RENDER_CONTROL);
156 vga_hdp_control = RREG32(VGA_HDP_CONTROL);
157 d1crtc_control = RREG32(D1CRTC_CONTROL);
158 d2crtc_control = RREG32(D2CRTC_CONTROL);
159 old_vram_start = (u64)(RREG32(MC_VM_FB_LOCATION) & 0xFFFF) << 24;
160 new_d1grph_primary = RREG32(D1GRPH_PRIMARY_SURFACE_ADDRESS);
161 new_d1grph_secondary = RREG32(D1GRPH_SECONDARY_SURFACE_ADDRESS);
162 new_d1grph_primary += rdev->mc.vram_start - old_vram_start;
163 new_d1grph_secondary += rdev->mc.vram_start - old_vram_start;
164 new_d2grph_primary = RREG32(D2GRPH_PRIMARY_SURFACE_ADDRESS);
165 new_d2grph_secondary = RREG32(D2GRPH_SECONDARY_SURFACE_ADDRESS);
166 new_d2grph_primary += rdev->mc.vram_start - old_vram_start;
167 new_d2grph_secondary += rdev->mc.vram_start - old_vram_start;
168
169 /* Stop all video */
170 WREG32(D1VGA_CONTROL, 0);
171 WREG32(D2VGA_CONTROL, 0);
172 WREG32(VGA_RENDER_CONTROL, 0);
173 WREG32(D1CRTC_UPDATE_LOCK, 1);
174 WREG32(D2CRTC_UPDATE_LOCK, 1);
175 WREG32(D1CRTC_CONTROL, 0);
176 WREG32(D2CRTC_CONTROL, 0);
177 WREG32(D1CRTC_UPDATE_LOCK, 0);
178 WREG32(D2CRTC_UPDATE_LOCK, 0);
179
180 mdelay(1);
181 if (r600_mc_wait_for_idle(rdev)) { 173 if (r600_mc_wait_for_idle(rdev)) {
182 printk(KERN_WARNING "[drm] MC not idle !\n"); 174 dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
183 } 175 }
184
185 /* Lockout access through VGA aperture*/ 176 /* Lockout access through VGA aperture*/
186 WREG32(VGA_HDP_CONTROL, VGA_MEMORY_DISABLE); 177 WREG32(VGA_HDP_CONTROL, VGA_MEMORY_DISABLE);
187
188 /* Update configuration */ 178 /* Update configuration */
189 WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.vram_start >> 12); 179 if (rdev->flags & RADEON_IS_AGP) {
190 WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, (rdev->mc.vram_end - 1) >> 12); 180 if (rdev->mc.vram_start < rdev->mc.gtt_start) {
181 /* VRAM before AGP */
182 WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR,
183 rdev->mc.vram_start >> 12);
184 WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR,
185 rdev->mc.gtt_end >> 12);
186 } else {
187 /* VRAM after AGP */
188 WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR,
189 rdev->mc.gtt_start >> 12);
190 WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR,
191 rdev->mc.vram_end >> 12);
192 }
193 } else {
194 WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR,
195 rdev->mc.vram_start >> 12);
196 WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR,
197 rdev->mc.vram_end >> 12);
198 }
191 WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0); 199 WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0);
192 tmp = (((rdev->mc.vram_end - 1) >> 24) & 0xFFFF) << 16; 200 tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16;
193 tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF); 201 tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF);
194 WREG32(MC_VM_FB_LOCATION, tmp); 202 WREG32(MC_VM_FB_LOCATION, tmp);
195 WREG32(HDP_NONSURFACE_BASE, (rdev->mc.vram_start >> 8)); 203 WREG32(HDP_NONSURFACE_BASE, (rdev->mc.vram_start >> 8));
196 WREG32(HDP_NONSURFACE_INFO, (2 << 7)); 204 WREG32(HDP_NONSURFACE_INFO, (2 << 7));
197 WREG32(HDP_NONSURFACE_SIZE, (rdev->mc.mc_vram_size - 1) | 0x3FF); 205 WREG32(HDP_NONSURFACE_SIZE, (rdev->mc.mc_vram_size - 1) | 0x3FF);
198 if (rdev->flags & RADEON_IS_AGP) { 206 if (rdev->flags & RADEON_IS_AGP) {
199 WREG32(MC_VM_AGP_TOP, (rdev->mc.gtt_end - 1) >> 16); 207 WREG32(MC_VM_AGP_TOP, rdev->mc.gtt_end >> 16);
200 WREG32(MC_VM_AGP_BOT, rdev->mc.gtt_start >> 16); 208 WREG32(MC_VM_AGP_BOT, rdev->mc.gtt_start >> 16);
201 WREG32(MC_VM_AGP_BASE, rdev->mc.agp_base >> 22); 209 WREG32(MC_VM_AGP_BASE, rdev->mc.agp_base >> 22);
202 } else { 210 } else {
@@ -204,31 +212,10 @@ static void rv770_mc_resume(struct radeon_device *rdev)
204 WREG32(MC_VM_AGP_TOP, 0x0FFFFFFF); 212 WREG32(MC_VM_AGP_TOP, 0x0FFFFFFF);
205 WREG32(MC_VM_AGP_BOT, 0x0FFFFFFF); 213 WREG32(MC_VM_AGP_BOT, 0x0FFFFFFF);
206 } 214 }
207 WREG32(D1GRPH_PRIMARY_SURFACE_ADDRESS, new_d1grph_primary);
208 WREG32(D1GRPH_SECONDARY_SURFACE_ADDRESS, new_d1grph_secondary);
209 WREG32(D2GRPH_PRIMARY_SURFACE_ADDRESS, new_d2grph_primary);
210 WREG32(D2GRPH_SECONDARY_SURFACE_ADDRESS, new_d2grph_secondary);
211 WREG32(VGA_MEMORY_BASE_ADDRESS, rdev->mc.vram_start);
212
213 /* Unlock host access */
214 WREG32(VGA_HDP_CONTROL, vga_hdp_control);
215
216 mdelay(1);
217 if (r600_mc_wait_for_idle(rdev)) { 215 if (r600_mc_wait_for_idle(rdev)) {
218 printk(KERN_WARNING "[drm] MC not idle !\n"); 216 dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
219 } 217 }
220 218 rv515_mc_resume(rdev, &save);
221 /* Restore video state */
222 WREG32(D1CRTC_UPDATE_LOCK, 1);
223 WREG32(D2CRTC_UPDATE_LOCK, 1);
224 WREG32(D1CRTC_CONTROL, d1crtc_control);
225 WREG32(D2CRTC_CONTROL, d2crtc_control);
226 WREG32(D1CRTC_UPDATE_LOCK, 0);
227 WREG32(D2CRTC_UPDATE_LOCK, 0);
228 WREG32(D1VGA_CONTROL, d1vga_control);
229 WREG32(D2VGA_CONTROL, d2vga_control);
230 WREG32(VGA_RENDER_CONTROL, vga_render_control);
231
232 /* we need to own VRAM, so turn off the VGA renderer here 219 /* we need to own VRAM, so turn off the VGA renderer here
233 * to stop it overwriting our objects */ 220 * to stop it overwriting our objects */
234 rv515_vga_render_disable(rdev); 221 rv515_vga_render_disable(rdev);
@@ -840,9 +827,9 @@ int rv770_mc_init(struct radeon_device *rdev)
840 rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; 827 rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
841 } 828 }
842 rdev->mc.vram_start = rdev->mc.vram_location; 829 rdev->mc.vram_start = rdev->mc.vram_location;
843 rdev->mc.vram_end = rdev->mc.vram_location + rdev->mc.mc_vram_size; 830 rdev->mc.vram_end = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1;
844 rdev->mc.gtt_start = rdev->mc.gtt_location; 831 rdev->mc.gtt_start = rdev->mc.gtt_location;
845 rdev->mc.gtt_end = rdev->mc.gtt_location + rdev->mc.gtt_size; 832 rdev->mc.gtt_end = rdev->mc.gtt_location + rdev->mc.gtt_size - 1;
846 /* FIXME: we should enforce default clock in case GPU is not in 833 /* FIXME: we should enforce default clock in case GPU is not in
847 * default setup 834 * default setup
848 */ 835 */
@@ -861,11 +848,14 @@ static int rv770_startup(struct radeon_device *rdev)
861{ 848{
862 int r; 849 int r;
863 850
864 radeon_gpu_reset(rdev); 851 rv770_mc_program(rdev);
865 rv770_mc_resume(rdev); 852 if (rdev->flags & RADEON_IS_AGP) {
866 r = rv770_pcie_gart_enable(rdev); 853 rv770_agp_enable(rdev);
867 if (r) 854 } else {
868 return r; 855 r = rv770_pcie_gart_enable(rdev);
856 if (r)
857 return r;
858 }
869 rv770_gpu_init(rdev); 859 rv770_gpu_init(rdev);
870 860
871 r = radeon_object_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM, 861 r = radeon_object_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM,
@@ -884,9 +874,8 @@ static int rv770_startup(struct radeon_device *rdev)
884 r = r600_cp_resume(rdev); 874 r = r600_cp_resume(rdev);
885 if (r) 875 if (r)
886 return r; 876 return r;
887 r = r600_wb_init(rdev); 877 /* write back buffer are not vital so don't worry about failure */
888 if (r) 878 r600_wb_enable(rdev);
889 return r;
890 return 0; 879 return 0;
891} 880}
892 881
@@ -894,15 +883,12 @@ int rv770_resume(struct radeon_device *rdev)
894{ 883{
895 int r; 884 int r;
896 885
897 if (radeon_gpu_reset(rdev)) { 886 /* Do not reset GPU before posting, on rv770 hw unlike on r500 hw,
898 /* FIXME: what do we want to do here ? */ 887 * posting will perform necessary task to bring back GPU into good
899 } 888 * shape.
889 */
900 /* post card */ 890 /* post card */
901 if (rdev->is_atom_bios) { 891 atom_asic_init(rdev->mode_info.atom_context);
902 atom_asic_init(rdev->mode_info.atom_context);
903 } else {
904 radeon_combios_asic_init(rdev->ddev);
905 }
906 /* Initialize clocks */ 892 /* Initialize clocks */
907 r = radeon_clocks_init(rdev); 893 r = radeon_clocks_init(rdev);
908 if (r) { 894 if (r) {
@@ -915,7 +901,7 @@ int rv770_resume(struct radeon_device *rdev)
915 return r; 901 return r;
916 } 902 }
917 903
918 r = radeon_ib_test(rdev); 904 r = r600_ib_test(rdev);
919 if (r) { 905 if (r) {
920 DRM_ERROR("radeon: failled testing IB (%d).\n", r); 906 DRM_ERROR("radeon: failled testing IB (%d).\n", r);
921 return r; 907 return r;
@@ -929,8 +915,8 @@ int rv770_suspend(struct radeon_device *rdev)
929 /* FIXME: we should wait for ring to be empty */ 915 /* FIXME: we should wait for ring to be empty */
930 r700_cp_stop(rdev); 916 r700_cp_stop(rdev);
931 rdev->cp.ready = false; 917 rdev->cp.ready = false;
918 r600_wb_disable(rdev);
932 rv770_pcie_gart_disable(rdev); 919 rv770_pcie_gart_disable(rdev);
933
934 /* unpin shaders bo */ 920 /* unpin shaders bo */
935 radeon_object_unpin(rdev->r600_blit.shader_obj); 921 radeon_object_unpin(rdev->r600_blit.shader_obj);
936 return 0; 922 return 0;
@@ -946,7 +932,6 @@ int rv770_init(struct radeon_device *rdev)
946{ 932{
947 int r; 933 int r;
948 934
949 rdev->new_init_path = true;
950 r = radeon_dummy_page_init(rdev); 935 r = radeon_dummy_page_init(rdev);
951 if (r) 936 if (r)
952 return r; 937 return r;
@@ -960,8 +945,10 @@ int rv770_init(struct radeon_device *rdev)
960 return -EINVAL; 945 return -EINVAL;
961 } 946 }
962 /* Must be an ATOMBIOS */ 947 /* Must be an ATOMBIOS */
963 if (!rdev->is_atom_bios) 948 if (!rdev->is_atom_bios) {
949 dev_err(rdev->dev, "Expecting atombios for R600 GPU\n");
964 return -EINVAL; 950 return -EINVAL;
951 }
965 r = radeon_atombios_init(rdev); 952 r = radeon_atombios_init(rdev);
966 if (r) 953 if (r)
967 return r; 954 return r;
@@ -983,15 +970,8 @@ int rv770_init(struct radeon_device *rdev)
983 if (r) 970 if (r)
984 return r; 971 return r;
985 r = rv770_mc_init(rdev); 972 r = rv770_mc_init(rdev);
986 if (r) { 973 if (r)
987 if (rdev->flags & RADEON_IS_AGP) {
988 /* Retry with disabling AGP */
989 rv770_fini(rdev);
990 rdev->flags &= ~RADEON_IS_AGP;
991 return rv770_init(rdev);
992 }
993 return r; 974 return r;
994 }
995 /* Memory manager */ 975 /* Memory manager */
996 r = radeon_object_init(rdev); 976 r = radeon_object_init(rdev);
997 if (r) 977 if (r)
@@ -1020,12 +1000,10 @@ int rv770_init(struct radeon_device *rdev)
1020 1000
1021 r = rv770_startup(rdev); 1001 r = rv770_startup(rdev);
1022 if (r) { 1002 if (r) {
1023 if (rdev->flags & RADEON_IS_AGP) { 1003 rv770_suspend(rdev);
1024 /* Retry with disabling AGP */ 1004 r600_wb_fini(rdev);
1025 rv770_fini(rdev); 1005 radeon_ring_fini(rdev);
1026 rdev->flags &= ~RADEON_IS_AGP; 1006 rv770_pcie_gart_fini(rdev);
1027 return rv770_init(rdev);
1028 }
1029 rdev->accel_working = false; 1007 rdev->accel_working = false;
1030 } 1008 }
1031 if (rdev->accel_working) { 1009 if (rdev->accel_working) {
@@ -1034,7 +1012,7 @@ int rv770_init(struct radeon_device *rdev)
1034 DRM_ERROR("radeon: failled initializing IB pool (%d).\n", r); 1012 DRM_ERROR("radeon: failled initializing IB pool (%d).\n", r);
1035 rdev->accel_working = false; 1013 rdev->accel_working = false;
1036 } 1014 }
1037 r = radeon_ib_test(rdev); 1015 r = r600_ib_test(rdev);
1038 if (r) { 1016 if (r) {
1039 DRM_ERROR("radeon: failled testing IB (%d).\n", r); 1017 DRM_ERROR("radeon: failled testing IB (%d).\n", r);
1040 rdev->accel_working = false; 1018 rdev->accel_working = false;
@@ -1049,20 +1027,15 @@ void rv770_fini(struct radeon_device *rdev)
1049 1027
1050 r600_blit_fini(rdev); 1028 r600_blit_fini(rdev);
1051 radeon_ring_fini(rdev); 1029 radeon_ring_fini(rdev);
1030 r600_wb_fini(rdev);
1052 rv770_pcie_gart_fini(rdev); 1031 rv770_pcie_gart_fini(rdev);
1053 radeon_gem_fini(rdev); 1032 radeon_gem_fini(rdev);
1054 radeon_fence_driver_fini(rdev); 1033 radeon_fence_driver_fini(rdev);
1055 radeon_clocks_fini(rdev); 1034 radeon_clocks_fini(rdev);
1056#if __OS_HAS_AGP
1057 if (rdev->flags & RADEON_IS_AGP) 1035 if (rdev->flags & RADEON_IS_AGP)
1058 radeon_agp_fini(rdev); 1036 radeon_agp_fini(rdev);
1059#endif
1060 radeon_object_fini(rdev); 1037 radeon_object_fini(rdev);
1061 if (rdev->is_atom_bios) { 1038 radeon_atombios_fini(rdev);
1062 radeon_atombios_fini(rdev);
1063 } else {
1064 radeon_combios_fini(rdev);
1065 }
1066 kfree(rdev->bios); 1039 kfree(rdev->bios);
1067 rdev->bios = NULL; 1040 rdev->bios = NULL;
1068 radeon_dummy_page_fini(rdev); 1041 radeon_dummy_page_fini(rdev);
diff --git a/drivers/gpu/drm/ttm/ttm_global.c b/drivers/gpu/drm/ttm/ttm_global.c
index 541744d00d3e..b17007178a36 100644
--- a/drivers/gpu/drm/ttm/ttm_global.c
+++ b/drivers/gpu/drm/ttm/ttm_global.c
@@ -82,8 +82,8 @@ int ttm_global_item_ref(struct ttm_global_reference *ref)
82 if (unlikely(ret != 0)) 82 if (unlikely(ret != 0))
83 goto out_err; 83 goto out_err;
84 84
85 ++item->refcount;
86 } 85 }
86 ++item->refcount;
87 ref->object = item->object; 87 ref->object = item->object;
88 object = item->object; 88 object = item->object;
89 mutex_unlock(&item->mutex); 89 mutex_unlock(&item->mutex);
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index be34d32906bd..7d05c4bb201e 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1066,7 +1066,7 @@ EXPORT_SYMBOL_GPL(hid_report_raw_event);
1066 * @type: HID report type (HID_*_REPORT) 1066 * @type: HID report type (HID_*_REPORT)
1067 * @data: report contents 1067 * @data: report contents
1068 * @size: size of data parameter 1068 * @size: size of data parameter
1069 * @interrupt: called from atomic? 1069 * @interrupt: distinguish between interrupt and control transfers
1070 * 1070 *
1071 * This is data entry for lower layers. 1071 * This is data entry for lower layers.
1072 */ 1072 */
diff --git a/drivers/hid/hid-twinhan.c b/drivers/hid/hid-twinhan.c
index b05f602c051e..c40afc57fc8f 100644
--- a/drivers/hid/hid-twinhan.c
+++ b/drivers/hid/hid-twinhan.c
@@ -132,12 +132,12 @@ static struct hid_driver twinhan_driver = {
132 .input_mapping = twinhan_input_mapping, 132 .input_mapping = twinhan_input_mapping,
133}; 133};
134 134
135static int twinhan_init(void) 135static int __init twinhan_init(void)
136{ 136{
137 return hid_register_driver(&twinhan_driver); 137 return hid_register_driver(&twinhan_driver);
138} 138}
139 139
140static void twinhan_exit(void) 140static void __exit twinhan_exit(void)
141{ 141{
142 hid_unregister_driver(&twinhan_driver); 142 hid_unregister_driver(&twinhan_driver);
143} 143}
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c
index 0c6639ea03dd..cdd136942bca 100644
--- a/drivers/hid/hidraw.c
+++ b/drivers/hid/hidraw.c
@@ -30,6 +30,7 @@
30#include <linux/major.h> 30#include <linux/major.h>
31#include <linux/hid.h> 31#include <linux/hid.h>
32#include <linux/mutex.h> 32#include <linux/mutex.h>
33#include <linux/sched.h>
33#include <linux/smp_lock.h> 34#include <linux/smp_lock.h>
34 35
35#include <linux/hidraw.h> 36#include <linux/hidraw.h>
@@ -47,10 +48,9 @@ static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count,
47 char *report; 48 char *report;
48 DECLARE_WAITQUEUE(wait, current); 49 DECLARE_WAITQUEUE(wait, current);
49 50
50 while (ret == 0) { 51 mutex_lock(&list->read_mutex);
51
52 mutex_lock(&list->read_mutex);
53 52
53 while (ret == 0) {
54 if (list->head == list->tail) { 54 if (list->head == list->tail) {
55 add_wait_queue(&list->hidraw->wait, &wait); 55 add_wait_queue(&list->hidraw->wait, &wait);
56 set_current_state(TASK_INTERRUPTIBLE); 56 set_current_state(TASK_INTERRUPTIBLE);
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 6857560144bd..700e93adeb33 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -675,7 +675,7 @@ config SENSORS_SHT15
675 675
676config SENSORS_S3C 676config SENSORS_S3C
677 tristate "S3C24XX/S3C64XX Inbuilt ADC" 677 tristate "S3C24XX/S3C64XX Inbuilt ADC"
678 depends on ARCH_S3C2410 || ARCH_S3C64XX 678 depends on ARCH_S3C2410
679 help 679 help
680 If you say yes here you get support for the on-board ADCs of 680 If you say yes here you get support for the on-board ADCs of
681 the Samsung S3C24XX or S3C64XX series of SoC 681 the Samsung S3C24XX or S3C64XX series of SoC
diff --git a/drivers/hwmon/asus_atk0110.c b/drivers/hwmon/asus_atk0110.c
index fe4fa29c9219..5a3ee00c0e7d 100644
--- a/drivers/hwmon/asus_atk0110.c
+++ b/drivers/hwmon/asus_atk0110.c
@@ -35,18 +35,22 @@
35#define METHOD_OLD_ENUM_FAN "FSIF" 35#define METHOD_OLD_ENUM_FAN "FSIF"
36 36
37#define ATK_MUX_HWMON 0x00000006ULL 37#define ATK_MUX_HWMON 0x00000006ULL
38#define ATK_MUX_MGMT 0x00000011ULL
38 39
39#define ATK_CLASS_MASK 0xff000000ULL 40#define ATK_CLASS_MASK 0xff000000ULL
40#define ATK_CLASS_FREQ_CTL 0x03000000ULL 41#define ATK_CLASS_FREQ_CTL 0x03000000ULL
41#define ATK_CLASS_FAN_CTL 0x04000000ULL 42#define ATK_CLASS_FAN_CTL 0x04000000ULL
42#define ATK_CLASS_HWMON 0x06000000ULL 43#define ATK_CLASS_HWMON 0x06000000ULL
44#define ATK_CLASS_MGMT 0x11000000ULL
43 45
44#define ATK_TYPE_MASK 0x00ff0000ULL 46#define ATK_TYPE_MASK 0x00ff0000ULL
45#define HWMON_TYPE_VOLT 0x00020000ULL 47#define HWMON_TYPE_VOLT 0x00020000ULL
46#define HWMON_TYPE_TEMP 0x00030000ULL 48#define HWMON_TYPE_TEMP 0x00030000ULL
47#define HWMON_TYPE_FAN 0x00040000ULL 49#define HWMON_TYPE_FAN 0x00040000ULL
48 50
49#define HWMON_SENSOR_ID_MASK 0x0000ffffULL 51#define ATK_ELEMENT_ID_MASK 0x0000ffffULL
52
53#define ATK_EC_ID 0x11060004ULL
50 54
51enum atk_pack_member { 55enum atk_pack_member {
52 HWMON_PACK_FLAGS, 56 HWMON_PACK_FLAGS,
@@ -89,6 +93,9 @@ struct atk_data {
89 /* new inteface */ 93 /* new inteface */
90 acpi_handle enumerate_handle; 94 acpi_handle enumerate_handle;
91 acpi_handle read_handle; 95 acpi_handle read_handle;
96 acpi_handle write_handle;
97
98 bool disable_ec;
92 99
93 int voltage_count; 100 int voltage_count;
94 int temperature_count; 101 int temperature_count;
@@ -129,9 +136,22 @@ struct atk_sensor_data {
129 char const *acpi_name; 136 char const *acpi_name;
130}; 137};
131 138
132struct atk_acpi_buffer_u64 { 139/* Return buffer format:
133 union acpi_object buf; 140 * [0-3] "value" is valid flag
134 u64 value; 141 * [4-7] value
142 * [8- ] unknown stuff on newer mobos
143 */
144struct atk_acpi_ret_buffer {
145 u32 flags;
146 u32 value;
147 u8 data[];
148};
149
150/* Input buffer used for GITM and SITM methods */
151struct atk_acpi_input_buf {
152 u32 id;
153 u32 param1;
154 u32 param2;
135}; 155};
136 156
137static int atk_add(struct acpi_device *device); 157static int atk_add(struct acpi_device *device);
@@ -439,52 +459,147 @@ static int atk_read_value_old(struct atk_sensor_data *sensor, u64 *value)
439 return 0; 459 return 0;
440} 460}
441 461
442static int atk_read_value_new(struct atk_sensor_data *sensor, u64 *value) 462static union acpi_object *atk_ggrp(struct atk_data *data, u16 mux)
443{ 463{
444 struct atk_data *data = sensor->data;
445 struct device *dev = &data->acpi_dev->dev; 464 struct device *dev = &data->acpi_dev->dev;
465 struct acpi_buffer buf;
466 acpi_status ret;
446 struct acpi_object_list params; 467 struct acpi_object_list params;
447 struct acpi_buffer ret;
448 union acpi_object id; 468 union acpi_object id;
449 struct atk_acpi_buffer_u64 tmp; 469 union acpi_object *pack;
450 acpi_status status;
451 470
452 id.type = ACPI_TYPE_INTEGER; 471 id.type = ACPI_TYPE_INTEGER;
453 id.integer.value = sensor->id; 472 id.integer.value = mux;
454
455 params.count = 1; 473 params.count = 1;
456 params.pointer = &id; 474 params.pointer = &id;
457 475
458 tmp.buf.type = ACPI_TYPE_BUFFER; 476 buf.length = ACPI_ALLOCATE_BUFFER;
459 tmp.buf.buffer.pointer = (u8 *)&tmp.value; 477 ret = acpi_evaluate_object(data->enumerate_handle, NULL, &params, &buf);
460 tmp.buf.buffer.length = sizeof(u64); 478 if (ret != AE_OK) {
461 ret.length = sizeof(tmp); 479 dev_err(dev, "GGRP[%#x] ACPI exception: %s\n", mux,
462 ret.pointer = &tmp; 480 acpi_format_exception(ret));
481 return ERR_PTR(-EIO);
482 }
483 pack = buf.pointer;
484 if (pack->type != ACPI_TYPE_PACKAGE) {
485 /* Execution was successful, but the id was not found */
486 ACPI_FREE(pack);
487 return ERR_PTR(-ENOENT);
488 }
489
490 if (pack->package.count < 1) {
491 dev_err(dev, "GGRP[%#x] package is too small\n", mux);
492 ACPI_FREE(pack);
493 return ERR_PTR(-EIO);
494 }
495 return pack;
496}
497
498static union acpi_object *atk_gitm(struct atk_data *data, u64 id)
499{
500 struct device *dev = &data->acpi_dev->dev;
501 struct atk_acpi_input_buf buf;
502 union acpi_object tmp;
503 struct acpi_object_list params;
504 struct acpi_buffer ret;
505 union acpi_object *obj;
506 acpi_status status;
507
508 buf.id = id;
509 buf.param1 = 0;
510 buf.param2 = 0;
463 511
512 tmp.type = ACPI_TYPE_BUFFER;
513 tmp.buffer.pointer = (u8 *)&buf;
514 tmp.buffer.length = sizeof(buf);
515
516 params.count = 1;
517 params.pointer = (void *)&tmp;
518
519 ret.length = ACPI_ALLOCATE_BUFFER;
464 status = acpi_evaluate_object_typed(data->read_handle, NULL, &params, 520 status = acpi_evaluate_object_typed(data->read_handle, NULL, &params,
465 &ret, ACPI_TYPE_BUFFER); 521 &ret, ACPI_TYPE_BUFFER);
466 if (status != AE_OK) { 522 if (status != AE_OK) {
467 dev_warn(dev, "%s: ACPI exception: %s\n", __func__, 523 dev_warn(dev, "GITM[%#llx] ACPI exception: %s\n", id,
468 acpi_format_exception(status)); 524 acpi_format_exception(status));
469 return -EIO; 525 return ERR_PTR(-EIO);
526 }
527 obj = ret.pointer;
528
529 /* Sanity check */
530 if (obj->buffer.length < 8) {
531 dev_warn(dev, "Unexpected ASBF length: %u\n",
532 obj->buffer.length);
533 ACPI_FREE(obj);
534 return ERR_PTR(-EIO);
470 } 535 }
536 return obj;
537}
471 538
472 /* Return buffer format: 539static union acpi_object *atk_sitm(struct atk_data *data,
473 * [0-3] "value" is valid flag 540 struct atk_acpi_input_buf *buf)
474 * [4-7] value 541{
475 */ 542 struct device *dev = &data->acpi_dev->dev;
476 if (!(tmp.value & 0xffffffff)) { 543 struct acpi_object_list params;
544 union acpi_object tmp;
545 struct acpi_buffer ret;
546 union acpi_object *obj;
547 acpi_status status;
548
549 tmp.type = ACPI_TYPE_BUFFER;
550 tmp.buffer.pointer = (u8 *)buf;
551 tmp.buffer.length = sizeof(*buf);
552
553 params.count = 1;
554 params.pointer = &tmp;
555
556 ret.length = ACPI_ALLOCATE_BUFFER;
557 status = acpi_evaluate_object_typed(data->write_handle, NULL, &params,
558 &ret, ACPI_TYPE_BUFFER);
559 if (status != AE_OK) {
560 dev_warn(dev, "SITM[%#x] ACPI exception: %s\n", buf->id,
561 acpi_format_exception(status));
562 return ERR_PTR(-EIO);
563 }
564 obj = ret.pointer;
565
566 /* Sanity check */
567 if (obj->buffer.length < 8) {
568 dev_warn(dev, "Unexpected ASBF length: %u\n",
569 obj->buffer.length);
570 ACPI_FREE(obj);
571 return ERR_PTR(-EIO);
572 }
573 return obj;
574}
575
576static int atk_read_value_new(struct atk_sensor_data *sensor, u64 *value)
577{
578 struct atk_data *data = sensor->data;
579 struct device *dev = &data->acpi_dev->dev;
580 union acpi_object *obj;
581 struct atk_acpi_ret_buffer *buf;
582 int err = 0;
583
584 obj = atk_gitm(data, sensor->id);
585 if (IS_ERR(obj))
586 return PTR_ERR(obj);
587
588 buf = (struct atk_acpi_ret_buffer *)obj->buffer.pointer;
589 if (buf->flags == 0) {
477 /* The reading is not valid, possible causes: 590 /* The reading is not valid, possible causes:
478 * - sensor failure 591 * - sensor failure
479 * - enumeration was FUBAR (and we didn't notice) 592 * - enumeration was FUBAR (and we didn't notice)
480 */ 593 */
481 dev_info(dev, "Failure: %#llx\n", tmp.value); 594 dev_warn(dev, "Read failed, sensor = %#llx\n", sensor->id);
482 return -EIO; 595 err = -EIO;
596 goto out;
483 } 597 }
484 598
485 *value = (tmp.value & 0xffffffff00000000ULL) >> 32; 599 *value = buf->value;
486 600out:
487 return 0; 601 ACPI_FREE(obj);
602 return err;
488} 603}
489 604
490static int atk_read_value(struct atk_sensor_data *sensor, u64 *value) 605static int atk_read_value(struct atk_sensor_data *sensor, u64 *value)
@@ -713,43 +828,141 @@ cleanup:
713 return ret; 828 return ret;
714} 829}
715 830
716static int atk_enumerate_new_hwmon(struct atk_data *data) 831static int atk_ec_present(struct atk_data *data)
717{ 832{
718 struct device *dev = &data->acpi_dev->dev; 833 struct device *dev = &data->acpi_dev->dev;
719 struct acpi_buffer buf;
720 acpi_status ret;
721 struct acpi_object_list params;
722 union acpi_object id;
723 union acpi_object *pack; 834 union acpi_object *pack;
724 int err; 835 union acpi_object *ec;
836 int ret;
725 int i; 837 int i;
726 838
727 dev_dbg(dev, "Enumerating hwmon sensors\n"); 839 pack = atk_ggrp(data, ATK_MUX_MGMT);
840 if (IS_ERR(pack)) {
841 if (PTR_ERR(pack) == -ENOENT) {
842 /* The MGMT class does not exists - that's ok */
843 dev_dbg(dev, "Class %#llx not found\n", ATK_MUX_MGMT);
844 return 0;
845 }
846 return PTR_ERR(pack);
847 }
728 848
729 id.type = ACPI_TYPE_INTEGER; 849 /* Search the EC */
730 id.integer.value = ATK_MUX_HWMON; 850 ec = NULL;
731 params.count = 1; 851 for (i = 0; i < pack->package.count; i++) {
732 params.pointer = &id; 852 union acpi_object *obj = &pack->package.elements[i];
853 union acpi_object *id;
733 854
734 buf.length = ACPI_ALLOCATE_BUFFER; 855 if (obj->type != ACPI_TYPE_PACKAGE)
735 ret = acpi_evaluate_object_typed(data->enumerate_handle, NULL, &params, 856 continue;
736 &buf, ACPI_TYPE_PACKAGE); 857
737 if (ret != AE_OK) { 858 id = &obj->package.elements[0];
738 dev_warn(dev, METHOD_ENUMERATE ": ACPI exception: %s\n", 859 if (id->type != ACPI_TYPE_INTEGER)
739 acpi_format_exception(ret)); 860 continue;
740 return -ENODEV; 861
862 if (id->integer.value == ATK_EC_ID) {
863 ec = obj;
864 break;
865 }
741 } 866 }
742 867
743 /* Result must be a package */ 868 ret = (ec != NULL);
744 pack = buf.pointer; 869 if (!ret)
870 /* The system has no EC */
871 dev_dbg(dev, "EC not found\n");
745 872
746 if (pack->package.count < 1) { 873 ACPI_FREE(pack);
747 dev_dbg(dev, "%s: hwmon package is too small: %d\n", __func__, 874 return ret;
748 pack->package.count); 875}
749 err = -EINVAL; 876
750 goto out; 877static int atk_ec_enabled(struct atk_data *data)
878{
879 struct device *dev = &data->acpi_dev->dev;
880 union acpi_object *obj;
881 struct atk_acpi_ret_buffer *buf;
882 int err;
883
884 obj = atk_gitm(data, ATK_EC_ID);
885 if (IS_ERR(obj)) {
886 dev_err(dev, "Unable to query EC status\n");
887 return PTR_ERR(obj);
888 }
889 buf = (struct atk_acpi_ret_buffer *)obj->buffer.pointer;
890
891 if (buf->flags == 0) {
892 dev_err(dev, "Unable to query EC status\n");
893 err = -EIO;
894 } else {
895 err = (buf->value != 0);
896 dev_dbg(dev, "EC is %sabled\n",
897 err ? "en" : "dis");
898 }
899
900 ACPI_FREE(obj);
901 return err;
902}
903
904static int atk_ec_ctl(struct atk_data *data, int enable)
905{
906 struct device *dev = &data->acpi_dev->dev;
907 union acpi_object *obj;
908 struct atk_acpi_input_buf sitm;
909 struct atk_acpi_ret_buffer *ec_ret;
910 int err = 0;
911
912 sitm.id = ATK_EC_ID;
913 sitm.param1 = enable;
914 sitm.param2 = 0;
915
916 obj = atk_sitm(data, &sitm);
917 if (IS_ERR(obj)) {
918 dev_err(dev, "Failed to %sable the EC\n",
919 enable ? "en" : "dis");
920 return PTR_ERR(obj);
921 }
922 ec_ret = (struct atk_acpi_ret_buffer *)obj->buffer.pointer;
923 if (ec_ret->flags == 0) {
924 dev_err(dev, "Failed to %sable the EC\n",
925 enable ? "en" : "dis");
926 err = -EIO;
927 } else {
928 dev_info(dev, "EC %sabled\n",
929 enable ? "en" : "dis");
930 }
931
932 ACPI_FREE(obj);
933 return err;
934}
935
936static int atk_enumerate_new_hwmon(struct atk_data *data)
937{
938 struct device *dev = &data->acpi_dev->dev;
939 union acpi_object *pack;
940 int err;
941 int i;
942
943 err = atk_ec_present(data);
944 if (err < 0)
945 return err;
946 if (err) {
947 err = atk_ec_enabled(data);
948 if (err < 0)
949 return err;
950 /* If the EC was disabled we will disable it again on unload */
951 data->disable_ec = err;
952
953 err = atk_ec_ctl(data, 1);
954 if (err) {
955 data->disable_ec = false;
956 return err;
957 }
751 } 958 }
752 959
960 dev_dbg(dev, "Enumerating hwmon sensors\n");
961
962 pack = atk_ggrp(data, ATK_MUX_HWMON);
963 if (IS_ERR(pack))
964 return PTR_ERR(pack);
965
753 for (i = 0; i < pack->package.count; i++) { 966 for (i = 0; i < pack->package.count; i++) {
754 union acpi_object *obj = &pack->package.elements[i]; 967 union acpi_object *obj = &pack->package.elements[i];
755 968
@@ -758,8 +971,7 @@ static int atk_enumerate_new_hwmon(struct atk_data *data)
758 971
759 err = data->voltage_count + data->temperature_count + data->fan_count; 972 err = data->voltage_count + data->temperature_count + data->fan_count;
760 973
761out: 974 ACPI_FREE(pack);
762 ACPI_FREE(buf.pointer);
763 return err; 975 return err;
764} 976}
765 977
@@ -895,6 +1107,15 @@ static int atk_check_new_if(struct atk_data *data)
895 } 1107 }
896 data->read_handle = ret; 1108 data->read_handle = ret;
897 1109
1110 /* De-multiplexer (write) */
1111 status = acpi_get_handle(data->atk_handle, METHOD_WRITE, &ret);
1112 if (status != AE_OK) {
1113 dev_dbg(dev, "method " METHOD_READ " not found: %s\n",
1114 acpi_format_exception(status));
1115 return -ENODEV;
1116 }
1117 data->write_handle = ret;
1118
898 return 0; 1119 return 0;
899} 1120}
900 1121
@@ -915,6 +1136,7 @@ static int atk_add(struct acpi_device *device)
915 data->acpi_dev = device; 1136 data->acpi_dev = device;
916 data->atk_handle = device->handle; 1137 data->atk_handle = device->handle;
917 INIT_LIST_HEAD(&data->sensor_list); 1138 INIT_LIST_HEAD(&data->sensor_list);
1139 data->disable_ec = false;
918 1140
919 buf.length = ACPI_ALLOCATE_BUFFER; 1141 buf.length = ACPI_ALLOCATE_BUFFER;
920 ret = acpi_evaluate_object_typed(data->atk_handle, BOARD_ID, NULL, 1142 ret = acpi_evaluate_object_typed(data->atk_handle, BOARD_ID, NULL,
@@ -973,6 +1195,8 @@ static int atk_add(struct acpi_device *device)
973cleanup: 1195cleanup:
974 atk_free_sensors(data); 1196 atk_free_sensors(data);
975out: 1197out:
1198 if (data->disable_ec)
1199 atk_ec_ctl(data, 0);
976 kfree(data); 1200 kfree(data);
977 return err; 1201 return err;
978} 1202}
@@ -988,6 +1212,11 @@ static int atk_remove(struct acpi_device *device, int type)
988 atk_free_sensors(data); 1212 atk_free_sensors(data);
989 hwmon_device_unregister(data->hwmon_dev); 1213 hwmon_device_unregister(data->hwmon_dev);
990 1214
1215 if (data->disable_ec) {
1216 if (atk_ec_ctl(data, 0))
1217 dev_err(&device->dev, "Failed to disable EC\n");
1218 }
1219
991 kfree(data); 1220 kfree(data);
992 1221
993 return 0; 1222 return 0;
diff --git a/drivers/hwmon/fschmd.c b/drivers/hwmon/fschmd.c
index ea955edde87e..2a7a85a6dc36 100644
--- a/drivers/hwmon/fschmd.c
+++ b/drivers/hwmon/fschmd.c
@@ -915,7 +915,7 @@ static int watchdog_ioctl(struct inode *inode, struct file *filp,
915 return ret; 915 return ret;
916} 916}
917 917
918static struct file_operations watchdog_fops = { 918static const struct file_operations watchdog_fops = {
919 .owner = THIS_MODULE, 919 .owner = THIS_MODULE,
920 .llseek = no_llseek, 920 .llseek = no_llseek,
921 .open = watchdog_open, 921 .open = watchdog_open,
diff --git a/drivers/hwmon/lis3lv02d_spi.c b/drivers/hwmon/lis3lv02d_spi.c
index ecd739534f6a..82b16808a274 100644
--- a/drivers/hwmon/lis3lv02d_spi.c
+++ b/drivers/hwmon/lis3lv02d_spi.c
@@ -83,7 +83,8 @@ static int __devexit lis302dl_spi_remove(struct spi_device *spi)
83 struct lis3lv02d *lis3 = spi_get_drvdata(spi); 83 struct lis3lv02d *lis3 = spi_get_drvdata(spi);
84 lis3lv02d_joystick_disable(); 84 lis3lv02d_joystick_disable();
85 lis3lv02d_poweroff(lis3); 85 lis3lv02d_poweroff(lis3);
86 return 0; 86
87 return lis3lv02d_remove_fs(&lis3_dev);
87} 88}
88 89
89#ifdef CONFIG_PM 90#ifdef CONFIG_PM
diff --git a/drivers/hwmon/ltc4215.c b/drivers/hwmon/ltc4215.c
index 6c9a04136e0a..00d975eb5b83 100644
--- a/drivers/hwmon/ltc4215.c
+++ b/drivers/hwmon/ltc4215.c
@@ -20,11 +20,6 @@
20#include <linux/hwmon.h> 20#include <linux/hwmon.h>
21#include <linux/hwmon-sysfs.h> 21#include <linux/hwmon-sysfs.h>
22 22
23static const unsigned short normal_i2c[] = { I2C_CLIENT_END };
24
25/* Insmod parameters */
26I2C_CLIENT_INSMOD_1(ltc4215);
27
28/* Here are names of the chip's registers (a.k.a. commands) */ 23/* Here are names of the chip's registers (a.k.a. commands) */
29enum ltc4215_cmd { 24enum ltc4215_cmd {
30 LTC4215_CONTROL = 0x00, /* rw */ 25 LTC4215_CONTROL = 0x00, /* rw */
@@ -246,9 +241,13 @@ static const struct attribute_group ltc4215_group = {
246static int ltc4215_probe(struct i2c_client *client, 241static int ltc4215_probe(struct i2c_client *client,
247 const struct i2c_device_id *id) 242 const struct i2c_device_id *id)
248{ 243{
244 struct i2c_adapter *adapter = client->adapter;
249 struct ltc4215_data *data; 245 struct ltc4215_data *data;
250 int ret; 246 int ret;
251 247
248 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
249 return -ENODEV;
250
252 data = kzalloc(sizeof(*data), GFP_KERNEL); 251 data = kzalloc(sizeof(*data), GFP_KERNEL);
253 if (!data) { 252 if (!data) {
254 ret = -ENOMEM; 253 ret = -ENOMEM;
@@ -294,56 +293,20 @@ static int ltc4215_remove(struct i2c_client *client)
294 return 0; 293 return 0;
295} 294}
296 295
297static int ltc4215_detect(struct i2c_client *client,
298 int kind,
299 struct i2c_board_info *info)
300{
301 struct i2c_adapter *adapter = client->adapter;
302
303 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
304 return -ENODEV;
305
306 if (kind < 0) { /* probed detection - check the chip type */
307 s32 v; /* 8 bits from the chip, or -ERRNO */
308
309 /*
310 * Register 0x01 bit b7 is reserved, expect 0
311 * Register 0x03 bit b6 and b7 are reserved, expect 0
312 */
313 v = i2c_smbus_read_byte_data(client, LTC4215_ALERT);
314 if (v < 0 || (v & (1 << 7)) != 0)
315 return -ENODEV;
316
317 v = i2c_smbus_read_byte_data(client, LTC4215_FAULT);
318 if (v < 0 || (v & ((1 << 6) | (1 << 7))) != 0)
319 return -ENODEV;
320 }
321
322 strlcpy(info->type, "ltc4215", I2C_NAME_SIZE);
323 dev_info(&adapter->dev, "ltc4215 %s at address 0x%02x\n",
324 kind < 0 ? "probed" : "forced",
325 client->addr);
326
327 return 0;
328}
329
330static const struct i2c_device_id ltc4215_id[] = { 296static const struct i2c_device_id ltc4215_id[] = {
331 { "ltc4215", ltc4215 }, 297 { "ltc4215", 0 },
332 { } 298 { }
333}; 299};
334MODULE_DEVICE_TABLE(i2c, ltc4215_id); 300MODULE_DEVICE_TABLE(i2c, ltc4215_id);
335 301
336/* This is the driver that will be inserted */ 302/* This is the driver that will be inserted */
337static struct i2c_driver ltc4215_driver = { 303static struct i2c_driver ltc4215_driver = {
338 .class = I2C_CLASS_HWMON,
339 .driver = { 304 .driver = {
340 .name = "ltc4215", 305 .name = "ltc4215",
341 }, 306 },
342 .probe = ltc4215_probe, 307 .probe = ltc4215_probe,
343 .remove = ltc4215_remove, 308 .remove = ltc4215_remove,
344 .id_table = ltc4215_id, 309 .id_table = ltc4215_id,
345 .detect = ltc4215_detect,
346 .address_data = &addr_data,
347}; 310};
348 311
349static int __init ltc4215_init(void) 312static int __init ltc4215_init(void)
diff --git a/drivers/hwmon/ltc4245.c b/drivers/hwmon/ltc4245.c
index e38964333612..65c232a9d0c5 100644
--- a/drivers/hwmon/ltc4245.c
+++ b/drivers/hwmon/ltc4245.c
@@ -22,15 +22,6 @@
22#include <linux/hwmon.h> 22#include <linux/hwmon.h>
23#include <linux/hwmon-sysfs.h> 23#include <linux/hwmon-sysfs.h>
24 24
25/* Valid addresses are 0x20 - 0x3f
26 *
27 * For now, we do not probe, since some of these addresses
28 * are known to be unfriendly to probing */
29static const unsigned short normal_i2c[] = { I2C_CLIENT_END };
30
31/* Insmod parameters */
32I2C_CLIENT_INSMOD_1(ltc4245);
33
34/* Here are names of the chip's registers (a.k.a. commands) */ 25/* Here are names of the chip's registers (a.k.a. commands) */
35enum ltc4245_cmd { 26enum ltc4245_cmd {
36 LTC4245_STATUS = 0x00, /* readonly */ 27 LTC4245_STATUS = 0x00, /* readonly */
@@ -369,9 +360,13 @@ static const struct attribute_group ltc4245_group = {
369static int ltc4245_probe(struct i2c_client *client, 360static int ltc4245_probe(struct i2c_client *client,
370 const struct i2c_device_id *id) 361 const struct i2c_device_id *id)
371{ 362{
363 struct i2c_adapter *adapter = client->adapter;
372 struct ltc4245_data *data; 364 struct ltc4245_data *data;
373 int ret; 365 int ret;
374 366
367 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
368 return -ENODEV;
369
375 data = kzalloc(sizeof(*data), GFP_KERNEL); 370 data = kzalloc(sizeof(*data), GFP_KERNEL);
376 if (!data) { 371 if (!data) {
377 ret = -ENOMEM; 372 ret = -ENOMEM;
@@ -418,136 +413,20 @@ static int ltc4245_remove(struct i2c_client *client)
418 return 0; 413 return 0;
419} 414}
420 415
421/* Check that some bits in a control register appear at all possible
422 * locations without changing value
423 *
424 * @client: the i2c client to use
425 * @reg: the register to read
426 * @bits: the bits to check (0xff checks all bits,
427 * 0x03 checks only the last two bits)
428 *
429 * return -ERRNO if the register read failed
430 * return -ENODEV if the register value doesn't stay constant at all
431 * possible addresses
432 *
433 * return 0 for success
434 */
435static int ltc4245_check_control_reg(struct i2c_client *client, u8 reg, u8 bits)
436{
437 int i;
438 s32 v, voff1, voff2;
439
440 /* Read register and check for error */
441 v = i2c_smbus_read_byte_data(client, reg);
442 if (v < 0)
443 return v;
444
445 v &= bits;
446
447 for (i = 0x00; i < 0xff; i += 0x20) {
448
449 voff1 = i2c_smbus_read_byte_data(client, reg + i);
450 if (voff1 < 0)
451 return voff1;
452
453 voff2 = i2c_smbus_read_byte_data(client, reg + i + 0x08);
454 if (voff2 < 0)
455 return voff2;
456
457 voff1 &= bits;
458 voff2 &= bits;
459
460 if (v != voff1 || v != voff2)
461 return -ENODEV;
462 }
463
464 return 0;
465}
466
467static int ltc4245_detect(struct i2c_client *client,
468 int kind,
469 struct i2c_board_info *info)
470{
471 struct i2c_adapter *adapter = client->adapter;
472
473 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
474 return -ENODEV;
475
476 if (kind < 0) { /* probed detection - check the chip type */
477 s32 v; /* 8 bits from the chip, or -ERRNO */
478
479 /* Chip registers 0x00-0x07 are control registers
480 * Chip registers 0x10-0x1f are data registers
481 *
482 * Address bits b7-b5 are ignored. This makes the chip "repeat"
483 * in steps of 0x20. Any control registers should appear with
484 * the same values across all duplicated addresses.
485 *
486 * Register 0x02 bit b2 is reserved, expect 0
487 * Register 0x07 bits b7 to b4 are reserved, expect 0
488 *
489 * Registers 0x01, 0x02 are control registers and should not
490 * change on their own.
491 *
492 * Register 0x06 bits b6 and b7 are control bits, and should
493 * not change on their own.
494 *
495 * Register 0x07 bits b3 to b0 are control bits, and should
496 * not change on their own.
497 */
498
499 /* read register 0x02 reserved bit, expect 0 */
500 v = i2c_smbus_read_byte_data(client, LTC4245_CONTROL);
501 if (v < 0 || (v & 0x04) != 0)
502 return -ENODEV;
503
504 /* read register 0x07 reserved bits, expect 0 */
505 v = i2c_smbus_read_byte_data(client, LTC4245_ADCADR);
506 if (v < 0 || (v & 0xf0) != 0)
507 return -ENODEV;
508
509 /* check that the alert register appears at all locations */
510 if (ltc4245_check_control_reg(client, LTC4245_ALERT, 0xff))
511 return -ENODEV;
512
513 /* check that the control register appears at all locations */
514 if (ltc4245_check_control_reg(client, LTC4245_CONTROL, 0xff))
515 return -ENODEV;
516
517 /* check that register 0x06 bits b6 and b7 stay constant */
518 if (ltc4245_check_control_reg(client, LTC4245_GPIO, 0xc0))
519 return -ENODEV;
520
521 /* check that register 0x07 bits b3-b0 stay constant */
522 if (ltc4245_check_control_reg(client, LTC4245_ADCADR, 0x0f))
523 return -ENODEV;
524 }
525
526 strlcpy(info->type, "ltc4245", I2C_NAME_SIZE);
527 dev_info(&adapter->dev, "ltc4245 %s at address 0x%02x\n",
528 kind < 0 ? "probed" : "forced",
529 client->addr);
530
531 return 0;
532}
533
534static const struct i2c_device_id ltc4245_id[] = { 416static const struct i2c_device_id ltc4245_id[] = {
535 { "ltc4245", ltc4245 }, 417 { "ltc4245", 0 },
536 { } 418 { }
537}; 419};
538MODULE_DEVICE_TABLE(i2c, ltc4245_id); 420MODULE_DEVICE_TABLE(i2c, ltc4245_id);
539 421
540/* This is the driver that will be inserted */ 422/* This is the driver that will be inserted */
541static struct i2c_driver ltc4245_driver = { 423static struct i2c_driver ltc4245_driver = {
542 .class = I2C_CLASS_HWMON,
543 .driver = { 424 .driver = {
544 .name = "ltc4245", 425 .name = "ltc4245",
545 }, 426 },
546 .probe = ltc4245_probe, 427 .probe = ltc4245_probe,
547 .remove = ltc4245_remove, 428 .remove = ltc4245_remove,
548 .id_table = ltc4245_id, 429 .id_table = ltc4245_id,
549 .detect = ltc4245_detect,
550 .address_data = &addr_data,
551}; 430};
552 431
553static int __init ltc4245_init(void) 432static int __init ltc4245_init(void)
diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c
index 303c02694c3c..ebe38b680ee3 100644
--- a/drivers/hwmon/sht15.c
+++ b/drivers/hwmon/sht15.c
@@ -30,6 +30,7 @@
30#include <linux/hwmon-sysfs.h> 30#include <linux/hwmon-sysfs.h>
31#include <linux/mutex.h> 31#include <linux/mutex.h>
32#include <linux/platform_device.h> 32#include <linux/platform_device.h>
33#include <linux/sched.h>
33#include <linux/delay.h> 34#include <linux/delay.h>
34#include <linux/jiffies.h> 35#include <linux/jiffies.h>
35#include <linux/err.h> 36#include <linux/err.h>
@@ -622,7 +623,12 @@ static int __devexit sht15_remove(struct platform_device *pdev)
622} 623}
623 624
624 625
625static struct platform_driver sht_drivers[] = { 626/*
627 * sht_drivers simultaneously refers to __devinit and __devexit function
628 * which causes spurious section mismatch warning. So use __refdata to
629 * get rid from this.
630 */
631static struct platform_driver __refdata sht_drivers[] = {
626 { 632 {
627 .driver = { 633 .driver = {
628 .name = "sht10", 634 .name = "sht10",
diff --git a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c
index f7d6fe9c49ba..8f0b90ef8c76 100644
--- a/drivers/i2c/busses/i2c-amd756.c
+++ b/drivers/i2c/busses/i2c-amd756.c
@@ -364,7 +364,7 @@ static int __devinit amd756_probe(struct pci_dev *pdev,
364 error = acpi_check_region(amd756_ioport, SMB_IOSIZE, 364 error = acpi_check_region(amd756_ioport, SMB_IOSIZE,
365 amd756_driver.name); 365 amd756_driver.name);
366 if (error) 366 if (error)
367 return error; 367 return -ENODEV;
368 368
369 if (!request_region(amd756_ioport, SMB_IOSIZE, amd756_driver.name)) { 369 if (!request_region(amd756_ioport, SMB_IOSIZE, amd756_driver.name)) {
370 dev_err(&pdev->dev, "SMB region 0x%x already in use!\n", 370 dev_err(&pdev->dev, "SMB region 0x%x already in use!\n",
diff --git a/drivers/i2c/busses/i2c-amd8111.c b/drivers/i2c/busses/i2c-amd8111.c
index a7c59908c457..5b4ad86ca166 100644
--- a/drivers/i2c/busses/i2c-amd8111.c
+++ b/drivers/i2c/busses/i2c-amd8111.c
@@ -376,8 +376,10 @@ static int __devinit amd8111_probe(struct pci_dev *dev,
376 smbus->size = pci_resource_len(dev, 0); 376 smbus->size = pci_resource_len(dev, 0);
377 377
378 error = acpi_check_resource_conflict(&dev->resource[0]); 378 error = acpi_check_resource_conflict(&dev->resource[0]);
379 if (error) 379 if (error) {
380 error = -ENODEV;
380 goto out_kfree; 381 goto out_kfree;
382 }
381 383
382 if (!request_region(smbus->base, smbus->size, amd8111_driver.name)) { 384 if (!request_region(smbus->base, smbus->size, amd8111_driver.name)) {
383 error = -EBUSY; 385 error = -EBUSY;
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index 9d2c5adf5d4f..55edcfe5b851 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -732,8 +732,10 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id
732 } 732 }
733 733
734 err = acpi_check_resource_conflict(&dev->resource[SMBBAR]); 734 err = acpi_check_resource_conflict(&dev->resource[SMBBAR]);
735 if (err) 735 if (err) {
736 err = -ENODEV;
736 goto exit; 737 goto exit;
738 }
737 739
738 err = pci_request_region(dev, SMBBAR, i801_driver.name); 740 err = pci_request_region(dev, SMBBAR, i801_driver.name);
739 if (err) { 741 if (err) {
diff --git a/drivers/i2c/busses/i2c-isch.c b/drivers/i2c/busses/i2c-isch.c
index 9f6b8e0f8632..dba6eb053e2f 100644
--- a/drivers/i2c/busses/i2c-isch.c
+++ b/drivers/i2c/busses/i2c-isch.c
@@ -281,7 +281,7 @@ static int __devinit sch_probe(struct pci_dev *dev,
281 return -ENODEV; 281 return -ENODEV;
282 } 282 }
283 if (acpi_check_region(sch_smba, SMBIOSIZE, sch_driver.name)) 283 if (acpi_check_region(sch_smba, SMBIOSIZE, sch_driver.name))
284 return -EBUSY; 284 return -ENODEV;
285 if (!request_region(sch_smba, SMBIOSIZE, sch_driver.name)) { 285 if (!request_region(sch_smba, SMBIOSIZE, sch_driver.name)) {
286 dev_err(&dev->dev, "SMBus region 0x%x already in use!\n", 286 dev_err(&dev->dev, "SMBus region 0x%x already in use!\n",
287 sch_smba); 287 sch_smba);
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
index a782c7a08f9e..d26a972aacaa 100644
--- a/drivers/i2c/busses/i2c-piix4.c
+++ b/drivers/i2c/busses/i2c-piix4.c
@@ -169,7 +169,7 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
169 } 169 }
170 170
171 if (acpi_check_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) 171 if (acpi_check_region(piix4_smba, SMBIOSIZE, piix4_driver.name))
172 return -EBUSY; 172 return -ENODEV;
173 173
174 if (!request_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) { 174 if (!request_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) {
175 dev_err(&PIIX4_dev->dev, "SMBus region 0x%x already in use!\n", 175 dev_err(&PIIX4_dev->dev, "SMBus region 0x%x already in use!\n",
@@ -260,7 +260,7 @@ static int __devinit piix4_setup_sb800(struct pci_dev *PIIX4_dev,
260 260
261 piix4_smba = ((smba_en_hi << 8) | smba_en_lo) & 0xffe0; 261 piix4_smba = ((smba_en_hi << 8) | smba_en_lo) & 0xffe0;
262 if (acpi_check_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) 262 if (acpi_check_region(piix4_smba, SMBIOSIZE, piix4_driver.name))
263 return -EBUSY; 263 return -ENODEV;
264 264
265 if (!request_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) { 265 if (!request_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) {
266 dev_err(&PIIX4_dev->dev, "SMBus region 0x%x already in use!\n", 266 dev_err(&PIIX4_dev->dev, "SMBus region 0x%x already in use!\n",
diff --git a/drivers/i2c/busses/i2c-sis96x.c b/drivers/i2c/busses/i2c-sis96x.c
index 8295885b2fdb..1649963b00dc 100644
--- a/drivers/i2c/busses/i2c-sis96x.c
+++ b/drivers/i2c/busses/i2c-sis96x.c
@@ -280,7 +280,7 @@ static int __devinit sis96x_probe(struct pci_dev *dev,
280 280
281 retval = acpi_check_resource_conflict(&dev->resource[SIS96x_BAR]); 281 retval = acpi_check_resource_conflict(&dev->resource[SIS96x_BAR]);
282 if (retval) 282 if (retval)
283 return retval; 283 return -ENODEV;
284 284
285 /* Everything is happy, let's grab the memory and set things up. */ 285 /* Everything is happy, let's grab the memory and set things up. */
286 if (!request_region(sis96x_smbus_base, SMB_IOSIZE, 286 if (!request_region(sis96x_smbus_base, SMB_IOSIZE,
diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c
index 54d810a4d00f..e4b1543015af 100644
--- a/drivers/i2c/busses/i2c-viapro.c
+++ b/drivers/i2c/busses/i2c-viapro.c
@@ -365,7 +365,7 @@ static int __devinit vt596_probe(struct pci_dev *pdev,
365found: 365found:
366 error = acpi_check_region(vt596_smba, 8, vt596_driver.name); 366 error = acpi_check_region(vt596_smba, 8, vt596_driver.name);
367 if (error) 367 if (error)
368 return error; 368 return -ENODEV;
369 369
370 if (!request_region(vt596_smba, 8, vt596_driver.name)) { 370 if (!request_region(vt596_smba, 8, vt596_driver.name)) {
371 dev_err(&pdev->dev, "SMBus region 0x%x already in use!\n", 371 dev_err(&pdev->dev, "SMBus region 0x%x already in use!\n",
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c
index 28d09a5d8450..017c09540c2f 100644
--- a/drivers/ide/ide-proc.c
+++ b/drivers/ide/ide-proc.c
@@ -273,14 +273,8 @@ static const struct ide_proc_devset ide_generic_settings[] = {
273 273
274static void proc_ide_settings_warn(void) 274static void proc_ide_settings_warn(void)
275{ 275{
276 static int warned; 276 printk_once(KERN_WARNING "Warning: /proc/ide/hd?/settings interface is "
277
278 if (warned)
279 return;
280
281 printk(KERN_WARNING "Warning: /proc/ide/hd?/settings interface is "
282 "obsolete, and will be removed soon!\n"); 277 "obsolete, and will be removed soon!\n");
283 warned = 1;
284} 278}
285 279
286static int ide_settings_proc_show(struct seq_file *m, void *v) 280static int ide_settings_proc_show(struct seq_file *m, void *v)
diff --git a/drivers/ide/sis5513.c b/drivers/ide/sis5513.c
index afca22beaadf..3b88eba04c9c 100644
--- a/drivers/ide/sis5513.c
+++ b/drivers/ide/sis5513.c
@@ -2,7 +2,7 @@
2 * Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org> 2 * Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org>
3 * Copyright (C) 2002 Lionel Bouton <Lionel.Bouton@inet6.fr>, Maintainer 3 * Copyright (C) 2002 Lionel Bouton <Lionel.Bouton@inet6.fr>, Maintainer
4 * Copyright (C) 2003 Vojtech Pavlik <vojtech@suse.cz> 4 * Copyright (C) 2003 Vojtech Pavlik <vojtech@suse.cz>
5 * Copyright (C) 2007 Bartlomiej Zolnierkiewicz 5 * Copyright (C) 2007-2009 Bartlomiej Zolnierkiewicz
6 * 6 *
7 * May be copied or modified under the terms of the GNU General Public License 7 * May be copied or modified under the terms of the GNU General Public License
8 * 8 *
@@ -281,11 +281,13 @@ static void config_drive_art_rwp(ide_drive_t *drive)
281 281
282 pci_read_config_byte(dev, 0x4b, &reg4bh); 282 pci_read_config_byte(dev, 0x4b, &reg4bh);
283 283
284 rw_prefetch = reg4bh & ~(0x11 << drive->dn);
285
284 if (drive->media == ide_disk) 286 if (drive->media == ide_disk)
285 rw_prefetch = 0x11 << drive->dn; 287 rw_prefetch |= 0x11 << drive->dn;
286 288
287 if ((reg4bh & (0x11 << drive->dn)) != rw_prefetch) 289 if (reg4bh != rw_prefetch)
288 pci_write_config_byte(dev, 0x4b, reg4bh|rw_prefetch); 290 pci_write_config_byte(dev, 0x4b, rw_prefetch);
289} 291}
290 292
291static void sis_set_pio_mode(ide_drive_t *drive, const u8 pio) 293static void sis_set_pio_mode(ide_drive_t *drive, const u8 pio)
diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c
index 0bc3d78ce7b1..8aa56ac07e29 100644
--- a/drivers/ieee1394/raw1394.c
+++ b/drivers/ieee1394/raw1394.c
@@ -29,6 +29,7 @@
29 29
30#include <linux/kernel.h> 30#include <linux/kernel.h>
31#include <linux/list.h> 31#include <linux/list.h>
32#include <linux/sched.h>
32#include <linux/string.h> 33#include <linux/string.h>
33#include <linux/slab.h> 34#include <linux/slab.h>
34#include <linux/fs.h> 35#include <linux/fs.h>
diff --git a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c
index d287ba79821d..949064a05675 100644
--- a/drivers/ieee1394/video1394.c
+++ b/drivers/ieee1394/video1394.c
@@ -30,6 +30,7 @@
30 */ 30 */
31#include <linux/kernel.h> 31#include <linux/kernel.h>
32#include <linux/list.h> 32#include <linux/list.h>
33#include <linux/sched.h>
33#include <linux/slab.h> 34#include <linux/slab.h>
34#include <linux/interrupt.h> 35#include <linux/interrupt.h>
35#include <linux/wait.h> 36#include <linux/wait.h>
diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c
index 5be1bd4fc7ed..bd07803e9183 100644
--- a/drivers/infiniband/core/addr.c
+++ b/drivers/infiniband/core/addr.c
@@ -393,7 +393,7 @@ static int addr_resolve_local(struct sockaddr *src_in,
393 393
394 for_each_netdev(&init_net, dev) 394 for_each_netdev(&init_net, dev)
395 if (ipv6_chk_addr(&init_net, 395 if (ipv6_chk_addr(&init_net,
396 &((struct sockaddr_in6 *) addr)->sin6_addr, 396 &((struct sockaddr_in6 *) dst_in)->sin6_addr,
397 dev, 1)) 397 dev, 1))
398 break; 398 break;
399 399
diff --git a/drivers/infiniband/core/iwcm.c b/drivers/infiniband/core/iwcm.c
index 55d093a36ae4..0f89909abce9 100644
--- a/drivers/infiniband/core/iwcm.c
+++ b/drivers/infiniband/core/iwcm.c
@@ -40,6 +40,7 @@
40#include <linux/idr.h> 40#include <linux/idr.h>
41#include <linux/interrupt.h> 41#include <linux/interrupt.h>
42#include <linux/rbtree.h> 42#include <linux/rbtree.h>
43#include <linux/sched.h>
43#include <linux/spinlock.h> 44#include <linux/spinlock.h>
44#include <linux/workqueue.h> 45#include <linux/workqueue.h>
45#include <linux/completion.h> 46#include <linux/completion.h>
@@ -362,7 +363,9 @@ static void destroy_cm_id(struct iw_cm_id *cm_id)
362 * In either case, must tell the provider to reject. 363 * In either case, must tell the provider to reject.
363 */ 364 */
364 cm_id_priv->state = IW_CM_STATE_DESTROYING; 365 cm_id_priv->state = IW_CM_STATE_DESTROYING;
366 spin_unlock_irqrestore(&cm_id_priv->lock, flags);
365 cm_id->device->iwcm->reject(cm_id, NULL, 0); 367 cm_id->device->iwcm->reject(cm_id, NULL, 0);
368 spin_lock_irqsave(&cm_id_priv->lock, flags);
366 break; 369 break;
367 case IW_CM_STATE_CONN_SENT: 370 case IW_CM_STATE_CONN_SENT:
368 case IW_CM_STATE_DESTROYING: 371 case IW_CM_STATE_DESTROYING:
diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c
index 51bd9669cb1f..f504c9b00c1b 100644
--- a/drivers/infiniband/core/ucm.c
+++ b/drivers/infiniband/core/ucm.c
@@ -38,6 +38,7 @@
38#include <linux/device.h> 38#include <linux/device.h>
39#include <linux/err.h> 39#include <linux/err.h>
40#include <linux/poll.h> 40#include <linux/poll.h>
41#include <linux/sched.h>
41#include <linux/file.h> 42#include <linux/file.h>
42#include <linux/mount.h> 43#include <linux/mount.h>
43#include <linux/cdev.h> 44#include <linux/cdev.h>
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c
index 4346a24568fb..bb96d3c4b0f4 100644
--- a/drivers/infiniband/core/ucma.c
+++ b/drivers/infiniband/core/ucma.c
@@ -34,6 +34,7 @@
34#include <linux/file.h> 34#include <linux/file.h>
35#include <linux/mutex.h> 35#include <linux/mutex.h>
36#include <linux/poll.h> 36#include <linux/poll.h>
37#include <linux/sched.h>
37#include <linux/idr.h> 38#include <linux/idr.h>
38#include <linux/in.h> 39#include <linux/in.h>
39#include <linux/in6.h> 40#include <linux/in6.h>
diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c
index 8c46f2257098..7de02969ed7d 100644
--- a/drivers/infiniband/core/user_mad.c
+++ b/drivers/infiniband/core/user_mad.c
@@ -44,6 +44,7 @@
44#include <linux/mutex.h> 44#include <linux/mutex.h>
45#include <linux/kref.h> 45#include <linux/kref.h>
46#include <linux/compat.h> 46#include <linux/compat.h>
47#include <linux/sched.h>
47#include <linux/semaphore.h> 48#include <linux/semaphore.h>
48 49
49#include <asm/uaccess.h> 50#include <asm/uaccess.h>
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
index d3fff9e008a3..aec0fbdfe7f0 100644
--- a/drivers/infiniband/core/uverbs_main.c
+++ b/drivers/infiniband/core/uverbs_main.c
@@ -40,6 +40,7 @@
40#include <linux/err.h> 40#include <linux/err.h>
41#include <linux/fs.h> 41#include <linux/fs.h>
42#include <linux/poll.h> 42#include <linux/poll.h>
43#include <linux/sched.h>
43#include <linux/file.h> 44#include <linux/file.h>
44#include <linux/mount.h> 45#include <linux/mount.h>
45#include <linux/cdev.h> 46#include <linux/cdev.h>
diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.c b/drivers/infiniband/hw/cxgb3/iwch_provider.c
index 6895523779d0..ed7175549ebd 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_provider.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_provider.c
@@ -37,6 +37,7 @@
37#include <linux/delay.h> 37#include <linux/delay.h>
38#include <linux/errno.h> 38#include <linux/errno.h>
39#include <linux/list.h> 39#include <linux/list.h>
40#include <linux/sched.h>
40#include <linux/spinlock.h> 41#include <linux/spinlock.h>
41#include <linux/ethtool.h> 42#include <linux/ethtool.h>
42#include <linux/rtnetlink.h> 43#include <linux/rtnetlink.h>
@@ -1199,11 +1200,14 @@ static int iwch_query_port(struct ib_device *ibdev,
1199 props->state = IB_PORT_DOWN; 1200 props->state = IB_PORT_DOWN;
1200 else { 1201 else {
1201 inetdev = in_dev_get(netdev); 1202 inetdev = in_dev_get(netdev);
1202 if (inetdev->ifa_list) 1203 if (inetdev) {
1203 props->state = IB_PORT_ACTIVE; 1204 if (inetdev->ifa_list)
1204 else 1205 props->state = IB_PORT_ACTIVE;
1206 else
1207 props->state = IB_PORT_INIT;
1208 in_dev_put(inetdev);
1209 } else
1205 props->state = IB_PORT_INIT; 1210 props->state = IB_PORT_INIT;
1206 in_dev_put(inetdev);
1207 } 1211 }
1208 1212
1209 props->port_cap_flags = 1213 props->port_cap_flags =
diff --git a/drivers/infiniband/hw/cxgb3/iwch_qp.c b/drivers/infiniband/hw/cxgb3/iwch_qp.c
index 6e8653471941..1cecf98829ac 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_qp.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_qp.c
@@ -29,6 +29,7 @@
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE. 30 * SOFTWARE.
31 */ 31 */
32#include <linux/sched.h>
32#include "iwch_provider.h" 33#include "iwch_provider.h"
33#include "iwch.h" 34#include "iwch.h"
34#include "iwch_cm.h" 35#include "iwch_cm.h"
diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c
index 04e88b600558..013d1380e77c 100644
--- a/drivers/infiniband/hw/ipath/ipath_driver.c
+++ b/drivers/infiniband/hw/ipath/ipath_driver.c
@@ -31,6 +31,7 @@
31 * SOFTWARE. 31 * SOFTWARE.
32 */ 32 */
33 33
34#include <linux/sched.h>
34#include <linux/spinlock.h> 35#include <linux/spinlock.h>
35#include <linux/idr.h> 36#include <linux/idr.h>
36#include <linux/pci.h> 37#include <linux/pci.h>
diff --git a/drivers/infiniband/hw/ipath/ipath_iba7220.c b/drivers/infiniband/hw/ipath/ipath_iba7220.c
index b2a9d4c155d1..a805402dd4ae 100644
--- a/drivers/infiniband/hw/ipath/ipath_iba7220.c
+++ b/drivers/infiniband/hw/ipath/ipath_iba7220.c
@@ -37,6 +37,7 @@
37 37
38#include <linux/interrupt.h> 38#include <linux/interrupt.h>
39#include <linux/pci.h> 39#include <linux/pci.h>
40#include <linux/sched.h>
40#include <linux/delay.h> 41#include <linux/delay.h>
41#include <linux/io.h> 42#include <linux/io.h>
42#include <rdma/ib_verbs.h> 43#include <rdma/ib_verbs.h>
diff --git a/drivers/infiniband/hw/ipath/ipath_intr.c b/drivers/infiniband/hw/ipath/ipath_intr.c
index 6c21b4b5ec71..c0a03ac03ee7 100644
--- a/drivers/infiniband/hw/ipath/ipath_intr.c
+++ b/drivers/infiniband/hw/ipath/ipath_intr.c
@@ -33,6 +33,7 @@
33 33
34#include <linux/pci.h> 34#include <linux/pci.h>
35#include <linux/delay.h> 35#include <linux/delay.h>
36#include <linux/sched.h>
36 37
37#include "ipath_kernel.h" 38#include "ipath_kernel.h"
38#include "ipath_verbs.h" 39#include "ipath_verbs.h"
diff --git a/drivers/infiniband/hw/ipath/ipath_qp.c b/drivers/infiniband/hw/ipath/ipath_qp.c
index 3a5a89b609c4..cb2d3ef2ae12 100644
--- a/drivers/infiniband/hw/ipath/ipath_qp.c
+++ b/drivers/infiniband/hw/ipath/ipath_qp.c
@@ -32,6 +32,7 @@
32 */ 32 */
33 33
34#include <linux/err.h> 34#include <linux/err.h>
35#include <linux/sched.h>
35#include <linux/vmalloc.h> 36#include <linux/vmalloc.h>
36 37
37#include "ipath_verbs.h" 38#include "ipath_verbs.h"
diff --git a/drivers/infiniband/hw/ipath/ipath_ruc.c b/drivers/infiniband/hw/ipath/ipath_ruc.c
index 2296832f94da..1f95bbaf7602 100644
--- a/drivers/infiniband/hw/ipath/ipath_ruc.c
+++ b/drivers/infiniband/hw/ipath/ipath_ruc.c
@@ -31,6 +31,7 @@
31 * SOFTWARE. 31 * SOFTWARE.
32 */ 32 */
33 33
34#include <linux/sched.h>
34#include <linux/spinlock.h> 35#include <linux/spinlock.h>
35 36
36#include "ipath_verbs.h" 37#include "ipath_verbs.h"
diff --git a/drivers/infiniband/hw/ipath/ipath_ud.c b/drivers/infiniband/hw/ipath/ipath_ud.c
index 6076cb61bf6a..7420715256a9 100644
--- a/drivers/infiniband/hw/ipath/ipath_ud.c
+++ b/drivers/infiniband/hw/ipath/ipath_ud.c
@@ -31,6 +31,7 @@
31 * SOFTWARE. 31 * SOFTWARE.
32 */ 32 */
33 33
34#include <linux/sched.h>
34#include <rdma/ib_smi.h> 35#include <rdma/ib_smi.h>
35 36
36#include "ipath_verbs.h" 37#include "ipath_verbs.h"
diff --git a/drivers/infiniband/hw/ipath/ipath_user_pages.c b/drivers/infiniband/hw/ipath/ipath_user_pages.c
index 855911e7396d..82878e348627 100644
--- a/drivers/infiniband/hw/ipath/ipath_user_pages.c
+++ b/drivers/infiniband/hw/ipath/ipath_user_pages.c
@@ -33,6 +33,7 @@
33 33
34#include <linux/mm.h> 34#include <linux/mm.h>
35#include <linux/device.h> 35#include <linux/device.h>
36#include <linux/sched.h>
36 37
37#include "ipath_kernel.h" 38#include "ipath_kernel.h"
38 39
diff --git a/drivers/infiniband/hw/ipath/ipath_user_sdma.c b/drivers/infiniband/hw/ipath/ipath_user_sdma.c
index 7bff4b9baa0a..be78f6643c06 100644
--- a/drivers/infiniband/hw/ipath/ipath_user_sdma.c
+++ b/drivers/infiniband/hw/ipath/ipath_user_sdma.c
@@ -33,6 +33,7 @@
33#include <linux/types.h> 33#include <linux/types.h>
34#include <linux/device.h> 34#include <linux/device.h>
35#include <linux/dmapool.h> 35#include <linux/dmapool.h>
36#include <linux/sched.h>
36#include <linux/slab.h> 37#include <linux/slab.h>
37#include <linux/list.h> 38#include <linux/list.h>
38#include <linux/highmem.h> 39#include <linux/highmem.h>
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs_mcast.c b/drivers/infiniband/hw/ipath/ipath_verbs_mcast.c
index d73e32232879..6923e1d986da 100644
--- a/drivers/infiniband/hw/ipath/ipath_verbs_mcast.c
+++ b/drivers/infiniband/hw/ipath/ipath_verbs_mcast.c
@@ -32,6 +32,7 @@
32 */ 32 */
33 33
34#include <linux/rculist.h> 34#include <linux/rculist.h>
35#include <linux/sched.h>
35 36
36#include "ipath_verbs.h" 37#include "ipath_verbs.h"
37 38
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c
index 0ba6ec876296..add9188663ff 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.c
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.c
@@ -426,7 +426,7 @@ iscsi_iser_session_create(struct iscsi_endpoint *ep,
426 * because we preallocate so many resources 426 * because we preallocate so many resources
427 */ 427 */
428 cls_session = iscsi_session_setup(&iscsi_iser_transport, shost, 428 cls_session = iscsi_session_setup(&iscsi_iser_transport, shost,
429 ISCSI_DEF_XMIT_CMDS_MAX, 429 ISCSI_DEF_XMIT_CMDS_MAX, 0,
430 sizeof(struct iscsi_iser_task), 430 sizeof(struct iscsi_iser_task),
431 initial_cmdsn, 0); 431 initial_cmdsn, 0);
432 if (!cls_session) 432 if (!cls_session)
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 1148140d08a1..dee6706038aa 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -13,6 +13,7 @@
13#define EVDEV_BUFFER_SIZE 64 13#define EVDEV_BUFFER_SIZE 64
14 14
15#include <linux/poll.h> 15#include <linux/poll.h>
16#include <linux/sched.h>
16#include <linux/slab.h> 17#include <linux/slab.h>
17#include <linux/module.h> 18#include <linux/module.h>
18#include <linux/init.h> 19#include <linux/init.h>
diff --git a/drivers/input/input.c b/drivers/input/input.c
index e828aab7dace..c6f88ebb40c7 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -17,6 +17,7 @@
17#include <linux/random.h> 17#include <linux/random.h>
18#include <linux/major.h> 18#include <linux/major.h>
19#include <linux/proc_fs.h> 19#include <linux/proc_fs.h>
20#include <linux/sched.h>
20#include <linux/seq_file.h> 21#include <linux/seq_file.h>
21#include <linux/poll.h> 22#include <linux/poll.h>
22#include <linux/device.h> 23#include <linux/device.h>
@@ -1273,6 +1274,7 @@ static int input_dev_uevent(struct device *device, struct kobj_uevent_env *env)
1273 } \ 1274 } \
1274 } while (0) 1275 } while (0)
1275 1276
1277#ifdef CONFIG_PM
1276static void input_dev_reset(struct input_dev *dev, bool activate) 1278static void input_dev_reset(struct input_dev *dev, bool activate)
1277{ 1279{
1278 if (!dev->event) 1280 if (!dev->event)
@@ -1287,7 +1289,6 @@ static void input_dev_reset(struct input_dev *dev, bool activate)
1287 } 1289 }
1288} 1290}
1289 1291
1290#ifdef CONFIG_PM
1291static int input_dev_suspend(struct device *dev) 1292static int input_dev_suspend(struct device *dev)
1292{ 1293{
1293 struct input_dev *input_dev = to_input_dev(dev); 1294 struct input_dev *input_dev = to_input_dev(dev);
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c
index 901b2525993e..b1bd6dd32286 100644
--- a/drivers/input/joydev.c
+++ b/drivers/input/joydev.c
@@ -18,6 +18,7 @@
18#include <linux/input.h> 18#include <linux/input.h>
19#include <linux/kernel.h> 19#include <linux/kernel.h>
20#include <linux/major.h> 20#include <linux/major.h>
21#include <linux/sched.h>
21#include <linux/slab.h> 22#include <linux/slab.h>
22#include <linux/mm.h> 23#include <linux/mm.h>
23#include <linux/miscdevice.h> 24#include <linux/miscdevice.h>
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 2388cf578a62..79e3edcced1a 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -143,6 +143,7 @@ static const struct xpad_device {
143 { 0x12ab, 0x8809, "Xbox DDR dancepad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, 143 { 0x12ab, 0x8809, "Xbox DDR dancepad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
144 { 0x1430, 0x4748, "RedOctane Guitar Hero X-plorer", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, 144 { 0x1430, 0x4748, "RedOctane Guitar Hero X-plorer", MAP_DPAD_TO_AXES, XTYPE_XBOX360 },
145 { 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, 145 { 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
146 { 0x146b, 0x0601, "BigBen Interactive XBOX 360 Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX360 },
146 { 0x045e, 0x028e, "Microsoft X-Box 360 pad", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, 147 { 0x045e, 0x028e, "Microsoft X-Box 360 pad", MAP_DPAD_TO_AXES, XTYPE_XBOX360 },
147 { 0x1bad, 0x0003, "Harmonix Rock Band Drumkit", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 }, 148 { 0x1bad, 0x0003, "Harmonix Rock Band Drumkit", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 },
148 { 0xffff, 0xffff, "Chinese-made Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, 149 { 0xffff, 0xffff, "Chinese-made Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX },
@@ -209,6 +210,7 @@ static struct usb_device_id xpad_table [] = {
209 XPAD_XBOX360_VENDOR(0x0738), /* Mad Catz X-Box 360 controllers */ 210 XPAD_XBOX360_VENDOR(0x0738), /* Mad Catz X-Box 360 controllers */
210 XPAD_XBOX360_VENDOR(0x0e6f), /* 0x0e6f X-Box 360 controllers */ 211 XPAD_XBOX360_VENDOR(0x0e6f), /* 0x0e6f X-Box 360 controllers */
211 XPAD_XBOX360_VENDOR(0x1430), /* RedOctane X-Box 360 controllers */ 212 XPAD_XBOX360_VENDOR(0x1430), /* RedOctane X-Box 360 controllers */
213 XPAD_XBOX360_VENDOR(0x146b), /* BigBen Interactive Controllers */
212 XPAD_XBOX360_VENDOR(0x1bad), /* Rock Band Drums */ 214 XPAD_XBOX360_VENDOR(0x1bad), /* Rock Band Drums */
213 { } 215 { }
214}; 216};
diff --git a/drivers/input/keyboard/hilkbd.c b/drivers/input/keyboard/hilkbd.c
index e9d639ec283d..5f72440b50c8 100644
--- a/drivers/input/keyboard/hilkbd.c
+++ b/drivers/input/keyboard/hilkbd.c
@@ -24,6 +24,7 @@
24#include <linux/interrupt.h> 24#include <linux/interrupt.h>
25#include <linux/hil.h> 25#include <linux/hil.h>
26#include <linux/io.h> 26#include <linux/io.h>
27#include <linux/sched.h>
27#include <linux/spinlock.h> 28#include <linux/spinlock.h>
28#include <asm/irq.h> 29#include <asm/irq.h>
29#ifdef CONFIG_HP300 30#ifdef CONFIG_HP300
diff --git a/drivers/input/keyboard/sunkbd.c b/drivers/input/keyboard/sunkbd.c
index 472b56639cdb..a99a04b03ee4 100644
--- a/drivers/input/keyboard/sunkbd.c
+++ b/drivers/input/keyboard/sunkbd.c
@@ -27,6 +27,7 @@
27 */ 27 */
28 28
29#include <linux/delay.h> 29#include <linux/delay.h>
30#include <linux/sched.h>
30#include <linux/slab.h> 31#include <linux/slab.h>
31#include <linux/module.h> 32#include <linux/module.h>
32#include <linux/interrupt.h> 33#include <linux/interrupt.h>
diff --git a/drivers/input/misc/rotary_encoder.c b/drivers/input/misc/rotary_encoder.c
index c806fbf1e174..3b9f588fc747 100644
--- a/drivers/input/misc/rotary_encoder.c
+++ b/drivers/input/misc/rotary_encoder.c
@@ -106,8 +106,8 @@ static int __devinit rotary_encoder_probe(struct platform_device *pdev)
106 struct input_dev *input; 106 struct input_dev *input;
107 int err; 107 int err;
108 108
109 if (!pdata || !pdata->steps) { 109 if (!pdata) {
110 dev_err(&pdev->dev, "invalid platform data\n"); 110 dev_err(&pdev->dev, "missing platform data\n");
111 return -ENOENT; 111 return -ENOENT;
112 } 112 }
113 113
diff --git a/drivers/input/misc/sparcspkr.c b/drivers/input/misc/sparcspkr.c
index c4f42311fdec..b064419b90a2 100644
--- a/drivers/input/misc/sparcspkr.c
+++ b/drivers/input/misc/sparcspkr.c
@@ -230,7 +230,7 @@ out_err:
230 return err; 230 return err;
231} 231}
232 232
233static int bbc_remove(struct of_device *op) 233static int __devexit bbc_remove(struct of_device *op)
234{ 234{
235 struct sparcspkr_state *state = dev_get_drvdata(&op->dev); 235 struct sparcspkr_state *state = dev_get_drvdata(&op->dev);
236 struct input_dev *input_dev = state->input_dev; 236 struct input_dev *input_dev = state->input_dev;
@@ -308,7 +308,7 @@ out_err:
308 return err; 308 return err;
309} 309}
310 310
311static int grover_remove(struct of_device *op) 311static int __devexit grover_remove(struct of_device *op)
312{ 312{
313 struct sparcspkr_state *state = dev_get_drvdata(&op->dev); 313 struct sparcspkr_state *state = dev_get_drvdata(&op->dev);
314 struct grover_beep_info *info = &state->u.grover; 314 struct grover_beep_info *info = &state->u.grover;
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
index c5a49aba418f..d3f57245420a 100644
--- a/drivers/input/misc/uinput.c
+++ b/drivers/input/misc/uinput.c
@@ -30,6 +30,7 @@
30 * - first public version 30 * - first public version
31 */ 31 */
32#include <linux/poll.h> 32#include <linux/poll.h>
33#include <linux/sched.h>
33#include <linux/slab.h> 34#include <linux/slab.h>
34#include <linux/module.h> 35#include <linux/module.h>
35#include <linux/init.h> 36#include <linux/init.h>
diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c
index 11fd038a078f..a932179c4c9e 100644
--- a/drivers/input/misc/wistron_btns.c
+++ b/drivers/input/misc/wistron_btns.c
@@ -936,6 +936,15 @@ static struct dmi_system_id dmi_ids[] __initdata = {
936 }, 936 },
937 { 937 {
938 .callback = dmi_matched, 938 .callback = dmi_matched,
939 .ident = "Medion MD 42200",
940 .matches = {
941 DMI_MATCH(DMI_SYS_VENDOR, "Medion"),
942 DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2030"),
943 },
944 .driver_data = keymap_fs_amilo_pro_v2000
945 },
946 {
947 .callback = dmi_matched,
939 .ident = "Medion MD 96500", 948 .ident = "Medion MD 96500",
940 .matches = { 949 .matches = {
941 DMI_MATCH(DMI_SYS_VENDOR, "MEDIONPC"), 950 DMI_MATCH(DMI_SYS_VENDOR, "MEDIONPC"),
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c
index 966b8868f792..a13d80f7da17 100644
--- a/drivers/input/mousedev.c
+++ b/drivers/input/mousedev.c
@@ -13,6 +13,7 @@
13#define MOUSEDEV_MINORS 32 13#define MOUSEDEV_MINORS 32
14#define MOUSEDEV_MIX 31 14#define MOUSEDEV_MIX 31
15 15
16#include <linux/sched.h>
16#include <linux/slab.h> 17#include <linux/slab.h>
17#include <linux/smp_lock.h> 18#include <linux/smp_lock.h>
18#include <linux/poll.h> 19#include <linux/poll.h>
diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig
index c4b3fbd1a80f..aa533ceffe34 100644
--- a/drivers/input/serio/Kconfig
+++ b/drivers/input/serio/Kconfig
@@ -4,7 +4,7 @@
4config SERIO 4config SERIO
5 tristate "Serial I/O support" if EMBEDDED || !X86 5 tristate "Serial I/O support" if EMBEDDED || !X86
6 default y 6 default y
7 ---help--- 7 help
8 Say Yes here if you have any input device that uses serial I/O to 8 Say Yes here if you have any input device that uses serial I/O to
9 communicate with the system. This includes the 9 communicate with the system. This includes the
10 * standard AT keyboard and PS/2 mouse * 10 * standard AT keyboard and PS/2 mouse *
@@ -22,7 +22,7 @@ config SERIO_I8042
22 tristate "i8042 PC Keyboard controller" if EMBEDDED || !X86 22 tristate "i8042 PC Keyboard controller" if EMBEDDED || !X86
23 default y 23 default y
24 depends on !PARISC && (!ARM || ARCH_SHARK || FOOTBRIDGE_HOST) && !M68K && !BLACKFIN 24 depends on !PARISC && (!ARM || ARCH_SHARK || FOOTBRIDGE_HOST) && !M68K && !BLACKFIN
25 ---help--- 25 help
26 i8042 is the chip over which the standard AT keyboard and PS/2 26 i8042 is the chip over which the standard AT keyboard and PS/2
27 mouse are connected to the computer. If you use these devices, 27 mouse are connected to the computer. If you use these devices,
28 you'll need to say Y here. 28 you'll need to say Y here.
@@ -35,7 +35,7 @@ config SERIO_I8042
35config SERIO_SERPORT 35config SERIO_SERPORT
36 tristate "Serial port line discipline" 36 tristate "Serial port line discipline"
37 default y 37 default y
38 ---help--- 38 help
39 Say Y here if you plan to use an input device (mouse, joystick, 39 Say Y here if you plan to use an input device (mouse, joystick,
40 tablet, 6dof) that communicates over the RS232 serial (COM) port. 40 tablet, 6dof) that communicates over the RS232 serial (COM) port.
41 41
@@ -49,7 +49,7 @@ config SERIO_SERPORT
49config SERIO_CT82C710 49config SERIO_CT82C710
50 tristate "ct82c710 Aux port controller" 50 tristate "ct82c710 Aux port controller"
51 depends on X86 51 depends on X86
52 ---help--- 52 help
53 Say Y here if you have a Texas Instruments TravelMate notebook 53 Say Y here if you have a Texas Instruments TravelMate notebook
54 equipped with the ct82c710 chip and want to use a mouse connected 54 equipped with the ct82c710 chip and want to use a mouse connected
55 to the "QuickPort". 55 to the "QuickPort".
@@ -66,7 +66,7 @@ config SERIO_Q40KBD
66config SERIO_PARKBD 66config SERIO_PARKBD
67 tristate "Parallel port keyboard adapter" 67 tristate "Parallel port keyboard adapter"
68 depends on PARPORT 68 depends on PARPORT
69 ---help--- 69 help
70 Say Y here if you built a simple parallel port adapter to attach 70 Say Y here if you built a simple parallel port adapter to attach
71 an additional AT keyboard, XT keyboard or PS/2 mouse. 71 an additional AT keyboard, XT keyboard or PS/2 mouse.
72 72
@@ -124,7 +124,7 @@ config HP_SDC
124 tristate "HP System Device Controller i8042 Support" 124 tristate "HP System Device Controller i8042 Support"
125 depends on (GSC || HP300) && SERIO 125 depends on (GSC || HP300) && SERIO
126 default y 126 default y
127 ---help--- 127 help
128 This option enables support for the "System Device 128 This option enables support for the "System Device
129 Controller", an i8042 carrying microcode to manage a 129 Controller", an i8042 carrying microcode to manage a
130 few miscellaneous devices on some Hewlett Packard systems. 130 few miscellaneous devices on some Hewlett Packard systems.
@@ -168,6 +168,7 @@ config SERIO_MACEPS2
168 168
169config SERIO_LIBPS2 169config SERIO_LIBPS2
170 tristate "PS/2 driver library" if EMBEDDED 170 tristate "PS/2 driver library" if EMBEDDED
171 depends on SERIO_I8042 || SERIO_I8042=n
171 help 172 help
172 Say Y here if you are using a driver for device connected 173 Say Y here if you are using a driver for device connected
173 to a PS/2 port, such as PS/2 mouse or standard AT keyboard. 174 to a PS/2 port, such as PS/2 mouse or standard AT keyboard.
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index bc56e52b945f..a31578170ccc 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -609,6 +609,8 @@ static irqreturn_t __init i8042_aux_test_irq(int irq, void *dev_id)
609 str = i8042_read_status(); 609 str = i8042_read_status();
610 if (str & I8042_STR_OBF) { 610 if (str & I8042_STR_OBF) {
611 data = i8042_read_data(); 611 data = i8042_read_data();
612 dbg("%02x <- i8042 (aux_test_irq, %s)",
613 data, str & I8042_STR_AUXDATA ? "aux" : "kbd");
612 if (i8042_irq_being_tested && 614 if (i8042_irq_being_tested &&
613 data == 0xa5 && (str & I8042_STR_AUXDATA)) 615 data == 0xa5 && (str & I8042_STR_AUXDATA))
614 complete(&i8042_aux_irq_delivered); 616 complete(&i8042_aux_irq_delivered);
@@ -750,6 +752,7 @@ static int __init i8042_check_aux(void)
750 * AUX IRQ was never delivered so we need to flush the controller to 752 * AUX IRQ was never delivered so we need to flush the controller to
751 * get rid of the byte we put there; otherwise keyboard may not work. 753 * get rid of the byte we put there; otherwise keyboard may not work.
752 */ 754 */
755 dbg(" -- i8042 (aux irq test timeout)");
753 i8042_flush(); 756 i8042_flush();
754 retval = -1; 757 retval = -1;
755 } 758 }
diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c
index 769ba65a585a..f3876acc3e83 100644
--- a/drivers/input/serio/libps2.c
+++ b/drivers/input/serio/libps2.c
@@ -13,6 +13,7 @@
13 13
14#include <linux/delay.h> 14#include <linux/delay.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/sched.h>
16#include <linux/slab.h> 17#include <linux/slab.h>
17#include <linux/interrupt.h> 18#include <linux/interrupt.h>
18#include <linux/input.h> 19#include <linux/input.h>
diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c
index b03009bb7468..27fdaaffbb40 100644
--- a/drivers/input/serio/serio_raw.c
+++ b/drivers/input/serio/serio_raw.c
@@ -9,6 +9,7 @@
9 * the Free Software Foundation. 9 * the Free Software Foundation.
10 */ 10 */
11 11
12#include <linux/sched.h>
12#include <linux/slab.h> 13#include <linux/slab.h>
13#include <linux/smp_lock.h> 14#include <linux/smp_lock.h>
14#include <linux/poll.h> 15#include <linux/poll.h>
diff --git a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c
index b9694b6445d0..6d345112bcb7 100644
--- a/drivers/input/serio/serport.c
+++ b/drivers/input/serio/serport.c
@@ -15,6 +15,7 @@
15 15
16#include <asm/uaccess.h> 16#include <asm/uaccess.h>
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/sched.h>
18#include <linux/slab.h> 19#include <linux/slab.h>
19#include <linux/module.h> 20#include <linux/module.h>
20#include <linux/init.h> 21#include <linux/init.h>
diff --git a/drivers/input/touchscreen/ad7879.c b/drivers/input/touchscreen/ad7879.c
index f06332c9e21b..c21e6d3a8844 100644
--- a/drivers/input/touchscreen/ad7879.c
+++ b/drivers/input/touchscreen/ad7879.c
@@ -645,7 +645,7 @@ static int __devinit ad7879_probe(struct spi_device *spi)
645 kfree(ts); 645 kfree(ts);
646 } 646 }
647 647
648 return 0; 648 return error;
649} 649}
650 650
651static int __devexit ad7879_remove(struct spi_device *spi) 651static int __devexit ad7879_remove(struct spi_device *spi)
@@ -732,7 +732,7 @@ static int __devinit ad7879_probe(struct i2c_client *client,
732 kfree(ts); 732 kfree(ts);
733 } 733 }
734 734
735 return 0; 735 return error;
736} 736}
737 737
738static int __devexit ad7879_remove(struct i2c_client *client) 738static int __devexit ad7879_remove(struct i2c_client *client)
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c
index 2d8352419c0d..65bf91e16a42 100644
--- a/drivers/isdn/capi/capi.c
+++ b/drivers/isdn/capi/capi.c
@@ -603,7 +603,7 @@ static void capi_recv_message(struct capi20_appl *ap, struct sk_buff *skb)
603 603
604 if (CAPIMSG_CMD(skb->data) == CAPI_CONNECT_B3_CONF) { 604 if (CAPIMSG_CMD(skb->data) == CAPI_CONNECT_B3_CONF) {
605 u16 info = CAPIMSG_U16(skb->data, 12); // Info field 605 u16 info = CAPIMSG_U16(skb->data, 12); // Info field
606 if (info == 0) { 606 if ((info & 0xff00) == 0) {
607 mutex_lock(&cdev->ncci_list_mtx); 607 mutex_lock(&cdev->ncci_list_mtx);
608 capincci_alloc(cdev, CAPIMSG_NCCI(skb->data)); 608 capincci_alloc(cdev, CAPIMSG_NCCI(skb->data));
609 mutex_unlock(&cdev->ncci_list_mtx); 609 mutex_unlock(&cdev->ncci_list_mtx);
diff --git a/drivers/isdn/capi/capidrv.c b/drivers/isdn/capi/capidrv.c
index 650120261abf..3e6d17f42a98 100644
--- a/drivers/isdn/capi/capidrv.c
+++ b/drivers/isdn/capi/capidrv.c
@@ -40,7 +40,7 @@ static int debugmode = 0;
40MODULE_DESCRIPTION("CAPI4Linux: Interface to ISDN4Linux"); 40MODULE_DESCRIPTION("CAPI4Linux: Interface to ISDN4Linux");
41MODULE_AUTHOR("Carsten Paeth"); 41MODULE_AUTHOR("Carsten Paeth");
42MODULE_LICENSE("GPL"); 42MODULE_LICENSE("GPL");
43module_param(debugmode, uint, 0); 43module_param(debugmode, uint, S_IRUGO|S_IWUSR);
44 44
45/* -------- type definitions ----------------------------------------- */ 45/* -------- type definitions ----------------------------------------- */
46 46
@@ -671,8 +671,8 @@ static void n0(capidrv_contr * card, capidrv_ncci * ncci)
671 NULL, /* Useruserdata */ /* $$$$ */ 671 NULL, /* Useruserdata */ /* $$$$ */
672 NULL /* Facilitydataarray */ 672 NULL /* Facilitydataarray */
673 ); 673 );
674 send_message(card, &cmsg);
675 plci_change_state(card, ncci->plcip, EV_PLCI_DISCONNECT_REQ); 674 plci_change_state(card, ncci->plcip, EV_PLCI_DISCONNECT_REQ);
675 send_message(card, &cmsg);
676 676
677 cmd.command = ISDN_STAT_BHUP; 677 cmd.command = ISDN_STAT_BHUP;
678 cmd.driver = card->myid; 678 cmd.driver = card->myid;
@@ -924,8 +924,8 @@ static void handle_incoming_call(capidrv_contr * card, _cmsg * cmsg)
924 */ 924 */
925 capi_cmsg_answer(cmsg); 925 capi_cmsg_answer(cmsg);
926 cmsg->Reject = 1; /* ignore */ 926 cmsg->Reject = 1; /* ignore */
927 send_message(card, cmsg);
928 plci_change_state(card, plcip, EV_PLCI_CONNECT_REJECT); 927 plci_change_state(card, plcip, EV_PLCI_CONNECT_REJECT);
928 send_message(card, cmsg);
929 printk(KERN_INFO "capidrv-%d: incoming call %s,%d,%d,%s ignored\n", 929 printk(KERN_INFO "capidrv-%d: incoming call %s,%d,%d,%s ignored\n",
930 card->contrnr, 930 card->contrnr,
931 cmd.parm.setup.phone, 931 cmd.parm.setup.phone,
@@ -974,8 +974,8 @@ static void handle_incoming_call(capidrv_contr * card, _cmsg * cmsg)
974 case 2: /* Call will be rejected. */ 974 case 2: /* Call will be rejected. */
975 capi_cmsg_answer(cmsg); 975 capi_cmsg_answer(cmsg);
976 cmsg->Reject = 2; /* reject call, normal call clearing */ 976 cmsg->Reject = 2; /* reject call, normal call clearing */
977 send_message(card, cmsg);
978 plci_change_state(card, plcip, EV_PLCI_CONNECT_REJECT); 977 plci_change_state(card, plcip, EV_PLCI_CONNECT_REJECT);
978 send_message(card, cmsg);
979 break; 979 break;
980 980
981 default: 981 default:
@@ -983,8 +983,8 @@ static void handle_incoming_call(capidrv_contr * card, _cmsg * cmsg)
983 capi_cmsg_answer(cmsg); 983 capi_cmsg_answer(cmsg);
984 cmsg->Reject = 8; /* reject call, 984 cmsg->Reject = 8; /* reject call,
985 destination out of order */ 985 destination out of order */
986 send_message(card, cmsg);
987 plci_change_state(card, plcip, EV_PLCI_CONNECT_REJECT); 986 plci_change_state(card, plcip, EV_PLCI_CONNECT_REJECT);
987 send_message(card, cmsg);
988 break; 988 break;
989 } 989 }
990 return; 990 return;
@@ -1020,8 +1020,8 @@ static void handle_plci(_cmsg * cmsg)
1020 card->bchans[plcip->chan].disconnecting = 1; 1020 card->bchans[plcip->chan].disconnecting = 1;
1021 plci_change_state(card, plcip, EV_PLCI_DISCONNECT_IND); 1021 plci_change_state(card, plcip, EV_PLCI_DISCONNECT_IND);
1022 capi_cmsg_answer(cmsg); 1022 capi_cmsg_answer(cmsg);
1023 send_message(card, cmsg);
1024 plci_change_state(card, plcip, EV_PLCI_DISCONNECT_RESP); 1023 plci_change_state(card, plcip, EV_PLCI_DISCONNECT_RESP);
1024 send_message(card, cmsg);
1025 break; 1025 break;
1026 1026
1027 case CAPI_DISCONNECT_CONF: /* plci */ 1027 case CAPI_DISCONNECT_CONF: /* plci */
@@ -1078,8 +1078,8 @@ static void handle_plci(_cmsg * cmsg)
1078 1078
1079 if (card->bchans[plcip->chan].incoming) { 1079 if (card->bchans[plcip->chan].incoming) {
1080 capi_cmsg_answer(cmsg); 1080 capi_cmsg_answer(cmsg);
1081 send_message(card, cmsg);
1082 plci_change_state(card, plcip, EV_PLCI_CONNECT_ACTIVE_IND); 1081 plci_change_state(card, plcip, EV_PLCI_CONNECT_ACTIVE_IND);
1082 send_message(card, cmsg);
1083 } else { 1083 } else {
1084 capidrv_ncci *nccip; 1084 capidrv_ncci *nccip;
1085 capi_cmsg_answer(cmsg); 1085 capi_cmsg_answer(cmsg);
@@ -1098,13 +1098,14 @@ static void handle_plci(_cmsg * cmsg)
1098 NULL /* NCPI */ 1098 NULL /* NCPI */
1099 ); 1099 );
1100 nccip->msgid = cmsg->Messagenumber; 1100 nccip->msgid = cmsg->Messagenumber;
1101 plci_change_state(card, plcip,
1102 EV_PLCI_CONNECT_ACTIVE_IND);
1103 ncci_change_state(card, nccip, EV_NCCI_CONNECT_B3_REQ);
1101 send_message(card, cmsg); 1104 send_message(card, cmsg);
1102 cmd.command = ISDN_STAT_DCONN; 1105 cmd.command = ISDN_STAT_DCONN;
1103 cmd.driver = card->myid; 1106 cmd.driver = card->myid;
1104 cmd.arg = plcip->chan; 1107 cmd.arg = plcip->chan;
1105 card->interface.statcallb(&cmd); 1108 card->interface.statcallb(&cmd);
1106 plci_change_state(card, plcip, EV_PLCI_CONNECT_ACTIVE_IND);
1107 ncci_change_state(card, nccip, EV_NCCI_CONNECT_B3_REQ);
1108 } 1109 }
1109 break; 1110 break;
1110 1111
@@ -1193,8 +1194,8 @@ static void handle_ncci(_cmsg * cmsg)
1193 goto notfound; 1194 goto notfound;
1194 1195
1195 capi_cmsg_answer(cmsg); 1196 capi_cmsg_answer(cmsg);
1196 send_message(card, cmsg);
1197 ncci_change_state(card, nccip, EV_NCCI_CONNECT_B3_ACTIVE_IND); 1197 ncci_change_state(card, nccip, EV_NCCI_CONNECT_B3_ACTIVE_IND);
1198 send_message(card, cmsg);
1198 1199
1199 cmd.command = ISDN_STAT_BCONN; 1200 cmd.command = ISDN_STAT_BCONN;
1200 cmd.driver = card->myid; 1201 cmd.driver = card->myid;
@@ -1222,8 +1223,8 @@ static void handle_ncci(_cmsg * cmsg)
1222 0, /* Reject */ 1223 0, /* Reject */
1223 NULL /* NCPI */ 1224 NULL /* NCPI */
1224 ); 1225 );
1225 send_message(card, cmsg);
1226 ncci_change_state(card, nccip, EV_NCCI_CONNECT_B3_RESP); 1226 ncci_change_state(card, nccip, EV_NCCI_CONNECT_B3_RESP);
1227 send_message(card, cmsg);
1227 break; 1228 break;
1228 } 1229 }
1229 printk(KERN_ERR "capidrv-%d: no mem for ncci, sorry\n", card->contrnr); 1230 printk(KERN_ERR "capidrv-%d: no mem for ncci, sorry\n", card->contrnr);
@@ -1299,8 +1300,8 @@ static void handle_ncci(_cmsg * cmsg)
1299 card->bchans[nccip->chan].disconnecting = 1; 1300 card->bchans[nccip->chan].disconnecting = 1;
1300 ncci_change_state(card, nccip, EV_NCCI_DISCONNECT_B3_IND); 1301 ncci_change_state(card, nccip, EV_NCCI_DISCONNECT_B3_IND);
1301 capi_cmsg_answer(cmsg); 1302 capi_cmsg_answer(cmsg);
1302 send_message(card, cmsg);
1303 ncci_change_state(card, nccip, EV_NCCI_DISCONNECT_B3_RESP); 1303 ncci_change_state(card, nccip, EV_NCCI_DISCONNECT_B3_RESP);
1304 send_message(card, cmsg);
1304 break; 1305 break;
1305 1306
1306 case CAPI_DISCONNECT_B3_CONF: /* ncci */ 1307 case CAPI_DISCONNECT_B3_CONF: /* ncci */
@@ -2014,8 +2015,8 @@ static void send_listen(capidrv_contr *card)
2014 card->cipmask, 2015 card->cipmask,
2015 card->cipmask2, 2016 card->cipmask2,
2016 NULL, NULL); 2017 NULL, NULL);
2017 send_message(card, &cmdcmsg);
2018 listen_change_state(card, EV_LISTEN_REQ); 2018 listen_change_state(card, EV_LISTEN_REQ);
2019 send_message(card, &cmdcmsg);
2019} 2020}
2020 2021
2021static void listentimerfunc(unsigned long x) 2022static void listentimerfunc(unsigned long x)
diff --git a/drivers/isdn/capi/kcapi.c b/drivers/isdn/capi/kcapi.c
index 57d26360f64e..dc506ab99cac 100644
--- a/drivers/isdn/capi/kcapi.c
+++ b/drivers/isdn/capi/kcapi.c
@@ -18,6 +18,7 @@
18#include <linux/interrupt.h> 18#include <linux/interrupt.h>
19#include <linux/ioport.h> 19#include <linux/ioport.h>
20#include <linux/proc_fs.h> 20#include <linux/proc_fs.h>
21#include <linux/sched.h>
21#include <linux/seq_file.h> 22#include <linux/seq_file.h>
22#include <linux/skbuff.h> 23#include <linux/skbuff.h>
23#include <linux/workqueue.h> 24#include <linux/workqueue.h>
diff --git a/drivers/isdn/divert/divert_procfs.c b/drivers/isdn/divert/divert_procfs.c
index 8b256a617c8a..3697c409bec6 100644
--- a/drivers/isdn/divert/divert_procfs.c
+++ b/drivers/isdn/divert/divert_procfs.c
@@ -16,6 +16,7 @@
16#else 16#else
17#include <linux/fs.h> 17#include <linux/fs.h>
18#endif 18#endif
19#include <linux/sched.h>
19#include <linux/isdnif.h> 20#include <linux/isdnif.h>
20#include <net/net_namespace.h> 21#include <net/net_namespace.h>
21#include "isdn_divert.h" 22#include "isdn_divert.h"
diff --git a/drivers/isdn/gigaset/asyncdata.c b/drivers/isdn/gigaset/asyncdata.c
index 234cc5d53312..44a58e6f8f65 100644
--- a/drivers/isdn/gigaset/asyncdata.c
+++ b/drivers/isdn/gigaset/asyncdata.c
@@ -334,7 +334,14 @@ static inline int iraw_loop(unsigned char c, unsigned char *src, int numbytes,
334 return startbytes - numbytes; 334 return startbytes - numbytes;
335} 335}
336 336
337/* process a block of data received from the device 337/**
338 * gigaset_m10x_input() - process a block of data received from the device
339 * @inbuf: received data and device descriptor structure.
340 *
341 * Called by hardware module {ser,usb}_gigaset with a block of received
342 * bytes. Separates the bytes received over the serial data channel into
343 * user data and command replies (locked/unlocked) according to the
344 * current state of the interface.
338 */ 345 */
339void gigaset_m10x_input(struct inbuf_t *inbuf) 346void gigaset_m10x_input(struct inbuf_t *inbuf)
340{ 347{
@@ -543,16 +550,17 @@ static struct sk_buff *iraw_encode(struct sk_buff *skb, int head, int tail)
543 return iraw_skb; 550 return iraw_skb;
544} 551}
545 552
546/* gigaset_send_skb 553/**
547 * called by common.c to queue an skb for sending 554 * gigaset_m10x_send_skb() - queue an skb for sending
548 * and start transmission if necessary 555 * @bcs: B channel descriptor structure.
549 * parameters: 556 * @skb: data to send.
550 * B Channel control structure 557 *
551 * skb 558 * Called by i4l.c to encode and queue an skb for sending, and start
559 * transmission if necessary.
560 *
552 * Return value: 561 * Return value:
553 * number of bytes accepted for sending 562 * number of bytes accepted for sending (skb->len) if ok,
554 * (skb->len if ok, 0 if out of buffer space) 563 * error code < 0 (eg. -ENOMEM) on error
555 * or error code (< 0, eg. -EINVAL)
556 */ 564 */
557int gigaset_m10x_send_skb(struct bc_state *bcs, struct sk_buff *skb) 565int gigaset_m10x_send_skb(struct bc_state *bcs, struct sk_buff *skb)
558{ 566{
diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c
index 781c4041f7b0..5ed1d99eb9f3 100644
--- a/drivers/isdn/gigaset/bas-gigaset.c
+++ b/drivers/isdn/gigaset/bas-gigaset.c
@@ -134,6 +134,7 @@ struct bas_cardstate {
134#define BS_ATRDPEND 0x040 /* urb_cmd_in in use */ 134#define BS_ATRDPEND 0x040 /* urb_cmd_in in use */
135#define BS_ATWRPEND 0x080 /* urb_cmd_out in use */ 135#define BS_ATWRPEND 0x080 /* urb_cmd_out in use */
136#define BS_SUSPEND 0x100 /* USB port suspended */ 136#define BS_SUSPEND 0x100 /* USB port suspended */
137#define BS_RESETTING 0x200 /* waiting for HD_RESET_INTERRUPT_PIPE_ACK */
137 138
138 139
139static struct gigaset_driver *driver = NULL; 140static struct gigaset_driver *driver = NULL;
@@ -319,6 +320,21 @@ static int gigaset_set_line_ctrl(struct cardstate *cs, unsigned cflag)
319 return -EINVAL; 320 return -EINVAL;
320} 321}
321 322
323/* set/clear bits in base connection state, return previous state
324 */
325static inline int update_basstate(struct bas_cardstate *ucs,
326 int set, int clear)
327{
328 unsigned long flags;
329 int state;
330
331 spin_lock_irqsave(&ucs->lock, flags);
332 state = ucs->basstate;
333 ucs->basstate = (state & ~clear) | set;
334 spin_unlock_irqrestore(&ucs->lock, flags);
335 return state;
336}
337
322/* error_hangup 338/* error_hangup
323 * hang up any existing connection because of an unrecoverable error 339 * hang up any existing connection because of an unrecoverable error
324 * This function may be called from any context and takes care of scheduling 340 * This function may be called from any context and takes care of scheduling
@@ -350,12 +366,9 @@ static inline void error_hangup(struct bc_state *bcs)
350 */ 366 */
351static inline void error_reset(struct cardstate *cs) 367static inline void error_reset(struct cardstate *cs)
352{ 368{
353 /* close AT command channel to recover (ignore errors) */ 369 /* reset interrupt pipe to recover (ignore errors) */
354 req_submit(cs->bcs, HD_CLOSE_ATCHANNEL, 0, BAS_TIMEOUT); 370 update_basstate(cs->hw.bas, BS_RESETTING, 0);
355 371 req_submit(cs->bcs, HD_RESET_INTERRUPT_PIPE, 0, BAS_TIMEOUT);
356 //FIXME try to recover without bothering the user
357 dev_err(cs->dev,
358 "unrecoverable error - please disconnect Gigaset base to reset\n");
359} 372}
360 373
361/* check_pending 374/* check_pending
@@ -398,8 +411,13 @@ static void check_pending(struct bas_cardstate *ucs)
398 case HD_DEVICE_INIT_ACK: /* no reply expected */ 411 case HD_DEVICE_INIT_ACK: /* no reply expected */
399 ucs->pending = 0; 412 ucs->pending = 0;
400 break; 413 break;
401 /* HD_READ_ATMESSAGE, HD_WRITE_ATMESSAGE, HD_RESET_INTERRUPTPIPE 414 case HD_RESET_INTERRUPT_PIPE:
402 * are handled separately and should never end up here 415 if (!(ucs->basstate & BS_RESETTING))
416 ucs->pending = 0;
417 break;
418 /*
419 * HD_READ_ATMESSAGE and HD_WRITE_ATMESSAGE are handled separately
420 * and should never end up here
403 */ 421 */
404 default: 422 default:
405 dev_warn(&ucs->interface->dev, 423 dev_warn(&ucs->interface->dev,
@@ -449,21 +467,6 @@ static void cmd_in_timeout(unsigned long data)
449 error_reset(cs); 467 error_reset(cs);
450} 468}
451 469
452/* set/clear bits in base connection state, return previous state
453 */
454inline static int update_basstate(struct bas_cardstate *ucs,
455 int set, int clear)
456{
457 unsigned long flags;
458 int state;
459
460 spin_lock_irqsave(&ucs->lock, flags);
461 state = ucs->basstate;
462 ucs->basstate = (state & ~clear) | set;
463 spin_unlock_irqrestore(&ucs->lock, flags);
464 return state;
465}
466
467/* read_ctrl_callback 470/* read_ctrl_callback
468 * USB completion handler for control pipe input 471 * USB completion handler for control pipe input
469 * called by the USB subsystem in interrupt context 472 * called by the USB subsystem in interrupt context
@@ -762,7 +765,8 @@ static void read_int_callback(struct urb *urb)
762 break; 765 break;
763 766
764 case HD_RESET_INTERRUPT_PIPE_ACK: 767 case HD_RESET_INTERRUPT_PIPE_ACK:
765 gig_dbg(DEBUG_USBREQ, "HD_RESET_INTERRUPT_PIPE_ACK"); 768 update_basstate(ucs, 0, BS_RESETTING);
769 dev_notice(cs->dev, "interrupt pipe reset\n");
766 break; 770 break;
767 771
768 case HD_SUSPEND_END: 772 case HD_SUSPEND_END:
@@ -1331,28 +1335,24 @@ static void read_iso_tasklet(unsigned long data)
1331 rcvbuf = urb->transfer_buffer; 1335 rcvbuf = urb->transfer_buffer;
1332 totleft = urb->actual_length; 1336 totleft = urb->actual_length;
1333 for (frame = 0; totleft > 0 && frame < BAS_NUMFRAMES; frame++) { 1337 for (frame = 0; totleft > 0 && frame < BAS_NUMFRAMES; frame++) {
1334 if (unlikely(urb->iso_frame_desc[frame].status)) { 1338 numbytes = urb->iso_frame_desc[frame].actual_length;
1339 if (unlikely(urb->iso_frame_desc[frame].status))
1335 dev_warn(cs->dev, 1340 dev_warn(cs->dev,
1336 "isochronous read: frame %d: %s\n", 1341 "isochronous read: frame %d[%d]: %s\n",
1337 frame, 1342 frame, numbytes,
1338 get_usb_statmsg( 1343 get_usb_statmsg(
1339 urb->iso_frame_desc[frame].status)); 1344 urb->iso_frame_desc[frame].status));
1340 break; 1345 if (unlikely(numbytes > BAS_MAXFRAME))
1341 }
1342 numbytes = urb->iso_frame_desc[frame].actual_length;
1343 if (unlikely(numbytes > BAS_MAXFRAME)) {
1344 dev_warn(cs->dev, 1346 dev_warn(cs->dev,
1345 "isochronous read: frame %d: " 1347 "isochronous read: frame %d: "
1346 "numbytes (%d) > BAS_MAXFRAME\n", 1348 "numbytes (%d) > BAS_MAXFRAME\n",
1347 frame, numbytes); 1349 frame, numbytes);
1348 break;
1349 }
1350 if (unlikely(numbytes > totleft)) { 1350 if (unlikely(numbytes > totleft)) {
1351 dev_warn(cs->dev, 1351 dev_warn(cs->dev,
1352 "isochronous read: frame %d: " 1352 "isochronous read: frame %d: "
1353 "numbytes (%d) > totleft (%d)\n", 1353 "numbytes (%d) > totleft (%d)\n",
1354 frame, numbytes, totleft); 1354 frame, numbytes, totleft);
1355 break; 1355 numbytes = totleft;
1356 } 1356 }
1357 offset = urb->iso_frame_desc[frame].offset; 1357 offset = urb->iso_frame_desc[frame].offset;
1358 if (unlikely(offset + numbytes > BAS_INBUFSIZE)) { 1358 if (unlikely(offset + numbytes > BAS_INBUFSIZE)) {
@@ -1361,7 +1361,7 @@ static void read_iso_tasklet(unsigned long data)
1361 "offset (%d) + numbytes (%d) " 1361 "offset (%d) + numbytes (%d) "
1362 "> BAS_INBUFSIZE\n", 1362 "> BAS_INBUFSIZE\n",
1363 frame, offset, numbytes); 1363 frame, offset, numbytes);
1364 break; 1364 numbytes = BAS_INBUFSIZE - offset;
1365 } 1365 }
1366 gigaset_isoc_receive(rcvbuf + offset, numbytes, bcs); 1366 gigaset_isoc_receive(rcvbuf + offset, numbytes, bcs);
1367 totleft -= numbytes; 1367 totleft -= numbytes;
@@ -1433,6 +1433,7 @@ static void req_timeout(unsigned long data)
1433 1433
1434 case HD_CLOSE_ATCHANNEL: 1434 case HD_CLOSE_ATCHANNEL:
1435 dev_err(bcs->cs->dev, "timeout closing AT channel\n"); 1435 dev_err(bcs->cs->dev, "timeout closing AT channel\n");
1436 error_reset(bcs->cs);
1436 break; 1437 break;
1437 1438
1438 case HD_CLOSE_B2CHANNEL: 1439 case HD_CLOSE_B2CHANNEL:
@@ -1442,6 +1443,13 @@ static void req_timeout(unsigned long data)
1442 error_reset(bcs->cs); 1443 error_reset(bcs->cs);
1443 break; 1444 break;
1444 1445
1446 case HD_RESET_INTERRUPT_PIPE:
1447 /* error recovery escalation */
1448 dev_err(bcs->cs->dev,
1449 "reset interrupt pipe timeout, attempting USB reset\n");
1450 usb_queue_reset_device(bcs->cs->hw.bas->interface);
1451 break;
1452
1445 default: 1453 default:
1446 dev_warn(bcs->cs->dev, "request 0x%02x timed out, clearing\n", 1454 dev_warn(bcs->cs->dev, "request 0x%02x timed out, clearing\n",
1447 pending); 1455 pending);
@@ -1934,6 +1942,15 @@ static int gigaset_write_cmd(struct cardstate *cs,
1934 goto notqueued; 1942 goto notqueued;
1935 } 1943 }
1936 1944
1945 /* translate "+++" escape sequence sent as a single separate command
1946 * into "close AT channel" command for error recovery
1947 * The next command will reopen the AT channel automatically.
1948 */
1949 if (len == 3 && !memcmp(buf, "+++", 3)) {
1950 rc = req_submit(cs->bcs, HD_CLOSE_ATCHANNEL, 0, BAS_TIMEOUT);
1951 goto notqueued;
1952 }
1953
1937 if (len > IF_WRITEBUF) 1954 if (len > IF_WRITEBUF)
1938 len = IF_WRITEBUF; 1955 len = IF_WRITEBUF;
1939 if (!(cb = kmalloc(sizeof(struct cmdbuf_t) + len, GFP_ATOMIC))) { 1956 if (!(cb = kmalloc(sizeof(struct cmdbuf_t) + len, GFP_ATOMIC))) {
diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c
index e4141bf8b2f3..33dcd8d72b7c 100644
--- a/drivers/isdn/gigaset/common.c
+++ b/drivers/isdn/gigaset/common.c
@@ -22,6 +22,12 @@
22#define DRIVER_AUTHOR "Hansjoerg Lipp <hjlipp@web.de>, Tilman Schmidt <tilman@imap.cc>, Stefan Eilers" 22#define DRIVER_AUTHOR "Hansjoerg Lipp <hjlipp@web.de>, Tilman Schmidt <tilman@imap.cc>, Stefan Eilers"
23#define DRIVER_DESC "Driver for Gigaset 307x" 23#define DRIVER_DESC "Driver for Gigaset 307x"
24 24
25#ifdef CONFIG_GIGASET_DEBUG
26#define DRIVER_DESC_DEBUG " (debug build)"
27#else
28#define DRIVER_DESC_DEBUG ""
29#endif
30
25/* Module parameters */ 31/* Module parameters */
26int gigaset_debuglevel = DEBUG_DEFAULT; 32int gigaset_debuglevel = DEBUG_DEFAULT;
27EXPORT_SYMBOL_GPL(gigaset_debuglevel); 33EXPORT_SYMBOL_GPL(gigaset_debuglevel);
@@ -32,6 +38,17 @@ MODULE_PARM_DESC(debug, "debug level");
32#define VALID_MINOR 0x01 38#define VALID_MINOR 0x01
33#define VALID_ID 0x02 39#define VALID_ID 0x02
34 40
41/**
42 * gigaset_dbg_buffer() - dump data in ASCII and hex for debugging
43 * @level: debugging level.
44 * @msg: message prefix.
45 * @len: number of bytes to dump.
46 * @buf: data to dump.
47 *
48 * If the current debugging level includes one of the bits set in @level,
49 * @len bytes starting at @buf are logged to dmesg at KERN_DEBUG prio,
50 * prefixed by the text @msg.
51 */
35void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg, 52void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg,
36 size_t len, const unsigned char *buf) 53 size_t len, const unsigned char *buf)
37{ 54{
@@ -274,6 +291,20 @@ static void clear_events(struct cardstate *cs)
274 spin_unlock_irqrestore(&cs->ev_lock, flags); 291 spin_unlock_irqrestore(&cs->ev_lock, flags);
275} 292}
276 293
294/**
295 * gigaset_add_event() - add event to device event queue
296 * @cs: device descriptor structure.
297 * @at_state: connection state structure.
298 * @type: event type.
299 * @ptr: pointer parameter for event.
300 * @parameter: integer parameter for event.
301 * @arg: pointer parameter for event.
302 *
303 * Allocate an event queue entry from the device's event queue, and set it up
304 * with the parameters given.
305 *
306 * Return value: added event
307 */
277struct event_t *gigaset_add_event(struct cardstate *cs, 308struct event_t *gigaset_add_event(struct cardstate *cs,
278 struct at_state_t *at_state, int type, 309 struct at_state_t *at_state, int type,
279 void *ptr, int parameter, void *arg) 310 void *ptr, int parameter, void *arg)
@@ -398,6 +429,15 @@ static void make_invalid(struct cardstate *cs, unsigned mask)
398 spin_unlock_irqrestore(&drv->lock, flags); 429 spin_unlock_irqrestore(&drv->lock, flags);
399} 430}
400 431
432/**
433 * gigaset_freecs() - free all associated ressources of a device
434 * @cs: device descriptor structure.
435 *
436 * Stops all tasklets and timers, unregisters the device from all
437 * subsystems it was registered to, deallocates the device structure
438 * @cs and all structures referenced from it.
439 * Operations on the device should be stopped before calling this.
440 */
401void gigaset_freecs(struct cardstate *cs) 441void gigaset_freecs(struct cardstate *cs)
402{ 442{
403 int i; 443 int i;
@@ -506,7 +546,12 @@ static void gigaset_inbuf_init(struct inbuf_t *inbuf, struct bc_state *bcs,
506 inbuf->inputstate = inputstate; 546 inbuf->inputstate = inputstate;
507} 547}
508 548
509/* append received bytes to inbuf */ 549/**
550 * gigaset_fill_inbuf() - append received data to input buffer
551 * @inbuf: buffer structure.
552 * @src: received data.
553 * @numbytes: number of bytes received.
554 */
510int gigaset_fill_inbuf(struct inbuf_t *inbuf, const unsigned char *src, 555int gigaset_fill_inbuf(struct inbuf_t *inbuf, const unsigned char *src,
511 unsigned numbytes) 556 unsigned numbytes)
512{ 557{
@@ -606,20 +651,22 @@ static struct bc_state *gigaset_initbcs(struct bc_state *bcs,
606 return NULL; 651 return NULL;
607} 652}
608 653
609/* gigaset_initcs 654/**
655 * gigaset_initcs() - initialize device structure
656 * @drv: hardware driver the device belongs to
657 * @channels: number of B channels supported by device
658 * @onechannel: !=0 if B channel data and AT commands share one
659 * communication channel (M10x),
660 * ==0 if B channels have separate communication channels (base)
661 * @ignoreframes: number of frames to ignore after setting up B channel
662 * @cidmode: !=0: start in CallID mode
663 * @modulename: name of driver module for LL registration
664 *
610 * Allocate and initialize cardstate structure for Gigaset driver 665 * Allocate and initialize cardstate structure for Gigaset driver
611 * Calls hardware dependent gigaset_initcshw() function 666 * Calls hardware dependent gigaset_initcshw() function
612 * Calls B channel initialization function gigaset_initbcs() for each B channel 667 * Calls B channel initialization function gigaset_initbcs() for each B channel
613 * parameters: 668 *
614 * drv hardware driver the device belongs to 669 * Return value:
615 * channels number of B channels supported by device
616 * onechannel !=0: B channel data and AT commands share one
617 * communication channel
618 * ==0: B channels have separate communication channels
619 * ignoreframes number of frames to ignore after setting up B channel
620 * cidmode !=0: start in CallID mode
621 * modulename name of driver module (used for I4L registration)
622 * return value:
623 * pointer to cardstate structure 670 * pointer to cardstate structure
624 */ 671 */
625struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, 672struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels,
@@ -837,6 +884,17 @@ static void cleanup_cs(struct cardstate *cs)
837} 884}
838 885
839 886
887/**
888 * gigaset_start() - start device operations
889 * @cs: device descriptor structure.
890 *
891 * Prepares the device for use by setting up communication parameters,
892 * scheduling an EV_START event to initiate device initialization, and
893 * waiting for completion of the initialization.
894 *
895 * Return value:
896 * 1 - success, 0 - error
897 */
840int gigaset_start(struct cardstate *cs) 898int gigaset_start(struct cardstate *cs)
841{ 899{
842 unsigned long flags; 900 unsigned long flags;
@@ -879,9 +937,15 @@ error:
879} 937}
880EXPORT_SYMBOL_GPL(gigaset_start); 938EXPORT_SYMBOL_GPL(gigaset_start);
881 939
882/* gigaset_shutdown 940/**
883 * check if a device is associated to the cardstate structure and stop it 941 * gigaset_shutdown() - shut down device operations
884 * return value: 0 if ok, -1 if no device was associated 942 * @cs: device descriptor structure.
943 *
944 * Deactivates the device by scheduling an EV_SHUTDOWN event and
945 * waiting for completion of the shutdown.
946 *
947 * Return value:
948 * 0 - success, -1 - error (no device associated)
885 */ 949 */
886int gigaset_shutdown(struct cardstate *cs) 950int gigaset_shutdown(struct cardstate *cs)
887{ 951{
@@ -912,6 +976,13 @@ exit:
912} 976}
913EXPORT_SYMBOL_GPL(gigaset_shutdown); 977EXPORT_SYMBOL_GPL(gigaset_shutdown);
914 978
979/**
980 * gigaset_stop() - stop device operations
981 * @cs: device descriptor structure.
982 *
983 * Stops operations on the device by scheduling an EV_STOP event and
984 * waiting for completion of the shutdown.
985 */
915void gigaset_stop(struct cardstate *cs) 986void gigaset_stop(struct cardstate *cs)
916{ 987{
917 mutex_lock(&cs->mutex); 988 mutex_lock(&cs->mutex);
@@ -1020,6 +1091,14 @@ struct cardstate *gigaset_get_cs_by_tty(struct tty_struct *tty)
1020 return gigaset_get_cs_by_minor(tty->index + tty->driver->minor_start); 1091 return gigaset_get_cs_by_minor(tty->index + tty->driver->minor_start);
1021} 1092}
1022 1093
1094/**
1095 * gigaset_freedriver() - free all associated ressources of a driver
1096 * @drv: driver descriptor structure.
1097 *
1098 * Unregisters the driver from the system and deallocates the driver
1099 * structure @drv and all structures referenced from it.
1100 * All devices should be shut down before calling this.
1101 */
1023void gigaset_freedriver(struct gigaset_driver *drv) 1102void gigaset_freedriver(struct gigaset_driver *drv)
1024{ 1103{
1025 unsigned long flags; 1104 unsigned long flags;
@@ -1035,14 +1114,16 @@ void gigaset_freedriver(struct gigaset_driver *drv)
1035} 1114}
1036EXPORT_SYMBOL_GPL(gigaset_freedriver); 1115EXPORT_SYMBOL_GPL(gigaset_freedriver);
1037 1116
1038/* gigaset_initdriver 1117/**
1118 * gigaset_initdriver() - initialize driver structure
1119 * @minor: First minor number
1120 * @minors: Number of minors this driver can handle
1121 * @procname: Name of the driver
1122 * @devname: Name of the device files (prefix without minor number)
1123 *
1039 * Allocate and initialize gigaset_driver structure. Initialize interface. 1124 * Allocate and initialize gigaset_driver structure. Initialize interface.
1040 * parameters: 1125 *
1041 * minor First minor number 1126 * Return value:
1042 * minors Number of minors this driver can handle
1043 * procname Name of the driver
1044 * devname Name of the device files (prefix without minor number)
1045 * return value:
1046 * Pointer to the gigaset_driver structure on success, NULL on failure. 1127 * Pointer to the gigaset_driver structure on success, NULL on failure.
1047 */ 1128 */
1048struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors, 1129struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors,
@@ -1095,6 +1176,13 @@ error:
1095} 1176}
1096EXPORT_SYMBOL_GPL(gigaset_initdriver); 1177EXPORT_SYMBOL_GPL(gigaset_initdriver);
1097 1178
1179/**
1180 * gigaset_blockdriver() - block driver
1181 * @drv: driver descriptor structure.
1182 *
1183 * Prevents the driver from attaching new devices, in preparation for
1184 * deregistration.
1185 */
1098void gigaset_blockdriver(struct gigaset_driver *drv) 1186void gigaset_blockdriver(struct gigaset_driver *drv)
1099{ 1187{
1100 drv->blocked = 1; 1188 drv->blocked = 1;
@@ -1110,7 +1198,7 @@ static int __init gigaset_init_module(void)
1110 if (gigaset_debuglevel == 1) 1198 if (gigaset_debuglevel == 1)
1111 gigaset_debuglevel = DEBUG_DEFAULT; 1199 gigaset_debuglevel = DEBUG_DEFAULT;
1112 1200
1113 pr_info(DRIVER_DESC "\n"); 1201 pr_info(DRIVER_DESC DRIVER_DESC_DEBUG "\n");
1114 return 0; 1202 return 0;
1115} 1203}
1116 1204
diff --git a/drivers/isdn/gigaset/ev-layer.c b/drivers/isdn/gigaset/ev-layer.c
index 2d91049571a4..cc768caa38f5 100644
--- a/drivers/isdn/gigaset/ev-layer.c
+++ b/drivers/isdn/gigaset/ev-layer.c
@@ -207,7 +207,6 @@ struct reply_t gigaset_tab_nocid[] =
207 /* leave dle mode */ 207 /* leave dle mode */
208 {RSP_INIT, 0, 0,SEQ_DLE0, 201, 5, {0}, "^SDLE=0\r"}, 208 {RSP_INIT, 0, 0,SEQ_DLE0, 201, 5, {0}, "^SDLE=0\r"},
209 {RSP_OK, 201,201, -1, 202,-1}, 209 {RSP_OK, 201,201, -1, 202,-1},
210 //{RSP_ZDLE, 202,202, 0, 202, 0, {ACT_ERROR}},//DELETE
211 {RSP_ZDLE, 202,202, 0, 0, 0, {ACT_DLE0}}, 210 {RSP_ZDLE, 202,202, 0, 0, 0, {ACT_DLE0}},
212 {RSP_NODEV, 200,249, -1, 0, 0, {ACT_FAKEDLE0}}, 211 {RSP_NODEV, 200,249, -1, 0, 0, {ACT_FAKEDLE0}},
213 {RSP_ERROR, 200,249, -1, 0, 0, {ACT_FAILDLE0}}, 212 {RSP_ERROR, 200,249, -1, 0, 0, {ACT_FAILDLE0}},
@@ -265,6 +264,7 @@ struct reply_t gigaset_tab_nocid[] =
265 {EV_SHUTDOWN, -1, -1, -1, -1,-1, {ACT_SHUTDOWN}}, //FIXME 264 {EV_SHUTDOWN, -1, -1, -1, -1,-1, {ACT_SHUTDOWN}}, //FIXME
266 265
267 /* misc. */ 266 /* misc. */
267 {RSP_ERROR, -1, -1, -1, -1, -1, {ACT_ERROR} },
268 {RSP_EMPTY, -1, -1, -1, -1,-1, {ACT_DEBUG}}, //FIXME 268 {RSP_EMPTY, -1, -1, -1, -1,-1, {ACT_DEBUG}}, //FIXME
269 {RSP_ZCFGT, -1, -1, -1, -1,-1, {ACT_DEBUG}}, //FIXME 269 {RSP_ZCFGT, -1, -1, -1, -1,-1, {ACT_DEBUG}}, //FIXME
270 {RSP_ZCFG, -1, -1, -1, -1,-1, {ACT_DEBUG}}, //FIXME 270 {RSP_ZCFG, -1, -1, -1, -1,-1, {ACT_DEBUG}}, //FIXME
@@ -328,10 +328,9 @@ struct reply_t gigaset_tab_cid[] =
328 {RSP_INIT, -1, -1,SEQ_HUP, 401, 5, {0}, "+VLS=0\r"}, /* hang up */ //-1,-1? 328 {RSP_INIT, -1, -1,SEQ_HUP, 401, 5, {0}, "+VLS=0\r"}, /* hang up */ //-1,-1?
329 {RSP_OK, 401,401, -1, 402, 5}, 329 {RSP_OK, 401,401, -1, 402, 5},
330 {RSP_ZVLS, 402,402, 0, 403, 5}, 330 {RSP_ZVLS, 402,402, 0, 403, 5},
331 {RSP_ZSAU, 403,403,ZSAU_DISCONNECT_REQ, -1,-1, {ACT_DEBUG}}, /* if not remote hup */ 331 {RSP_ZSAU, 403, 403, ZSAU_DISCONNECT_REQ, -1, -1, {ACT_DEBUG} },
332 //{RSP_ZSAU, 403,403,ZSAU_NULL, 401, 0, {ACT_ERROR}}, //DELETE//FIXME -> DLE0 // should we do this _before_ hanging up for base driver? 332 {RSP_ZSAU, 403, 403, ZSAU_NULL, 0, 0, {ACT_DISCONNECT} },
333 {RSP_ZSAU, 403,403,ZSAU_NULL, 0, 0, {ACT_DISCONNECT}}, //FIXME -> DLE0 // should we do this _before_ hanging up for base driver? 333 {RSP_NODEV, 401, 403, -1, 0, 0, {ACT_FAKEHUP} },
334 {RSP_NODEV, 401,403, -1, 0, 0, {ACT_FAKEHUP}}, //FIXME -> DLE0 // should we do this _before_ hanging up for base driver?
335 {RSP_ERROR, 401,401, -1, 0, 0, {ACT_ABORTHUP}}, 334 {RSP_ERROR, 401,401, -1, 0, 0, {ACT_ABORTHUP}},
336 {EV_TIMEOUT, 401,403, -1, 0, 0, {ACT_ABORTHUP}}, 335 {EV_TIMEOUT, 401,403, -1, 0, 0, {ACT_ABORTHUP}},
337 336
@@ -474,8 +473,13 @@ static int cid_of_response(char *s)
474 //FIXME is ;<digit>+ at end of non-CID response really impossible? 473 //FIXME is ;<digit>+ at end of non-CID response really impossible?
475} 474}
476 475
477/* This function will be called via task queue from the callback handler. 476/**
478 * We received a modem response and have to handle it.. 477 * gigaset_handle_modem_response() - process received modem response
478 * @cs: device descriptor structure.
479 *
480 * Called by asyncdata/isocdata if a block of data received from the
481 * device must be processed as a modem command response. The data is
482 * already in the cs structure.
479 */ 483 */
480void gigaset_handle_modem_response(struct cardstate *cs) 484void gigaset_handle_modem_response(struct cardstate *cs)
481{ 485{
@@ -707,6 +711,11 @@ static void disconnect(struct at_state_t **at_state_p)
707 if (bcs) { 711 if (bcs) {
708 /* B channel assigned: invoke hardware specific handler */ 712 /* B channel assigned: invoke hardware specific handler */
709 cs->ops->close_bchannel(bcs); 713 cs->ops->close_bchannel(bcs);
714 /* notify LL */
715 if (bcs->chstate & (CHS_D_UP | CHS_NOTIFY_LL)) {
716 bcs->chstate &= ~(CHS_D_UP | CHS_NOTIFY_LL);
717 gigaset_i4l_channel_cmd(bcs, ISDN_STAT_DHUP);
718 }
710 } else { 719 } else {
711 /* no B channel assigned: just deallocate */ 720 /* no B channel assigned: just deallocate */
712 spin_lock_irqsave(&cs->lock, flags); 721 spin_lock_irqsave(&cs->lock, flags);
@@ -1429,11 +1438,12 @@ static void do_action(int action, struct cardstate *cs,
1429 cs->gotfwver = -1; 1438 cs->gotfwver = -1;
1430 dev_err(cs->dev, "could not read firmware version.\n"); 1439 dev_err(cs->dev, "could not read firmware version.\n");
1431 break; 1440 break;
1432#ifdef CONFIG_GIGASET_DEBUG
1433 case ACT_ERROR: 1441 case ACT_ERROR:
1434 *p_genresp = 1; 1442 gig_dbg(DEBUG_ANY, "%s: ERROR response in ConState %d",
1435 *p_resp_code = RSP_ERROR; 1443 __func__, at_state->ConState);
1444 cs->cur_at_seq = SEQ_NONE;
1436 break; 1445 break;
1446#ifdef CONFIG_GIGASET_DEBUG
1437 case ACT_TEST: 1447 case ACT_TEST:
1438 { 1448 {
1439 static int count = 3; //2; //1; 1449 static int count = 3; //2; //1;
diff --git a/drivers/isdn/gigaset/i4l.c b/drivers/isdn/gigaset/i4l.c
index 9b22f9cf2f33..654489d836cd 100644
--- a/drivers/isdn/gigaset/i4l.c
+++ b/drivers/isdn/gigaset/i4l.c
@@ -51,6 +51,12 @@ static int writebuf_from_LL(int driverID, int channel, int ack,
51 return -ENODEV; 51 return -ENODEV;
52 } 52 }
53 bcs = &cs->bcs[channel]; 53 bcs = &cs->bcs[channel];
54
55 /* can only handle linear sk_buffs */
56 if (skb_linearize(skb) < 0) {
57 dev_err(cs->dev, "%s: skb_linearize failed\n", __func__);
58 return -ENOMEM;
59 }
54 len = skb->len; 60 len = skb->len;
55 61
56 gig_dbg(DEBUG_LLDATA, 62 gig_dbg(DEBUG_LLDATA,
@@ -79,6 +85,14 @@ static int writebuf_from_LL(int driverID, int channel, int ack,
79 return cs->ops->send_skb(bcs, skb); 85 return cs->ops->send_skb(bcs, skb);
80} 86}
81 87
88/**
89 * gigaset_skb_sent() - acknowledge sending an skb
90 * @bcs: B channel descriptor structure.
91 * @skb: sent data.
92 *
93 * Called by hardware module {bas,ser,usb}_gigaset when the data in a
94 * skb has been successfully sent, for signalling completion to the LL.
95 */
82void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb) 96void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb)
83{ 97{
84 unsigned len; 98 unsigned len;
@@ -455,6 +469,15 @@ int gigaset_isdn_setup_accept(struct at_state_t *at_state)
455 return 0; 469 return 0;
456} 470}
457 471
472/**
473 * gigaset_isdn_icall() - signal incoming call
474 * @at_state: connection state structure.
475 *
476 * Called by main module to notify the LL that an incoming call has been
477 * received. @at_state contains the parameters of the call.
478 *
479 * Return value: call disposition (ICALL_*)
480 */
458int gigaset_isdn_icall(struct at_state_t *at_state) 481int gigaset_isdn_icall(struct at_state_t *at_state)
459{ 482{
460 struct cardstate *cs = at_state->cs; 483 struct cardstate *cs = at_state->cs;
diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c
index f33ac27de643..6a8e1384e7bd 100644
--- a/drivers/isdn/gigaset/interface.c
+++ b/drivers/isdn/gigaset/interface.c
@@ -616,6 +616,15 @@ void gigaset_if_free(struct cardstate *cs)
616 tty_unregister_device(drv->tty, cs->minor_index); 616 tty_unregister_device(drv->tty, cs->minor_index);
617} 617}
618 618
619/**
620 * gigaset_if_receive() - pass a received block of data to the tty device
621 * @cs: device descriptor structure.
622 * @buffer: received data.
623 * @len: number of bytes received.
624 *
625 * Called by asyncdata/isocdata if a block of data received from the
626 * device must be sent to userspace through the ttyG* device.
627 */
619void gigaset_if_receive(struct cardstate *cs, 628void gigaset_if_receive(struct cardstate *cs,
620 unsigned char *buffer, size_t len) 629 unsigned char *buffer, size_t len)
621{ 630{
diff --git a/drivers/isdn/gigaset/isocdata.c b/drivers/isdn/gigaset/isocdata.c
index bed38fcc432b..9f3ef7b4248c 100644
--- a/drivers/isdn/gigaset/isocdata.c
+++ b/drivers/isdn/gigaset/isocdata.c
@@ -429,7 +429,7 @@ static inline int hdlc_buildframe(struct isowbuf_t *iwb,
429 return -EAGAIN; 429 return -EAGAIN;
430 } 430 }
431 431
432 dump_bytes(DEBUG_STREAM, "snd data", in, count); 432 dump_bytes(DEBUG_STREAM_DUMP, "snd data", in, count);
433 433
434 /* bitstuff and checksum input data */ 434 /* bitstuff and checksum input data */
435 fcs = PPP_INITFCS; 435 fcs = PPP_INITFCS;
@@ -448,7 +448,6 @@ static inline int hdlc_buildframe(struct isowbuf_t *iwb,
448 /* put closing flag and repeat byte for flag idle */ 448 /* put closing flag and repeat byte for flag idle */
449 isowbuf_putflag(iwb); 449 isowbuf_putflag(iwb);
450 end = isowbuf_donewrite(iwb); 450 end = isowbuf_donewrite(iwb);
451 dump_bytes(DEBUG_STREAM_DUMP, "isowbuf", iwb->data, end + 1);
452 return end; 451 return end;
453} 452}
454 453
@@ -482,6 +481,8 @@ static inline int trans_buildframe(struct isowbuf_t *iwb,
482 } 481 }
483 482
484 gig_dbg(DEBUG_STREAM, "put %d bytes", count); 483 gig_dbg(DEBUG_STREAM, "put %d bytes", count);
484 dump_bytes(DEBUG_STREAM_DUMP, "snd data", in, count);
485
485 write = iwb->write; 486 write = iwb->write;
486 do { 487 do {
487 c = bitrev8(*in++); 488 c = bitrev8(*in++);
@@ -583,7 +584,7 @@ static inline void hdlc_done(struct bc_state *bcs)
583 procskb->tail -= 2; 584 procskb->tail -= 2;
584 gig_dbg(DEBUG_ISO, "%s: good frame (%d octets)", 585 gig_dbg(DEBUG_ISO, "%s: good frame (%d octets)",
585 __func__, procskb->len); 586 __func__, procskb->len);
586 dump_bytes(DEBUG_STREAM, 587 dump_bytes(DEBUG_STREAM_DUMP,
587 "rcv data", procskb->data, procskb->len); 588 "rcv data", procskb->data, procskb->len);
588 bcs->hw.bas->goodbytes += procskb->len; 589 bcs->hw.bas->goodbytes += procskb->len;
589 gigaset_rcv_skb(procskb, bcs->cs, bcs); 590 gigaset_rcv_skb(procskb, bcs->cs, bcs);
@@ -878,6 +879,8 @@ static inline void trans_receive(unsigned char *src, unsigned count,
878 dobytes--; 879 dobytes--;
879 } 880 }
880 if (dobytes == 0) { 881 if (dobytes == 0) {
882 dump_bytes(DEBUG_STREAM_DUMP,
883 "rcv data", skb->data, skb->len);
881 gigaset_rcv_skb(skb, bcs->cs, bcs); 884 gigaset_rcv_skb(skb, bcs->cs, bcs);
882 bcs->skb = skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN); 885 bcs->skb = skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN);
883 if (!skb) { 886 if (!skb) {
@@ -973,16 +976,17 @@ void gigaset_isoc_input(struct inbuf_t *inbuf)
973 976
974/* == data output ========================================================== */ 977/* == data output ========================================================== */
975 978
976/* gigaset_send_skb 979/**
977 * called by common.c to queue an skb for sending 980 * gigaset_isoc_send_skb() - queue an skb for sending
978 * and start transmission if necessary 981 * @bcs: B channel descriptor structure.
979 * parameters: 982 * @skb: data to send.
980 * B Channel control structure 983 *
981 * skb 984 * Called by i4l.c to queue an skb for sending, and start transmission if
982 * return value: 985 * necessary.
983 * number of bytes accepted for sending 986 *
984 * (skb->len if ok, 0 if out of buffer space) 987 * Return value:
985 * or error code (< 0, eg. -EINVAL) 988 * number of bytes accepted for sending (skb->len) if ok,
989 * error code < 0 (eg. -ENODEV) on error
986 */ 990 */
987int gigaset_isoc_send_skb(struct bc_state *bcs, struct sk_buff *skb) 991int gigaset_isoc_send_skb(struct bc_state *bcs, struct sk_buff *skb)
988{ 992{
diff --git a/drivers/isdn/hisax/arcofi.c b/drivers/isdn/hisax/arcofi.c
index d30ce5b978c2..85a8fd8dd0b7 100644
--- a/drivers/isdn/hisax/arcofi.c
+++ b/drivers/isdn/hisax/arcofi.c
@@ -10,6 +10,7 @@
10 * 10 *
11 */ 11 */
12 12
13#include <linux/sched.h>
13#include "hisax.h" 14#include "hisax.h"
14#include "isdnl1.h" 15#include "isdnl1.h"
15#include "isac.h" 16#include "isac.h"
diff --git a/drivers/isdn/hisax/hfc_2bds0.c b/drivers/isdn/hisax/hfc_2bds0.c
index 5c46a7130e06..8d22f50760eb 100644
--- a/drivers/isdn/hisax/hfc_2bds0.c
+++ b/drivers/isdn/hisax/hfc_2bds0.c
@@ -11,6 +11,7 @@
11 */ 11 */
12 12
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/sched.h>
14#include "hisax.h" 15#include "hisax.h"
15#include "hfc_2bds0.h" 16#include "hfc_2bds0.h"
16#include "isdnl1.h" 17#include "isdnl1.h"
diff --git a/drivers/isdn/hisax/hfc_pci.c b/drivers/isdn/hisax/hfc_pci.c
index d110a77940a4..10914731b304 100644
--- a/drivers/isdn/hisax/hfc_pci.c
+++ b/drivers/isdn/hisax/hfc_pci.c
@@ -20,6 +20,7 @@
20#include "hfc_pci.h" 20#include "hfc_pci.h"
21#include "isdnl1.h" 21#include "isdnl1.h"
22#include <linux/pci.h> 22#include <linux/pci.h>
23#include <linux/sched.h>
23#include <linux/interrupt.h> 24#include <linux/interrupt.h>
24 25
25static const char *hfcpci_revision = "$Revision: 1.48.2.4 $"; 26static const char *hfcpci_revision = "$Revision: 1.48.2.4 $";
diff --git a/drivers/isdn/hysdn/hysdn_procconf.c b/drivers/isdn/hysdn/hysdn_procconf.c
index 8f9f4912de32..90b35e1a4b7e 100644
--- a/drivers/isdn/hysdn/hysdn_procconf.c
+++ b/drivers/isdn/hysdn/hysdn_procconf.c
@@ -11,6 +11,7 @@
11 * 11 *
12 */ 12 */
13 13
14#include <linux/cred.h>
14#include <linux/module.h> 15#include <linux/module.h>
15#include <linux/poll.h> 16#include <linux/poll.h>
16#include <linux/proc_fs.h> 17#include <linux/proc_fs.h>
diff --git a/drivers/isdn/hysdn/hysdn_proclog.c b/drivers/isdn/hysdn/hysdn_proclog.c
index 8991d2c8ee4a..8bcae28c4409 100644
--- a/drivers/isdn/hysdn/hysdn_proclog.c
+++ b/drivers/isdn/hysdn/hysdn_proclog.c
@@ -13,6 +13,7 @@
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/poll.h> 14#include <linux/poll.h>
15#include <linux/proc_fs.h> 15#include <linux/proc_fs.h>
16#include <linux/sched.h>
16#include <linux/smp_lock.h> 17#include <linux/smp_lock.h>
17 18
18#include "hysdn_defs.h" 19#include "hysdn_defs.h"
diff --git a/drivers/isdn/mISDN/socket.c b/drivers/isdn/mISDN/socket.c
index c36f52137456..feb0fa45b664 100644
--- a/drivers/isdn/mISDN/socket.c
+++ b/drivers/isdn/mISDN/socket.c
@@ -415,7 +415,7 @@ data_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
415} 415}
416 416
417static int data_sock_setsockopt(struct socket *sock, int level, int optname, 417static int data_sock_setsockopt(struct socket *sock, int level, int optname,
418 char __user *optval, int len) 418 char __user *optval, unsigned int len)
419{ 419{
420 struct sock *sk = sock->sk; 420 struct sock *sk = sock->sk;
421 int err = 0, opt = 0; 421 int err = 0, opt = 0;
diff --git a/drivers/isdn/pcbit/drv.c b/drivers/isdn/pcbit/drv.c
index 8c66bcb953a1..123c1d6c43b4 100644
--- a/drivers/isdn/pcbit/drv.c
+++ b/drivers/isdn/pcbit/drv.c
@@ -23,6 +23,7 @@
23#include <linux/kernel.h> 23#include <linux/kernel.h>
24 24
25#include <linux/types.h> 25#include <linux/types.h>
26#include <linux/sched.h>
26#include <linux/slab.h> 27#include <linux/slab.h>
27#include <linux/mm.h> 28#include <linux/mm.h>
28#include <linux/interrupt.h> 29#include <linux/interrupt.h>
diff --git a/drivers/isdn/pcbit/layer2.c b/drivers/isdn/pcbit/layer2.c
index e075e8d2fce0..30f0f45e3139 100644
--- a/drivers/isdn/pcbit/layer2.c
+++ b/drivers/isdn/pcbit/layer2.c
@@ -27,6 +27,7 @@
27#include <linux/string.h> 27#include <linux/string.h>
28#include <linux/kernel.h> 28#include <linux/kernel.h>
29#include <linux/types.h> 29#include <linux/types.h>
30#include <linux/sched.h>
30#include <linux/slab.h> 31#include <linux/slab.h>
31#include <linux/interrupt.h> 32#include <linux/interrupt.h>
32#include <linux/workqueue.h> 33#include <linux/workqueue.h>
diff --git a/drivers/isdn/sc/init.c b/drivers/isdn/sc/init.c
index dd0acd06750b..5a0774880d56 100644
--- a/drivers/isdn/sc/init.c
+++ b/drivers/isdn/sc/init.c
@@ -8,6 +8,7 @@
8#include <linux/init.h> 8#include <linux/init.h>
9#include <linux/interrupt.h> 9#include <linux/interrupt.h>
10#include <linux/delay.h> 10#include <linux/delay.h>
11#include <linux/sched.h>
11#include "includes.h" 12#include "includes.h"
12#include "hardware.h" 13#include "hardware.h"
13#include "card.h" 14#include "card.h"
diff --git a/drivers/leds/leds-pca9532.c b/drivers/leds/leds-pca9532.c
index 708a8017c21d..adc561eb59d2 100644
--- a/drivers/leds/leds-pca9532.c
+++ b/drivers/leds/leds-pca9532.c
@@ -19,9 +19,6 @@
19#include <linux/workqueue.h> 19#include <linux/workqueue.h>
20#include <linux/leds-pca9532.h> 20#include <linux/leds-pca9532.h>
21 21
22static const unsigned short normal_i2c[] = { /*0x60,*/ I2C_CLIENT_END};
23I2C_CLIENT_INSMOD_1(pca9532);
24
25#define PCA9532_REG_PSC(i) (0x2+(i)*2) 22#define PCA9532_REG_PSC(i) (0x2+(i)*2)
26#define PCA9532_REG_PWM(i) (0x3+(i)*2) 23#define PCA9532_REG_PWM(i) (0x3+(i)*2)
27#define PCA9532_REG_LS0 0x6 24#define PCA9532_REG_LS0 0x6
diff --git a/drivers/lguest/interrupts_and_traps.c b/drivers/lguest/interrupts_and_traps.c
index 18648180db02..daaf86631647 100644
--- a/drivers/lguest/interrupts_and_traps.c
+++ b/drivers/lguest/interrupts_and_traps.c
@@ -16,6 +16,7 @@
16#include <linux/uaccess.h> 16#include <linux/uaccess.h>
17#include <linux/interrupt.h> 17#include <linux/interrupt.h>
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/sched.h>
19#include "lg.h" 20#include "lg.h"
20 21
21/* Allow Guests to use a non-128 (ie. non-Linux) syscall trap. */ 22/* Allow Guests to use a non-128 (ie. non-Linux) syscall trap. */
diff --git a/drivers/lguest/lguest_user.c b/drivers/lguest/lguest_user.c
index b4d3f7ca554f..bd1632388e4a 100644
--- a/drivers/lguest/lguest_user.c
+++ b/drivers/lguest/lguest_user.c
@@ -508,7 +508,7 @@ static int close(struct inode *inode, struct file *file)
508 * uses: reading and writing a character device called /dev/lguest. All the 508 * uses: reading and writing a character device called /dev/lguest. All the
509 * work happens in the read(), write() and close() routines: 509 * work happens in the read(), write() and close() routines:
510 */ 510 */
511static struct file_operations lguest_fops = { 511static const struct file_operations lguest_fops = {
512 .owner = THIS_MODULE, 512 .owner = THIS_MODULE,
513 .release = close, 513 .release = close,
514 .write = write, 514 .write = write,
diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c
index fde377c60cca..556f0feaa4df 100644
--- a/drivers/macintosh/therm_adt746x.c
+++ b/drivers/macintosh/therm_adt746x.c
@@ -124,6 +124,8 @@ read_reg(struct thermostat* th, int reg)
124 return data; 124 return data;
125} 125}
126 126
127static struct i2c_driver thermostat_driver;
128
127static int 129static int
128attach_thermostat(struct i2c_adapter *adapter) 130attach_thermostat(struct i2c_adapter *adapter)
129{ 131{
@@ -148,7 +150,7 @@ attach_thermostat(struct i2c_adapter *adapter)
148 * Let i2c-core delete that device on driver removal. 150 * Let i2c-core delete that device on driver removal.
149 * This is safe because i2c-core holds the core_lock mutex for us. 151 * This is safe because i2c-core holds the core_lock mutex for us.
150 */ 152 */
151 list_add_tail(&client->detected, &client->driver->clients); 153 list_add_tail(&client->detected, &thermostat_driver.clients);
152 return 0; 154 return 0;
153} 155}
154 156
diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c
index a028598af2d3..ea32c7e5a9af 100644
--- a/drivers/macintosh/therm_pm72.c
+++ b/drivers/macintosh/therm_pm72.c
@@ -286,6 +286,8 @@ struct fcu_fan_table fcu_fans[] = {
286 }, 286 },
287}; 287};
288 288
289static struct i2c_driver therm_pm72_driver;
290
289/* 291/*
290 * Utility function to create an i2c_client structure and 292 * Utility function to create an i2c_client structure and
291 * attach it to one of u3 adapters 293 * attach it to one of u3 adapters
@@ -318,7 +320,7 @@ static struct i2c_client *attach_i2c_chip(int id, const char *name)
318 * Let i2c-core delete that device on driver removal. 320 * Let i2c-core delete that device on driver removal.
319 * This is safe because i2c-core holds the core_lock mutex for us. 321 * This is safe because i2c-core holds the core_lock mutex for us.
320 */ 322 */
321 list_add_tail(&clt->detected, &clt->driver->clients); 323 list_add_tail(&clt->detected, &therm_pm72_driver.clients);
322 return clt; 324 return clt;
323} 325}
324 326
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
index b40fb9b6c862..6f308a4757ee 100644
--- a/drivers/macintosh/via-pmu.c
+++ b/drivers/macintosh/via-pmu.c
@@ -405,7 +405,11 @@ static int __init via_pmu_start(void)
405 printk(KERN_ERR "via-pmu: can't map interrupt\n"); 405 printk(KERN_ERR "via-pmu: can't map interrupt\n");
406 return -ENODEV; 406 return -ENODEV;
407 } 407 }
408 if (request_irq(irq, via_pmu_interrupt, 0, "VIA-PMU", (void *)0)) { 408 /* We set IRQF_TIMER because we don't want the interrupt to be disabled
409 * between the 2 passes of driver suspend, we control our own disabling
410 * for that one
411 */
412 if (request_irq(irq, via_pmu_interrupt, IRQF_TIMER, "VIA-PMU", (void *)0)) {
409 printk(KERN_ERR "via-pmu: can't request irq %d\n", irq); 413 printk(KERN_ERR "via-pmu: can't request irq %d\n", irq);
410 return -ENODEV; 414 return -ENODEV;
411 } 415 }
@@ -419,7 +423,7 @@ static int __init via_pmu_start(void)
419 gpio_irq = irq_of_parse_and_map(gpio_node, 0); 423 gpio_irq = irq_of_parse_and_map(gpio_node, 0);
420 424
421 if (gpio_irq != NO_IRQ) { 425 if (gpio_irq != NO_IRQ) {
422 if (request_irq(gpio_irq, gpio1_interrupt, 0, 426 if (request_irq(gpio_irq, gpio1_interrupt, IRQF_TIMER,
423 "GPIO1 ADB", (void *)0)) 427 "GPIO1 ADB", (void *)0))
424 printk(KERN_ERR "pmu: can't get irq %d" 428 printk(KERN_ERR "pmu: can't get irq %d"
425 " (GPIO1)\n", gpio_irq); 429 " (GPIO1)\n", gpio_irq);
@@ -925,8 +929,7 @@ proc_write_options(struct file *file, const char __user *buffer,
925 929
926#ifdef CONFIG_ADB 930#ifdef CONFIG_ADB
927/* Send an ADB command */ 931/* Send an ADB command */
928static int 932static int pmu_send_request(struct adb_request *req, int sync)
929pmu_send_request(struct adb_request *req, int sync)
930{ 933{
931 int i, ret; 934 int i, ret;
932 935
@@ -1005,16 +1008,11 @@ pmu_send_request(struct adb_request *req, int sync)
1005} 1008}
1006 1009
1007/* Enable/disable autopolling */ 1010/* Enable/disable autopolling */
1008static int 1011static int __pmu_adb_autopoll(int devs)
1009pmu_adb_autopoll(int devs)
1010{ 1012{
1011 struct adb_request req; 1013 struct adb_request req;
1012 1014
1013 if ((vias == NULL) || (!pmu_fully_inited) || !pmu_has_adb)
1014 return -ENXIO;
1015
1016 if (devs) { 1015 if (devs) {
1017 adb_dev_map = devs;
1018 pmu_request(&req, NULL, 5, PMU_ADB_CMD, 0, 0x86, 1016 pmu_request(&req, NULL, 5, PMU_ADB_CMD, 0, 0x86,
1019 adb_dev_map >> 8, adb_dev_map); 1017 adb_dev_map >> 8, adb_dev_map);
1020 pmu_adb_flags = 2; 1018 pmu_adb_flags = 2;
@@ -1027,9 +1025,17 @@ pmu_adb_autopoll(int devs)
1027 return 0; 1025 return 0;
1028} 1026}
1029 1027
1028static int pmu_adb_autopoll(int devs)
1029{
1030 if ((vias == NULL) || (!pmu_fully_inited) || !pmu_has_adb)
1031 return -ENXIO;
1032
1033 adb_dev_map = devs;
1034 return __pmu_adb_autopoll(devs);
1035}
1036
1030/* Reset the ADB bus */ 1037/* Reset the ADB bus */
1031static int 1038static int pmu_adb_reset_bus(void)
1032pmu_adb_reset_bus(void)
1033{ 1039{
1034 struct adb_request req; 1040 struct adb_request req;
1035 int save_autopoll = adb_dev_map; 1041 int save_autopoll = adb_dev_map;
@@ -1038,13 +1044,13 @@ pmu_adb_reset_bus(void)
1038 return -ENXIO; 1044 return -ENXIO;
1039 1045
1040 /* anyone got a better idea?? */ 1046 /* anyone got a better idea?? */
1041 pmu_adb_autopoll(0); 1047 __pmu_adb_autopoll(0);
1042 1048
1043 req.nbytes = 5; 1049 req.nbytes = 4;
1044 req.done = NULL; 1050 req.done = NULL;
1045 req.data[0] = PMU_ADB_CMD; 1051 req.data[0] = PMU_ADB_CMD;
1046 req.data[1] = 0; 1052 req.data[1] = ADB_BUSRESET;
1047 req.data[2] = ADB_BUSRESET; 1053 req.data[2] = 0;
1048 req.data[3] = 0; 1054 req.data[3] = 0;
1049 req.data[4] = 0; 1055 req.data[4] = 0;
1050 req.reply_len = 0; 1056 req.reply_len = 0;
@@ -1056,7 +1062,7 @@ pmu_adb_reset_bus(void)
1056 pmu_wait_complete(&req); 1062 pmu_wait_complete(&req);
1057 1063
1058 if (save_autopoll != 0) 1064 if (save_autopoll != 0)
1059 pmu_adb_autopoll(save_autopoll); 1065 __pmu_adb_autopoll(save_autopoll);
1060 1066
1061 return 0; 1067 return 0;
1062} 1068}
diff --git a/drivers/macintosh/windfarm_lm75_sensor.c b/drivers/macintosh/windfarm_lm75_sensor.c
index 529886c7a826..ed6426a10773 100644
--- a/drivers/macintosh/windfarm_lm75_sensor.c
+++ b/drivers/macintosh/windfarm_lm75_sensor.c
@@ -115,6 +115,8 @@ static int wf_lm75_probe(struct i2c_client *client,
115 return rc; 115 return rc;
116} 116}
117 117
118static struct i2c_driver wf_lm75_driver;
119
118static struct i2c_client *wf_lm75_create(struct i2c_adapter *adapter, 120static struct i2c_client *wf_lm75_create(struct i2c_adapter *adapter,
119 u8 addr, int ds1775, 121 u8 addr, int ds1775,
120 const char *loc) 122 const char *loc)
@@ -157,7 +159,7 @@ static struct i2c_client *wf_lm75_create(struct i2c_adapter *adapter,
157 * Let i2c-core delete that device on driver removal. 159 * Let i2c-core delete that device on driver removal.
158 * This is safe because i2c-core holds the core_lock mutex for us. 160 * This is safe because i2c-core holds the core_lock mutex for us.
159 */ 161 */
160 list_add_tail(&client->detected, &client->driver->clients); 162 list_add_tail(&client->detected, &wf_lm75_driver.clients);
161 return client; 163 return client;
162 fail: 164 fail:
163 return NULL; 165 return NULL;
diff --git a/drivers/macintosh/windfarm_max6690_sensor.c b/drivers/macintosh/windfarm_max6690_sensor.c
index e2a55ecda2b2..a67b349319e9 100644
--- a/drivers/macintosh/windfarm_max6690_sensor.c
+++ b/drivers/macintosh/windfarm_max6690_sensor.c
@@ -88,6 +88,8 @@ static int wf_max6690_probe(struct i2c_client *client,
88 return rc; 88 return rc;
89} 89}
90 90
91static struct i2c_driver wf_max6690_driver;
92
91static struct i2c_client *wf_max6690_create(struct i2c_adapter *adapter, 93static struct i2c_client *wf_max6690_create(struct i2c_adapter *adapter,
92 u8 addr, const char *loc) 94 u8 addr, const char *loc)
93{ 95{
@@ -119,7 +121,7 @@ static struct i2c_client *wf_max6690_create(struct i2c_adapter *adapter,
119 * Let i2c-core delete that device on driver removal. 121 * Let i2c-core delete that device on driver removal.
120 * This is safe because i2c-core holds the core_lock mutex for us. 122 * This is safe because i2c-core holds the core_lock mutex for us.
121 */ 123 */
122 list_add_tail(&client->detected, &client->driver->clients); 124 list_add_tail(&client->detected, &wf_max6690_driver.clients);
123 return client; 125 return client;
124 126
125 fail: 127 fail:
diff --git a/drivers/macintosh/windfarm_smu_sat.c b/drivers/macintosh/windfarm_smu_sat.c
index 5da729e58f99..e20330a28959 100644
--- a/drivers/macintosh/windfarm_smu_sat.c
+++ b/drivers/macintosh/windfarm_smu_sat.c
@@ -194,6 +194,8 @@ static struct wf_sensor_ops wf_sat_ops = {
194 .owner = THIS_MODULE, 194 .owner = THIS_MODULE,
195}; 195};
196 196
197static struct i2c_driver wf_sat_driver;
198
197static void wf_sat_create(struct i2c_adapter *adapter, struct device_node *dev) 199static void wf_sat_create(struct i2c_adapter *adapter, struct device_node *dev)
198{ 200{
199 struct i2c_board_info info; 201 struct i2c_board_info info;
@@ -222,7 +224,7 @@ static void wf_sat_create(struct i2c_adapter *adapter, struct device_node *dev)
222 * Let i2c-core delete that device on driver removal. 224 * Let i2c-core delete that device on driver removal.
223 * This is safe because i2c-core holds the core_lock mutex for us. 225 * This is safe because i2c-core holds the core_lock mutex for us.
224 */ 226 */
225 list_add_tail(&client->detected, &client->driver->clients); 227 list_add_tail(&client->detected, &wf_sat_driver.clients);
226} 228}
227 229
228static int wf_sat_probe(struct i2c_client *client, 230static int wf_sat_probe(struct i2c_client *client,
diff --git a/drivers/md/dm-log-userspace-transfer.c b/drivers/md/dm-log-userspace-transfer.c
index ba0edad2d048..54abf9e303b7 100644
--- a/drivers/md/dm-log-userspace-transfer.c
+++ b/drivers/md/dm-log-userspace-transfer.c
@@ -129,11 +129,13 @@ static int fill_pkg(struct cn_msg *msg, struct dm_ulog_request *tfr)
129 * This is the connector callback that delivers data 129 * This is the connector callback that delivers data
130 * that was sent from userspace. 130 * that was sent from userspace.
131 */ 131 */
132static void cn_ulog_callback(void *data) 132static void cn_ulog_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
133{ 133{
134 struct cn_msg *msg = (struct cn_msg *)data;
135 struct dm_ulog_request *tfr = (struct dm_ulog_request *)(msg + 1); 134 struct dm_ulog_request *tfr = (struct dm_ulog_request *)(msg + 1);
136 135
136 if (!cap_raised(nsp->eff_cap, CAP_SYS_ADMIN))
137 return;
138
137 spin_lock(&receiving_list_lock); 139 spin_lock(&receiving_list_lock);
138 if (msg->len == 0) 140 if (msg->len == 0)
139 fill_pkg(msg, NULL); 141 fill_pkg(msg, NULL);
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c
index 3750ff48cba1..c37790ad92d0 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.c
+++ b/drivers/media/dvb/dvb-core/dmxdev.c
@@ -20,6 +20,7 @@
20 * 20 *
21 */ 21 */
22 22
23#include <linux/sched.h>
23#include <linux/spinlock.h> 24#include <linux/spinlock.h>
24#include <linux/slab.h> 25#include <linux/slab.h>
25#include <linux/vmalloc.h> 26#include <linux/vmalloc.h>
@@ -1203,7 +1204,7 @@ static unsigned int dvb_dvr_poll(struct file *file, poll_table *wait)
1203 return mask; 1204 return mask;
1204} 1205}
1205 1206
1206static struct file_operations dvb_dvr_fops = { 1207static const struct file_operations dvb_dvr_fops = {
1207 .owner = THIS_MODULE, 1208 .owner = THIS_MODULE,
1208 .read = dvb_dvr_read, 1209 .read = dvb_dvr_read,
1209 .write = dvb_dvr_write, 1210 .write = dvb_dvr_write,
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c
index eef6d3616626..91c537bca8ad 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -21,6 +21,7 @@
21 * 21 *
22 */ 22 */
23 23
24#include <linux/sched.h>
24#include <linux/spinlock.h> 25#include <linux/spinlock.h>
25#include <linux/slab.h> 26#include <linux/slab.h>
26#include <linux/vmalloc.h> 27#include <linux/vmalloc.h>
diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c
index 8c9ae0a3a272..0241a7c5c34a 100644
--- a/drivers/media/dvb/dvb-core/dvb_net.c
+++ b/drivers/media/dvb/dvb-core/dvb_net.c
@@ -63,6 +63,7 @@
63#include <asm/uaccess.h> 63#include <asm/uaccess.h>
64#include <linux/crc32.h> 64#include <linux/crc32.h>
65#include <linux/mutex.h> 65#include <linux/mutex.h>
66#include <linux/sched.h>
66 67
67#include "dvb_demux.h" 68#include "dvb_demux.h"
68#include "dvb_net.h" 69#include "dvb_net.h"
diff --git a/drivers/media/dvb/firewire/firedtv-ci.c b/drivers/media/dvb/firewire/firedtv-ci.c
index eeb80d0ea3ff..853e04b7cb36 100644
--- a/drivers/media/dvb/firewire/firedtv-ci.c
+++ b/drivers/media/dvb/firewire/firedtv-ci.c
@@ -215,7 +215,7 @@ static unsigned int fdtv_ca_io_poll(struct file *file, poll_table *wait)
215 return POLLIN; 215 return POLLIN;
216} 216}
217 217
218static struct file_operations fdtv_ca_fops = { 218static const struct file_operations fdtv_ca_fops = {
219 .owner = THIS_MODULE, 219 .owner = THIS_MODULE,
220 .ioctl = dvb_generic_ioctl, 220 .ioctl = dvb_generic_ioctl,
221 .open = dvb_generic_open, 221 .open = dvb_generic_open,
diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c
index 8b1440136c45..482d0f3be5ff 100644
--- a/drivers/media/radio/radio-cadet.c
+++ b/drivers/media/radio/radio-cadet.c
@@ -38,6 +38,7 @@
38#include <linux/videodev2.h> /* V4L2 API defs */ 38#include <linux/videodev2.h> /* V4L2 API defs */
39#include <linux/param.h> 39#include <linux/param.h>
40#include <linux/pnp.h> 40#include <linux/pnp.h>
41#include <linux/sched.h>
41#include <linux/io.h> /* outb, outb_p */ 42#include <linux/io.h> /* outb, outb_p */
42#include <media/v4l2-device.h> 43#include <media/v4l2-device.h>
43#include <media/v4l2-ioctl.h> 44#include <media/v4l2-ioctl.h>
diff --git a/drivers/media/video/cpia.c b/drivers/media/video/cpia.c
index 43ab0adf3b61..2377313c041a 100644
--- a/drivers/media/video/cpia.c
+++ b/drivers/media/video/cpia.c
@@ -31,6 +31,7 @@
31#include <linux/init.h> 31#include <linux/init.h>
32#include <linux/fs.h> 32#include <linux/fs.h>
33#include <linux/vmalloc.h> 33#include <linux/vmalloc.h>
34#include <linux/sched.h>
34#include <linux/slab.h> 35#include <linux/slab.h>
35#include <linux/proc_fs.h> 36#include <linux/proc_fs.h>
36#include <linux/ctype.h> 37#include <linux/ctype.h>
diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c
index 4b1bc05a462c..01e1eefcf1eb 100644
--- a/drivers/media/video/meye.c
+++ b/drivers/media/video/meye.c
@@ -28,6 +28,7 @@
28 */ 28 */
29#include <linux/module.h> 29#include <linux/module.h>
30#include <linux/pci.h> 30#include <linux/pci.h>
31#include <linux/sched.h>
31#include <linux/init.h> 32#include <linux/init.h>
32#include <linux/videodev.h> 33#include <linux/videodev.h>
33#include <media/v4l2-common.h> 34#include <media/v4l2-common.h>
diff --git a/drivers/media/video/videobuf-core.c b/drivers/media/video/videobuf-core.c
index f1ccf98c0a6f..8e93c6f25c83 100644
--- a/drivers/media/video/videobuf-core.c
+++ b/drivers/media/video/videobuf-core.c
@@ -17,6 +17,7 @@
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/moduleparam.h> 18#include <linux/moduleparam.h>
19#include <linux/mm.h> 19#include <linux/mm.h>
20#include <linux/sched.h>
20#include <linux/slab.h> 21#include <linux/slab.h>
21#include <linux/interrupt.h> 22#include <linux/interrupt.h>
22 23
diff --git a/drivers/media/video/videobuf-dma-sg.c b/drivers/media/video/videobuf-dma-sg.c
index 53cdd67cebe1..032ebae0134a 100644
--- a/drivers/media/video/videobuf-dma-sg.c
+++ b/drivers/media/video/videobuf-dma-sg.c
@@ -21,6 +21,7 @@
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/module.h> 22#include <linux/module.h>
23#include <linux/moduleparam.h> 23#include <linux/moduleparam.h>
24#include <linux/sched.h>
24#include <linux/slab.h> 25#include <linux/slab.h>
25#include <linux/interrupt.h> 26#include <linux/interrupt.h>
26 27
diff --git a/drivers/message/fusion/mptlan.c b/drivers/message/fusion/mptlan.c
index bc2ec2182c00..34f3f36f819b 100644
--- a/drivers/message/fusion/mptlan.c
+++ b/drivers/message/fusion/mptlan.c
@@ -56,6 +56,7 @@
56#include <linux/init.h> 56#include <linux/init.h>
57#include <linux/module.h> 57#include <linux/module.h>
58#include <linux/fs.h> 58#include <linux/fs.h>
59#include <linux/sched.h>
59 60
60#define my_VERSION MPT_LINUX_VERSION_COMMON 61#define my_VERSION MPT_LINUX_VERSION_COMMON
61#define MYNAM "mptlan" 62#define MYNAM "mptlan"
diff --git a/drivers/mfd/ab3100-core.c b/drivers/mfd/ab3100-core.c
index 5447da16a170..613481028272 100644
--- a/drivers/mfd/ab3100-core.c
+++ b/drivers/mfd/ab3100-core.c
@@ -57,8 +57,6 @@
57 * The AB3100 is usually assigned address 0x48 (7-bit) 57 * The AB3100 is usually assigned address 0x48 (7-bit)
58 * The chip is defined in the platform i2c_board_data section. 58 * The chip is defined in the platform i2c_board_data section.
59 */ 59 */
60static unsigned short normal_i2c[] = { 0x48, I2C_CLIENT_END };
61I2C_CLIENT_INSMOD_1(ab3100);
62 60
63u8 ab3100_get_chip_type(struct ab3100 *ab3100) 61u8 ab3100_get_chip_type(struct ab3100 *ab3100)
64{ 62{
@@ -966,7 +964,7 @@ static int __exit ab3100_remove(struct i2c_client *client)
966} 964}
967 965
968static const struct i2c_device_id ab3100_id[] = { 966static const struct i2c_device_id ab3100_id[] = {
969 { "ab3100", ab3100 }, 967 { "ab3100", 0 },
970 { } 968 { }
971}; 969};
972MODULE_DEVICE_TABLE(i2c, ab3100_id); 970MODULE_DEVICE_TABLE(i2c, ab3100_id);
diff --git a/drivers/mfd/twl4030-core.c b/drivers/mfd/twl4030-core.c
index e424cf6d8e9e..e832e975da60 100644
--- a/drivers/mfd/twl4030-core.c
+++ b/drivers/mfd/twl4030-core.c
@@ -480,7 +480,6 @@ static int
480add_children(struct twl4030_platform_data *pdata, unsigned long features) 480add_children(struct twl4030_platform_data *pdata, unsigned long features)
481{ 481{
482 struct device *child; 482 struct device *child;
483 struct device *usb_transceiver = NULL;
484 483
485 if (twl_has_bci() && pdata->bci && !(features & TPS_SUBSET)) { 484 if (twl_has_bci() && pdata->bci && !(features & TPS_SUBSET)) {
486 child = add_child(3, "twl4030_bci", 485 child = add_child(3, "twl4030_bci",
@@ -532,16 +531,61 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features)
532 } 531 }
533 532
534 if (twl_has_usb() && pdata->usb) { 533 if (twl_has_usb() && pdata->usb) {
534
535 static struct regulator_consumer_supply usb1v5 = {
536 .supply = "usb1v5",
537 };
538 static struct regulator_consumer_supply usb1v8 = {
539 .supply = "usb1v8",
540 };
541 static struct regulator_consumer_supply usb3v1 = {
542 .supply = "usb3v1",
543 };
544
545 /* First add the regulators so that they can be used by transceiver */
546 if (twl_has_regulator()) {
547 /* this is a template that gets copied */
548 struct regulator_init_data usb_fixed = {
549 .constraints.valid_modes_mask =
550 REGULATOR_MODE_NORMAL
551 | REGULATOR_MODE_STANDBY,
552 .constraints.valid_ops_mask =
553 REGULATOR_CHANGE_MODE
554 | REGULATOR_CHANGE_STATUS,
555 };
556
557 child = add_regulator_linked(TWL4030_REG_VUSB1V5,
558 &usb_fixed, &usb1v5, 1);
559 if (IS_ERR(child))
560 return PTR_ERR(child);
561
562 child = add_regulator_linked(TWL4030_REG_VUSB1V8,
563 &usb_fixed, &usb1v8, 1);
564 if (IS_ERR(child))
565 return PTR_ERR(child);
566
567 child = add_regulator_linked(TWL4030_REG_VUSB3V1,
568 &usb_fixed, &usb3v1, 1);
569 if (IS_ERR(child))
570 return PTR_ERR(child);
571
572 }
573
535 child = add_child(0, "twl4030_usb", 574 child = add_child(0, "twl4030_usb",
536 pdata->usb, sizeof(*pdata->usb), 575 pdata->usb, sizeof(*pdata->usb),
537 true, 576 true,
538 /* irq0 = USB_PRES, irq1 = USB */ 577 /* irq0 = USB_PRES, irq1 = USB */
539 pdata->irq_base + 8 + 2, pdata->irq_base + 4); 578 pdata->irq_base + 8 + 2, pdata->irq_base + 4);
579
540 if (IS_ERR(child)) 580 if (IS_ERR(child))
541 return PTR_ERR(child); 581 return PTR_ERR(child);
542 582
543 /* we need to connect regulators to this transceiver */ 583 /* we need to connect regulators to this transceiver */
544 usb_transceiver = child; 584 if (twl_has_regulator() && child) {
585 usb1v5.dev = child;
586 usb1v8.dev = child;
587 usb3v1.dev = child;
588 }
545 } 589 }
546 590
547 if (twl_has_watchdog()) { 591 if (twl_has_watchdog()) {
@@ -580,47 +624,6 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features)
580 return PTR_ERR(child); 624 return PTR_ERR(child);
581 } 625 }
582 626
583 if (twl_has_regulator() && usb_transceiver) {
584 static struct regulator_consumer_supply usb1v5 = {
585 .supply = "usb1v5",
586 };
587 static struct regulator_consumer_supply usb1v8 = {
588 .supply = "usb1v8",
589 };
590 static struct regulator_consumer_supply usb3v1 = {
591 .supply = "usb3v1",
592 };
593
594 /* this is a template that gets copied */
595 struct regulator_init_data usb_fixed = {
596 .constraints.valid_modes_mask =
597 REGULATOR_MODE_NORMAL
598 | REGULATOR_MODE_STANDBY,
599 .constraints.valid_ops_mask =
600 REGULATOR_CHANGE_MODE
601 | REGULATOR_CHANGE_STATUS,
602 };
603
604 usb1v5.dev = usb_transceiver;
605 usb1v8.dev = usb_transceiver;
606 usb3v1.dev = usb_transceiver;
607
608 child = add_regulator_linked(TWL4030_REG_VUSB1V5, &usb_fixed,
609 &usb1v5, 1);
610 if (IS_ERR(child))
611 return PTR_ERR(child);
612
613 child = add_regulator_linked(TWL4030_REG_VUSB1V8, &usb_fixed,
614 &usb1v8, 1);
615 if (IS_ERR(child))
616 return PTR_ERR(child);
617
618 child = add_regulator_linked(TWL4030_REG_VUSB3V1, &usb_fixed,
619 &usb3v1, 1);
620 if (IS_ERR(child))
621 return PTR_ERR(child);
622 }
623
624 /* maybe add LDOs that are omitted on cost-reduced parts */ 627 /* maybe add LDOs that are omitted on cost-reduced parts */
625 if (twl_has_regulator() && !(features & TPS_SUBSET)) { 628 if (twl_has_regulator() && !(features & TPS_SUBSET)) {
626 child = add_regulator(TWL4030_REG_VPLL2, pdata->vpll2); 629 child = add_regulator(TWL4030_REG_VPLL2, pdata->vpll2);
diff --git a/drivers/mfd/ucb1400_core.c b/drivers/mfd/ucb1400_core.c
index 2afc08006e6d..fa294b6d600a 100644
--- a/drivers/mfd/ucb1400_core.c
+++ b/drivers/mfd/ucb1400_core.c
@@ -21,6 +21,7 @@
21 */ 21 */
22 22
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/sched.h>
24#include <linux/ucb1400.h> 25#include <linux/ucb1400.h>
25 26
26unsigned int ucb1400_adc_read(struct snd_ac97 *ac97, u16 adc_channel, 27unsigned int ucb1400_adc_read(struct snd_ac97 *ac97, u16 adc_channel,
diff --git a/drivers/mfd/ucb1x00-core.c b/drivers/mfd/ucb1x00-core.c
index fea9085fe52c..60c3988f3cf3 100644
--- a/drivers/mfd/ucb1x00-core.c
+++ b/drivers/mfd/ucb1x00-core.c
@@ -18,6 +18,7 @@
18 */ 18 */
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/kernel.h> 20#include <linux/kernel.h>
21#include <linux/sched.h>
21#include <linux/slab.h> 22#include <linux/slab.h>
22#include <linux/init.h> 23#include <linux/init.h>
23#include <linux/errno.h> 24#include <linux/errno.h>
diff --git a/drivers/misc/eeprom/max6875.c b/drivers/misc/eeprom/max6875.c
index 3c0c58eed347..5a6b2bce8ad5 100644
--- a/drivers/misc/eeprom/max6875.c
+++ b/drivers/misc/eeprom/max6875.c
@@ -33,12 +33,6 @@
33#include <linux/i2c.h> 33#include <linux/i2c.h>
34#include <linux/mutex.h> 34#include <linux/mutex.h>
35 35
36/* Do not scan - the MAX6875 access method will write to some EEPROM chips */
37static const unsigned short normal_i2c[] = { I2C_CLIENT_END };
38
39/* Insmod parameters */
40I2C_CLIENT_INSMOD_1(max6875);
41
42/* The MAX6875 can only read/write 16 bytes at a time */ 36/* The MAX6875 can only read/write 16 bytes at a time */
43#define SLICE_SIZE 16 37#define SLICE_SIZE 16
44#define SLICE_BITS 4 38#define SLICE_BITS 4
@@ -146,31 +140,21 @@ static struct bin_attribute user_eeprom_attr = {
146 .read = max6875_read, 140 .read = max6875_read,
147}; 141};
148 142
149/* Return 0 if detection is successful, -ENODEV otherwise */ 143static int max6875_probe(struct i2c_client *client,
150static int max6875_detect(struct i2c_client *client, int kind, 144 const struct i2c_device_id *id)
151 struct i2c_board_info *info)
152{ 145{
153 struct i2c_adapter *adapter = client->adapter; 146 struct i2c_adapter *adapter = client->adapter;
147 struct max6875_data *data;
148 int err;
154 149
155 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE_DATA 150 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE_DATA
156 | I2C_FUNC_SMBUS_READ_BYTE)) 151 | I2C_FUNC_SMBUS_READ_BYTE))
157 return -ENODEV; 152 return -ENODEV;
158 153
159 /* Only check even addresses */ 154 /* Only bind to even addresses */
160 if (client->addr & 1) 155 if (client->addr & 1)
161 return -ENODEV; 156 return -ENODEV;
162 157
163 strlcpy(info->type, "max6875", I2C_NAME_SIZE);
164
165 return 0;
166}
167
168static int max6875_probe(struct i2c_client *client,
169 const struct i2c_device_id *id)
170{
171 struct max6875_data *data;
172 int err;
173
174 if (!(data = kzalloc(sizeof(struct max6875_data), GFP_KERNEL))) 158 if (!(data = kzalloc(sizeof(struct max6875_data), GFP_KERNEL)))
175 return -ENOMEM; 159 return -ENOMEM;
176 160
@@ -222,9 +206,6 @@ static struct i2c_driver max6875_driver = {
222 .probe = max6875_probe, 206 .probe = max6875_probe,
223 .remove = max6875_remove, 207 .remove = max6875_remove,
224 .id_table = max6875_id, 208 .id_table = max6875_id,
225
226 .detect = max6875_detect,
227 .address_data = &addr_data,
228}; 209};
229 210
230static int __init max6875_init(void) 211static int __init max6875_init(void)
diff --git a/drivers/misc/hpilo.c b/drivers/misc/hpilo.c
index 1ad27c6abcca..a92a3a742b43 100644
--- a/drivers/misc/hpilo.c
+++ b/drivers/misc/hpilo.c
@@ -18,6 +18,7 @@
18#include <linux/device.h> 18#include <linux/device.h>
19#include <linux/file.h> 19#include <linux/file.h>
20#include <linux/cdev.h> 20#include <linux/cdev.h>
21#include <linux/sched.h>
21#include <linux/spinlock.h> 22#include <linux/spinlock.h>
22#include <linux/delay.h> 23#include <linux/delay.h>
23#include <linux/uaccess.h> 24#include <linux/uaccess.h>
diff --git a/drivers/misc/ibmasm/command.c b/drivers/misc/ibmasm/command.c
index 276d3fb68094..e2031739aa29 100644
--- a/drivers/misc/ibmasm/command.c
+++ b/drivers/misc/ibmasm/command.c
@@ -22,6 +22,7 @@
22 * 22 *
23 */ 23 */
24 24
25#include <linux/sched.h>
25#include "ibmasm.h" 26#include "ibmasm.h"
26#include "lowlevel.h" 27#include "lowlevel.h"
27 28
diff --git a/drivers/misc/ibmasm/event.c b/drivers/misc/ibmasm/event.c
index 68a0a5b94795..572d41ffc186 100644
--- a/drivers/misc/ibmasm/event.c
+++ b/drivers/misc/ibmasm/event.c
@@ -22,6 +22,7 @@
22 * 22 *
23 */ 23 */
24 24
25#include <linux/sched.h>
25#include "ibmasm.h" 26#include "ibmasm.h"
26#include "lowlevel.h" 27#include "lowlevel.h"
27 28
diff --git a/drivers/misc/ibmasm/r_heartbeat.c b/drivers/misc/ibmasm/r_heartbeat.c
index bec9e2c44bef..2de487ac788c 100644
--- a/drivers/misc/ibmasm/r_heartbeat.c
+++ b/drivers/misc/ibmasm/r_heartbeat.c
@@ -20,6 +20,7 @@
20 * 20 *
21 */ 21 */
22 22
23#include <linux/sched.h>
23#include "ibmasm.h" 24#include "ibmasm.h"
24#include "dot_command.h" 25#include "dot_command.h"
25 26
diff --git a/drivers/misc/phantom.c b/drivers/misc/phantom.c
index fa57b67593ae..04c27266f567 100644
--- a/drivers/misc/phantom.c
+++ b/drivers/misc/phantom.c
@@ -22,6 +22,7 @@
22#include <linux/interrupt.h> 22#include <linux/interrupt.h>
23#include <linux/cdev.h> 23#include <linux/cdev.h>
24#include <linux/phantom.h> 24#include <linux/phantom.h>
25#include <linux/sched.h>
25#include <linux/smp_lock.h> 26#include <linux/smp_lock.h>
26 27
27#include <asm/atomic.h> 28#include <asm/atomic.h>
@@ -271,7 +272,7 @@ static unsigned int phantom_poll(struct file *file, poll_table *wait)
271 return mask; 272 return mask;
272} 273}
273 274
274static struct file_operations phantom_file_ops = { 275static const struct file_operations phantom_file_ops = {
275 .open = phantom_open, 276 .open = phantom_open,
276 .release = phantom_release, 277 .release = phantom_release,
277 .unlocked_ioctl = phantom_ioctl, 278 .unlocked_ioctl = phantom_ioctl,
diff --git a/drivers/misc/sgi-gru/grufile.c b/drivers/misc/sgi-gru/grufile.c
index 300e7ba391a0..41c8fe2a928c 100644
--- a/drivers/misc/sgi-gru/grufile.c
+++ b/drivers/misc/sgi-gru/grufile.c
@@ -53,7 +53,6 @@ struct gru_stats_s gru_stats;
53/* Guaranteed user available resources on each node */ 53/* Guaranteed user available resources on each node */
54static int max_user_cbrs, max_user_dsr_bytes; 54static int max_user_cbrs, max_user_dsr_bytes;
55 55
56static struct file_operations gru_fops;
57static struct miscdevice gru_miscdev; 56static struct miscdevice gru_miscdev;
58 57
59 58
@@ -426,7 +425,7 @@ static void __exit gru_exit(void)
426 gru_proc_exit(); 425 gru_proc_exit();
427} 426}
428 427
429static struct file_operations gru_fops = { 428static const struct file_operations gru_fops = {
430 .owner = THIS_MODULE, 429 .owner = THIS_MODULE,
431 .unlocked_ioctl = gru_file_unlocked_ioctl, 430 .unlocked_ioctl = gru_file_unlocked_ioctl,
432 .mmap = gru_file_mmap, 431 .mmap = gru_file_mmap,
diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c
index 610dbd1fcc82..96d10f40fb23 100644
--- a/drivers/mmc/core/debugfs.c
+++ b/drivers/mmc/core/debugfs.c
@@ -240,7 +240,7 @@ static int mmc_ext_csd_release(struct inode *inode, struct file *file)
240 return 0; 240 return 0;
241} 241}
242 242
243static struct file_operations mmc_dbg_ext_csd_fops = { 243static const struct file_operations mmc_dbg_ext_csd_fops = {
244 .open = mmc_ext_csd_open, 244 .open = mmc_ext_csd_open,
245 .read = mmc_ext_csd_read, 245 .read = mmc_ext_csd_read,
246 .release = mmc_ext_csd_release, 246 .release = mmc_ext_csd_release,
diff --git a/drivers/mmc/core/sdio_cis.c b/drivers/mmc/core/sdio_cis.c
index 6636354b48ce..f85dcd536508 100644
--- a/drivers/mmc/core/sdio_cis.c
+++ b/drivers/mmc/core/sdio_cis.c
@@ -29,6 +29,8 @@ static int cistpl_vers_1(struct mmc_card *card, struct sdio_func *func,
29 unsigned i, nr_strings; 29 unsigned i, nr_strings;
30 char **buffer, *string; 30 char **buffer, *string;
31 31
32 /* Find all null-terminated (including zero length) strings in
33 the TPLLV1_INFO field. Trailing garbage is ignored. */
32 buf += 2; 34 buf += 2;
33 size -= 2; 35 size -= 2;
34 36
@@ -39,11 +41,8 @@ static int cistpl_vers_1(struct mmc_card *card, struct sdio_func *func,
39 if (buf[i] == 0) 41 if (buf[i] == 0)
40 nr_strings++; 42 nr_strings++;
41 } 43 }
42 44 if (nr_strings == 0)
43 if (nr_strings < 4) {
44 printk(KERN_WARNING "SDIO: ignoring broken CISTPL_VERS_1\n");
45 return 0; 45 return 0;
46 }
47 46
48 size = i; 47 size = i;
49 48
@@ -98,6 +97,22 @@ static const unsigned char speed_val[16] =
98static const unsigned int speed_unit[8] = 97static const unsigned int speed_unit[8] =
99 { 10000, 100000, 1000000, 10000000, 0, 0, 0, 0 }; 98 { 10000, 100000, 1000000, 10000000, 0, 0, 0, 0 };
100 99
100/* FUNCE tuples with these types get passed to SDIO drivers */
101static const unsigned char funce_type_whitelist[] = {
102 4 /* CISTPL_FUNCE_LAN_NODE_ID used in Broadcom cards */
103};
104
105static int cistpl_funce_whitelisted(unsigned char type)
106{
107 int i;
108
109 for (i = 0; i < ARRAY_SIZE(funce_type_whitelist); i++) {
110 if (funce_type_whitelist[i] == type)
111 return 1;
112 }
113 return 0;
114}
115
101static int cistpl_funce_common(struct mmc_card *card, 116static int cistpl_funce_common(struct mmc_card *card,
102 const unsigned char *buf, unsigned size) 117 const unsigned char *buf, unsigned size)
103{ 118{
@@ -120,6 +135,10 @@ static int cistpl_funce_func(struct sdio_func *func,
120 unsigned vsn; 135 unsigned vsn;
121 unsigned min_size; 136 unsigned min_size;
122 137
138 /* let SDIO drivers take care of whitelisted FUNCE tuples */
139 if (cistpl_funce_whitelisted(buf[0]))
140 return -EILSEQ;
141
123 vsn = func->card->cccr.sdio_vsn; 142 vsn = func->card->cccr.sdio_vsn;
124 min_size = (vsn == SDIO_SDIO_REV_1_00) ? 28 : 42; 143 min_size = (vsn == SDIO_SDIO_REV_1_00) ? 28 : 42;
125 144
@@ -154,13 +173,12 @@ static int cistpl_funce(struct mmc_card *card, struct sdio_func *func,
154 else 173 else
155 ret = cistpl_funce_common(card, buf, size); 174 ret = cistpl_funce_common(card, buf, size);
156 175
157 if (ret) { 176 if (ret && ret != -EILSEQ) {
158 printk(KERN_ERR "%s: bad CISTPL_FUNCE size %u " 177 printk(KERN_ERR "%s: bad CISTPL_FUNCE size %u "
159 "type %u\n", mmc_hostname(card->host), size, buf[0]); 178 "type %u\n", mmc_hostname(card->host), size, buf[0]);
160 return ret;
161 } 179 }
162 180
163 return 0; 181 return ret;
164} 182}
165 183
166typedef int (tpl_parse_t)(struct mmc_card *, struct sdio_func *, 184typedef int (tpl_parse_t)(struct mmc_card *, struct sdio_func *,
@@ -253,21 +271,12 @@ static int sdio_read_cis(struct mmc_card *card, struct sdio_func *func)
253 for (i = 0; i < ARRAY_SIZE(cis_tpl_list); i++) 271 for (i = 0; i < ARRAY_SIZE(cis_tpl_list); i++)
254 if (cis_tpl_list[i].code == tpl_code) 272 if (cis_tpl_list[i].code == tpl_code)
255 break; 273 break;
256 if (i >= ARRAY_SIZE(cis_tpl_list)) { 274 if (i < ARRAY_SIZE(cis_tpl_list)) {
257 /* this tuple is unknown to the core */
258 this->next = NULL;
259 this->code = tpl_code;
260 this->size = tpl_link;
261 *prev = this;
262 prev = &this->next;
263 printk(KERN_DEBUG
264 "%s: queuing CIS tuple 0x%02x length %u\n",
265 mmc_hostname(card->host), tpl_code, tpl_link);
266 } else {
267 const struct cis_tpl *tpl = cis_tpl_list + i; 275 const struct cis_tpl *tpl = cis_tpl_list + i;
268 if (tpl_link < tpl->min_size) { 276 if (tpl_link < tpl->min_size) {
269 printk(KERN_ERR 277 printk(KERN_ERR
270 "%s: bad CIS tuple 0x%02x (length = %u, expected >= %u)\n", 278 "%s: bad CIS tuple 0x%02x"
279 " (length = %u, expected >= %u)\n",
271 mmc_hostname(card->host), 280 mmc_hostname(card->host),
272 tpl_code, tpl_link, tpl->min_size); 281 tpl_code, tpl_link, tpl->min_size);
273 ret = -EINVAL; 282 ret = -EINVAL;
@@ -275,7 +284,30 @@ static int sdio_read_cis(struct mmc_card *card, struct sdio_func *func)
275 ret = tpl->parse(card, func, 284 ret = tpl->parse(card, func,
276 this->data, tpl_link); 285 this->data, tpl_link);
277 } 286 }
278 kfree(this); 287 /*
288 * We don't need the tuple anymore if it was
289 * successfully parsed by the SDIO core or if it is
290 * not going to be parsed by SDIO drivers.
291 */
292 if (!ret || ret != -EILSEQ)
293 kfree(this);
294 } else {
295 /* unknown tuple */
296 ret = -EILSEQ;
297 }
298
299 if (ret == -EILSEQ) {
300 /* this tuple is unknown to the core or whitelisted */
301 this->next = NULL;
302 this->code = tpl_code;
303 this->size = tpl_link;
304 *prev = this;
305 prev = &this->next;
306 printk(KERN_DEBUG
307 "%s: queuing CIS tuple 0x%02x length %u\n",
308 mmc_hostname(card->host), tpl_code, tpl_link);
309 /* keep on analyzing tuples */
310 ret = 0;
279 } 311 }
280 312
281 ptr += tpl_link; 313 ptr += tpl_link;
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 7cb057f3f883..432ae8358c86 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -276,6 +276,47 @@ config MMC_S3C
276 276
277 If unsure, say N. 277 If unsure, say N.
278 278
279config MMC_S3C_HW_SDIO_IRQ
280 bool "Hardware support for SDIO IRQ"
281 depends on MMC_S3C
282 help
283 Enable the hardware support for SDIO interrupts instead of using
284 the generic polling code.
285
286choice
287 prompt "Samsung S3C SD/MMC transfer code"
288 depends on MMC_S3C
289
290config MMC_S3C_PIO
291 bool "Use PIO transfers only"
292 help
293 Use PIO to transfer data between memory and the hardware.
294
295 PIO is slower than DMA as it requires CPU instructions to
296 move the data. This has been the traditional default for
297 the S3C MCI driver.
298
299config MMC_S3C_DMA
300 bool "Use DMA transfers only (EXPERIMENTAL)"
301 depends on EXPERIMENTAL
302 help
303 Use DMA to transfer data between memory and the hardare.
304
305 Currently, the DMA support in this driver seems to not be
306 working properly and needs to be debugged before this
307 option is useful.
308
309config MMC_S3C_PIODMA
310 bool "Support for both PIO and DMA (EXPERIMENTAL)"
311 help
312 Compile both the PIO and DMA transfer routines into the
313 driver and let the platform select at run-time which one
314 is best.
315
316 See notes for the DMA option.
317
318endchoice
319
279config MMC_SDRICOH_CS 320config MMC_SDRICOH_CS
280 tristate "MMC/SD driver for Ricoh Bay1Controllers (EXPERIMENTAL)" 321 tristate "MMC/SD driver for Ricoh Bay1Controllers (EXPERIMENTAL)"
281 depends on EXPERIMENTAL && PCI && PCMCIA 322 depends on EXPERIMENTAL && PCI && PCMCIA
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 3d1e5329da12..705a5894a6bb 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -678,7 +678,6 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
678 writel(0, host->base + MMCIMASK1); 678 writel(0, host->base + MMCIMASK1);
679 writel(0xfff, host->base + MMCICLEAR); 679 writel(0xfff, host->base + MMCICLEAR);
680 680
681#ifdef CONFIG_GPIOLIB
682 if (gpio_is_valid(plat->gpio_cd)) { 681 if (gpio_is_valid(plat->gpio_cd)) {
683 ret = gpio_request(plat->gpio_cd, DRIVER_NAME " (cd)"); 682 ret = gpio_request(plat->gpio_cd, DRIVER_NAME " (cd)");
684 if (ret == 0) 683 if (ret == 0)
@@ -697,7 +696,6 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
697 else if (ret != -ENOSYS) 696 else if (ret != -ENOSYS)
698 goto err_gpio_wp; 697 goto err_gpio_wp;
699 } 698 }
700#endif
701 699
702 ret = request_irq(dev->irq[0], mmci_irq, IRQF_SHARED, DRIVER_NAME " (cmd)", host); 700 ret = request_irq(dev->irq[0], mmci_irq, IRQF_SHARED, DRIVER_NAME " (cmd)", host);
703 if (ret) 701 if (ret)
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c
index 5e0b1529964d..b00d67319058 100644
--- a/drivers/mmc/host/pxamci.c
+++ b/drivers/mmc/host/pxamci.c
@@ -693,7 +693,7 @@ static int pxamci_probe(struct platform_device *pdev)
693 if (gpio_is_valid(gpio_ro)) { 693 if (gpio_is_valid(gpio_ro)) {
694 ret = gpio_request(gpio_ro, "mmc card read only"); 694 ret = gpio_request(gpio_ro, "mmc card read only");
695 if (ret) { 695 if (ret) {
696 dev_err(&pdev->dev, "Failed requesting gpio_ro %d\n", gpio_power); 696 dev_err(&pdev->dev, "Failed requesting gpio_ro %d\n", gpio_ro);
697 goto err_gpio_ro; 697 goto err_gpio_ro;
698 } 698 }
699 gpio_direction_input(gpio_ro); 699 gpio_direction_input(gpio_ro);
@@ -701,7 +701,7 @@ static int pxamci_probe(struct platform_device *pdev)
701 if (gpio_is_valid(gpio_cd)) { 701 if (gpio_is_valid(gpio_cd)) {
702 ret = gpio_request(gpio_cd, "mmc card detect"); 702 ret = gpio_request(gpio_cd, "mmc card detect");
703 if (ret) { 703 if (ret) {
704 dev_err(&pdev->dev, "Failed requesting gpio_cd %d\n", gpio_power); 704 dev_err(&pdev->dev, "Failed requesting gpio_cd %d\n", gpio_cd);
705 goto err_gpio_cd; 705 goto err_gpio_cd;
706 } 706 }
707 gpio_direction_input(gpio_cd); 707 gpio_direction_input(gpio_cd);
diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c
index 8c08cd7efa7f..99b74a351020 100644
--- a/drivers/mmc/host/s3cmci.c
+++ b/drivers/mmc/host/s3cmci.c
@@ -17,6 +17,8 @@
17#include <linux/mmc/host.h> 17#include <linux/mmc/host.h>
18#include <linux/platform_device.h> 18#include <linux/platform_device.h>
19#include <linux/cpufreq.h> 19#include <linux/cpufreq.h>
20#include <linux/debugfs.h>
21#include <linux/seq_file.h>
20#include <linux/gpio.h> 22#include <linux/gpio.h>
21#include <linux/irq.h> 23#include <linux/irq.h>
22#include <linux/io.h> 24#include <linux/io.h>
@@ -58,8 +60,6 @@ static const int dbgmap_debug = dbg_err | dbg_debug;
58 dev_dbg(&host->pdev->dev, args); \ 60 dev_dbg(&host->pdev->dev, args); \
59 } while (0) 61 } while (0)
60 62
61#define RESSIZE(ressource) (((ressource)->end - (ressource)->start)+1)
62
63static struct s3c2410_dma_client s3cmci_dma_client = { 63static struct s3c2410_dma_client s3cmci_dma_client = {
64 .name = "s3c-mci", 64 .name = "s3c-mci",
65}; 65};
@@ -164,6 +164,40 @@ static void dbg_dumpregs(struct s3cmci_host *host, char *prefix) { }
164 164
165#endif /* CONFIG_MMC_DEBUG */ 165#endif /* CONFIG_MMC_DEBUG */
166 166
167/**
168 * s3cmci_host_usedma - return whether the host is using dma or pio
169 * @host: The host state
170 *
171 * Return true if the host is using DMA to transfer data, else false
172 * to use PIO mode. Will return static data depending on the driver
173 * configuration.
174 */
175static inline bool s3cmci_host_usedma(struct s3cmci_host *host)
176{
177#ifdef CONFIG_MMC_S3C_PIO
178 return false;
179#elif defined(CONFIG_MMC_S3C_DMA)
180 return true;
181#else
182 return host->dodma;
183#endif
184}
185
186/**
187 * s3cmci_host_canpio - return true if host has pio code available
188 *
189 * Return true if the driver has been compiled with the PIO support code
190 * available.
191 */
192static inline bool s3cmci_host_canpio(void)
193{
194#ifdef CONFIG_MMC_S3C_PIO
195 return true;
196#else
197 return false;
198#endif
199}
200
167static inline u32 enable_imask(struct s3cmci_host *host, u32 imask) 201static inline u32 enable_imask(struct s3cmci_host *host, u32 imask)
168{ 202{
169 u32 newmask; 203 u32 newmask;
@@ -190,7 +224,33 @@ static inline u32 disable_imask(struct s3cmci_host *host, u32 imask)
190 224
191static inline void clear_imask(struct s3cmci_host *host) 225static inline void clear_imask(struct s3cmci_host *host)
192{ 226{
193 writel(0, host->base + host->sdiimsk); 227 u32 mask = readl(host->base + host->sdiimsk);
228
229 /* preserve the SDIO IRQ mask state */
230 mask &= S3C2410_SDIIMSK_SDIOIRQ;
231 writel(mask, host->base + host->sdiimsk);
232}
233
234/**
235 * s3cmci_check_sdio_irq - test whether the SDIO IRQ is being signalled
236 * @host: The host to check.
237 *
238 * Test to see if the SDIO interrupt is being signalled in case the
239 * controller has failed to re-detect a card interrupt. Read GPE8 and
240 * see if it is low and if so, signal a SDIO interrupt.
241 *
242 * This is currently called if a request is finished (we assume that the
243 * bus is now idle) and when the SDIO IRQ is enabled in case the IRQ is
244 * already being indicated.
245*/
246static void s3cmci_check_sdio_irq(struct s3cmci_host *host)
247{
248 if (host->sdio_irqen) {
249 if (gpio_get_value(S3C2410_GPE(8)) == 0) {
250 printk(KERN_DEBUG "%s: signalling irq\n", __func__);
251 mmc_signal_sdio_irq(host->mmc);
252 }
253 }
194} 254}
195 255
196static inline int get_data_buffer(struct s3cmci_host *host, 256static inline int get_data_buffer(struct s3cmci_host *host,
@@ -238,6 +298,64 @@ static inline u32 fifo_free(struct s3cmci_host *host)
238 return 63 - fifostat; 298 return 63 - fifostat;
239} 299}
240 300
301/**
302 * s3cmci_enable_irq - enable IRQ, after having disabled it.
303 * @host: The device state.
304 * @more: True if more IRQs are expected from transfer.
305 *
306 * Enable the main IRQ if needed after it has been disabled.
307 *
308 * The IRQ can be one of the following states:
309 * - disabled during IDLE
310 * - disabled whilst processing data
311 * - enabled during transfer
312 * - enabled whilst awaiting SDIO interrupt detection
313 */
314static void s3cmci_enable_irq(struct s3cmci_host *host, bool more)
315{
316 unsigned long flags;
317 bool enable = false;
318
319 local_irq_save(flags);
320
321 host->irq_enabled = more;
322 host->irq_disabled = false;
323
324 enable = more | host->sdio_irqen;
325
326 if (host->irq_state != enable) {
327 host->irq_state = enable;
328
329 if (enable)
330 enable_irq(host->irq);
331 else
332 disable_irq(host->irq);
333 }
334
335 local_irq_restore(flags);
336}
337
338/**
339 *
340 */
341static void s3cmci_disable_irq(struct s3cmci_host *host, bool transfer)
342{
343 unsigned long flags;
344
345 local_irq_save(flags);
346
347 //printk(KERN_DEBUG "%s: transfer %d\n", __func__, transfer);
348
349 host->irq_disabled = transfer;
350
351 if (transfer && host->irq_state) {
352 host->irq_state = false;
353 disable_irq(host->irq);
354 }
355
356 local_irq_restore(flags);
357}
358
241static void do_pio_read(struct s3cmci_host *host) 359static void do_pio_read(struct s3cmci_host *host)
242{ 360{
243 int res; 361 int res;
@@ -374,8 +492,7 @@ static void pio_tasklet(unsigned long data)
374{ 492{
375 struct s3cmci_host *host = (struct s3cmci_host *) data; 493 struct s3cmci_host *host = (struct s3cmci_host *) data;
376 494
377 495 s3cmci_disable_irq(host, true);
378 disable_irq(host->irq);
379 496
380 if (host->pio_active == XFER_WRITE) 497 if (host->pio_active == XFER_WRITE)
381 do_pio_write(host); 498 do_pio_write(host);
@@ -395,9 +512,10 @@ static void pio_tasklet(unsigned long data)
395 host->mrq->data->error = -EINVAL; 512 host->mrq->data->error = -EINVAL;
396 } 513 }
397 514
515 s3cmci_enable_irq(host, false);
398 finalize_request(host); 516 finalize_request(host);
399 } else 517 } else
400 enable_irq(host->irq); 518 s3cmci_enable_irq(host, true);
401} 519}
402 520
403/* 521/*
@@ -432,17 +550,27 @@ static irqreturn_t s3cmci_irq(int irq, void *dev_id)
432 struct s3cmci_host *host = dev_id; 550 struct s3cmci_host *host = dev_id;
433 struct mmc_command *cmd; 551 struct mmc_command *cmd;
434 u32 mci_csta, mci_dsta, mci_fsta, mci_dcnt, mci_imsk; 552 u32 mci_csta, mci_dsta, mci_fsta, mci_dcnt, mci_imsk;
435 u32 mci_cclear, mci_dclear; 553 u32 mci_cclear = 0, mci_dclear;
436 unsigned long iflags; 554 unsigned long iflags;
437 555
556 mci_dsta = readl(host->base + S3C2410_SDIDSTA);
557 mci_imsk = readl(host->base + host->sdiimsk);
558
559 if (mci_dsta & S3C2410_SDIDSTA_SDIOIRQDETECT) {
560 if (mci_imsk & S3C2410_SDIIMSK_SDIOIRQ) {
561 mci_dclear = S3C2410_SDIDSTA_SDIOIRQDETECT;
562 writel(mci_dclear, host->base + S3C2410_SDIDSTA);
563
564 mmc_signal_sdio_irq(host->mmc);
565 return IRQ_HANDLED;
566 }
567 }
568
438 spin_lock_irqsave(&host->complete_lock, iflags); 569 spin_lock_irqsave(&host->complete_lock, iflags);
439 570
440 mci_csta = readl(host->base + S3C2410_SDICMDSTAT); 571 mci_csta = readl(host->base + S3C2410_SDICMDSTAT);
441 mci_dsta = readl(host->base + S3C2410_SDIDSTA);
442 mci_dcnt = readl(host->base + S3C2410_SDIDCNT); 572 mci_dcnt = readl(host->base + S3C2410_SDIDCNT);
443 mci_fsta = readl(host->base + S3C2410_SDIFSTA); 573 mci_fsta = readl(host->base + S3C2410_SDIFSTA);
444 mci_imsk = readl(host->base + host->sdiimsk);
445 mci_cclear = 0;
446 mci_dclear = 0; 574 mci_dclear = 0;
447 575
448 if ((host->complete_what == COMPLETION_NONE) || 576 if ((host->complete_what == COMPLETION_NONE) ||
@@ -466,7 +594,7 @@ static irqreturn_t s3cmci_irq(int irq, void *dev_id)
466 goto irq_out; 594 goto irq_out;
467 } 595 }
468 596
469 if (!host->dodma) { 597 if (!s3cmci_host_usedma(host)) {
470 if ((host->pio_active == XFER_WRITE) && 598 if ((host->pio_active == XFER_WRITE) &&
471 (mci_fsta & S3C2410_SDIFSTA_TFDET)) { 599 (mci_fsta & S3C2410_SDIFSTA_TFDET)) {
472 600
@@ -673,6 +801,7 @@ static void s3cmci_dma_done_callback(struct s3c2410_dma_chan *dma_ch,
673 dbg(host, dbg_dma, "DMA FINISHED Size:%i DSTA:%08x DCNT:%08x\n", 801 dbg(host, dbg_dma, "DMA FINISHED Size:%i DSTA:%08x DCNT:%08x\n",
674 size, mci_dsta, mci_dcnt); 802 size, mci_dsta, mci_dcnt);
675 803
804 host->dma_complete = 1;
676 host->complete_what = COMPLETION_FINALIZE; 805 host->complete_what = COMPLETION_FINALIZE;
677 806
678out: 807out:
@@ -683,9 +812,9 @@ out:
683fail_request: 812fail_request:
684 host->mrq->data->error = -EINVAL; 813 host->mrq->data->error = -EINVAL;
685 host->complete_what = COMPLETION_FINALIZE; 814 host->complete_what = COMPLETION_FINALIZE;
686 writel(0, host->base + host->sdiimsk); 815 clear_imask(host);
687 goto out;
688 816
817 goto out;
689} 818}
690 819
691static void finalize_request(struct s3cmci_host *host) 820static void finalize_request(struct s3cmci_host *host)
@@ -702,8 +831,9 @@ static void finalize_request(struct s3cmci_host *host)
702 831
703 if (cmd->data && (cmd->error == 0) && 832 if (cmd->data && (cmd->error == 0) &&
704 (cmd->data->error == 0)) { 833 (cmd->data->error == 0)) {
705 if (host->dodma && (!host->dma_complete)) { 834 if (s3cmci_host_usedma(host) && (!host->dma_complete)) {
706 dbg(host, dbg_dma, "DMA Missing!\n"); 835 dbg(host, dbg_dma, "DMA Missing (%d)!\n",
836 host->dma_complete);
707 return; 837 return;
708 } 838 }
709 } 839 }
@@ -728,7 +858,7 @@ static void finalize_request(struct s3cmci_host *host)
728 writel(0, host->base + S3C2410_SDICMDARG); 858 writel(0, host->base + S3C2410_SDICMDARG);
729 writel(S3C2410_SDIDCON_STOP, host->base + S3C2410_SDIDCON); 859 writel(S3C2410_SDIDCON_STOP, host->base + S3C2410_SDIDCON);
730 writel(0, host->base + S3C2410_SDICMDCON); 860 writel(0, host->base + S3C2410_SDICMDCON);
731 writel(0, host->base + host->sdiimsk); 861 clear_imask(host);
732 862
733 if (cmd->data && cmd->error) 863 if (cmd->data && cmd->error)
734 cmd->data->error = cmd->error; 864 cmd->data->error = cmd->error;
@@ -754,7 +884,7 @@ static void finalize_request(struct s3cmci_host *host)
754 /* If we had an error while transfering data we flush the 884 /* If we had an error while transfering data we flush the
755 * DMA channel and the fifo to clear out any garbage. */ 885 * DMA channel and the fifo to clear out any garbage. */
756 if (mrq->data->error != 0) { 886 if (mrq->data->error != 0) {
757 if (host->dodma) 887 if (s3cmci_host_usedma(host))
758 s3c2410_dma_ctrl(host->dma, S3C2410_DMAOP_FLUSH); 888 s3c2410_dma_ctrl(host->dma, S3C2410_DMAOP_FLUSH);
759 889
760 if (host->is2440) { 890 if (host->is2440) {
@@ -776,6 +906,8 @@ static void finalize_request(struct s3cmci_host *host)
776request_done: 906request_done:
777 host->complete_what = COMPLETION_NONE; 907 host->complete_what = COMPLETION_NONE;
778 host->mrq = NULL; 908 host->mrq = NULL;
909
910 s3cmci_check_sdio_irq(host);
779 mmc_request_done(host->mmc, mrq); 911 mmc_request_done(host->mmc, mrq);
780} 912}
781 913
@@ -872,7 +1004,7 @@ static int s3cmci_setup_data(struct s3cmci_host *host, struct mmc_data *data)
872 1004
873 dcon = data->blocks & S3C2410_SDIDCON_BLKNUM_MASK; 1005 dcon = data->blocks & S3C2410_SDIDCON_BLKNUM_MASK;
874 1006
875 if (host->dodma) 1007 if (s3cmci_host_usedma(host))
876 dcon |= S3C2410_SDIDCON_DMAEN; 1008 dcon |= S3C2410_SDIDCON_DMAEN;
877 1009
878 if (host->bus_width == MMC_BUS_WIDTH_4) 1010 if (host->bus_width == MMC_BUS_WIDTH_4)
@@ -950,7 +1082,7 @@ static int s3cmci_prepare_pio(struct s3cmci_host *host, struct mmc_data *data)
950static int s3cmci_prepare_dma(struct s3cmci_host *host, struct mmc_data *data) 1082static int s3cmci_prepare_dma(struct s3cmci_host *host, struct mmc_data *data)
951{ 1083{
952 int dma_len, i; 1084 int dma_len, i;
953 int rw = (data->flags & MMC_DATA_WRITE) ? 1 : 0; 1085 int rw = data->flags & MMC_DATA_WRITE;
954 1086
955 BUG_ON((data->flags & BOTH_DIR) == BOTH_DIR); 1087 BUG_ON((data->flags & BOTH_DIR) == BOTH_DIR);
956 1088
@@ -958,7 +1090,7 @@ static int s3cmci_prepare_dma(struct s3cmci_host *host, struct mmc_data *data)
958 s3c2410_dma_ctrl(host->dma, S3C2410_DMAOP_FLUSH); 1090 s3c2410_dma_ctrl(host->dma, S3C2410_DMAOP_FLUSH);
959 1091
960 dma_len = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len, 1092 dma_len = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
961 (rw) ? DMA_TO_DEVICE : DMA_FROM_DEVICE); 1093 rw ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
962 1094
963 if (dma_len == 0) 1095 if (dma_len == 0)
964 return -ENOMEM; 1096 return -ENOMEM;
@@ -969,11 +1101,11 @@ static int s3cmci_prepare_dma(struct s3cmci_host *host, struct mmc_data *data)
969 for (i = 0; i < dma_len; i++) { 1101 for (i = 0; i < dma_len; i++) {
970 int res; 1102 int res;
971 1103
972 dbg(host, dbg_dma, "enqueue %i:%u@%u\n", i, 1104 dbg(host, dbg_dma, "enqueue %i: %08x@%u\n", i,
973 sg_dma_address(&data->sg[i]), 1105 sg_dma_address(&data->sg[i]),
974 sg_dma_len(&data->sg[i])); 1106 sg_dma_len(&data->sg[i]));
975 1107
976 res = s3c2410_dma_enqueue(host->dma, (void *) host, 1108 res = s3c2410_dma_enqueue(host->dma, host,
977 sg_dma_address(&data->sg[i]), 1109 sg_dma_address(&data->sg[i]),
978 sg_dma_len(&data->sg[i])); 1110 sg_dma_len(&data->sg[i]));
979 1111
@@ -1018,7 +1150,7 @@ static void s3cmci_send_request(struct mmc_host *mmc)
1018 return; 1150 return;
1019 } 1151 }
1020 1152
1021 if (host->dodma) 1153 if (s3cmci_host_usedma(host))
1022 res = s3cmci_prepare_dma(host, cmd->data); 1154 res = s3cmci_prepare_dma(host, cmd->data);
1023 else 1155 else
1024 res = s3cmci_prepare_pio(host, cmd->data); 1156 res = s3cmci_prepare_pio(host, cmd->data);
@@ -1037,7 +1169,7 @@ static void s3cmci_send_request(struct mmc_host *mmc)
1037 s3cmci_send_command(host, cmd); 1169 s3cmci_send_command(host, cmd);
1038 1170
1039 /* Enable Interrupt */ 1171 /* Enable Interrupt */
1040 enable_irq(host->irq); 1172 s3cmci_enable_irq(host, true);
1041} 1173}
1042 1174
1043static int s3cmci_card_present(struct mmc_host *mmc) 1175static int s3cmci_card_present(struct mmc_host *mmc)
@@ -1049,7 +1181,7 @@ static int s3cmci_card_present(struct mmc_host *mmc)
1049 if (pdata->gpio_detect == 0) 1181 if (pdata->gpio_detect == 0)
1050 return -ENOSYS; 1182 return -ENOSYS;
1051 1183
1052 ret = s3c2410_gpio_getpin(pdata->gpio_detect) ? 0 : 1; 1184 ret = gpio_get_value(pdata->gpio_detect) ? 0 : 1;
1053 return ret ^ pdata->detect_invert; 1185 return ret ^ pdata->detect_invert;
1054} 1186}
1055 1187
@@ -1104,12 +1236,12 @@ static void s3cmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
1104 switch (ios->power_mode) { 1236 switch (ios->power_mode) {
1105 case MMC_POWER_ON: 1237 case MMC_POWER_ON:
1106 case MMC_POWER_UP: 1238 case MMC_POWER_UP:
1107 s3c2410_gpio_cfgpin(S3C2410_GPE5, S3C2410_GPE5_SDCLK); 1239 s3c2410_gpio_cfgpin(S3C2410_GPE(5), S3C2410_GPE5_SDCLK);
1108 s3c2410_gpio_cfgpin(S3C2410_GPE6, S3C2410_GPE6_SDCMD); 1240 s3c2410_gpio_cfgpin(S3C2410_GPE(6), S3C2410_GPE6_SDCMD);
1109 s3c2410_gpio_cfgpin(S3C2410_GPE7, S3C2410_GPE7_SDDAT0); 1241 s3c2410_gpio_cfgpin(S3C2410_GPE(7), S3C2410_GPE7_SDDAT0);
1110 s3c2410_gpio_cfgpin(S3C2410_GPE8, S3C2410_GPE8_SDDAT1); 1242 s3c2410_gpio_cfgpin(S3C2410_GPE(8), S3C2410_GPE8_SDDAT1);
1111 s3c2410_gpio_cfgpin(S3C2410_GPE9, S3C2410_GPE9_SDDAT2); 1243 s3c2410_gpio_cfgpin(S3C2410_GPE(9), S3C2410_GPE9_SDDAT2);
1112 s3c2410_gpio_cfgpin(S3C2410_GPE10, S3C2410_GPE10_SDDAT3); 1244 s3c2410_gpio_cfgpin(S3C2410_GPE(10), S3C2410_GPE10_SDDAT3);
1113 1245
1114 if (host->pdata->set_power) 1246 if (host->pdata->set_power)
1115 host->pdata->set_power(ios->power_mode, ios->vdd); 1247 host->pdata->set_power(ios->power_mode, ios->vdd);
@@ -1121,8 +1253,7 @@ static void s3cmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
1121 1253
1122 case MMC_POWER_OFF: 1254 case MMC_POWER_OFF:
1123 default: 1255 default:
1124 s3c2410_gpio_setpin(S3C2410_GPE5, 0); 1256 gpio_direction_output(S3C2410_GPE(5), 0);
1125 s3c2410_gpio_cfgpin(S3C2410_GPE5, S3C2410_GPIO_OUTPUT);
1126 1257
1127 if (host->is2440) 1258 if (host->is2440)
1128 mci_con |= S3C2440_SDICON_SDRESET; 1259 mci_con |= S3C2440_SDICON_SDRESET;
@@ -1168,7 +1299,7 @@ static int s3cmci_get_ro(struct mmc_host *mmc)
1168 struct s3c24xx_mci_pdata *pdata = host->pdata; 1299 struct s3c24xx_mci_pdata *pdata = host->pdata;
1169 int ret; 1300 int ret;
1170 1301
1171 if (pdata->gpio_wprotect == 0) 1302 if (pdata->no_wprotect)
1172 return 0; 1303 return 0;
1173 1304
1174 ret = s3c2410_gpio_getpin(pdata->gpio_wprotect); 1305 ret = s3c2410_gpio_getpin(pdata->gpio_wprotect);
@@ -1179,11 +1310,52 @@ static int s3cmci_get_ro(struct mmc_host *mmc)
1179 return ret; 1310 return ret;
1180} 1311}
1181 1312
1313static void s3cmci_enable_sdio_irq(struct mmc_host *mmc, int enable)
1314{
1315 struct s3cmci_host *host = mmc_priv(mmc);
1316 unsigned long flags;
1317 u32 con;
1318
1319 local_irq_save(flags);
1320
1321 con = readl(host->base + S3C2410_SDICON);
1322 host->sdio_irqen = enable;
1323
1324 if (enable == host->sdio_irqen)
1325 goto same_state;
1326
1327 if (enable) {
1328 con |= S3C2410_SDICON_SDIOIRQ;
1329 enable_imask(host, S3C2410_SDIIMSK_SDIOIRQ);
1330
1331 if (!host->irq_state && !host->irq_disabled) {
1332 host->irq_state = true;
1333 enable_irq(host->irq);
1334 }
1335 } else {
1336 disable_imask(host, S3C2410_SDIIMSK_SDIOIRQ);
1337 con &= ~S3C2410_SDICON_SDIOIRQ;
1338
1339 if (!host->irq_enabled && host->irq_state) {
1340 disable_irq_nosync(host->irq);
1341 host->irq_state = false;
1342 }
1343 }
1344
1345 writel(con, host->base + S3C2410_SDICON);
1346
1347 same_state:
1348 local_irq_restore(flags);
1349
1350 s3cmci_check_sdio_irq(host);
1351}
1352
1182static struct mmc_host_ops s3cmci_ops = { 1353static struct mmc_host_ops s3cmci_ops = {
1183 .request = s3cmci_request, 1354 .request = s3cmci_request,
1184 .set_ios = s3cmci_set_ios, 1355 .set_ios = s3cmci_set_ios,
1185 .get_ro = s3cmci_get_ro, 1356 .get_ro = s3cmci_get_ro,
1186 .get_cd = s3cmci_card_present, 1357 .get_cd = s3cmci_card_present,
1358 .enable_sdio_irq = s3cmci_enable_sdio_irq,
1187}; 1359};
1188 1360
1189static struct s3c24xx_mci_pdata s3cmci_def_pdata = { 1361static struct s3c24xx_mci_pdata s3cmci_def_pdata = {
@@ -1246,11 +1418,140 @@ static inline void s3cmci_cpufreq_deregister(struct s3cmci_host *host)
1246} 1418}
1247#endif 1419#endif
1248 1420
1249static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440) 1421
1422#ifdef CONFIG_DEBUG_FS
1423
1424static int s3cmci_state_show(struct seq_file *seq, void *v)
1425{
1426 struct s3cmci_host *host = seq->private;
1427
1428 seq_printf(seq, "Register base = 0x%08x\n", (u32)host->base);
1429 seq_printf(seq, "Clock rate = %ld\n", host->clk_rate);
1430 seq_printf(seq, "Prescale = %d\n", host->prescaler);
1431 seq_printf(seq, "is2440 = %d\n", host->is2440);
1432 seq_printf(seq, "IRQ = %d\n", host->irq);
1433 seq_printf(seq, "IRQ enabled = %d\n", host->irq_enabled);
1434 seq_printf(seq, "IRQ disabled = %d\n", host->irq_disabled);
1435 seq_printf(seq, "IRQ state = %d\n", host->irq_state);
1436 seq_printf(seq, "CD IRQ = %d\n", host->irq_cd);
1437 seq_printf(seq, "Do DMA = %d\n", s3cmci_host_usedma(host));
1438 seq_printf(seq, "SDIIMSK at %d\n", host->sdiimsk);
1439 seq_printf(seq, "SDIDATA at %d\n", host->sdidata);
1440
1441 return 0;
1442}
1443
1444static int s3cmci_state_open(struct inode *inode, struct file *file)
1445{
1446 return single_open(file, s3cmci_state_show, inode->i_private);
1447}
1448
1449static const struct file_operations s3cmci_fops_state = {
1450 .owner = THIS_MODULE,
1451 .open = s3cmci_state_open,
1452 .read = seq_read,
1453 .llseek = seq_lseek,
1454 .release = single_release,
1455};
1456
1457#define DBG_REG(_r) { .addr = S3C2410_SDI##_r, .name = #_r }
1458
1459struct s3cmci_reg {
1460 unsigned short addr;
1461 unsigned char *name;
1462} debug_regs[] = {
1463 DBG_REG(CON),
1464 DBG_REG(PRE),
1465 DBG_REG(CMDARG),
1466 DBG_REG(CMDCON),
1467 DBG_REG(CMDSTAT),
1468 DBG_REG(RSP0),
1469 DBG_REG(RSP1),
1470 DBG_REG(RSP2),
1471 DBG_REG(RSP3),
1472 DBG_REG(TIMER),
1473 DBG_REG(BSIZE),
1474 DBG_REG(DCON),
1475 DBG_REG(DCNT),
1476 DBG_REG(DSTA),
1477 DBG_REG(FSTA),
1478 {}
1479};
1480
1481static int s3cmci_regs_show(struct seq_file *seq, void *v)
1482{
1483 struct s3cmci_host *host = seq->private;
1484 struct s3cmci_reg *rptr = debug_regs;
1485
1486 for (; rptr->name; rptr++)
1487 seq_printf(seq, "SDI%s\t=0x%08x\n", rptr->name,
1488 readl(host->base + rptr->addr));
1489
1490 seq_printf(seq, "SDIIMSK\t=0x%08x\n", readl(host->base + host->sdiimsk));
1491
1492 return 0;
1493}
1494
1495static int s3cmci_regs_open(struct inode *inode, struct file *file)
1496{
1497 return single_open(file, s3cmci_regs_show, inode->i_private);
1498}
1499
1500static const struct file_operations s3cmci_fops_regs = {
1501 .owner = THIS_MODULE,
1502 .open = s3cmci_regs_open,
1503 .read = seq_read,
1504 .llseek = seq_lseek,
1505 .release = single_release,
1506};
1507
1508static void s3cmci_debugfs_attach(struct s3cmci_host *host)
1509{
1510 struct device *dev = &host->pdev->dev;
1511
1512 host->debug_root = debugfs_create_dir(dev_name(dev), NULL);
1513 if (IS_ERR(host->debug_root)) {
1514 dev_err(dev, "failed to create debugfs root\n");
1515 return;
1516 }
1517
1518 host->debug_state = debugfs_create_file("state", 0444,
1519 host->debug_root, host,
1520 &s3cmci_fops_state);
1521
1522 if (IS_ERR(host->debug_state))
1523 dev_err(dev, "failed to create debug state file\n");
1524
1525 host->debug_regs = debugfs_create_file("regs", 0444,
1526 host->debug_root, host,
1527 &s3cmci_fops_regs);
1528
1529 if (IS_ERR(host->debug_regs))
1530 dev_err(dev, "failed to create debug regs file\n");
1531}
1532
1533static void s3cmci_debugfs_remove(struct s3cmci_host *host)
1534{
1535 debugfs_remove(host->debug_regs);
1536 debugfs_remove(host->debug_state);
1537 debugfs_remove(host->debug_root);
1538}
1539
1540#else
1541static inline void s3cmci_debugfs_attach(struct s3cmci_host *host) { }
1542static inline void s3cmci_debugfs_remove(struct s3cmci_host *host) { }
1543
1544#endif /* CONFIG_DEBUG_FS */
1545
1546static int __devinit s3cmci_probe(struct platform_device *pdev)
1250{ 1547{
1251 struct s3cmci_host *host; 1548 struct s3cmci_host *host;
1252 struct mmc_host *mmc; 1549 struct mmc_host *mmc;
1253 int ret; 1550 int ret;
1551 int is2440;
1552 int i;
1553
1554 is2440 = platform_get_device_id(pdev)->driver_data;
1254 1555
1255 mmc = mmc_alloc_host(sizeof(struct s3cmci_host), &pdev->dev); 1556 mmc = mmc_alloc_host(sizeof(struct s3cmci_host), &pdev->dev);
1256 if (!mmc) { 1557 if (!mmc) {
@@ -1258,6 +1559,18 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440)
1258 goto probe_out; 1559 goto probe_out;
1259 } 1560 }
1260 1561
1562 for (i = S3C2410_GPE(5); i <= S3C2410_GPE(10); i++) {
1563 ret = gpio_request(i, dev_name(&pdev->dev));
1564 if (ret) {
1565 dev_err(&pdev->dev, "failed to get gpio %d\n", i);
1566
1567 for (i--; i >= S3C2410_GPE(5); i--)
1568 gpio_free(i);
1569
1570 goto probe_free_host;
1571 }
1572 }
1573
1261 host = mmc_priv(mmc); 1574 host = mmc_priv(mmc);
1262 host->mmc = mmc; 1575 host->mmc = mmc;
1263 host->pdev = pdev; 1576 host->pdev = pdev;
@@ -1282,11 +1595,12 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440)
1282 host->clk_div = 2; 1595 host->clk_div = 2;
1283 } 1596 }
1284 1597
1285 host->dodma = 0;
1286 host->complete_what = COMPLETION_NONE; 1598 host->complete_what = COMPLETION_NONE;
1287 host->pio_active = XFER_NONE; 1599 host->pio_active = XFER_NONE;
1288 1600
1289 host->dma = S3CMCI_DMA; 1601#ifdef CONFIG_MMC_S3C_PIODMA
1602 host->dodma = host->pdata->dma;
1603#endif
1290 1604
1291 host->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1605 host->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1292 if (!host->mem) { 1606 if (!host->mem) {
@@ -1294,19 +1608,19 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440)
1294 "failed to get io memory region resouce.\n"); 1608 "failed to get io memory region resouce.\n");
1295 1609
1296 ret = -ENOENT; 1610 ret = -ENOENT;
1297 goto probe_free_host; 1611 goto probe_free_gpio;
1298 } 1612 }
1299 1613
1300 host->mem = request_mem_region(host->mem->start, 1614 host->mem = request_mem_region(host->mem->start,
1301 RESSIZE(host->mem), pdev->name); 1615 resource_size(host->mem), pdev->name);
1302 1616
1303 if (!host->mem) { 1617 if (!host->mem) {
1304 dev_err(&pdev->dev, "failed to request io memory region.\n"); 1618 dev_err(&pdev->dev, "failed to request io memory region.\n");
1305 ret = -ENOENT; 1619 ret = -ENOENT;
1306 goto probe_free_host; 1620 goto probe_free_gpio;
1307 } 1621 }
1308 1622
1309 host->base = ioremap(host->mem->start, RESSIZE(host->mem)); 1623 host->base = ioremap(host->mem->start, resource_size(host->mem));
1310 if (!host->base) { 1624 if (!host->base) {
1311 dev_err(&pdev->dev, "failed to ioremap() io memory region.\n"); 1625 dev_err(&pdev->dev, "failed to ioremap() io memory region.\n");
1312 ret = -EINVAL; 1626 ret = -EINVAL;
@@ -1331,31 +1645,60 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440)
1331 * ensure we don't lock the system with un-serviceable requests. */ 1645 * ensure we don't lock the system with un-serviceable requests. */
1332 1646
1333 disable_irq(host->irq); 1647 disable_irq(host->irq);
1648 host->irq_state = false;
1334 1649
1335 host->irq_cd = s3c2410_gpio_getirq(host->pdata->gpio_detect); 1650 if (!host->pdata->no_detect) {
1336 1651 ret = gpio_request(host->pdata->gpio_detect, "s3cmci detect");
1337 if (host->irq_cd >= 0) { 1652 if (ret) {
1338 if (request_irq(host->irq_cd, s3cmci_irq_cd, 1653 dev_err(&pdev->dev, "failed to get detect gpio\n");
1339 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
1340 DRIVER_NAME, host)) {
1341 dev_err(&pdev->dev, "can't get card detect irq.\n");
1342 ret = -ENOENT;
1343 goto probe_free_irq; 1654 goto probe_free_irq;
1344 } 1655 }
1345 } else { 1656
1346 dev_warn(&pdev->dev, "host detect has no irq available\n"); 1657 host->irq_cd = s3c2410_gpio_getirq(host->pdata->gpio_detect);
1347 s3c2410_gpio_cfgpin(host->pdata->gpio_detect, 1658
1348 S3C2410_GPIO_INPUT); 1659 if (host->irq_cd >= 0) {
1660 if (request_irq(host->irq_cd, s3cmci_irq_cd,
1661 IRQF_TRIGGER_RISING |
1662 IRQF_TRIGGER_FALLING,
1663 DRIVER_NAME, host)) {
1664 dev_err(&pdev->dev,
1665 "can't get card detect irq.\n");
1666 ret = -ENOENT;
1667 goto probe_free_gpio_cd;
1668 }
1669 } else {
1670 dev_warn(&pdev->dev,
1671 "host detect has no irq available\n");
1672 gpio_direction_input(host->pdata->gpio_detect);
1673 }
1674 } else
1675 host->irq_cd = -1;
1676
1677 if (!host->pdata->no_wprotect) {
1678 ret = gpio_request(host->pdata->gpio_wprotect, "s3cmci wp");
1679 if (ret) {
1680 dev_err(&pdev->dev, "failed to get writeprotect\n");
1681 goto probe_free_irq_cd;
1682 }
1683
1684 gpio_direction_input(host->pdata->gpio_wprotect);
1349 } 1685 }
1350 1686
1351 if (host->pdata->gpio_wprotect) 1687 /* depending on the dma state, get a dma channel to use. */
1352 s3c2410_gpio_cfgpin(host->pdata->gpio_wprotect,
1353 S3C2410_GPIO_INPUT);
1354 1688
1355 if (s3c2410_dma_request(S3CMCI_DMA, &s3cmci_dma_client, NULL) < 0) { 1689 if (s3cmci_host_usedma(host)) {
1356 dev_err(&pdev->dev, "unable to get DMA channel.\n"); 1690 host->dma = s3c2410_dma_request(DMACH_SDI, &s3cmci_dma_client,
1357 ret = -EBUSY; 1691 host);
1358 goto probe_free_irq_cd; 1692 if (host->dma < 0) {
1693 dev_err(&pdev->dev, "cannot get DMA channel.\n");
1694 if (!s3cmci_host_canpio()) {
1695 ret = -EBUSY;
1696 goto probe_free_gpio_wp;
1697 } else {
1698 dev_warn(&pdev->dev, "falling back to PIO.\n");
1699 host->dodma = 0;
1700 }
1701 }
1359 } 1702 }
1360 1703
1361 host->clk = clk_get(&pdev->dev, "sdi"); 1704 host->clk = clk_get(&pdev->dev, "sdi");
@@ -1363,7 +1706,7 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440)
1363 dev_err(&pdev->dev, "failed to find clock source.\n"); 1706 dev_err(&pdev->dev, "failed to find clock source.\n");
1364 ret = PTR_ERR(host->clk); 1707 ret = PTR_ERR(host->clk);
1365 host->clk = NULL; 1708 host->clk = NULL;
1366 goto probe_free_host; 1709 goto probe_free_dma;
1367 } 1710 }
1368 1711
1369 ret = clk_enable(host->clk); 1712 ret = clk_enable(host->clk);
@@ -1376,7 +1719,11 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440)
1376 1719
1377 mmc->ops = &s3cmci_ops; 1720 mmc->ops = &s3cmci_ops;
1378 mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; 1721 mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
1722#ifdef CONFIG_MMC_S3C_HW_SDIO_IRQ
1723 mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ;
1724#else
1379 mmc->caps = MMC_CAP_4_BIT_DATA; 1725 mmc->caps = MMC_CAP_4_BIT_DATA;
1726#endif
1380 mmc->f_min = host->clk_rate / (host->clk_div * 256); 1727 mmc->f_min = host->clk_rate / (host->clk_div * 256);
1381 mmc->f_max = host->clk_rate / host->clk_div; 1728 mmc->f_max = host->clk_rate / host->clk_div;
1382 1729
@@ -1408,8 +1755,12 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440)
1408 goto free_cpufreq; 1755 goto free_cpufreq;
1409 } 1756 }
1410 1757
1758 s3cmci_debugfs_attach(host);
1759
1411 platform_set_drvdata(pdev, mmc); 1760 platform_set_drvdata(pdev, mmc);
1412 dev_info(&pdev->dev, "initialisation done.\n"); 1761 dev_info(&pdev->dev, "%s - using %s, %s SDIO IRQ\n", mmc_hostname(mmc),
1762 s3cmci_host_usedma(host) ? "dma" : "pio",
1763 mmc->caps & MMC_CAP_SDIO_IRQ ? "hw" : "sw");
1413 1764
1414 return 0; 1765 return 0;
1415 1766
@@ -1422,6 +1773,18 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440)
1422 clk_free: 1773 clk_free:
1423 clk_put(host->clk); 1774 clk_put(host->clk);
1424 1775
1776 probe_free_dma:
1777 if (s3cmci_host_usedma(host))
1778 s3c2410_dma_free(host->dma, &s3cmci_dma_client);
1779
1780 probe_free_gpio_wp:
1781 if (!host->pdata->no_wprotect)
1782 gpio_free(host->pdata->gpio_wprotect);
1783
1784 probe_free_gpio_cd:
1785 if (!host->pdata->no_detect)
1786 gpio_free(host->pdata->gpio_detect);
1787
1425 probe_free_irq_cd: 1788 probe_free_irq_cd:
1426 if (host->irq_cd >= 0) 1789 if (host->irq_cd >= 0)
1427 free_irq(host->irq_cd, host); 1790 free_irq(host->irq_cd, host);
@@ -1433,10 +1796,15 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440)
1433 iounmap(host->base); 1796 iounmap(host->base);
1434 1797
1435 probe_free_mem_region: 1798 probe_free_mem_region:
1436 release_mem_region(host->mem->start, RESSIZE(host->mem)); 1799 release_mem_region(host->mem->start, resource_size(host->mem));
1800
1801 probe_free_gpio:
1802 for (i = S3C2410_GPE(5); i <= S3C2410_GPE(10); i++)
1803 gpio_free(i);
1437 1804
1438 probe_free_host: 1805 probe_free_host:
1439 mmc_free_host(mmc); 1806 mmc_free_host(mmc);
1807
1440 probe_out: 1808 probe_out:
1441 return ret; 1809 return ret;
1442} 1810}
@@ -1449,6 +1817,7 @@ static void s3cmci_shutdown(struct platform_device *pdev)
1449 if (host->irq_cd >= 0) 1817 if (host->irq_cd >= 0)
1450 free_irq(host->irq_cd, host); 1818 free_irq(host->irq_cd, host);
1451 1819
1820 s3cmci_debugfs_remove(host);
1452 s3cmci_cpufreq_deregister(host); 1821 s3cmci_cpufreq_deregister(host);
1453 mmc_remove_host(mmc); 1822 mmc_remove_host(mmc);
1454 clk_disable(host->clk); 1823 clk_disable(host->clk);
@@ -1458,104 +1827,102 @@ static int __devexit s3cmci_remove(struct platform_device *pdev)
1458{ 1827{
1459 struct mmc_host *mmc = platform_get_drvdata(pdev); 1828 struct mmc_host *mmc = platform_get_drvdata(pdev);
1460 struct s3cmci_host *host = mmc_priv(mmc); 1829 struct s3cmci_host *host = mmc_priv(mmc);
1830 struct s3c24xx_mci_pdata *pd = host->pdata;
1831 int i;
1461 1832
1462 s3cmci_shutdown(pdev); 1833 s3cmci_shutdown(pdev);
1463 1834
1464 clk_put(host->clk); 1835 clk_put(host->clk);
1465 1836
1466 tasklet_disable(&host->pio_tasklet); 1837 tasklet_disable(&host->pio_tasklet);
1467 s3c2410_dma_free(S3CMCI_DMA, &s3cmci_dma_client); 1838
1839 if (s3cmci_host_usedma(host))
1840 s3c2410_dma_free(host->dma, &s3cmci_dma_client);
1468 1841
1469 free_irq(host->irq, host); 1842 free_irq(host->irq, host);
1470 1843
1844 if (!pd->no_wprotect)
1845 gpio_free(pd->gpio_wprotect);
1846
1847 if (!pd->no_detect)
1848 gpio_free(pd->gpio_detect);
1849
1850 for (i = S3C2410_GPE(5); i <= S3C2410_GPE(10); i++)
1851 gpio_free(i);
1852
1853
1471 iounmap(host->base); 1854 iounmap(host->base);
1472 release_mem_region(host->mem->start, RESSIZE(host->mem)); 1855 release_mem_region(host->mem->start, resource_size(host->mem));
1473 1856
1474 mmc_free_host(mmc); 1857 mmc_free_host(mmc);
1475 return 0; 1858 return 0;
1476} 1859}
1477 1860
1478static int __devinit s3cmci_2410_probe(struct platform_device *dev) 1861static struct platform_device_id s3cmci_driver_ids[] = {
1479{ 1862 {
1480 return s3cmci_probe(dev, 0); 1863 .name = "s3c2410-sdi",
1481} 1864 .driver_data = 0,
1865 }, {
1866 .name = "s3c2412-sdi",
1867 .driver_data = 1,
1868 }, {
1869 .name = "s3c2440-sdi",
1870 .driver_data = 1,
1871 },
1872 { }
1873};
1482 1874
1483static int __devinit s3cmci_2412_probe(struct platform_device *dev) 1875MODULE_DEVICE_TABLE(platform, s3cmci_driver_ids);
1484{
1485 return s3cmci_probe(dev, 1);
1486}
1487 1876
1488static int __devinit s3cmci_2440_probe(struct platform_device *dev)
1489{
1490 return s3cmci_probe(dev, 1);
1491}
1492 1877
1493#ifdef CONFIG_PM 1878#ifdef CONFIG_PM
1494 1879
1495static int s3cmci_suspend(struct platform_device *dev, pm_message_t state) 1880static int s3cmci_suspend(struct device *dev)
1496{ 1881{
1497 struct mmc_host *mmc = platform_get_drvdata(dev); 1882 struct mmc_host *mmc = platform_get_drvdata(to_platform_device(dev));
1883 struct pm_message event = { PM_EVENT_SUSPEND };
1498 1884
1499 return mmc_suspend_host(mmc, state); 1885 return mmc_suspend_host(mmc, event);
1500} 1886}
1501 1887
1502static int s3cmci_resume(struct platform_device *dev) 1888static int s3cmci_resume(struct device *dev)
1503{ 1889{
1504 struct mmc_host *mmc = platform_get_drvdata(dev); 1890 struct mmc_host *mmc = platform_get_drvdata(to_platform_device(dev));
1505 1891
1506 return mmc_resume_host(mmc); 1892 return mmc_resume_host(mmc);
1507} 1893}
1508 1894
1509#else /* CONFIG_PM */ 1895static struct dev_pm_ops s3cmci_pm = {
1510#define s3cmci_suspend NULL
1511#define s3cmci_resume NULL
1512#endif /* CONFIG_PM */
1513
1514
1515static struct platform_driver s3cmci_2410_driver = {
1516 .driver.name = "s3c2410-sdi",
1517 .driver.owner = THIS_MODULE,
1518 .probe = s3cmci_2410_probe,
1519 .remove = __devexit_p(s3cmci_remove),
1520 .shutdown = s3cmci_shutdown,
1521 .suspend = s3cmci_suspend, 1896 .suspend = s3cmci_suspend,
1522 .resume = s3cmci_resume, 1897 .resume = s3cmci_resume,
1523}; 1898};
1524 1899
1525static struct platform_driver s3cmci_2412_driver = { 1900#define s3cmci_pm_ops &s3cmci_pm
1526 .driver.name = "s3c2412-sdi", 1901#else /* CONFIG_PM */
1527 .driver.owner = THIS_MODULE, 1902#define s3cmci_pm_ops NULL
1528 .probe = s3cmci_2412_probe, 1903#endif /* CONFIG_PM */
1529 .remove = __devexit_p(s3cmci_remove),
1530 .shutdown = s3cmci_shutdown,
1531 .suspend = s3cmci_suspend,
1532 .resume = s3cmci_resume,
1533};
1534 1904
1535static struct platform_driver s3cmci_2440_driver = { 1905
1536 .driver.name = "s3c2440-sdi", 1906static struct platform_driver s3cmci_driver = {
1537 .driver.owner = THIS_MODULE, 1907 .driver = {
1538 .probe = s3cmci_2440_probe, 1908 .name = "s3c-sdi",
1909 .owner = THIS_MODULE,
1910 .pm = s3cmci_pm_ops,
1911 },
1912 .id_table = s3cmci_driver_ids,
1913 .probe = s3cmci_probe,
1539 .remove = __devexit_p(s3cmci_remove), 1914 .remove = __devexit_p(s3cmci_remove),
1540 .shutdown = s3cmci_shutdown, 1915 .shutdown = s3cmci_shutdown,
1541 .suspend = s3cmci_suspend,
1542 .resume = s3cmci_resume,
1543}; 1916};
1544 1917
1545
1546static int __init s3cmci_init(void) 1918static int __init s3cmci_init(void)
1547{ 1919{
1548 platform_driver_register(&s3cmci_2410_driver); 1920 return platform_driver_register(&s3cmci_driver);
1549 platform_driver_register(&s3cmci_2412_driver);
1550 platform_driver_register(&s3cmci_2440_driver);
1551 return 0;
1552} 1921}
1553 1922
1554static void __exit s3cmci_exit(void) 1923static void __exit s3cmci_exit(void)
1555{ 1924{
1556 platform_driver_unregister(&s3cmci_2410_driver); 1925 platform_driver_unregister(&s3cmci_driver);
1557 platform_driver_unregister(&s3cmci_2412_driver);
1558 platform_driver_unregister(&s3cmci_2440_driver);
1559} 1926}
1560 1927
1561module_init(s3cmci_init); 1928module_init(s3cmci_init);
@@ -1564,6 +1931,3 @@ module_exit(s3cmci_exit);
1564MODULE_DESCRIPTION("Samsung S3C MMC/SD Card Interface driver"); 1931MODULE_DESCRIPTION("Samsung S3C MMC/SD Card Interface driver");
1565MODULE_LICENSE("GPL v2"); 1932MODULE_LICENSE("GPL v2");
1566MODULE_AUTHOR("Thomas Kleffel <tk@maintech.de>, Ben Dooks <ben-linux@fluff.org>"); 1933MODULE_AUTHOR("Thomas Kleffel <tk@maintech.de>, Ben Dooks <ben-linux@fluff.org>");
1567MODULE_ALIAS("platform:s3c2410-sdi");
1568MODULE_ALIAS("platform:s3c2412-sdi");
1569MODULE_ALIAS("platform:s3c2440-sdi");
diff --git a/drivers/mmc/host/s3cmci.h b/drivers/mmc/host/s3cmci.h
index ca1ba3d58cfd..c76b53dbeb61 100644
--- a/drivers/mmc/host/s3cmci.h
+++ b/drivers/mmc/host/s3cmci.h
@@ -8,9 +8,6 @@
8 * published by the Free Software Foundation. 8 * published by the Free Software Foundation.
9 */ 9 */
10 10
11/* FIXME: DMA Resource management ?! */
12#define S3CMCI_DMA 0
13
14enum s3cmci_waitfor { 11enum s3cmci_waitfor {
15 COMPLETION_NONE, 12 COMPLETION_NONE,
16 COMPLETION_FINALIZE, 13 COMPLETION_FINALIZE,
@@ -42,6 +39,11 @@ struct s3cmci_host {
42 int dodma; 39 int dodma;
43 int dmatogo; 40 int dmatogo;
44 41
42 bool irq_disabled;
43 bool irq_enabled;
44 bool irq_state;
45 int sdio_irqen;
46
45 struct mmc_request *mrq; 47 struct mmc_request *mrq;
46 int cmd_is_stop; 48 int cmd_is_stop;
47 49
@@ -68,6 +70,12 @@ struct s3cmci_host {
68 unsigned int ccnt, dcnt; 70 unsigned int ccnt, dcnt;
69 struct tasklet_struct pio_tasklet; 71 struct tasklet_struct pio_tasklet;
70 72
73#ifdef CONFIG_DEBUG_FS
74 struct dentry *debug_root;
75 struct dentry *debug_state;
76 struct dentry *debug_regs;
77#endif
78
71#ifdef CONFIG_CPU_FREQ 79#ifdef CONFIG_CPU_FREQ
72 struct notifier_block freq_transition; 80 struct notifier_block freq_transition;
73#endif 81#endif
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 379c316f329e..4c19269de91a 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -21,6 +21,7 @@
21#include <linux/interrupt.h> 21#include <linux/interrupt.h>
22#include <linux/mutex.h> 22#include <linux/mutex.h>
23#include <linux/math64.h> 23#include <linux/math64.h>
24#include <linux/sched.h>
24 25
25#include <linux/mtd/mtd.h> 26#include <linux/mtd/mtd.h>
26#include <linux/mtd/partitions.h> 27#include <linux/mtd/partitions.h>
diff --git a/drivers/mtd/devices/sst25l.c b/drivers/mtd/devices/sst25l.c
index c2baf3353f84..0a11721f146e 100644
--- a/drivers/mtd/devices/sst25l.c
+++ b/drivers/mtd/devices/sst25l.c
@@ -20,6 +20,7 @@
20#include <linux/device.h> 20#include <linux/device.h>
21#include <linux/mutex.h> 21#include <linux/mutex.h>
22#include <linux/interrupt.h> 22#include <linux/interrupt.h>
23#include <linux/sched.h>
23 24
24#include <linux/mtd/mtd.h> 25#include <linux/mtd/mtd.h>
25#include <linux/mtd/partitions.h> 26#include <linux/mtd/partitions.h>
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index 0acbf4f5be50..8ca17a3e96ea 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -32,14 +32,6 @@ struct mtd_blkcore_priv {
32 spinlock_t queue_lock; 32 spinlock_t queue_lock;
33}; 33};
34 34
35static int blktrans_discard_request(struct request_queue *q,
36 struct request *req)
37{
38 req->cmd_type = REQ_TYPE_LINUX_BLOCK;
39 req->cmd[0] = REQ_LB_OP_DISCARD;
40 return 0;
41}
42
43static int do_blktrans_request(struct mtd_blktrans_ops *tr, 35static int do_blktrans_request(struct mtd_blktrans_ops *tr,
44 struct mtd_blktrans_dev *dev, 36 struct mtd_blktrans_dev *dev,
45 struct request *req) 37 struct request *req)
@@ -52,10 +44,6 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr,
52 44
53 buf = req->buffer; 45 buf = req->buffer;
54 46
55 if (req->cmd_type == REQ_TYPE_LINUX_BLOCK &&
56 req->cmd[0] == REQ_LB_OP_DISCARD)
57 return tr->discard(dev, block, nsect);
58
59 if (!blk_fs_request(req)) 47 if (!blk_fs_request(req))
60 return -EIO; 48 return -EIO;
61 49
@@ -63,6 +51,9 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr,
63 get_capacity(req->rq_disk)) 51 get_capacity(req->rq_disk))
64 return -EIO; 52 return -EIO;
65 53
54 if (blk_discard_rq(req))
55 return tr->discard(dev, block, nsect);
56
66 switch(rq_data_dir(req)) { 57 switch(rq_data_dir(req)) {
67 case READ: 58 case READ:
68 for (; nsect > 0; nsect--, block++, buf += tr->blksize) 59 for (; nsect > 0; nsect--, block++, buf += tr->blksize)
@@ -380,8 +371,8 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
380 tr->blkcore_priv->rq->queuedata = tr; 371 tr->blkcore_priv->rq->queuedata = tr;
381 blk_queue_logical_block_size(tr->blkcore_priv->rq, tr->blksize); 372 blk_queue_logical_block_size(tr->blkcore_priv->rq, tr->blksize);
382 if (tr->discard) 373 if (tr->discard)
383 blk_queue_set_discard(tr->blkcore_priv->rq, 374 queue_flag_set_unlocked(QUEUE_FLAG_DISCARD,
384 blktrans_discard_request); 375 tr->blkcore_priv->rq);
385 376
386 tr->blkshift = ffs(tr->blksize) - 1; 377 tr->blkshift = ffs(tr->blksize) - 1;
387 378
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index b9eeadf01b74..975e25b19ebe 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -805,52 +805,54 @@ static void poll_vortex(struct net_device *dev)
805 805
806#ifdef CONFIG_PM 806#ifdef CONFIG_PM
807 807
808static int vortex_suspend(struct pci_dev *pdev, pm_message_t state) 808static int vortex_suspend(struct device *dev)
809{ 809{
810 struct net_device *dev = pci_get_drvdata(pdev); 810 struct pci_dev *pdev = to_pci_dev(dev);
811 struct net_device *ndev = pci_get_drvdata(pdev);
812
813 if (!ndev || !netif_running(ndev))
814 return 0;
815
816 netif_device_detach(ndev);
817 vortex_down(ndev, 1);
811 818
812 if (dev && netdev_priv(dev)) {
813 if (netif_running(dev)) {
814 netif_device_detach(dev);
815 vortex_down(dev, 1);
816 disable_irq(dev->irq);
817 }
818 pci_save_state(pdev);
819 pci_enable_wake(pdev, pci_choose_state(pdev, state), 0);
820 pci_disable_device(pdev);
821 pci_set_power_state(pdev, pci_choose_state(pdev, state));
822 }
823 return 0; 819 return 0;
824} 820}
825 821
826static int vortex_resume(struct pci_dev *pdev) 822static int vortex_resume(struct device *dev)
827{ 823{
828 struct net_device *dev = pci_get_drvdata(pdev); 824 struct pci_dev *pdev = to_pci_dev(dev);
829 struct vortex_private *vp = netdev_priv(dev); 825 struct net_device *ndev = pci_get_drvdata(pdev);
830 int err; 826 int err;
831 827
832 if (dev && vp) { 828 if (!ndev || !netif_running(ndev))
833 pci_set_power_state(pdev, PCI_D0); 829 return 0;
834 pci_restore_state(pdev); 830
835 err = pci_enable_device(pdev); 831 err = vortex_up(ndev);
836 if (err) { 832 if (err)
837 pr_warning("%s: Could not enable device\n", 833 return err;
838 dev->name); 834
839 return err; 835 netif_device_attach(ndev);
840 } 836
841 pci_set_master(pdev);
842 if (netif_running(dev)) {
843 err = vortex_up(dev);
844 if (err)
845 return err;
846 enable_irq(dev->irq);
847 netif_device_attach(dev);
848 }
849 }
850 return 0; 837 return 0;
851} 838}
852 839
853#endif /* CONFIG_PM */ 840static struct dev_pm_ops vortex_pm_ops = {
841 .suspend = vortex_suspend,
842 .resume = vortex_resume,
843 .freeze = vortex_suspend,
844 .thaw = vortex_resume,
845 .poweroff = vortex_suspend,
846 .restore = vortex_resume,
847};
848
849#define VORTEX_PM_OPS (&vortex_pm_ops)
850
851#else /* !CONFIG_PM */
852
853#define VORTEX_PM_OPS NULL
854
855#endif /* !CONFIG_PM */
854 856
855#ifdef CONFIG_EISA 857#ifdef CONFIG_EISA
856static struct eisa_device_id vortex_eisa_ids[] = { 858static struct eisa_device_id vortex_eisa_ids[] = {
@@ -3199,10 +3201,7 @@ static struct pci_driver vortex_driver = {
3199 .probe = vortex_init_one, 3201 .probe = vortex_init_one,
3200 .remove = __devexit_p(vortex_remove_one), 3202 .remove = __devexit_p(vortex_remove_one),
3201 .id_table = vortex_pci_tbl, 3203 .id_table = vortex_pci_tbl,
3202#ifdef CONFIG_PM 3204 .driver.pm = VORTEX_PM_OPS,
3203 .suspend = vortex_suspend,
3204 .resume = vortex_resume,
3205#endif
3206}; 3205};
3207 3206
3208 3207
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 2bea67c134f0..e19ca4bb7510 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1738,6 +1738,14 @@ config KS8851
1738 help 1738 help
1739 SPI driver for Micrel KS8851 SPI attached network chip. 1739 SPI driver for Micrel KS8851 SPI attached network chip.
1740 1740
1741config KS8851_MLL
1742 tristate "Micrel KS8851 MLL"
1743 depends on HAS_IOMEM
1744 select MII
1745 help
1746 This platform driver is for Micrel KS8851 Address/data bus
1747 multiplexed network chip.
1748
1741config VIA_RHINE 1749config VIA_RHINE
1742 tristate "VIA Rhine support" 1750 tristate "VIA Rhine support"
1743 depends on NET_PCI && PCI 1751 depends on NET_PCI && PCI
@@ -2475,6 +2483,8 @@ config S6GMAC
2475 To compile this driver as a module, choose M here. The module 2483 To compile this driver as a module, choose M here. The module
2476 will be called s6gmac. 2484 will be called s6gmac.
2477 2485
2486source "drivers/net/stmmac/Kconfig"
2487
2478endif # NETDEV_1000 2488endif # NETDEV_1000
2479 2489
2480# 2490#
@@ -3223,4 +3233,12 @@ config VIRTIO_NET
3223 This is the virtual network driver for virtio. It can be used with 3233 This is the virtual network driver for virtio. It can be used with
3224 lguest or QEMU based VMMs (like KVM or Xen). Say Y or M. 3234 lguest or QEMU based VMMs (like KVM or Xen). Say Y or M.
3225 3235
3236config VMXNET3
3237 tristate "VMware VMXNET3 ethernet driver"
3238 depends on PCI && X86 && INET
3239 help
3240 This driver supports VMware's vmxnet3 virtual ethernet NIC.
3241 To compile this driver as a module, choose M here: the
3242 module will be called vmxnet3.
3243
3226endif # NETDEVICES 3244endif # NETDEVICES
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index ae8cd30f13d6..246323d7f161 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -2,6 +2,10 @@
2# Makefile for the Linux network (ethercard) device drivers. 2# Makefile for the Linux network (ethercard) device drivers.
3# 3#
4 4
5obj-$(CONFIG_MII) += mii.o
6obj-$(CONFIG_MDIO) += mdio.o
7obj-$(CONFIG_PHYLIB) += phy/
8
5obj-$(CONFIG_TI_DAVINCI_EMAC) += davinci_emac.o 9obj-$(CONFIG_TI_DAVINCI_EMAC) += davinci_emac.o
6 10
7obj-$(CONFIG_E1000) += e1000/ 11obj-$(CONFIG_E1000) += e1000/
@@ -26,6 +30,7 @@ obj-$(CONFIG_TEHUTI) += tehuti.o
26obj-$(CONFIG_ENIC) += enic/ 30obj-$(CONFIG_ENIC) += enic/
27obj-$(CONFIG_JME) += jme.o 31obj-$(CONFIG_JME) += jme.o
28obj-$(CONFIG_BE2NET) += benet/ 32obj-$(CONFIG_BE2NET) += benet/
33obj-$(CONFIG_VMXNET3) += vmxnet3/
29 34
30gianfar_driver-objs := gianfar.o \ 35gianfar_driver-objs := gianfar.o \
31 gianfar_ethtool.o \ 36 gianfar_ethtool.o \
@@ -89,20 +94,18 @@ obj-$(CONFIG_SKY2) += sky2.o
89obj-$(CONFIG_SKFP) += skfp/ 94obj-$(CONFIG_SKFP) += skfp/
90obj-$(CONFIG_KS8842) += ks8842.o 95obj-$(CONFIG_KS8842) += ks8842.o
91obj-$(CONFIG_KS8851) += ks8851.o 96obj-$(CONFIG_KS8851) += ks8851.o
97obj-$(CONFIG_KS8851_MLL) += ks8851_mll.o
92obj-$(CONFIG_VIA_RHINE) += via-rhine.o 98obj-$(CONFIG_VIA_RHINE) += via-rhine.o
93obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o 99obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o
94obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o 100obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o
95obj-$(CONFIG_RIONET) += rionet.o 101obj-$(CONFIG_RIONET) += rionet.o
96obj-$(CONFIG_SH_ETH) += sh_eth.o 102obj-$(CONFIG_SH_ETH) += sh_eth.o
103obj-$(CONFIG_STMMAC_ETH) += stmmac/
97 104
98# 105#
99# end link order section 106# end link order section
100# 107#
101 108
102obj-$(CONFIG_MII) += mii.o
103obj-$(CONFIG_MDIO) += mdio.o
104obj-$(CONFIG_PHYLIB) += phy/
105
106obj-$(CONFIG_SUNDANCE) += sundance.o 109obj-$(CONFIG_SUNDANCE) += sundance.o
107obj-$(CONFIG_HAMACHI) += hamachi.o 110obj-$(CONFIG_HAMACHI) += hamachi.o
108obj-$(CONFIG_NET) += Space.o loopback.o 111obj-$(CONFIG_NET) += Space.o loopback.o
diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c
index 5f0b05c2d71f..d82a9a994753 100644
--- a/drivers/net/acenic.c
+++ b/drivers/net/acenic.c
@@ -1209,7 +1209,8 @@ static int __devinit ace_init(struct net_device *dev)
1209 memset(ap->info, 0, sizeof(struct ace_info)); 1209 memset(ap->info, 0, sizeof(struct ace_info));
1210 memset(ap->skb, 0, sizeof(struct ace_skb)); 1210 memset(ap->skb, 0, sizeof(struct ace_skb));
1211 1211
1212 if (ace_load_firmware(dev)) 1212 ecode = ace_load_firmware(dev);
1213 if (ecode)
1213 goto init_error; 1214 goto init_error;
1214 1215
1215 ap->fw_running = 0; 1216 ap->fw_running = 0;
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index fdf5937233fc..04f63c77071d 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -721,7 +721,7 @@ static inline void update_rx_stats(struct net_device *dev, u32 status)
721 ps->rx_errors++; 721 ps->rx_errors++;
722 if (status & RX_MISSED_FRAME) 722 if (status & RX_MISSED_FRAME)
723 ps->rx_missed_errors++; 723 ps->rx_missed_errors++;
724 if (status & (RX_OVERLEN | RX_OVERLEN | RX_LEN_ERROR)) 724 if (status & (RX_OVERLEN | RX_RUNT | RX_LEN_ERROR))
725 ps->rx_length_errors++; 725 ps->rx_length_errors++;
726 if (status & RX_CRC_ERROR) 726 if (status & RX_CRC_ERROR)
727 ps->rx_crc_errors++; 727 ps->rx_crc_errors++;
@@ -794,8 +794,6 @@ static int au1000_rx(struct net_device *dev)
794 printk("rx len error\n"); 794 printk("rx len error\n");
795 if (status & RX_U_CNTRL_FRAME) 795 if (status & RX_U_CNTRL_FRAME)
796 printk("rx u control frame\n"); 796 printk("rx u control frame\n");
797 if (status & RX_MISSED_FRAME)
798 printk("rx miss\n");
799 } 797 }
800 } 798 }
801 prxd->buff_stat = (u32)(pDB->dma_addr | RX_DMA_ENABLE); 799 prxd->buff_stat = (u32)(pDB->dma_addr | RX_DMA_ENABLE);
diff --git a/drivers/net/bcm63xx_enet.c b/drivers/net/bcm63xx_enet.c
index 09d270913c50..ba29dc319b34 100644
--- a/drivers/net/bcm63xx_enet.c
+++ b/drivers/net/bcm63xx_enet.c
@@ -90,7 +90,7 @@ static int do_mdio_op(struct bcm_enet_priv *priv, unsigned int data)
90 if (enet_readl(priv, ENET_IR_REG) & ENET_IR_MII) 90 if (enet_readl(priv, ENET_IR_REG) & ENET_IR_MII)
91 break; 91 break;
92 udelay(1); 92 udelay(1);
93 } while (limit-- >= 0); 93 } while (limit-- > 0);
94 94
95 return (limit < 0) ? 1 : 0; 95 return (limit < 0) ? 1 : 0;
96} 96}
diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h
index 684c6fe24c8d..a80da0e14a52 100644
--- a/drivers/net/benet/be.h
+++ b/drivers/net/benet/be.h
@@ -258,6 +258,7 @@ struct be_adapter {
258 bool link_up; 258 bool link_up;
259 u32 port_num; 259 u32 port_num;
260 bool promiscuous; 260 bool promiscuous;
261 u32 cap;
261}; 262};
262 263
263extern const struct ethtool_ops be_ethtool_ops; 264extern const struct ethtool_ops be_ethtool_ops;
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c
index 3dd76c4170bf..89876ade5e33 100644
--- a/drivers/net/benet/be_cmds.c
+++ b/drivers/net/benet/be_cmds.c
@@ -1068,7 +1068,7 @@ int be_cmd_get_flow_control(struct be_adapter *adapter, u32 *tx_fc, u32 *rx_fc)
1068} 1068}
1069 1069
1070/* Uses mbox */ 1070/* Uses mbox */
1071int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num) 1071int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num, u32 *cap)
1072{ 1072{
1073 struct be_mcc_wrb *wrb; 1073 struct be_mcc_wrb *wrb;
1074 struct be_cmd_req_query_fw_cfg *req; 1074 struct be_cmd_req_query_fw_cfg *req;
@@ -1088,6 +1088,7 @@ int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num)
1088 if (!status) { 1088 if (!status) {
1089 struct be_cmd_resp_query_fw_cfg *resp = embedded_payload(wrb); 1089 struct be_cmd_resp_query_fw_cfg *resp = embedded_payload(wrb);
1090 *port_num = le32_to_cpu(resp->phys_port); 1090 *port_num = le32_to_cpu(resp->phys_port);
1091 *cap = le32_to_cpu(resp->function_cap);
1091 } 1092 }
1092 1093
1093 spin_unlock(&adapter->mbox_lock); 1094 spin_unlock(&adapter->mbox_lock);
@@ -1128,7 +1129,6 @@ int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd,
1128 spin_lock_bh(&adapter->mcc_lock); 1129 spin_lock_bh(&adapter->mcc_lock);
1129 1130
1130 wrb = wrb_from_mccq(adapter); 1131 wrb = wrb_from_mccq(adapter);
1131 req = embedded_payload(wrb);
1132 sge = nonembedded_sgl(wrb); 1132 sge = nonembedded_sgl(wrb);
1133 1133
1134 be_wrb_hdr_prepare(wrb, cmd->size, false, 1); 1134 be_wrb_hdr_prepare(wrb, cmd->size, false, 1);
diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h
index 93e432f3d926..a86f917f85f4 100644
--- a/drivers/net/benet/be_cmds.h
+++ b/drivers/net/benet/be_cmds.h
@@ -62,7 +62,7 @@ enum {
62 MCC_STATUS_QUEUE_FLUSHING = 0x4, 62 MCC_STATUS_QUEUE_FLUSHING = 0x4,
63/* The command is completing with a DMA error */ 63/* The command is completing with a DMA error */
64 MCC_STATUS_DMA_FAILED = 0x5, 64 MCC_STATUS_DMA_FAILED = 0x5,
65 MCC_STATUS_NOT_SUPPORTED = 0x66 65 MCC_STATUS_NOT_SUPPORTED = 66
66}; 66};
67 67
68#define CQE_STATUS_COMPL_MASK 0xFFFF 68#define CQE_STATUS_COMPL_MASK 0xFFFF
@@ -760,7 +760,8 @@ extern int be_cmd_set_flow_control(struct be_adapter *adapter,
760 u32 tx_fc, u32 rx_fc); 760 u32 tx_fc, u32 rx_fc);
761extern int be_cmd_get_flow_control(struct be_adapter *adapter, 761extern int be_cmd_get_flow_control(struct be_adapter *adapter,
762 u32 *tx_fc, u32 *rx_fc); 762 u32 *tx_fc, u32 *rx_fc);
763extern int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num); 763extern int be_cmd_query_fw_cfg(struct be_adapter *adapter,
764 u32 *port_num, u32 *cap);
764extern int be_cmd_reset_function(struct be_adapter *adapter); 765extern int be_cmd_reset_function(struct be_adapter *adapter);
765extern int be_process_mcc(struct be_adapter *adapter); 766extern int be_process_mcc(struct be_adapter *adapter);
766extern int be_cmd_write_flashrom(struct be_adapter *adapter, 767extern int be_cmd_write_flashrom(struct be_adapter *adapter,
diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c
index 11445df3dbc0..cda5bf2fc50a 100644
--- a/drivers/net/benet/be_ethtool.c
+++ b/drivers/net/benet/be_ethtool.c
@@ -358,7 +358,7 @@ const struct ethtool_ops be_ethtool_ops = {
358 .get_rx_csum = be_get_rx_csum, 358 .get_rx_csum = be_get_rx_csum,
359 .set_rx_csum = be_set_rx_csum, 359 .set_rx_csum = be_set_rx_csum,
360 .get_tx_csum = ethtool_op_get_tx_csum, 360 .get_tx_csum = ethtool_op_get_tx_csum,
361 .set_tx_csum = ethtool_op_set_tx_csum, 361 .set_tx_csum = ethtool_op_set_tx_hw_csum,
362 .get_sg = ethtool_op_get_sg, 362 .get_sg = ethtool_op_get_sg,
363 .set_sg = ethtool_op_set_sg, 363 .set_sg = ethtool_op_set_sg,
364 .get_tso = ethtool_op_get_tso, 364 .get_tso = ethtool_op_get_tso,
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index 409cf0595903..6d5e81f7046f 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -197,7 +197,7 @@ void netdev_stats_update(struct be_adapter *adapter)
197 /* no space available in linux */ 197 /* no space available in linux */
198 dev_stats->tx_dropped = 0; 198 dev_stats->tx_dropped = 0;
199 199
200 dev_stats->multicast = port_stats->tx_multicastframes; 200 dev_stats->multicast = port_stats->rx_multicast_frames;
201 dev_stats->collisions = 0; 201 dev_stats->collisions = 0;
202 202
203 /* detailed tx_errors */ 203 /* detailed tx_errors */
@@ -747,9 +747,16 @@ static void be_rx_compl_process(struct be_adapter *adapter,
747 struct be_eth_rx_compl *rxcp) 747 struct be_eth_rx_compl *rxcp)
748{ 748{
749 struct sk_buff *skb; 749 struct sk_buff *skb;
750 u32 vtp, vid; 750 u32 vlanf, vid;
751 u8 vtm;
751 752
752 vtp = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp); 753 vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp);
754 vtm = AMAP_GET_BITS(struct amap_eth_rx_compl, vtm, rxcp);
755
756 /* vlanf could be wrongly set in some cards.
757 * ignore if vtm is not set */
758 if ((adapter->cap == 0x400) && !vtm)
759 vlanf = 0;
753 760
754 skb = netdev_alloc_skb(adapter->netdev, BE_HDR_LEN + NET_IP_ALIGN); 761 skb = netdev_alloc_skb(adapter->netdev, BE_HDR_LEN + NET_IP_ALIGN);
755 if (!skb) { 762 if (!skb) {
@@ -772,7 +779,7 @@ static void be_rx_compl_process(struct be_adapter *adapter,
772 skb->protocol = eth_type_trans(skb, adapter->netdev); 779 skb->protocol = eth_type_trans(skb, adapter->netdev);
773 skb->dev = adapter->netdev; 780 skb->dev = adapter->netdev;
774 781
775 if (vtp) { 782 if (vlanf) {
776 if (!adapter->vlan_grp || adapter->num_vlans == 0) { 783 if (!adapter->vlan_grp || adapter->num_vlans == 0) {
777 kfree_skb(skb); 784 kfree_skb(skb);
778 return; 785 return;
@@ -797,11 +804,18 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter,
797 struct be_eq_obj *eq_obj = &adapter->rx_eq; 804 struct be_eq_obj *eq_obj = &adapter->rx_eq;
798 u32 num_rcvd, pkt_size, remaining, vlanf, curr_frag_len; 805 u32 num_rcvd, pkt_size, remaining, vlanf, curr_frag_len;
799 u16 i, rxq_idx = 0, vid, j; 806 u16 i, rxq_idx = 0, vid, j;
807 u8 vtm;
800 808
801 num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp); 809 num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp);
802 pkt_size = AMAP_GET_BITS(struct amap_eth_rx_compl, pktsize, rxcp); 810 pkt_size = AMAP_GET_BITS(struct amap_eth_rx_compl, pktsize, rxcp);
803 vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp); 811 vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp);
804 rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp); 812 rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp);
813 vtm = AMAP_GET_BITS(struct amap_eth_rx_compl, vtm, rxcp);
814
815 /* vlanf could be wrongly set in some cards.
816 * ignore if vtm is not set */
817 if ((adapter->cap == 0x400) && !vtm)
818 vlanf = 0;
805 819
806 skb = napi_get_frags(&eq_obj->napi); 820 skb = napi_get_frags(&eq_obj->napi);
807 if (!skb) { 821 if (!skb) {
@@ -1885,8 +1899,8 @@ static void be_netdev_init(struct net_device *netdev)
1885 struct be_adapter *adapter = netdev_priv(netdev); 1899 struct be_adapter *adapter = netdev_priv(netdev);
1886 1900
1887 netdev->features |= NETIF_F_SG | NETIF_F_HW_VLAN_RX | NETIF_F_TSO | 1901 netdev->features |= NETIF_F_SG | NETIF_F_HW_VLAN_RX | NETIF_F_TSO |
1888 NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER | NETIF_F_IP_CSUM | 1902 NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER | NETIF_F_HW_CSUM |
1889 NETIF_F_IPV6_CSUM | NETIF_F_GRO; 1903 NETIF_F_GRO;
1890 1904
1891 netdev->flags |= IFF_MULTICAST; 1905 netdev->flags |= IFF_MULTICAST;
1892 1906
@@ -2045,7 +2059,8 @@ static int be_hw_up(struct be_adapter *adapter)
2045 if (status) 2059 if (status)
2046 return status; 2060 return status;
2047 2061
2048 status = be_cmd_query_fw_cfg(adapter, &adapter->port_num); 2062 status = be_cmd_query_fw_cfg(adapter,
2063 &adapter->port_num, &adapter->cap);
2049 return status; 2064 return status;
2050} 2065}
2051 2066
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 6044e12ff9fc..8762a27a2a18 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -22,6 +22,7 @@
22#include <linux/kernel.h> 22#include <linux/kernel.h>
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/device.h> 24#include <linux/device.h>
25#include <linux/sched.h>
25#include <linux/sysdev.h> 26#include <linux/sysdev.h>
26#include <linux/fs.h> 27#include <linux/fs.h>
27#include <linux/types.h> 28#include <linux/types.h>
@@ -1182,6 +1183,7 @@ static ssize_t bonding_store_primary(struct device *d,
1182 ": %s: Setting %s as primary slave.\n", 1183 ": %s: Setting %s as primary slave.\n",
1183 bond->dev->name, slave->dev->name); 1184 bond->dev->name, slave->dev->name);
1184 bond->primary_slave = slave; 1185 bond->primary_slave = slave;
1186 strcpy(bond->params.primary, slave->dev->name);
1185 bond_select_active_slave(bond); 1187 bond_select_active_slave(bond);
1186 goto out; 1188 goto out;
1187 } 1189 }
diff --git a/drivers/net/can/sja1000/sja1000_of_platform.c b/drivers/net/can/sja1000/sja1000_of_platform.c
index 3373560405ba..9dd076a626a5 100644
--- a/drivers/net/can/sja1000/sja1000_of_platform.c
+++ b/drivers/net/can/sja1000/sja1000_of_platform.c
@@ -213,6 +213,7 @@ static struct of_device_id __devinitdata sja1000_ofp_table[] = {
213 {.compatible = "nxp,sja1000"}, 213 {.compatible = "nxp,sja1000"},
214 {}, 214 {},
215}; 215};
216MODULE_DEVICE_TABLE(of, sja1000_ofp_table);
216 217
217static struct of_platform_driver sja1000_ofp_driver = { 218static struct of_platform_driver sja1000_ofp_driver = {
218 .owner = THIS_MODULE, 219 .owner = THIS_MODULE,
diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c
index 211c8e9182fc..46c87ec7960c 100644
--- a/drivers/net/cnic.c
+++ b/drivers/net/cnic.c
@@ -2733,7 +2733,8 @@ static int cnic_netdev_event(struct notifier_block *this, unsigned long event,
2733 cnic_ulp_init(dev); 2733 cnic_ulp_init(dev);
2734 else if (event == NETDEV_UNREGISTER) 2734 else if (event == NETDEV_UNREGISTER)
2735 cnic_ulp_exit(dev); 2735 cnic_ulp_exit(dev);
2736 else if (event == NETDEV_UP) { 2736
2737 if (event == NETDEV_UP) {
2737 if (cnic_register_netdev(dev) != 0) { 2738 if (cnic_register_netdev(dev) != 0) {
2738 cnic_put(dev); 2739 cnic_put(dev);
2739 goto done; 2740 goto done;
diff --git a/drivers/net/cnic_if.h b/drivers/net/cnic_if.h
index a49235739eef..d8b09efdcb52 100644
--- a/drivers/net/cnic_if.h
+++ b/drivers/net/cnic_if.h
@@ -12,8 +12,8 @@
12#ifndef CNIC_IF_H 12#ifndef CNIC_IF_H
13#define CNIC_IF_H 13#define CNIC_IF_H
14 14
15#define CNIC_MODULE_VERSION "2.0.0" 15#define CNIC_MODULE_VERSION "2.0.1"
16#define CNIC_MODULE_RELDATE "May 21, 2009" 16#define CNIC_MODULE_RELDATE "Oct 01, 2009"
17 17
18#define CNIC_ULP_RDMA 0 18#define CNIC_ULP_RDMA 0
19#define CNIC_ULP_ISCSI 1 19#define CNIC_ULP_ISCSI 1
diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c
index 65a2d0ba64e2..f72c56dec33c 100644
--- a/drivers/net/davinci_emac.c
+++ b/drivers/net/davinci_emac.c
@@ -333,6 +333,9 @@ static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1";
333#define EMAC_DM646X_MAC_EOI_C0_RXEN (0x01) 333#define EMAC_DM646X_MAC_EOI_C0_RXEN (0x01)
334#define EMAC_DM646X_MAC_EOI_C0_TXEN (0x02) 334#define EMAC_DM646X_MAC_EOI_C0_TXEN (0x02)
335 335
336/* EMAC Stats Clear Mask */
337#define EMAC_STATS_CLR_MASK (0xFFFFFFFF)
338
336/** net_buf_obj: EMAC network bufferdata structure 339/** net_buf_obj: EMAC network bufferdata structure
337 * 340 *
338 * EMAC network buffer data structure 341 * EMAC network buffer data structure
@@ -2548,40 +2551,49 @@ static int emac_dev_stop(struct net_device *ndev)
2548static struct net_device_stats *emac_dev_getnetstats(struct net_device *ndev) 2551static struct net_device_stats *emac_dev_getnetstats(struct net_device *ndev)
2549{ 2552{
2550 struct emac_priv *priv = netdev_priv(ndev); 2553 struct emac_priv *priv = netdev_priv(ndev);
2554 u32 mac_control;
2555 u32 stats_clear_mask;
2551 2556
2552 /* update emac hardware stats and reset the registers*/ 2557 /* update emac hardware stats and reset the registers*/
2553 2558
2559 mac_control = emac_read(EMAC_MACCONTROL);
2560
2561 if (mac_control & EMAC_MACCONTROL_GMIIEN)
2562 stats_clear_mask = EMAC_STATS_CLR_MASK;
2563 else
2564 stats_clear_mask = 0;
2565
2554 priv->net_dev_stats.multicast += emac_read(EMAC_RXMCASTFRAMES); 2566 priv->net_dev_stats.multicast += emac_read(EMAC_RXMCASTFRAMES);
2555 emac_write(EMAC_RXMCASTFRAMES, EMAC_ALL_MULTI_REG_VALUE); 2567 emac_write(EMAC_RXMCASTFRAMES, stats_clear_mask);
2556 2568
2557 priv->net_dev_stats.collisions += (emac_read(EMAC_TXCOLLISION) + 2569 priv->net_dev_stats.collisions += (emac_read(EMAC_TXCOLLISION) +
2558 emac_read(EMAC_TXSINGLECOLL) + 2570 emac_read(EMAC_TXSINGLECOLL) +
2559 emac_read(EMAC_TXMULTICOLL)); 2571 emac_read(EMAC_TXMULTICOLL));
2560 emac_write(EMAC_TXCOLLISION, EMAC_ALL_MULTI_REG_VALUE); 2572 emac_write(EMAC_TXCOLLISION, stats_clear_mask);
2561 emac_write(EMAC_TXSINGLECOLL, EMAC_ALL_MULTI_REG_VALUE); 2573 emac_write(EMAC_TXSINGLECOLL, stats_clear_mask);
2562 emac_write(EMAC_TXMULTICOLL, EMAC_ALL_MULTI_REG_VALUE); 2574 emac_write(EMAC_TXMULTICOLL, stats_clear_mask);
2563 2575
2564 priv->net_dev_stats.rx_length_errors += (emac_read(EMAC_RXOVERSIZED) + 2576 priv->net_dev_stats.rx_length_errors += (emac_read(EMAC_RXOVERSIZED) +
2565 emac_read(EMAC_RXJABBER) + 2577 emac_read(EMAC_RXJABBER) +
2566 emac_read(EMAC_RXUNDERSIZED)); 2578 emac_read(EMAC_RXUNDERSIZED));
2567 emac_write(EMAC_RXOVERSIZED, EMAC_ALL_MULTI_REG_VALUE); 2579 emac_write(EMAC_RXOVERSIZED, stats_clear_mask);
2568 emac_write(EMAC_RXJABBER, EMAC_ALL_MULTI_REG_VALUE); 2580 emac_write(EMAC_RXJABBER, stats_clear_mask);
2569 emac_write(EMAC_RXUNDERSIZED, EMAC_ALL_MULTI_REG_VALUE); 2581 emac_write(EMAC_RXUNDERSIZED, stats_clear_mask);
2570 2582
2571 priv->net_dev_stats.rx_over_errors += (emac_read(EMAC_RXSOFOVERRUNS) + 2583 priv->net_dev_stats.rx_over_errors += (emac_read(EMAC_RXSOFOVERRUNS) +
2572 emac_read(EMAC_RXMOFOVERRUNS)); 2584 emac_read(EMAC_RXMOFOVERRUNS));
2573 emac_write(EMAC_RXSOFOVERRUNS, EMAC_ALL_MULTI_REG_VALUE); 2585 emac_write(EMAC_RXSOFOVERRUNS, stats_clear_mask);
2574 emac_write(EMAC_RXMOFOVERRUNS, EMAC_ALL_MULTI_REG_VALUE); 2586 emac_write(EMAC_RXMOFOVERRUNS, stats_clear_mask);
2575 2587
2576 priv->net_dev_stats.rx_fifo_errors += emac_read(EMAC_RXDMAOVERRUNS); 2588 priv->net_dev_stats.rx_fifo_errors += emac_read(EMAC_RXDMAOVERRUNS);
2577 emac_write(EMAC_RXDMAOVERRUNS, EMAC_ALL_MULTI_REG_VALUE); 2589 emac_write(EMAC_RXDMAOVERRUNS, stats_clear_mask);
2578 2590
2579 priv->net_dev_stats.tx_carrier_errors += 2591 priv->net_dev_stats.tx_carrier_errors +=
2580 emac_read(EMAC_TXCARRIERSENSE); 2592 emac_read(EMAC_TXCARRIERSENSE);
2581 emac_write(EMAC_TXCARRIERSENSE, EMAC_ALL_MULTI_REG_VALUE); 2593 emac_write(EMAC_TXCARRIERSENSE, stats_clear_mask);
2582 2594
2583 priv->net_dev_stats.tx_fifo_errors = emac_read(EMAC_TXUNDERRUN); 2595 priv->net_dev_stats.tx_fifo_errors = emac_read(EMAC_TXUNDERRUN);
2584 emac_write(EMAC_TXUNDERRUN, EMAC_ALL_MULTI_REG_VALUE); 2596 emac_write(EMAC_TXUNDERRUN, stats_clear_mask);
2585 2597
2586 return &priv->net_dev_stats; 2598 return &priv->net_dev_stats;
2587} 2599}
diff --git a/drivers/net/depca.c b/drivers/net/depca.c
index 9686c1fa28f1..7a3bdac84abe 100644
--- a/drivers/net/depca.c
+++ b/drivers/net/depca.c
@@ -237,6 +237,7 @@
237 237
238#include <linux/module.h> 238#include <linux/module.h>
239#include <linux/kernel.h> 239#include <linux/kernel.h>
240#include <linux/sched.h>
240#include <linux/string.h> 241#include <linux/string.h>
241#include <linux/errno.h> 242#include <linux/errno.h>
242#include <linux/ioport.h> 243#include <linux/ioport.h>
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index 679965c2bb86..5d2f48f02251 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -151,6 +151,7 @@
151#include <linux/moduleparam.h> 151#include <linux/moduleparam.h>
152#include <linux/kernel.h> 152#include <linux/kernel.h>
153#include <linux/types.h> 153#include <linux/types.h>
154#include <linux/sched.h>
154#include <linux/slab.h> 155#include <linux/slab.h>
155#include <linux/delay.h> 156#include <linux/delay.h>
156#include <linux/init.h> 157#include <linux/init.h>
diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c
index b53b40ba88a8..d1e0563a67df 100644
--- a/drivers/net/e1000e/82571.c
+++ b/drivers/net/e1000e/82571.c
@@ -1803,7 +1803,7 @@ struct e1000_info e1000_82574_info = {
1803 | FLAG_HAS_AMT 1803 | FLAG_HAS_AMT
1804 | FLAG_HAS_CTRLEXT_ON_LOAD, 1804 | FLAG_HAS_CTRLEXT_ON_LOAD,
1805 .pba = 20, 1805 .pba = 20,
1806 .max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN, 1806 .max_hw_frame_size = DEFAULT_JUMBO,
1807 .get_variants = e1000_get_variants_82571, 1807 .get_variants = e1000_get_variants_82571,
1808 .mac_ops = &e82571_mac_ops, 1808 .mac_ops = &e82571_mac_ops,
1809 .phy_ops = &e82_phy_ops_bm, 1809 .phy_ops = &e82_phy_ops_bm,
@@ -1820,7 +1820,7 @@ struct e1000_info e1000_82583_info = {
1820 | FLAG_HAS_AMT 1820 | FLAG_HAS_AMT
1821 | FLAG_HAS_CTRLEXT_ON_LOAD, 1821 | FLAG_HAS_CTRLEXT_ON_LOAD,
1822 .pba = 20, 1822 .pba = 20,
1823 .max_hw_frame_size = DEFAULT_JUMBO, 1823 .max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN,
1824 .get_variants = e1000_get_variants_82571, 1824 .get_variants = e1000_get_variants_82571,
1825 .mac_ops = &e82571_mac_ops, 1825 .mac_ops = &e82571_mac_ops,
1826 .phy_ops = &e82_phy_ops_bm, 1826 .phy_ops = &e82_phy_ops_bm,
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 16c193a6c95c..0687c6aa4e46 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -4982,12 +4982,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
4982 goto err_pci_reg; 4982 goto err_pci_reg;
4983 4983
4984 /* AER (Advanced Error Reporting) hooks */ 4984 /* AER (Advanced Error Reporting) hooks */
4985 err = pci_enable_pcie_error_reporting(pdev); 4985 pci_enable_pcie_error_reporting(pdev);
4986 if (err) {
4987 dev_err(&pdev->dev, "pci_enable_pcie_error_reporting failed "
4988 "0x%x\n", err);
4989 /* non-fatal, continue */
4990 }
4991 4986
4992 pci_set_master(pdev); 4987 pci_set_master(pdev);
4993 /* PCI config space info */ 4988 /* PCI config space info */
@@ -5263,7 +5258,6 @@ static void __devexit e1000_remove(struct pci_dev *pdev)
5263{ 5258{
5264 struct net_device *netdev = pci_get_drvdata(pdev); 5259 struct net_device *netdev = pci_get_drvdata(pdev);
5265 struct e1000_adapter *adapter = netdev_priv(netdev); 5260 struct e1000_adapter *adapter = netdev_priv(netdev);
5266 int err;
5267 5261
5268 /* 5262 /*
5269 * flush_scheduled work may reschedule our watchdog task, so 5263 * flush_scheduled work may reschedule our watchdog task, so
@@ -5299,10 +5293,7 @@ static void __devexit e1000_remove(struct pci_dev *pdev)
5299 free_netdev(netdev); 5293 free_netdev(netdev);
5300 5294
5301 /* AER disable */ 5295 /* AER disable */
5302 err = pci_disable_pcie_error_reporting(pdev); 5296 pci_disable_pcie_error_reporting(pdev);
5303 if (err)
5304 dev_err(&pdev->dev,
5305 "pci_disable_pcie_error_reporting failed 0x%x\n", err);
5306 5297
5307 pci_disable_device(pdev); 5298 pci_disable_device(pdev);
5308} 5299}
diff --git a/drivers/net/eql.c b/drivers/net/eql.c
index d4d9a3eda695..f5b96cadeb25 100644
--- a/drivers/net/eql.c
+++ b/drivers/net/eql.c
@@ -111,6 +111,7 @@
111 * Sorry, I had to rewrite most of this for 2.5.x -DaveM 111 * Sorry, I had to rewrite most of this for 2.5.x -DaveM
112 */ 112 */
113 113
114#include <linux/capability.h>
114#include <linux/module.h> 115#include <linux/module.h>
115#include <linux/kernel.h> 116#include <linux/kernel.h>
116#include <linux/init.h> 117#include <linux/init.h>
diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c
index b7311bc00258..9c950bb5e90c 100644
--- a/drivers/net/ethoc.c
+++ b/drivers/net/ethoc.c
@@ -17,8 +17,13 @@
17#include <linux/mii.h> 17#include <linux/mii.h>
18#include <linux/phy.h> 18#include <linux/phy.h>
19#include <linux/platform_device.h> 19#include <linux/platform_device.h>
20#include <linux/sched.h>
20#include <net/ethoc.h> 21#include <net/ethoc.h>
21 22
23static int buffer_size = 0x8000; /* 32 KBytes */
24module_param(buffer_size, int, 0);
25MODULE_PARM_DESC(buffer_size, "DMA buffer allocation size");
26
22/* register offsets */ 27/* register offsets */
23#define MODER 0x00 28#define MODER 0x00
24#define INT_SOURCE 0x04 29#define INT_SOURCE 0x04
@@ -167,6 +172,7 @@
167 * struct ethoc - driver-private device structure 172 * struct ethoc - driver-private device structure
168 * @iobase: pointer to I/O memory region 173 * @iobase: pointer to I/O memory region
169 * @membase: pointer to buffer memory region 174 * @membase: pointer to buffer memory region
175 * @dma_alloc: dma allocated buffer size
170 * @num_tx: number of send buffers 176 * @num_tx: number of send buffers
171 * @cur_tx: last send buffer written 177 * @cur_tx: last send buffer written
172 * @dty_tx: last buffer actually sent 178 * @dty_tx: last buffer actually sent
@@ -185,6 +191,7 @@
185struct ethoc { 191struct ethoc {
186 void __iomem *iobase; 192 void __iomem *iobase;
187 void __iomem *membase; 193 void __iomem *membase;
194 int dma_alloc;
188 195
189 unsigned int num_tx; 196 unsigned int num_tx;
190 unsigned int cur_tx; 197 unsigned int cur_tx;
@@ -284,7 +291,7 @@ static int ethoc_init_ring(struct ethoc *dev)
284 dev->cur_rx = 0; 291 dev->cur_rx = 0;
285 292
286 /* setup transmission buffers */ 293 /* setup transmission buffers */
287 bd.addr = 0; 294 bd.addr = virt_to_phys(dev->membase);
288 bd.stat = TX_BD_IRQ | TX_BD_CRC; 295 bd.stat = TX_BD_IRQ | TX_BD_CRC;
289 296
290 for (i = 0; i < dev->num_tx; i++) { 297 for (i = 0; i < dev->num_tx; i++) {
@@ -295,7 +302,6 @@ static int ethoc_init_ring(struct ethoc *dev)
295 bd.addr += ETHOC_BUFSIZ; 302 bd.addr += ETHOC_BUFSIZ;
296 } 303 }
297 304
298 bd.addr = dev->num_tx * ETHOC_BUFSIZ;
299 bd.stat = RX_BD_EMPTY | RX_BD_IRQ; 305 bd.stat = RX_BD_EMPTY | RX_BD_IRQ;
300 306
301 for (i = 0; i < dev->num_rx; i++) { 307 for (i = 0; i < dev->num_rx; i++) {
@@ -400,8 +406,12 @@ static int ethoc_rx(struct net_device *dev, int limit)
400 if (ethoc_update_rx_stats(priv, &bd) == 0) { 406 if (ethoc_update_rx_stats(priv, &bd) == 0) {
401 int size = bd.stat >> 16; 407 int size = bd.stat >> 16;
402 struct sk_buff *skb = netdev_alloc_skb(dev, size); 408 struct sk_buff *skb = netdev_alloc_skb(dev, size);
409
410 size -= 4; /* strip the CRC */
411 skb_reserve(skb, 2); /* align TCP/IP header */
412
403 if (likely(skb)) { 413 if (likely(skb)) {
404 void *src = priv->membase + bd.addr; 414 void *src = phys_to_virt(bd.addr);
405 memcpy_fromio(skb_put(skb, size), src, size); 415 memcpy_fromio(skb_put(skb, size), src, size);
406 skb->protocol = eth_type_trans(skb, dev); 416 skb->protocol = eth_type_trans(skb, dev);
407 priv->stats.rx_packets++; 417 priv->stats.rx_packets++;
@@ -653,9 +663,10 @@ static int ethoc_open(struct net_device *dev)
653 if (ret) 663 if (ret)
654 return ret; 664 return ret;
655 665
656 /* calculate the number of TX/RX buffers */ 666 /* calculate the number of TX/RX buffers, maximum 128 supported */
657 num_bd = (dev->mem_end - dev->mem_start + 1) / ETHOC_BUFSIZ; 667 num_bd = min_t(unsigned int,
658 priv->num_tx = min(min_tx, num_bd / 4); 668 128, (dev->mem_end - dev->mem_start + 1) / ETHOC_BUFSIZ);
669 priv->num_tx = max(min_tx, num_bd / 4);
659 priv->num_rx = num_bd - priv->num_tx; 670 priv->num_rx = num_bd - priv->num_tx;
660 ethoc_write(priv, TX_BD_NUM, priv->num_tx); 671 ethoc_write(priv, TX_BD_NUM, priv->num_tx);
661 672
@@ -823,7 +834,7 @@ static netdev_tx_t ethoc_start_xmit(struct sk_buff *skb, struct net_device *dev)
823 else 834 else
824 bd.stat &= ~TX_BD_PAD; 835 bd.stat &= ~TX_BD_PAD;
825 836
826 dest = priv->membase + bd.addr; 837 dest = phys_to_virt(bd.addr);
827 memcpy_toio(dest, skb->data, skb->len); 838 memcpy_toio(dest, skb->data, skb->len);
828 839
829 bd.stat &= ~(TX_BD_STATS | TX_BD_LEN_MASK); 840 bd.stat &= ~(TX_BD_STATS | TX_BD_LEN_MASK);
@@ -903,22 +914,19 @@ static int ethoc_probe(struct platform_device *pdev)
903 914
904 /* obtain buffer memory space */ 915 /* obtain buffer memory space */
905 res = platform_get_resource(pdev, IORESOURCE_MEM, 1); 916 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
906 if (!res) { 917 if (res) {
907 dev_err(&pdev->dev, "cannot obtain memory space\n"); 918 mem = devm_request_mem_region(&pdev->dev, res->start,
908 ret = -ENXIO;
909 goto free;
910 }
911
912 mem = devm_request_mem_region(&pdev->dev, res->start,
913 res->end - res->start + 1, res->name); 919 res->end - res->start + 1, res->name);
914 if (!mem) { 920 if (!mem) {
915 dev_err(&pdev->dev, "cannot request memory space\n"); 921 dev_err(&pdev->dev, "cannot request memory space\n");
916 ret = -ENXIO; 922 ret = -ENXIO;
917 goto free; 923 goto free;
924 }
925
926 netdev->mem_start = mem->start;
927 netdev->mem_end = mem->end;
918 } 928 }
919 929
920 netdev->mem_start = mem->start;
921 netdev->mem_end = mem->end;
922 930
923 /* obtain device IRQ number */ 931 /* obtain device IRQ number */
924 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 932 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
@@ -933,6 +941,7 @@ static int ethoc_probe(struct platform_device *pdev)
933 /* setup driver-private data */ 941 /* setup driver-private data */
934 priv = netdev_priv(netdev); 942 priv = netdev_priv(netdev);
935 priv->netdev = netdev; 943 priv->netdev = netdev;
944 priv->dma_alloc = 0;
936 945
937 priv->iobase = devm_ioremap_nocache(&pdev->dev, netdev->base_addr, 946 priv->iobase = devm_ioremap_nocache(&pdev->dev, netdev->base_addr,
938 mmio->end - mmio->start + 1); 947 mmio->end - mmio->start + 1);
@@ -942,12 +951,27 @@ static int ethoc_probe(struct platform_device *pdev)
942 goto error; 951 goto error;
943 } 952 }
944 953
945 priv->membase = devm_ioremap_nocache(&pdev->dev, netdev->mem_start, 954 if (netdev->mem_end) {
946 mem->end - mem->start + 1); 955 priv->membase = devm_ioremap_nocache(&pdev->dev,
947 if (!priv->membase) { 956 netdev->mem_start, mem->end - mem->start + 1);
948 dev_err(&pdev->dev, "cannot remap memory space\n"); 957 if (!priv->membase) {
949 ret = -ENXIO; 958 dev_err(&pdev->dev, "cannot remap memory space\n");
950 goto error; 959 ret = -ENXIO;
960 goto error;
961 }
962 } else {
963 /* Allocate buffer memory */
964 priv->membase = dma_alloc_coherent(NULL,
965 buffer_size, (void *)&netdev->mem_start,
966 GFP_KERNEL);
967 if (!priv->membase) {
968 dev_err(&pdev->dev, "cannot allocate %dB buffer\n",
969 buffer_size);
970 ret = -ENOMEM;
971 goto error;
972 }
973 netdev->mem_end = netdev->mem_start + buffer_size;
974 priv->dma_alloc = buffer_size;
951 } 975 }
952 976
953 /* Allow the platform setup code to pass in a MAC address. */ 977 /* Allow the platform setup code to pass in a MAC address. */
@@ -1034,6 +1058,9 @@ free_mdio:
1034 kfree(priv->mdio->irq); 1058 kfree(priv->mdio->irq);
1035 mdiobus_free(priv->mdio); 1059 mdiobus_free(priv->mdio);
1036free: 1060free:
1061 if (priv->dma_alloc)
1062 dma_free_coherent(NULL, priv->dma_alloc, priv->membase,
1063 netdev->mem_start);
1037 free_netdev(netdev); 1064 free_netdev(netdev);
1038out: 1065out:
1039 return ret; 1066 return ret;
@@ -1059,7 +1086,9 @@ static int ethoc_remove(struct platform_device *pdev)
1059 kfree(priv->mdio->irq); 1086 kfree(priv->mdio->irq);
1060 mdiobus_free(priv->mdio); 1087 mdiobus_free(priv->mdio);
1061 } 1088 }
1062 1089 if (priv->dma_alloc)
1090 dma_free_coherent(NULL, priv->dma_alloc, priv->membase,
1091 netdev->mem_start);
1063 unregister_netdev(netdev); 1092 unregister_netdev(netdev);
1064 free_netdev(netdev); 1093 free_netdev(netdev);
1065 } 1094 }
diff --git a/drivers/net/ewrk3.c b/drivers/net/ewrk3.c
index b2a5ec8f3721..dd4ba01fd92d 100644
--- a/drivers/net/ewrk3.c
+++ b/drivers/net/ewrk3.c
@@ -145,6 +145,7 @@
145 145
146#include <linux/module.h> 146#include <linux/module.h>
147#include <linux/kernel.h> 147#include <linux/kernel.h>
148#include <linux/sched.h>
148#include <linux/string.h> 149#include <linux/string.h>
149#include <linux/errno.h> 150#include <linux/errno.h>
150#include <linux/ioport.h> 151#include <linux/ioport.h>
diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c
index c40113f58963..66dace6d324f 100644
--- a/drivers/net/fec_mpc52xx.c
+++ b/drivers/net/fec_mpc52xx.c
@@ -759,12 +759,6 @@ static void mpc52xx_fec_reset(struct net_device *dev)
759 759
760 mpc52xx_fec_hw_init(dev); 760 mpc52xx_fec_hw_init(dev);
761 761
762 if (priv->phydev) {
763 phy_stop(priv->phydev);
764 phy_write(priv->phydev, MII_BMCR, BMCR_RESET);
765 phy_start(priv->phydev);
766 }
767
768 bcom_fec_rx_reset(priv->rx_dmatsk); 762 bcom_fec_rx_reset(priv->rx_dmatsk);
769 bcom_fec_tx_reset(priv->tx_dmatsk); 763 bcom_fec_tx_reset(priv->tx_dmatsk);
770 764
diff --git a/drivers/net/fec_mpc52xx_phy.c b/drivers/net/fec_mpc52xx_phy.c
index 31e6d62b785d..ee0f3c6d3f88 100644
--- a/drivers/net/fec_mpc52xx_phy.c
+++ b/drivers/net/fec_mpc52xx_phy.c
@@ -155,6 +155,7 @@ static struct of_device_id mpc52xx_fec_mdio_match[] = {
155 { .compatible = "mpc5200b-fec-phy", }, 155 { .compatible = "mpc5200b-fec-phy", },
156 {} 156 {}
157}; 157};
158MODULE_DEVICE_TABLE(of, mpc52xx_fec_mdio_match);
158 159
159struct of_platform_driver mpc52xx_fec_mdio_driver = { 160struct of_platform_driver mpc52xx_fec_mdio_driver = {
160 .name = "mpc5200b-fec-phy", 161 .name = "mpc5200b-fec-phy",
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 0a1c2bb27d4d..e1da4666f204 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -49,6 +49,7 @@
49#include <linux/netdevice.h> 49#include <linux/netdevice.h>
50#include <linux/etherdevice.h> 50#include <linux/etherdevice.h>
51#include <linux/delay.h> 51#include <linux/delay.h>
52#include <linux/sched.h>
52#include <linux/spinlock.h> 53#include <linux/spinlock.h>
53#include <linux/ethtool.h> 54#include <linux/ethtool.h>
54#include <linux/timer.h> 55#include <linux/timer.h>
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c
index 2bc2d2b20644..ec2f5034457f 100644
--- a/drivers/net/fs_enet/fs_enet-main.c
+++ b/drivers/net/fs_enet/fs_enet-main.c
@@ -1110,6 +1110,7 @@ static struct of_device_id fs_enet_match[] = {
1110#endif 1110#endif
1111 {} 1111 {}
1112}; 1112};
1113MODULE_DEVICE_TABLE(of, fs_enet_match);
1113 1114
1114static struct of_platform_driver fs_enet_driver = { 1115static struct of_platform_driver fs_enet_driver = {
1115 .name = "fs_enet", 1116 .name = "fs_enet",
diff --git a/drivers/net/fs_enet/mii-bitbang.c b/drivers/net/fs_enet/mii-bitbang.c
index 93b481b0e3c7..24ff9f43a62b 100644
--- a/drivers/net/fs_enet/mii-bitbang.c
+++ b/drivers/net/fs_enet/mii-bitbang.c
@@ -221,6 +221,7 @@ static struct of_device_id fs_enet_mdio_bb_match[] = {
221 }, 221 },
222 {}, 222 {},
223}; 223};
224MODULE_DEVICE_TABLE(of, fs_enet_mdio_bb_match);
224 225
225static struct of_platform_driver fs_enet_bb_mdio_driver = { 226static struct of_platform_driver fs_enet_bb_mdio_driver = {
226 .name = "fsl-bb-mdio", 227 .name = "fsl-bb-mdio",
diff --git a/drivers/net/fs_enet/mii-fec.c b/drivers/net/fs_enet/mii-fec.c
index a2d69c1cd07e..96eba4280c5c 100644
--- a/drivers/net/fs_enet/mii-fec.c
+++ b/drivers/net/fs_enet/mii-fec.c
@@ -219,6 +219,7 @@ static struct of_device_id fs_enet_mdio_fec_match[] = {
219#endif 219#endif
220 {}, 220 {},
221}; 221};
222MODULE_DEVICE_TABLE(of, fs_enet_mdio_fec_match);
222 223
223static struct of_platform_driver fs_enet_fec_mdio_driver = { 224static struct of_platform_driver fs_enet_fec_mdio_driver = {
224 .name = "fsl-fec-mdio", 225 .name = "fsl-fec-mdio",
diff --git a/drivers/net/fsl_pq_mdio.c b/drivers/net/fsl_pq_mdio.c
index d167090248e2..6ac464866972 100644
--- a/drivers/net/fsl_pq_mdio.c
+++ b/drivers/net/fsl_pq_mdio.c
@@ -407,6 +407,7 @@ static struct of_device_id fsl_pq_mdio_match[] = {
407 }, 407 },
408 {}, 408 {},
409}; 409};
410MODULE_DEVICE_TABLE(of, fsl_pq_mdio_match);
410 411
411static struct of_platform_driver fsl_pq_mdio_driver = { 412static struct of_platform_driver fsl_pq_mdio_driver = {
412 .name = "fsl-pq_mdio", 413 .name = "fsl-pq_mdio",
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 1e5289ffef6f..5bf31f1509c9 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -2325,9 +2325,6 @@ static irqreturn_t gfar_error(int irq, void *dev_id)
2325 return IRQ_HANDLED; 2325 return IRQ_HANDLED;
2326} 2326}
2327 2327
2328/* work with hotplug and coldplug */
2329MODULE_ALIAS("platform:fsl-gianfar");
2330
2331static struct of_device_id gfar_match[] = 2328static struct of_device_id gfar_match[] =
2332{ 2329{
2333 { 2330 {
@@ -2336,6 +2333,7 @@ static struct of_device_id gfar_match[] =
2336 }, 2333 },
2337 {}, 2334 {},
2338}; 2335};
2336MODULE_DEVICE_TABLE(of, gfar_match);
2339 2337
2340/* Structure for a device driver */ 2338/* Structure for a device driver */
2341static struct of_platform_driver gfar_driver = { 2339static struct of_platform_driver gfar_driver = {
diff --git a/drivers/net/hamachi.c b/drivers/net/hamachi.c
index 1d5064a09aca..f7519a594945 100644
--- a/drivers/net/hamachi.c
+++ b/drivers/net/hamachi.c
@@ -145,6 +145,7 @@ static int tx_params[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
145/* Time in jiffies before concluding the transmitter is hung. */ 145/* Time in jiffies before concluding the transmitter is hung. */
146#define TX_TIMEOUT (5*HZ) 146#define TX_TIMEOUT (5*HZ)
147 147
148#include <linux/capability.h>
148#include <linux/module.h> 149#include <linux/module.h>
149#include <linux/kernel.h> 150#include <linux/kernel.h>
150#include <linux/string.h> 151#include <linux/string.h>
diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c
index 7bcaf7c66243..e344c84c0ef9 100644
--- a/drivers/net/hamradio/baycom_epp.c
+++ b/drivers/net/hamradio/baycom_epp.c
@@ -44,6 +44,7 @@
44#include <linux/module.h> 44#include <linux/module.h>
45#include <linux/kernel.h> 45#include <linux/kernel.h>
46#include <linux/init.h> 46#include <linux/init.h>
47#include <linux/sched.h>
47#include <linux/string.h> 48#include <linux/string.h>
48#include <linux/workqueue.h> 49#include <linux/workqueue.h>
49#include <linux/fs.h> 50#include <linux/fs.h>
diff --git a/drivers/net/hamradio/baycom_ser_fdx.c b/drivers/net/hamradio/baycom_ser_fdx.c
index aa4488e871b2..ed60fd664273 100644
--- a/drivers/net/hamradio/baycom_ser_fdx.c
+++ b/drivers/net/hamradio/baycom_ser_fdx.c
@@ -71,6 +71,7 @@
71 71
72/*****************************************************************************/ 72/*****************************************************************************/
73 73
74#include <linux/capability.h>
74#include <linux/module.h> 75#include <linux/module.h>
75#include <linux/ioport.h> 76#include <linux/ioport.h>
76#include <linux/string.h> 77#include <linux/string.h>
diff --git a/drivers/net/hamradio/baycom_ser_hdx.c b/drivers/net/hamradio/baycom_ser_hdx.c
index 88c593596020..1686f6dcbbce 100644
--- a/drivers/net/hamradio/baycom_ser_hdx.c
+++ b/drivers/net/hamradio/baycom_ser_hdx.c
@@ -61,6 +61,7 @@
61 61
62/*****************************************************************************/ 62/*****************************************************************************/
63 63
64#include <linux/capability.h>
64#include <linux/module.h> 65#include <linux/module.h>
65#include <linux/ioport.h> 66#include <linux/ioport.h>
66#include <linux/string.h> 67#include <linux/string.h>
diff --git a/drivers/net/hamradio/hdlcdrv.c b/drivers/net/hamradio/hdlcdrv.c
index 0013c409782c..91c5790c9581 100644
--- a/drivers/net/hamradio/hdlcdrv.c
+++ b/drivers/net/hamradio/hdlcdrv.c
@@ -42,6 +42,7 @@
42 42
43/*****************************************************************************/ 43/*****************************************************************************/
44 44
45#include <linux/capability.h>
45#include <linux/module.h> 46#include <linux/module.h>
46#include <linux/types.h> 47#include <linux/types.h>
47#include <linux/net.h> 48#include <linux/net.h>
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index 33b55f729742..db4b7f1603f6 100644
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -258,7 +258,7 @@ static void ax_bump(struct mkiss *ax)
258 } 258 }
259 if (ax->crcmode != CRC_MODE_SMACK && ax->crcauto) { 259 if (ax->crcmode != CRC_MODE_SMACK && ax->crcauto) {
260 printk(KERN_INFO 260 printk(KERN_INFO
261 "mkiss: %s: Switchting to crc-smack\n", 261 "mkiss: %s: Switching to crc-smack\n",
262 ax->dev->name); 262 ax->dev->name);
263 ax->crcmode = CRC_MODE_SMACK; 263 ax->crcmode = CRC_MODE_SMACK;
264 } 264 }
@@ -272,7 +272,7 @@ static void ax_bump(struct mkiss *ax)
272 } 272 }
273 if (ax->crcmode != CRC_MODE_FLEX && ax->crcauto) { 273 if (ax->crcmode != CRC_MODE_FLEX && ax->crcauto) {
274 printk(KERN_INFO 274 printk(KERN_INFO
275 "mkiss: %s: Switchting to crc-flexnet\n", 275 "mkiss: %s: Switching to crc-flexnet\n",
276 ax->dev->name); 276 ax->dev->name);
277 ax->crcmode = CRC_MODE_FLEX; 277 ax->crcmode = CRC_MODE_FLEX;
278 } 278 }
diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c
index a9a1a99f02dd..dd8665138062 100644
--- a/drivers/net/hp100.c
+++ b/drivers/net/hp100.c
@@ -98,6 +98,7 @@
98 98
99#include <linux/module.h> 99#include <linux/module.h>
100#include <linux/kernel.h> 100#include <linux/kernel.h>
101#include <linux/sched.h>
101#include <linux/string.h> 102#include <linux/string.h>
102#include <linux/errno.h> 103#include <linux/errno.h>
103#include <linux/ioport.h> 104#include <linux/ioport.h>
diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c
index 89c82c5e63e4..3fae87559791 100644
--- a/drivers/net/ibm_newemac/core.c
+++ b/drivers/net/ibm_newemac/core.c
@@ -24,6 +24,7 @@
24 * 24 *
25 */ 25 */
26 26
27#include <linux/module.h>
27#include <linux/sched.h> 28#include <linux/sched.h>
28#include <linux/string.h> 29#include <linux/string.h>
29#include <linux/errno.h> 30#include <linux/errno.h>
@@ -443,7 +444,7 @@ static u32 __emac_calc_base_mr1(struct emac_instance *dev, int tx_size, int rx_s
443 ret |= EMAC_MR1_TFS_2K; 444 ret |= EMAC_MR1_TFS_2K;
444 break; 445 break;
445 default: 446 default:
446 printk(KERN_WARNING "%s: Unknown Rx FIFO size %d\n", 447 printk(KERN_WARNING "%s: Unknown Tx FIFO size %d\n",
447 dev->ndev->name, tx_size); 448 dev->ndev->name, tx_size);
448 } 449 }
449 450
@@ -470,6 +471,9 @@ static u32 __emac4_calc_base_mr1(struct emac_instance *dev, int tx_size, int rx_
470 DBG2(dev, "__emac4_calc_base_mr1" NL); 471 DBG2(dev, "__emac4_calc_base_mr1" NL);
471 472
472 switch(tx_size) { 473 switch(tx_size) {
474 case 16384:
475 ret |= EMAC4_MR1_TFS_16K;
476 break;
473 case 4096: 477 case 4096:
474 ret |= EMAC4_MR1_TFS_4K; 478 ret |= EMAC4_MR1_TFS_4K;
475 break; 479 break;
@@ -477,7 +481,7 @@ static u32 __emac4_calc_base_mr1(struct emac_instance *dev, int tx_size, int rx_
477 ret |= EMAC4_MR1_TFS_2K; 481 ret |= EMAC4_MR1_TFS_2K;
478 break; 482 break;
479 default: 483 default:
480 printk(KERN_WARNING "%s: Unknown Rx FIFO size %d\n", 484 printk(KERN_WARNING "%s: Unknown Tx FIFO size %d\n",
481 dev->ndev->name, tx_size); 485 dev->ndev->name, tx_size);
482 } 486 }
483 487
@@ -2985,6 +2989,7 @@ static struct of_device_id emac_match[] =
2985 }, 2989 },
2986 {}, 2990 {},
2987}; 2991};
2992MODULE_DEVICE_TABLE(of, emac_match);
2988 2993
2989static struct of_platform_driver emac_driver = { 2994static struct of_platform_driver emac_driver = {
2990 .name = "emac", 2995 .name = "emac",
diff --git a/drivers/net/ibm_newemac/emac.h b/drivers/net/ibm_newemac/emac.h
index 0afc2cf5c52b..d34adf99fc6a 100644
--- a/drivers/net/ibm_newemac/emac.h
+++ b/drivers/net/ibm_newemac/emac.h
@@ -153,6 +153,7 @@ struct emac_regs {
153#define EMAC4_MR1_RFS_16K 0x00280000 153#define EMAC4_MR1_RFS_16K 0x00280000
154#define EMAC4_MR1_TFS_2K 0x00020000 154#define EMAC4_MR1_TFS_2K 0x00020000
155#define EMAC4_MR1_TFS_4K 0x00030000 155#define EMAC4_MR1_TFS_4K 0x00030000
156#define EMAC4_MR1_TFS_16K 0x00050000
156#define EMAC4_MR1_TR 0x00008000 157#define EMAC4_MR1_TR 0x00008000
157#define EMAC4_MR1_MWSW_001 0x00001000 158#define EMAC4_MR1_MWSW_001 0x00001000
158#define EMAC4_MR1_JPSM 0x00000800 159#define EMAC4_MR1_JPSM 0x00000800
diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c
index d004c359244c..deaea8fa1032 100644
--- a/drivers/net/igb/igb_ethtool.c
+++ b/drivers/net/igb/igb_ethtool.c
@@ -34,6 +34,7 @@
34#include <linux/interrupt.h> 34#include <linux/interrupt.h>
35#include <linux/if_ether.h> 35#include <linux/if_ether.h>
36#include <linux/ethtool.h> 36#include <linux/ethtool.h>
37#include <linux/sched.h>
37 38
38#include "igb.h" 39#include "igb.h"
39 40
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index 5d6c1530a8c0..714c3a4a44ef 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -1246,12 +1246,7 @@ static int __devinit igb_probe(struct pci_dev *pdev,
1246 if (err) 1246 if (err)
1247 goto err_pci_reg; 1247 goto err_pci_reg;
1248 1248
1249 err = pci_enable_pcie_error_reporting(pdev); 1249 pci_enable_pcie_error_reporting(pdev);
1250 if (err) {
1251 dev_err(&pdev->dev, "pci_enable_pcie_error_reporting failed "
1252 "0x%x\n", err);
1253 /* non-fatal, continue */
1254 }
1255 1250
1256 pci_set_master(pdev); 1251 pci_set_master(pdev);
1257 pci_save_state(pdev); 1252 pci_save_state(pdev);
@@ -1628,7 +1623,6 @@ static void __devexit igb_remove(struct pci_dev *pdev)
1628 struct net_device *netdev = pci_get_drvdata(pdev); 1623 struct net_device *netdev = pci_get_drvdata(pdev);
1629 struct igb_adapter *adapter = netdev_priv(netdev); 1624 struct igb_adapter *adapter = netdev_priv(netdev);
1630 struct e1000_hw *hw = &adapter->hw; 1625 struct e1000_hw *hw = &adapter->hw;
1631 int err;
1632 1626
1633 /* flush_scheduled work may reschedule our watchdog task, so 1627 /* flush_scheduled work may reschedule our watchdog task, so
1634 * explicitly disable watchdog tasks from being rescheduled */ 1628 * explicitly disable watchdog tasks from being rescheduled */
@@ -1682,10 +1676,7 @@ static void __devexit igb_remove(struct pci_dev *pdev)
1682 1676
1683 free_netdev(netdev); 1677 free_netdev(netdev);
1684 1678
1685 err = pci_disable_pcie_error_reporting(pdev); 1679 pci_disable_pcie_error_reporting(pdev);
1686 if (err)
1687 dev_err(&pdev->dev,
1688 "pci_disable_pcie_error_reporting failed 0x%x\n", err);
1689 1680
1690 pci_disable_device(pdev); 1681 pci_disable_device(pdev);
1691} 1682}
diff --git a/drivers/net/irda/sa1100_ir.c b/drivers/net/irda/sa1100_ir.c
index 38bf7cf2256d..c412e8026173 100644
--- a/drivers/net/irda/sa1100_ir.c
+++ b/drivers/net/irda/sa1100_ir.c
@@ -232,8 +232,11 @@ static int sa1100_irda_startup(struct sa1100_irda *si)
232 /* 232 /*
233 * Ensure that the ports for this device are setup correctly. 233 * Ensure that the ports for this device are setup correctly.
234 */ 234 */
235 if (si->pdata->startup) 235 if (si->pdata->startup) {
236 si->pdata->startup(si->dev); 236 ret = si->pdata->startup(si->dev);
237 if (ret)
238 return ret;
239 }
237 240
238 /* 241 /*
239 * Configure PPC for IRDA - we want to drive TXD2 low. 242 * Configure PPC for IRDA - we want to drive TXD2 low.
diff --git a/drivers/net/irda/toim3232-sir.c b/drivers/net/irda/toim3232-sir.c
index fcf287b749db..99e1ec02a011 100644
--- a/drivers/net/irda/toim3232-sir.c
+++ b/drivers/net/irda/toim3232-sir.c
@@ -120,6 +120,7 @@
120#include <linux/module.h> 120#include <linux/module.h>
121#include <linux/delay.h> 121#include <linux/delay.h>
122#include <linux/init.h> 122#include <linux/init.h>
123#include <linux/sched.h>
123 124
124#include <net/irda/irda.h> 125#include <net/irda/irda.h>
125 126
diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c
index e36e951cbc65..aa7286bc4364 100644
--- a/drivers/net/iseries_veth.c
+++ b/drivers/net/iseries_veth.c
@@ -495,7 +495,7 @@ static void veth_take_cap_ack(struct veth_lpar_connection *cnx,
495 cnx->remote_lp); 495 cnx->remote_lp);
496 } else { 496 } else {
497 memcpy(&cnx->cap_ack_event, event, 497 memcpy(&cnx->cap_ack_event, event,
498 sizeof(&cnx->cap_ack_event)); 498 sizeof(cnx->cap_ack_event));
499 cnx->state |= VETH_STATE_GOTCAPACK; 499 cnx->state |= VETH_STATE_GOTCAPACK;
500 veth_kick_statemachine(cnx); 500 veth_kick_statemachine(cnx);
501 } 501 }
diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c
index 56b12f3192f1..e2d5343f1275 100644
--- a/drivers/net/ixgbe/ixgbe_82598.c
+++ b/drivers/net/ixgbe/ixgbe_82598.c
@@ -425,7 +425,7 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
425#endif /* CONFIG_DCB */ 425#endif /* CONFIG_DCB */
426 default: 426 default:
427 hw_dbg(hw, "Flow control param set incorrectly\n"); 427 hw_dbg(hw, "Flow control param set incorrectly\n");
428 ret_val = -IXGBE_ERR_CONFIG; 428 ret_val = IXGBE_ERR_CONFIG;
429 goto out; 429 goto out;
430 break; 430 break;
431 } 431 }
diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c
index 2ec58dcdb82b..34b04924c8a1 100644
--- a/drivers/net/ixgbe/ixgbe_82599.c
+++ b/drivers/net/ixgbe/ixgbe_82599.c
@@ -330,6 +330,8 @@ static enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw)
330 330
331 switch (hw->device_id) { 331 switch (hw->device_id) {
332 case IXGBE_DEV_ID_82599_KX4: 332 case IXGBE_DEV_ID_82599_KX4:
333 case IXGBE_DEV_ID_82599_KX4_MEZZ:
334 case IXGBE_DEV_ID_82599_COMBO_BACKPLANE:
333 case IXGBE_DEV_ID_82599_XAUI_LOM: 335 case IXGBE_DEV_ID_82599_XAUI_LOM:
334 /* Default device ID is mezzanine card KX/KX4 */ 336 /* Default device ID is mezzanine card KX/KX4 */
335 media_type = ixgbe_media_type_backplane; 337 media_type = ixgbe_media_type_backplane;
diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c
index 6621e172df3d..40ff120a9ad4 100644
--- a/drivers/net/ixgbe/ixgbe_common.c
+++ b/drivers/net/ixgbe/ixgbe_common.c
@@ -1355,9 +1355,7 @@ static void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq)
1355/** 1355/**
1356 * ixgbe_update_uc_addr_list_generic - Updates MAC list of secondary addresses 1356 * ixgbe_update_uc_addr_list_generic - Updates MAC list of secondary addresses
1357 * @hw: pointer to hardware structure 1357 * @hw: pointer to hardware structure
1358 * @addr_list: the list of new addresses 1358 * @uc_list: the list of new addresses
1359 * @addr_count: number of addresses
1360 * @next: iterator function to walk the address list
1361 * 1359 *
1362 * The given list replaces any existing list. Clears the secondary addrs from 1360 * The given list replaces any existing list. Clears the secondary addrs from
1363 * receive address registers. Uses unused receive address registers for the 1361 * receive address registers. Uses unused receive address registers for the
@@ -1663,7 +1661,7 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw, s32 packetbuf_num)
1663#endif /* CONFIG_DCB */ 1661#endif /* CONFIG_DCB */
1664 default: 1662 default:
1665 hw_dbg(hw, "Flow control param set incorrectly\n"); 1663 hw_dbg(hw, "Flow control param set incorrectly\n");
1666 ret_val = -IXGBE_ERR_CONFIG; 1664 ret_val = IXGBE_ERR_CONFIG;
1667 goto out; 1665 goto out;
1668 break; 1666 break;
1669 } 1667 }
@@ -1734,75 +1732,140 @@ s32 ixgbe_fc_autoneg(struct ixgbe_hw *hw)
1734 s32 ret_val = 0; 1732 s32 ret_val = 0;
1735 ixgbe_link_speed speed; 1733 ixgbe_link_speed speed;
1736 u32 pcs_anadv_reg, pcs_lpab_reg, linkstat; 1734 u32 pcs_anadv_reg, pcs_lpab_reg, linkstat;
1735 u32 links2, anlp1_reg, autoc_reg, links;
1737 bool link_up; 1736 bool link_up;
1738 1737
1739 /* 1738 /*
1740 * AN should have completed when the cable was plugged in. 1739 * AN should have completed when the cable was plugged in.
1741 * Look for reasons to bail out. Bail out if: 1740 * Look for reasons to bail out. Bail out if:
1742 * - FC autoneg is disabled, or if 1741 * - FC autoneg is disabled, or if
1743 * - we don't have multispeed fiber, or if 1742 * - link is not up.
1744 * - we're not running at 1G, or if
1745 * - link is not up, or if
1746 * - link is up but AN did not complete, or if
1747 * - link is up and AN completed but timed out
1748 * 1743 *
1749 * Since we're being called from an LSC, link is already know to be up. 1744 * Since we're being called from an LSC, link is already known to be up.
1750 * So use link_up_wait_to_complete=false. 1745 * So use link_up_wait_to_complete=false.
1751 */ 1746 */
1752 hw->mac.ops.check_link(hw, &speed, &link_up, false); 1747 hw->mac.ops.check_link(hw, &speed, &link_up, false);
1753 linkstat = IXGBE_READ_REG(hw, IXGBE_PCS1GLSTA); 1748
1754 1749 if (hw->fc.disable_fc_autoneg || (!link_up)) {
1755 if (hw->fc.disable_fc_autoneg ||
1756 !hw->phy.multispeed_fiber ||
1757 (speed != IXGBE_LINK_SPEED_1GB_FULL) ||
1758 !link_up ||
1759 ((linkstat & IXGBE_PCS1GLSTA_AN_COMPLETE) == 0) ||
1760 ((linkstat & IXGBE_PCS1GLSTA_AN_TIMED_OUT) == 1)) {
1761 hw->fc.fc_was_autonegged = false; 1750 hw->fc.fc_was_autonegged = false;
1762 hw->fc.current_mode = hw->fc.requested_mode; 1751 hw->fc.current_mode = hw->fc.requested_mode;
1763 hw_dbg(hw, "Autoneg FC was skipped.\n");
1764 goto out; 1752 goto out;
1765 } 1753 }
1766 1754
1767 /* 1755 /*
1756 * On backplane, bail out if
1757 * - backplane autoneg was not completed, or if
1758 * - link partner is not AN enabled
1759 */
1760 if (hw->phy.media_type == ixgbe_media_type_backplane) {
1761 links = IXGBE_READ_REG(hw, IXGBE_LINKS);
1762 links2 = IXGBE_READ_REG(hw, IXGBE_LINKS2);
1763 if (((links & IXGBE_LINKS_KX_AN_COMP) == 0) ||
1764 ((links2 & IXGBE_LINKS2_AN_SUPPORTED) == 0)) {
1765 hw->fc.fc_was_autonegged = false;
1766 hw->fc.current_mode = hw->fc.requested_mode;
1767 goto out;
1768 }
1769 }
1770
1771 /*
1772 * On multispeed fiber at 1g, bail out if
1773 * - link is up but AN did not complete, or if
1774 * - link is up and AN completed but timed out
1775 */
1776 if (hw->phy.multispeed_fiber && (speed == IXGBE_LINK_SPEED_1GB_FULL)) {
1777 linkstat = IXGBE_READ_REG(hw, IXGBE_PCS1GLSTA);
1778 if (((linkstat & IXGBE_PCS1GLSTA_AN_COMPLETE) == 0) ||
1779 ((linkstat & IXGBE_PCS1GLSTA_AN_TIMED_OUT) == 1)) {
1780 hw->fc.fc_was_autonegged = false;
1781 hw->fc.current_mode = hw->fc.requested_mode;
1782 goto out;
1783 }
1784 }
1785
1786 /*
1768 * Read the AN advertisement and LP ability registers and resolve 1787 * Read the AN advertisement and LP ability registers and resolve
1769 * local flow control settings accordingly 1788 * local flow control settings accordingly
1770 */ 1789 */
1771 pcs_anadv_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA); 1790 if ((speed == IXGBE_LINK_SPEED_1GB_FULL) &&
1772 pcs_lpab_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANLP); 1791 (hw->phy.media_type != ixgbe_media_type_backplane)) {
1773 if ((pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) && 1792 pcs_anadv_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA);
1774 (pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE)) { 1793 pcs_lpab_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANLP);
1794 if ((pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
1795 (pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE)) {
1796 /*
1797 * Now we need to check if the user selected Rx ONLY
1798 * of pause frames. In this case, we had to advertise
1799 * FULL flow control because we could not advertise RX
1800 * ONLY. Hence, we must now check to see if we need to
1801 * turn OFF the TRANSMISSION of PAUSE frames.
1802 */
1803 if (hw->fc.requested_mode == ixgbe_fc_full) {
1804 hw->fc.current_mode = ixgbe_fc_full;
1805 hw_dbg(hw, "Flow Control = FULL.\n");
1806 } else {
1807 hw->fc.current_mode = ixgbe_fc_rx_pause;
1808 hw_dbg(hw, "Flow Control=RX PAUSE only\n");
1809 }
1810 } else if (!(pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
1811 (pcs_anadv_reg & IXGBE_PCS1GANA_ASM_PAUSE) &&
1812 (pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
1813 (pcs_lpab_reg & IXGBE_PCS1GANA_ASM_PAUSE)) {
1814 hw->fc.current_mode = ixgbe_fc_tx_pause;
1815 hw_dbg(hw, "Flow Control = TX PAUSE frames only.\n");
1816 } else if ((pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
1817 (pcs_anadv_reg & IXGBE_PCS1GANA_ASM_PAUSE) &&
1818 !(pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
1819 (pcs_lpab_reg & IXGBE_PCS1GANA_ASM_PAUSE)) {
1820 hw->fc.current_mode = ixgbe_fc_rx_pause;
1821 hw_dbg(hw, "Flow Control = RX PAUSE frames only.\n");
1822 } else {
1823 hw->fc.current_mode = ixgbe_fc_none;
1824 hw_dbg(hw, "Flow Control = NONE.\n");
1825 }
1826 }
1827
1828 if (hw->phy.media_type == ixgbe_media_type_backplane) {
1775 /* 1829 /*
1776 * Now we need to check if the user selected Rx ONLY 1830 * Read the 10g AN autoc and LP ability registers and resolve
1777 * of pause frames. In this case, we had to advertise 1831 * local flow control settings accordingly
1778 * FULL flow control because we could not advertise RX
1779 * ONLY. Hence, we must now check to see if we need to
1780 * turn OFF the TRANSMISSION of PAUSE frames.
1781 */ 1832 */
1782 if (hw->fc.requested_mode == ixgbe_fc_full) { 1833 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
1783 hw->fc.current_mode = ixgbe_fc_full; 1834 anlp1_reg = IXGBE_READ_REG(hw, IXGBE_ANLP1);
1784 hw_dbg(hw, "Flow Control = FULL.\n"); 1835
1785 } else { 1836 if ((autoc_reg & IXGBE_AUTOC_SYM_PAUSE) &&
1837 (anlp1_reg & IXGBE_ANLP1_SYM_PAUSE)) {
1838 /*
1839 * Now we need to check if the user selected Rx ONLY
1840 * of pause frames. In this case, we had to advertise
1841 * FULL flow control because we could not advertise RX
1842 * ONLY. Hence, we must now check to see if we need to
1843 * turn OFF the TRANSMISSION of PAUSE frames.
1844 */
1845 if (hw->fc.requested_mode == ixgbe_fc_full) {
1846 hw->fc.current_mode = ixgbe_fc_full;
1847 hw_dbg(hw, "Flow Control = FULL.\n");
1848 } else {
1849 hw->fc.current_mode = ixgbe_fc_rx_pause;
1850 hw_dbg(hw, "Flow Control=RX PAUSE only\n");
1851 }
1852 } else if (!(autoc_reg & IXGBE_AUTOC_SYM_PAUSE) &&
1853 (autoc_reg & IXGBE_AUTOC_ASM_PAUSE) &&
1854 (anlp1_reg & IXGBE_ANLP1_SYM_PAUSE) &&
1855 (anlp1_reg & IXGBE_ANLP1_ASM_PAUSE)) {
1856 hw->fc.current_mode = ixgbe_fc_tx_pause;
1857 hw_dbg(hw, "Flow Control = TX PAUSE frames only.\n");
1858 } else if ((autoc_reg & IXGBE_AUTOC_SYM_PAUSE) &&
1859 (autoc_reg & IXGBE_AUTOC_ASM_PAUSE) &&
1860 !(anlp1_reg & IXGBE_ANLP1_SYM_PAUSE) &&
1861 (anlp1_reg & IXGBE_ANLP1_ASM_PAUSE)) {
1786 hw->fc.current_mode = ixgbe_fc_rx_pause; 1862 hw->fc.current_mode = ixgbe_fc_rx_pause;
1787 hw_dbg(hw, "Flow Control = RX PAUSE frames only.\n"); 1863 hw_dbg(hw, "Flow Control = RX PAUSE frames only.\n");
1864 } else {
1865 hw->fc.current_mode = ixgbe_fc_none;
1866 hw_dbg(hw, "Flow Control = NONE.\n");
1788 } 1867 }
1789 } else if (!(pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
1790 (pcs_anadv_reg & IXGBE_PCS1GANA_ASM_PAUSE) &&
1791 (pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
1792 (pcs_lpab_reg & IXGBE_PCS1GANA_ASM_PAUSE)) {
1793 hw->fc.current_mode = ixgbe_fc_tx_pause;
1794 hw_dbg(hw, "Flow Control = TX PAUSE frames only.\n");
1795 } else if ((pcs_anadv_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
1796 (pcs_anadv_reg & IXGBE_PCS1GANA_ASM_PAUSE) &&
1797 !(pcs_lpab_reg & IXGBE_PCS1GANA_SYM_PAUSE) &&
1798 (pcs_lpab_reg & IXGBE_PCS1GANA_ASM_PAUSE)) {
1799 hw->fc.current_mode = ixgbe_fc_rx_pause;
1800 hw_dbg(hw, "Flow Control = RX PAUSE frames only.\n");
1801 } else {
1802 hw->fc.current_mode = ixgbe_fc_none;
1803 hw_dbg(hw, "Flow Control = NONE.\n");
1804 } 1868 }
1805
1806 /* Record that current_mode is the result of a successful autoneg */ 1869 /* Record that current_mode is the result of a successful autoneg */
1807 hw->fc.fc_was_autonegged = true; 1870 hw->fc.fc_was_autonegged = true;
1808 1871
@@ -1919,7 +1982,7 @@ static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num)
1919#endif /* CONFIG_DCB */ 1982#endif /* CONFIG_DCB */
1920 default: 1983 default:
1921 hw_dbg(hw, "Flow control param set incorrectly\n"); 1984 hw_dbg(hw, "Flow control param set incorrectly\n");
1922 ret_val = -IXGBE_ERR_CONFIG; 1985 ret_val = IXGBE_ERR_CONFIG;
1923 goto out; 1986 goto out;
1924 break; 1987 break;
1925 } 1988 }
@@ -1927,9 +1990,6 @@ static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num)
1927 IXGBE_WRITE_REG(hw, IXGBE_PCS1GANA, reg); 1990 IXGBE_WRITE_REG(hw, IXGBE_PCS1GANA, reg);
1928 reg = IXGBE_READ_REG(hw, IXGBE_PCS1GLCTL); 1991 reg = IXGBE_READ_REG(hw, IXGBE_PCS1GLCTL);
1929 1992
1930 /* Enable and restart autoneg to inform the link partner */
1931 reg |= IXGBE_PCS1GLCTL_AN_ENABLE | IXGBE_PCS1GLCTL_AN_RESTART;
1932
1933 /* Disable AN timeout */ 1993 /* Disable AN timeout */
1934 if (hw->fc.strict_ieee) 1994 if (hw->fc.strict_ieee)
1935 reg &= ~IXGBE_PCS1GLCTL_AN_1G_TIMEOUT_EN; 1995 reg &= ~IXGBE_PCS1GLCTL_AN_1G_TIMEOUT_EN;
@@ -1937,6 +1997,70 @@ static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num)
1937 IXGBE_WRITE_REG(hw, IXGBE_PCS1GLCTL, reg); 1997 IXGBE_WRITE_REG(hw, IXGBE_PCS1GLCTL, reg);
1938 hw_dbg(hw, "Set up FC; PCS1GLCTL = 0x%08X\n", reg); 1998 hw_dbg(hw, "Set up FC; PCS1GLCTL = 0x%08X\n", reg);
1939 1999
2000 /*
2001 * Set up the 10G flow control advertisement registers so the HW
2002 * can do fc autoneg once the cable is plugged in. If we end up
2003 * using 1g instead, this is harmless.
2004 */
2005 reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
2006
2007 /*
2008 * The possible values of fc.requested_mode are:
2009 * 0: Flow control is completely disabled
2010 * 1: Rx flow control is enabled (we can receive pause frames,
2011 * but not send pause frames).
2012 * 2: Tx flow control is enabled (we can send pause frames but
2013 * we do not support receiving pause frames).
2014 * 3: Both Rx and Tx flow control (symmetric) are enabled.
2015 * other: Invalid.
2016 */
2017 switch (hw->fc.requested_mode) {
2018 case ixgbe_fc_none:
2019 /* Flow control completely disabled by software override. */
2020 reg &= ~(IXGBE_AUTOC_SYM_PAUSE | IXGBE_AUTOC_ASM_PAUSE);
2021 break;
2022 case ixgbe_fc_rx_pause:
2023 /*
2024 * Rx Flow control is enabled and Tx Flow control is
2025 * disabled by software override. Since there really
2026 * isn't a way to advertise that we are capable of RX
2027 * Pause ONLY, we will advertise that we support both
2028 * symmetric and asymmetric Rx PAUSE. Later, we will
2029 * disable the adapter's ability to send PAUSE frames.
2030 */
2031 reg |= (IXGBE_AUTOC_SYM_PAUSE | IXGBE_AUTOC_ASM_PAUSE);
2032 break;
2033 case ixgbe_fc_tx_pause:
2034 /*
2035 * Tx Flow control is enabled, and Rx Flow control is
2036 * disabled by software override.
2037 */
2038 reg |= (IXGBE_AUTOC_ASM_PAUSE);
2039 reg &= ~(IXGBE_AUTOC_SYM_PAUSE);
2040 break;
2041 case ixgbe_fc_full:
2042 /* Flow control (both Rx and Tx) is enabled by SW override. */
2043 reg |= (IXGBE_AUTOC_SYM_PAUSE | IXGBE_AUTOC_ASM_PAUSE);
2044 break;
2045#ifdef CONFIG_DCB
2046 case ixgbe_fc_pfc:
2047 goto out;
2048 break;
2049#endif /* CONFIG_DCB */
2050 default:
2051 hw_dbg(hw, "Flow control param set incorrectly\n");
2052 ret_val = IXGBE_ERR_CONFIG;
2053 goto out;
2054 break;
2055 }
2056 /*
2057 * AUTOC restart handles negotiation of 1G and 10G. There is
2058 * no need to set the PCS1GCTL register.
2059 */
2060 reg |= IXGBE_AUTOC_AN_RESTART;
2061 IXGBE_WRITE_REG(hw, IXGBE_AUTOC, reg);
2062 hw_dbg(hw, "Set up FC; IXGBE_AUTOC = 0x%08X\n", reg);
2063
1940out: 2064out:
1941 return ret_val; 2065 return ret_val;
1942} 2066}
@@ -2000,7 +2124,7 @@ s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask)
2000 2124
2001 while (timeout) { 2125 while (timeout) {
2002 if (ixgbe_get_eeprom_semaphore(hw)) 2126 if (ixgbe_get_eeprom_semaphore(hw))
2003 return -IXGBE_ERR_SWFW_SYNC; 2127 return IXGBE_ERR_SWFW_SYNC;
2004 2128
2005 gssr = IXGBE_READ_REG(hw, IXGBE_GSSR); 2129 gssr = IXGBE_READ_REG(hw, IXGBE_GSSR);
2006 if (!(gssr & (fwmask | swmask))) 2130 if (!(gssr & (fwmask | swmask)))
@@ -2017,7 +2141,7 @@ s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask)
2017 2141
2018 if (!timeout) { 2142 if (!timeout) {
2019 hw_dbg(hw, "Driver can't access resource, GSSR timeout.\n"); 2143 hw_dbg(hw, "Driver can't access resource, GSSR timeout.\n");
2020 return -IXGBE_ERR_SWFW_SYNC; 2144 return IXGBE_ERR_SWFW_SYNC;
2021 } 2145 }
2022 2146
2023 gssr |= swmask; 2147 gssr |= swmask;
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c
index 53b0a6680254..fa314cb005a4 100644
--- a/drivers/net/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ixgbe/ixgbe_ethtool.c
@@ -53,6 +53,10 @@ static struct ixgbe_stats ixgbe_gstrings_stats[] = {
53 {"tx_packets", IXGBE_STAT(net_stats.tx_packets)}, 53 {"tx_packets", IXGBE_STAT(net_stats.tx_packets)},
54 {"rx_bytes", IXGBE_STAT(net_stats.rx_bytes)}, 54 {"rx_bytes", IXGBE_STAT(net_stats.rx_bytes)},
55 {"tx_bytes", IXGBE_STAT(net_stats.tx_bytes)}, 55 {"tx_bytes", IXGBE_STAT(net_stats.tx_bytes)},
56 {"rx_pkts_nic", IXGBE_STAT(stats.gprc)},
57 {"tx_pkts_nic", IXGBE_STAT(stats.gptc)},
58 {"rx_bytes_nic", IXGBE_STAT(stats.gorc)},
59 {"tx_bytes_nic", IXGBE_STAT(stats.gotc)},
56 {"lsc_int", IXGBE_STAT(lsc_int)}, 60 {"lsc_int", IXGBE_STAT(lsc_int)},
57 {"tx_busy", IXGBE_STAT(tx_busy)}, 61 {"tx_busy", IXGBE_STAT(tx_busy)},
58 {"non_eop_descs", IXGBE_STAT(non_eop_descs)}, 62 {"non_eop_descs", IXGBE_STAT(non_eop_descs)},
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index c407bd9de0dd..cbb143ca1eb8 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -49,7 +49,7 @@ char ixgbe_driver_name[] = "ixgbe";
49static const char ixgbe_driver_string[] = 49static const char ixgbe_driver_string[] =
50 "Intel(R) 10 Gigabit PCI Express Network Driver"; 50 "Intel(R) 10 Gigabit PCI Express Network Driver";
51 51
52#define DRV_VERSION "2.0.37-k2" 52#define DRV_VERSION "2.0.44-k2"
53const char ixgbe_driver_version[] = DRV_VERSION; 53const char ixgbe_driver_version[] = DRV_VERSION;
54static char ixgbe_copyright[] = "Copyright (c) 1999-2009 Intel Corporation."; 54static char ixgbe_copyright[] = "Copyright (c) 1999-2009 Intel Corporation.";
55 55
@@ -97,8 +97,12 @@ static struct pci_device_id ixgbe_pci_tbl[] = {
97 board_82599 }, 97 board_82599 },
98 {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_SFP), 98 {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_SFP),
99 board_82599 }, 99 board_82599 },
100 {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_KX4_MEZZ),
101 board_82599 },
100 {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_CX4), 102 {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_CX4),
101 board_82599 }, 103 board_82599 },
104 {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_COMBO_BACKPLANE),
105 board_82599 },
102 106
103 /* required last entry */ 107 /* required last entry */
104 {0, } 108 {0, }
@@ -1885,12 +1889,29 @@ static void ixgbe_configure_tx(struct ixgbe_adapter *adapter)
1885 IXGBE_WRITE_REG(hw, IXGBE_TDT(j), 0); 1889 IXGBE_WRITE_REG(hw, IXGBE_TDT(j), 0);
1886 adapter->tx_ring[i].head = IXGBE_TDH(j); 1890 adapter->tx_ring[i].head = IXGBE_TDH(j);
1887 adapter->tx_ring[i].tail = IXGBE_TDT(j); 1891 adapter->tx_ring[i].tail = IXGBE_TDT(j);
1888 /* Disable Tx Head Writeback RO bit, since this hoses 1892 /*
1893 * Disable Tx Head Writeback RO bit, since this hoses
1889 * bookkeeping if things aren't delivered in order. 1894 * bookkeeping if things aren't delivered in order.
1890 */ 1895 */
1891 txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(j)); 1896 switch (hw->mac.type) {
1897 case ixgbe_mac_82598EB:
1898 txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(j));
1899 break;
1900 case ixgbe_mac_82599EB:
1901 default:
1902 txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(j));
1903 break;
1904 }
1892 txctrl &= ~IXGBE_DCA_TXCTRL_TX_WB_RO_EN; 1905 txctrl &= ~IXGBE_DCA_TXCTRL_TX_WB_RO_EN;
1893 IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(j), txctrl); 1906 switch (hw->mac.type) {
1907 case ixgbe_mac_82598EB:
1908 IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(j), txctrl);
1909 break;
1910 case ixgbe_mac_82599EB:
1911 default:
1912 IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(j), txctrl);
1913 break;
1914 }
1894 } 1915 }
1895 if (hw->mac.type == ixgbe_mac_82599EB) { 1916 if (hw->mac.type == ixgbe_mac_82599EB) {
1896 /* We enable 8 traffic classes, DCB only */ 1917 /* We enable 8 traffic classes, DCB only */
@@ -4432,10 +4453,13 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
4432 4453
4433 /* 82598 hardware only has a 32 bit counter in the high register */ 4454 /* 82598 hardware only has a 32 bit counter in the high register */
4434 if (hw->mac.type == ixgbe_mac_82599EB) { 4455 if (hw->mac.type == ixgbe_mac_82599EB) {
4456 u64 tmp;
4435 adapter->stats.gorc += IXGBE_READ_REG(hw, IXGBE_GORCL); 4457 adapter->stats.gorc += IXGBE_READ_REG(hw, IXGBE_GORCL);
4436 IXGBE_READ_REG(hw, IXGBE_GORCH); /* to clear */ 4458 tmp = IXGBE_READ_REG(hw, IXGBE_GORCH) & 0xF; /* 4 high bits of GORC */
4459 adapter->stats.gorc += (tmp << 32);
4437 adapter->stats.gotc += IXGBE_READ_REG(hw, IXGBE_GOTCL); 4460 adapter->stats.gotc += IXGBE_READ_REG(hw, IXGBE_GOTCL);
4438 IXGBE_READ_REG(hw, IXGBE_GOTCH); /* to clear */ 4461 tmp = IXGBE_READ_REG(hw, IXGBE_GOTCH) & 0xF; /* 4 high bits of GOTC */
4462 adapter->stats.gotc += (tmp << 32);
4439 adapter->stats.tor += IXGBE_READ_REG(hw, IXGBE_TORL); 4463 adapter->stats.tor += IXGBE_READ_REG(hw, IXGBE_TORL);
4440 IXGBE_READ_REG(hw, IXGBE_TORH); /* to clear */ 4464 IXGBE_READ_REG(hw, IXGBE_TORH); /* to clear */
4441 adapter->stats.lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXCNT); 4465 adapter->stats.lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXCNT);
@@ -5071,7 +5095,6 @@ static void ixgbe_atr(struct ixgbe_adapter *adapter, struct sk_buff *skb,
5071 /* Right now, we support IPv4 only */ 5095 /* Right now, we support IPv4 only */
5072 struct ixgbe_atr_input atr_input; 5096 struct ixgbe_atr_input atr_input;
5073 struct tcphdr *th; 5097 struct tcphdr *th;
5074 struct udphdr *uh;
5075 struct iphdr *iph = ip_hdr(skb); 5098 struct iphdr *iph = ip_hdr(skb);
5076 struct ethhdr *eth = (struct ethhdr *)skb->data; 5099 struct ethhdr *eth = (struct ethhdr *)skb->data;
5077 u16 vlan_id, src_port, dst_port, flex_bytes; 5100 u16 vlan_id, src_port, dst_port, flex_bytes;
@@ -5085,12 +5108,6 @@ static void ixgbe_atr(struct ixgbe_adapter *adapter, struct sk_buff *skb,
5085 dst_port = th->dest; 5108 dst_port = th->dest;
5086 l4type |= IXGBE_ATR_L4TYPE_TCP; 5109 l4type |= IXGBE_ATR_L4TYPE_TCP;
5087 /* l4type IPv4 type is 0, no need to assign */ 5110 /* l4type IPv4 type is 0, no need to assign */
5088 } else if(iph->protocol == IPPROTO_UDP) {
5089 uh = udp_hdr(skb);
5090 src_port = uh->source;
5091 dst_port = uh->dest;
5092 l4type |= IXGBE_ATR_L4TYPE_UDP;
5093 /* l4type IPv4 type is 0, no need to assign */
5094 } else { 5111 } else {
5095 /* Unsupported L4 header, just bail here */ 5112 /* Unsupported L4 header, just bail here */
5096 return; 5113 return;
@@ -5494,12 +5511,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
5494 goto err_pci_reg; 5511 goto err_pci_reg;
5495 } 5512 }
5496 5513
5497 err = pci_enable_pcie_error_reporting(pdev); 5514 pci_enable_pcie_error_reporting(pdev);
5498 if (err) {
5499 dev_err(&pdev->dev, "pci_enable_pcie_error_reporting failed "
5500 "0x%x\n", err);
5501 /* non-fatal, continue */
5502 }
5503 5515
5504 pci_set_master(pdev); 5516 pci_set_master(pdev);
5505 pci_save_state(pdev); 5517 pci_save_state(pdev);
@@ -5808,7 +5820,6 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
5808{ 5820{
5809 struct net_device *netdev = pci_get_drvdata(pdev); 5821 struct net_device *netdev = pci_get_drvdata(pdev);
5810 struct ixgbe_adapter *adapter = netdev_priv(netdev); 5822 struct ixgbe_adapter *adapter = netdev_priv(netdev);
5811 int err;
5812 5823
5813 set_bit(__IXGBE_DOWN, &adapter->state); 5824 set_bit(__IXGBE_DOWN, &adapter->state);
5814 /* clear the module not found bit to make sure the worker won't 5825 /* clear the module not found bit to make sure the worker won't
@@ -5859,10 +5870,7 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
5859 5870
5860 free_netdev(netdev); 5871 free_netdev(netdev);
5861 5872
5862 err = pci_disable_pcie_error_reporting(pdev); 5873 pci_disable_pcie_error_reporting(pdev);
5863 if (err)
5864 dev_err(&pdev->dev,
5865 "pci_disable_pcie_error_reporting failed 0x%x\n", err);
5866 5874
5867 pci_disable_device(pdev); 5875 pci_disable_device(pdev);
5868} 5876}
diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h
index 8761d7899f7d..ef4bdd58e016 100644
--- a/drivers/net/ixgbe/ixgbe_type.h
+++ b/drivers/net/ixgbe/ixgbe_type.h
@@ -49,9 +49,11 @@
49#define IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM 0x10E1 49#define IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM 0x10E1
50#define IXGBE_DEV_ID_82598EB_XF_LR 0x10F4 50#define IXGBE_DEV_ID_82598EB_XF_LR 0x10F4
51#define IXGBE_DEV_ID_82599_KX4 0x10F7 51#define IXGBE_DEV_ID_82599_KX4 0x10F7
52#define IXGBE_DEV_ID_82599_KX4_MEZZ 0x1514
52#define IXGBE_DEV_ID_82599_CX4 0x10F9 53#define IXGBE_DEV_ID_82599_CX4 0x10F9
53#define IXGBE_DEV_ID_82599_SFP 0x10FB 54#define IXGBE_DEV_ID_82599_SFP 0x10FB
54#define IXGBE_DEV_ID_82599_XAUI_LOM 0x10FC 55#define IXGBE_DEV_ID_82599_XAUI_LOM 0x10FC
56#define IXGBE_DEV_ID_82599_COMBO_BACKPLANE 0x10F8
55 57
56/* General Registers */ 58/* General Registers */
57#define IXGBE_CTRL 0x00000 59#define IXGBE_CTRL 0x00000
@@ -1336,6 +1338,8 @@
1336#define IXGBE_AUTOC_KX4_SUPP 0x80000000 1338#define IXGBE_AUTOC_KX4_SUPP 0x80000000
1337#define IXGBE_AUTOC_KX_SUPP 0x40000000 1339#define IXGBE_AUTOC_KX_SUPP 0x40000000
1338#define IXGBE_AUTOC_PAUSE 0x30000000 1340#define IXGBE_AUTOC_PAUSE 0x30000000
1341#define IXGBE_AUTOC_ASM_PAUSE 0x20000000
1342#define IXGBE_AUTOC_SYM_PAUSE 0x10000000
1339#define IXGBE_AUTOC_RF 0x08000000 1343#define IXGBE_AUTOC_RF 0x08000000
1340#define IXGBE_AUTOC_PD_TMR 0x06000000 1344#define IXGBE_AUTOC_PD_TMR 0x06000000
1341#define IXGBE_AUTOC_AN_RX_LOOSE 0x01000000 1345#define IXGBE_AUTOC_AN_RX_LOOSE 0x01000000
@@ -1404,6 +1408,8 @@
1404#define IXGBE_LINK_UP_TIME 90 /* 9.0 Seconds */ 1408#define IXGBE_LINK_UP_TIME 90 /* 9.0 Seconds */
1405#define IXGBE_AUTO_NEG_TIME 45 /* 4.5 Seconds */ 1409#define IXGBE_AUTO_NEG_TIME 45 /* 4.5 Seconds */
1406 1410
1411#define IXGBE_LINKS2_AN_SUPPORTED 0x00000040
1412
1407/* PCS1GLSTA Bit Masks */ 1413/* PCS1GLSTA Bit Masks */
1408#define IXGBE_PCS1GLSTA_LINK_OK 1 1414#define IXGBE_PCS1GLSTA_LINK_OK 1
1409#define IXGBE_PCS1GLSTA_SYNK_OK 0x10 1415#define IXGBE_PCS1GLSTA_SYNK_OK 0x10
@@ -1424,6 +1430,11 @@
1424#define IXGBE_PCS1GLCTL_AN_ENABLE 0x10000 1430#define IXGBE_PCS1GLCTL_AN_ENABLE 0x10000
1425#define IXGBE_PCS1GLCTL_AN_RESTART 0x20000 1431#define IXGBE_PCS1GLCTL_AN_RESTART 0x20000
1426 1432
1433/* ANLP1 Bit Masks */
1434#define IXGBE_ANLP1_PAUSE 0x0C00
1435#define IXGBE_ANLP1_SYM_PAUSE 0x0400
1436#define IXGBE_ANLP1_ASM_PAUSE 0x0800
1437
1427/* SW Semaphore Register bitmasks */ 1438/* SW Semaphore Register bitmasks */
1428#define IXGBE_SWSM_SMBI 0x00000001 /* Driver Semaphore bit */ 1439#define IXGBE_SWSM_SMBI 0x00000001 /* Driver Semaphore bit */
1429#define IXGBE_SWSM_SWESMBI 0x00000002 /* FW Semaphore bit */ 1440#define IXGBE_SWSM_SWESMBI 0x00000002 /* FW Semaphore bit */
diff --git a/drivers/net/ixp2000/enp2611.c b/drivers/net/ixp2000/enp2611.c
index b02a981c87a8..34a6cfd17930 100644
--- a/drivers/net/ixp2000/enp2611.c
+++ b/drivers/net/ixp2000/enp2611.c
@@ -119,24 +119,9 @@ static struct ixp2400_msf_parameters enp2611_msf_parameters =
119 } 119 }
120}; 120};
121 121
122struct enp2611_ixpdev_priv
123{
124 struct ixpdev_priv ixpdev_priv;
125 struct net_device_stats stats;
126};
127
128static struct net_device *nds[3]; 122static struct net_device *nds[3];
129static struct timer_list link_check_timer; 123static struct timer_list link_check_timer;
130 124
131static struct net_device_stats *enp2611_get_stats(struct net_device *dev)
132{
133 struct enp2611_ixpdev_priv *ip = netdev_priv(dev);
134
135 pm3386_get_stats(ip->ixpdev_priv.channel, &(ip->stats));
136
137 return &(ip->stats);
138}
139
140/* @@@ Poll the SFP moddef0 line too. */ 125/* @@@ Poll the SFP moddef0 line too. */
141/* @@@ Try to use the pm3386 DOOL interrupt as well. */ 126/* @@@ Try to use the pm3386 DOOL interrupt as well. */
142static void enp2611_check_link_status(unsigned long __dummy) 127static void enp2611_check_link_status(unsigned long __dummy)
@@ -203,14 +188,13 @@ static int __init enp2611_init_module(void)
203 188
204 ports = pm3386_port_count(); 189 ports = pm3386_port_count();
205 for (i = 0; i < ports; i++) { 190 for (i = 0; i < ports; i++) {
206 nds[i] = ixpdev_alloc(i, sizeof(struct enp2611_ixpdev_priv)); 191 nds[i] = ixpdev_alloc(i, sizeof(struct ixpdev_priv));
207 if (nds[i] == NULL) { 192 if (nds[i] == NULL) {
208 while (--i >= 0) 193 while (--i >= 0)
209 free_netdev(nds[i]); 194 free_netdev(nds[i]);
210 return -ENOMEM; 195 return -ENOMEM;
211 } 196 }
212 197
213 nds[i]->get_stats = enp2611_get_stats;
214 pm3386_init_port(i); 198 pm3386_init_port(i);
215 pm3386_get_mac(i, nds[i]->dev_addr); 199 pm3386_get_mac(i, nds[i]->dev_addr);
216 } 200 }
diff --git a/drivers/net/ixp2000/ixpdev.c b/drivers/net/ixp2000/ixpdev.c
index 127243461a51..9aee0cc922c9 100644
--- a/drivers/net/ixp2000/ixpdev.c
+++ b/drivers/net/ixp2000/ixpdev.c
@@ -21,6 +21,7 @@
21#include "ixp2400_tx.ucode" 21#include "ixp2400_tx.ucode"
22#include "ixpdev_priv.h" 22#include "ixpdev_priv.h"
23#include "ixpdev.h" 23#include "ixpdev.h"
24#include "pm3386.h"
24 25
25#define DRV_MODULE_VERSION "0.2" 26#define DRV_MODULE_VERSION "0.2"
26 27
@@ -271,6 +272,15 @@ static int ixpdev_close(struct net_device *dev)
271 return 0; 272 return 0;
272} 273}
273 274
275static struct net_device_stats *ixpdev_get_stats(struct net_device *dev)
276{
277 struct ixpdev_priv *ip = netdev_priv(dev);
278
279 pm3386_get_stats(ip->channel, &(dev->stats));
280
281 return &(dev->stats);
282}
283
274static const struct net_device_ops ixpdev_netdev_ops = { 284static const struct net_device_ops ixpdev_netdev_ops = {
275 .ndo_open = ixpdev_open, 285 .ndo_open = ixpdev_open,
276 .ndo_stop = ixpdev_close, 286 .ndo_stop = ixpdev_close,
@@ -278,6 +288,7 @@ static const struct net_device_ops ixpdev_netdev_ops = {
278 .ndo_change_mtu = eth_change_mtu, 288 .ndo_change_mtu = eth_change_mtu,
279 .ndo_validate_addr = eth_validate_addr, 289 .ndo_validate_addr = eth_validate_addr,
280 .ndo_set_mac_address = eth_mac_addr, 290 .ndo_set_mac_address = eth_mac_addr,
291 .ndo_get_stats = ixpdev_get_stats,
281#ifdef CONFIG_NET_POLL_CONTROLLER 292#ifdef CONFIG_NET_POLL_CONTROLLER
282 .ndo_poll_controller = ixpdev_poll_controller, 293 .ndo_poll_controller = ixpdev_poll_controller,
283#endif 294#endif
diff --git a/drivers/net/ks8851_mll.c b/drivers/net/ks8851_mll.c
new file mode 100644
index 000000000000..0be14d702beb
--- /dev/null
+++ b/drivers/net/ks8851_mll.c
@@ -0,0 +1,1697 @@
1/**
2 * drivers/net/ks8851_mll.c
3 * Copyright (c) 2009 Micrel Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19/**
20 * Supports:
21 * KS8851 16bit MLL chip from Micrel Inc.
22 */
23
24#include <linux/module.h>
25#include <linux/kernel.h>
26#include <linux/netdevice.h>
27#include <linux/etherdevice.h>
28#include <linux/ethtool.h>
29#include <linux/cache.h>
30#include <linux/crc32.h>
31#include <linux/mii.h>
32#include <linux/platform_device.h>
33#include <linux/delay.h>
34
35#define DRV_NAME "ks8851_mll"
36
37static u8 KS_DEFAULT_MAC_ADDRESS[] = { 0x00, 0x10, 0xA1, 0x86, 0x95, 0x11 };
38#define MAX_RECV_FRAMES 32
39#define MAX_BUF_SIZE 2048
40#define TX_BUF_SIZE 2000
41#define RX_BUF_SIZE 2000
42
43#define KS_CCR 0x08
44#define CCR_EEPROM (1 << 9)
45#define CCR_SPI (1 << 8)
46#define CCR_8BIT (1 << 7)
47#define CCR_16BIT (1 << 6)
48#define CCR_32BIT (1 << 5)
49#define CCR_SHARED (1 << 4)
50#define CCR_32PIN (1 << 0)
51
52/* MAC address registers */
53#define KS_MARL 0x10
54#define KS_MARM 0x12
55#define KS_MARH 0x14
56
57#define KS_OBCR 0x20
58#define OBCR_ODS_16MA (1 << 6)
59
60#define KS_EEPCR 0x22
61#define EEPCR_EESA (1 << 4)
62#define EEPCR_EESB (1 << 3)
63#define EEPCR_EEDO (1 << 2)
64#define EEPCR_EESCK (1 << 1)
65#define EEPCR_EECS (1 << 0)
66
67#define KS_MBIR 0x24
68#define MBIR_TXMBF (1 << 12)
69#define MBIR_TXMBFA (1 << 11)
70#define MBIR_RXMBF (1 << 4)
71#define MBIR_RXMBFA (1 << 3)
72
73#define KS_GRR 0x26
74#define GRR_QMU (1 << 1)
75#define GRR_GSR (1 << 0)
76
77#define KS_WFCR 0x2A
78#define WFCR_MPRXE (1 << 7)
79#define WFCR_WF3E (1 << 3)
80#define WFCR_WF2E (1 << 2)
81#define WFCR_WF1E (1 << 1)
82#define WFCR_WF0E (1 << 0)
83
84#define KS_WF0CRC0 0x30
85#define KS_WF0CRC1 0x32
86#define KS_WF0BM0 0x34
87#define KS_WF0BM1 0x36
88#define KS_WF0BM2 0x38
89#define KS_WF0BM3 0x3A
90
91#define KS_WF1CRC0 0x40
92#define KS_WF1CRC1 0x42
93#define KS_WF1BM0 0x44
94#define KS_WF1BM1 0x46
95#define KS_WF1BM2 0x48
96#define KS_WF1BM3 0x4A
97
98#define KS_WF2CRC0 0x50
99#define KS_WF2CRC1 0x52
100#define KS_WF2BM0 0x54
101#define KS_WF2BM1 0x56
102#define KS_WF2BM2 0x58
103#define KS_WF2BM3 0x5A
104
105#define KS_WF3CRC0 0x60
106#define KS_WF3CRC1 0x62
107#define KS_WF3BM0 0x64
108#define KS_WF3BM1 0x66
109#define KS_WF3BM2 0x68
110#define KS_WF3BM3 0x6A
111
112#define KS_TXCR 0x70
113#define TXCR_TCGICMP (1 << 8)
114#define TXCR_TCGUDP (1 << 7)
115#define TXCR_TCGTCP (1 << 6)
116#define TXCR_TCGIP (1 << 5)
117#define TXCR_FTXQ (1 << 4)
118#define TXCR_TXFCE (1 << 3)
119#define TXCR_TXPE (1 << 2)
120#define TXCR_TXCRC (1 << 1)
121#define TXCR_TXE (1 << 0)
122
123#define KS_TXSR 0x72
124#define TXSR_TXLC (1 << 13)
125#define TXSR_TXMC (1 << 12)
126#define TXSR_TXFID_MASK (0x3f << 0)
127#define TXSR_TXFID_SHIFT (0)
128#define TXSR_TXFID_GET(_v) (((_v) >> 0) & 0x3f)
129
130
131#define KS_RXCR1 0x74
132#define RXCR1_FRXQ (1 << 15)
133#define RXCR1_RXUDPFCC (1 << 14)
134#define RXCR1_RXTCPFCC (1 << 13)
135#define RXCR1_RXIPFCC (1 << 12)
136#define RXCR1_RXPAFMA (1 << 11)
137#define RXCR1_RXFCE (1 << 10)
138#define RXCR1_RXEFE (1 << 9)
139#define RXCR1_RXMAFMA (1 << 8)
140#define RXCR1_RXBE (1 << 7)
141#define RXCR1_RXME (1 << 6)
142#define RXCR1_RXUE (1 << 5)
143#define RXCR1_RXAE (1 << 4)
144#define RXCR1_RXINVF (1 << 1)
145#define RXCR1_RXE (1 << 0)
146#define RXCR1_FILTER_MASK (RXCR1_RXINVF | RXCR1_RXAE | \
147 RXCR1_RXMAFMA | RXCR1_RXPAFMA)
148
149#define KS_RXCR2 0x76
150#define RXCR2_SRDBL_MASK (0x7 << 5)
151#define RXCR2_SRDBL_SHIFT (5)
152#define RXCR2_SRDBL_4B (0x0 << 5)
153#define RXCR2_SRDBL_8B (0x1 << 5)
154#define RXCR2_SRDBL_16B (0x2 << 5)
155#define RXCR2_SRDBL_32B (0x3 << 5)
156/* #define RXCR2_SRDBL_FRAME (0x4 << 5) */
157#define RXCR2_IUFFP (1 << 4)
158#define RXCR2_RXIUFCEZ (1 << 3)
159#define RXCR2_UDPLFE (1 << 2)
160#define RXCR2_RXICMPFCC (1 << 1)
161#define RXCR2_RXSAF (1 << 0)
162
163#define KS_TXMIR 0x78
164
165#define KS_RXFHSR 0x7C
166#define RXFSHR_RXFV (1 << 15)
167#define RXFSHR_RXICMPFCS (1 << 13)
168#define RXFSHR_RXIPFCS (1 << 12)
169#define RXFSHR_RXTCPFCS (1 << 11)
170#define RXFSHR_RXUDPFCS (1 << 10)
171#define RXFSHR_RXBF (1 << 7)
172#define RXFSHR_RXMF (1 << 6)
173#define RXFSHR_RXUF (1 << 5)
174#define RXFSHR_RXMR (1 << 4)
175#define RXFSHR_RXFT (1 << 3)
176#define RXFSHR_RXFTL (1 << 2)
177#define RXFSHR_RXRF (1 << 1)
178#define RXFSHR_RXCE (1 << 0)
179#define RXFSHR_ERR (RXFSHR_RXCE | RXFSHR_RXRF |\
180 RXFSHR_RXFTL | RXFSHR_RXMR |\
181 RXFSHR_RXICMPFCS | RXFSHR_RXIPFCS |\
182 RXFSHR_RXTCPFCS)
183#define KS_RXFHBCR 0x7E
184#define RXFHBCR_CNT_MASK 0x0FFF
185
186#define KS_TXQCR 0x80
187#define TXQCR_AETFE (1 << 2)
188#define TXQCR_TXQMAM (1 << 1)
189#define TXQCR_METFE (1 << 0)
190
191#define KS_RXQCR 0x82
192#define RXQCR_RXDTTS (1 << 12)
193#define RXQCR_RXDBCTS (1 << 11)
194#define RXQCR_RXFCTS (1 << 10)
195#define RXQCR_RXIPHTOE (1 << 9)
196#define RXQCR_RXDTTE (1 << 7)
197#define RXQCR_RXDBCTE (1 << 6)
198#define RXQCR_RXFCTE (1 << 5)
199#define RXQCR_ADRFE (1 << 4)
200#define RXQCR_SDA (1 << 3)
201#define RXQCR_RRXEF (1 << 0)
202#define RXQCR_CMD_CNTL (RXQCR_RXFCTE|RXQCR_ADRFE)
203
204#define KS_TXFDPR 0x84
205#define TXFDPR_TXFPAI (1 << 14)
206#define TXFDPR_TXFP_MASK (0x7ff << 0)
207#define TXFDPR_TXFP_SHIFT (0)
208
209#define KS_RXFDPR 0x86
210#define RXFDPR_RXFPAI (1 << 14)
211
212#define KS_RXDTTR 0x8C
213#define KS_RXDBCTR 0x8E
214
215#define KS_IER 0x90
216#define KS_ISR 0x92
217#define IRQ_LCI (1 << 15)
218#define IRQ_TXI (1 << 14)
219#define IRQ_RXI (1 << 13)
220#define IRQ_RXOI (1 << 11)
221#define IRQ_TXPSI (1 << 9)
222#define IRQ_RXPSI (1 << 8)
223#define IRQ_TXSAI (1 << 6)
224#define IRQ_RXWFDI (1 << 5)
225#define IRQ_RXMPDI (1 << 4)
226#define IRQ_LDI (1 << 3)
227#define IRQ_EDI (1 << 2)
228#define IRQ_SPIBEI (1 << 1)
229#define IRQ_DEDI (1 << 0)
230
231#define KS_RXFCTR 0x9C
232#define RXFCTR_THRESHOLD_MASK 0x00FF
233
234#define KS_RXFC 0x9D
235#define RXFCTR_RXFC_MASK (0xff << 8)
236#define RXFCTR_RXFC_SHIFT (8)
237#define RXFCTR_RXFC_GET(_v) (((_v) >> 8) & 0xff)
238#define RXFCTR_RXFCT_MASK (0xff << 0)
239#define RXFCTR_RXFCT_SHIFT (0)
240
241#define KS_TXNTFSR 0x9E
242
243#define KS_MAHTR0 0xA0
244#define KS_MAHTR1 0xA2
245#define KS_MAHTR2 0xA4
246#define KS_MAHTR3 0xA6
247
248#define KS_FCLWR 0xB0
249#define KS_FCHWR 0xB2
250#define KS_FCOWR 0xB4
251
252#define KS_CIDER 0xC0
253#define CIDER_ID 0x8870
254#define CIDER_REV_MASK (0x7 << 1)
255#define CIDER_REV_SHIFT (1)
256#define CIDER_REV_GET(_v) (((_v) >> 1) & 0x7)
257
258#define KS_CGCR 0xC6
259#define KS_IACR 0xC8
260#define IACR_RDEN (1 << 12)
261#define IACR_TSEL_MASK (0x3 << 10)
262#define IACR_TSEL_SHIFT (10)
263#define IACR_TSEL_MIB (0x3 << 10)
264#define IACR_ADDR_MASK (0x1f << 0)
265#define IACR_ADDR_SHIFT (0)
266
267#define KS_IADLR 0xD0
268#define KS_IAHDR 0xD2
269
270#define KS_PMECR 0xD4
271#define PMECR_PME_DELAY (1 << 14)
272#define PMECR_PME_POL (1 << 12)
273#define PMECR_WOL_WAKEUP (1 << 11)
274#define PMECR_WOL_MAGICPKT (1 << 10)
275#define PMECR_WOL_LINKUP (1 << 9)
276#define PMECR_WOL_ENERGY (1 << 8)
277#define PMECR_AUTO_WAKE_EN (1 << 7)
278#define PMECR_WAKEUP_NORMAL (1 << 6)
279#define PMECR_WKEVT_MASK (0xf << 2)
280#define PMECR_WKEVT_SHIFT (2)
281#define PMECR_WKEVT_GET(_v) (((_v) >> 2) & 0xf)
282#define PMECR_WKEVT_ENERGY (0x1 << 2)
283#define PMECR_WKEVT_LINK (0x2 << 2)
284#define PMECR_WKEVT_MAGICPKT (0x4 << 2)
285#define PMECR_WKEVT_FRAME (0x8 << 2)
286#define PMECR_PM_MASK (0x3 << 0)
287#define PMECR_PM_SHIFT (0)
288#define PMECR_PM_NORMAL (0x0 << 0)
289#define PMECR_PM_ENERGY (0x1 << 0)
290#define PMECR_PM_SOFTDOWN (0x2 << 0)
291#define PMECR_PM_POWERSAVE (0x3 << 0)
292
293/* Standard MII PHY data */
294#define KS_P1MBCR 0xE4
295#define P1MBCR_FORCE_FDX (1 << 8)
296
297#define KS_P1MBSR 0xE6
298#define P1MBSR_AN_COMPLETE (1 << 5)
299#define P1MBSR_AN_CAPABLE (1 << 3)
300#define P1MBSR_LINK_UP (1 << 2)
301
302#define KS_PHY1ILR 0xE8
303#define KS_PHY1IHR 0xEA
304#define KS_P1ANAR 0xEC
305#define KS_P1ANLPR 0xEE
306
307#define KS_P1SCLMD 0xF4
308#define P1SCLMD_LEDOFF (1 << 15)
309#define P1SCLMD_TXIDS (1 << 14)
310#define P1SCLMD_RESTARTAN (1 << 13)
311#define P1SCLMD_DISAUTOMDIX (1 << 10)
312#define P1SCLMD_FORCEMDIX (1 << 9)
313#define P1SCLMD_AUTONEGEN (1 << 7)
314#define P1SCLMD_FORCE100 (1 << 6)
315#define P1SCLMD_FORCEFDX (1 << 5)
316#define P1SCLMD_ADV_FLOW (1 << 4)
317#define P1SCLMD_ADV_100BT_FDX (1 << 3)
318#define P1SCLMD_ADV_100BT_HDX (1 << 2)
319#define P1SCLMD_ADV_10BT_FDX (1 << 1)
320#define P1SCLMD_ADV_10BT_HDX (1 << 0)
321
322#define KS_P1CR 0xF6
323#define P1CR_HP_MDIX (1 << 15)
324#define P1CR_REV_POL (1 << 13)
325#define P1CR_OP_100M (1 << 10)
326#define P1CR_OP_FDX (1 << 9)
327#define P1CR_OP_MDI (1 << 7)
328#define P1CR_AN_DONE (1 << 6)
329#define P1CR_LINK_GOOD (1 << 5)
330#define P1CR_PNTR_FLOW (1 << 4)
331#define P1CR_PNTR_100BT_FDX (1 << 3)
332#define P1CR_PNTR_100BT_HDX (1 << 2)
333#define P1CR_PNTR_10BT_FDX (1 << 1)
334#define P1CR_PNTR_10BT_HDX (1 << 0)
335
336/* TX Frame control */
337
338#define TXFR_TXIC (1 << 15)
339#define TXFR_TXFID_MASK (0x3f << 0)
340#define TXFR_TXFID_SHIFT (0)
341
342#define KS_P1SR 0xF8
343#define P1SR_HP_MDIX (1 << 15)
344#define P1SR_REV_POL (1 << 13)
345#define P1SR_OP_100M (1 << 10)
346#define P1SR_OP_FDX (1 << 9)
347#define P1SR_OP_MDI (1 << 7)
348#define P1SR_AN_DONE (1 << 6)
349#define P1SR_LINK_GOOD (1 << 5)
350#define P1SR_PNTR_FLOW (1 << 4)
351#define P1SR_PNTR_100BT_FDX (1 << 3)
352#define P1SR_PNTR_100BT_HDX (1 << 2)
353#define P1SR_PNTR_10BT_FDX (1 << 1)
354#define P1SR_PNTR_10BT_HDX (1 << 0)
355
356#define ENUM_BUS_NONE 0
357#define ENUM_BUS_8BIT 1
358#define ENUM_BUS_16BIT 2
359#define ENUM_BUS_32BIT 3
360
361#define MAX_MCAST_LST 32
362#define HW_MCAST_SIZE 8
363#define MAC_ADDR_LEN 6
364
365/**
366 * union ks_tx_hdr - tx header data
367 * @txb: The header as bytes
368 * @txw: The header as 16bit, little-endian words
369 *
370 * A dual representation of the tx header data to allow
371 * access to individual bytes, and to allow 16bit accesses
372 * with 16bit alignment.
373 */
374union ks_tx_hdr {
375 u8 txb[4];
376 __le16 txw[2];
377};
378
379/**
380 * struct ks_net - KS8851 driver private data
381 * @net_device : The network device we're bound to
382 * @hw_addr : start address of data register.
383 * @hw_addr_cmd : start address of command register.
384 * @txh : temporaly buffer to save status/length.
385 * @lock : Lock to ensure that the device is not accessed when busy.
386 * @pdev : Pointer to platform device.
387 * @mii : The MII state information for the mii calls.
388 * @frame_head_info : frame header information for multi-pkt rx.
389 * @statelock : Lock on this structure for tx list.
390 * @msg_enable : The message flags controlling driver output (see ethtool).
391 * @frame_cnt : number of frames received.
392 * @bus_width : i/o bus width.
393 * @irq : irq number assigned to this device.
394 * @rc_rxqcr : Cached copy of KS_RXQCR.
395 * @rc_txcr : Cached copy of KS_TXCR.
396 * @rc_ier : Cached copy of KS_IER.
397 * @sharedbus : Multipex(addr and data bus) mode indicator.
398 * @cmd_reg_cache : command register cached.
399 * @cmd_reg_cache_int : command register cached. Used in the irq handler.
400 * @promiscuous : promiscuous mode indicator.
401 * @all_mcast : mutlicast indicator.
402 * @mcast_lst_size : size of multicast list.
403 * @mcast_lst : multicast list.
404 * @mcast_bits : multicast enabed.
405 * @mac_addr : MAC address assigned to this device.
406 * @fid : frame id.
407 * @extra_byte : number of extra byte prepended rx pkt.
408 * @enabled : indicator this device works.
409 *
410 * The @lock ensures that the chip is protected when certain operations are
411 * in progress. When the read or write packet transfer is in progress, most
412 * of the chip registers are not accessible until the transfer is finished and
413 * the DMA has been de-asserted.
414 *
415 * The @statelock is used to protect information in the structure which may
416 * need to be accessed via several sources, such as the network driver layer
417 * or one of the work queues.
418 *
419 */
420
421/* Receive multiplex framer header info */
422struct type_frame_head {
423 u16 sts; /* Frame status */
424 u16 len; /* Byte count */
425};
426
427struct ks_net {
428 struct net_device *netdev;
429 void __iomem *hw_addr;
430 void __iomem *hw_addr_cmd;
431 union ks_tx_hdr txh ____cacheline_aligned;
432 struct mutex lock; /* spinlock to be interrupt safe */
433 struct platform_device *pdev;
434 struct mii_if_info mii;
435 struct type_frame_head *frame_head_info;
436 spinlock_t statelock;
437 u32 msg_enable;
438 u32 frame_cnt;
439 int bus_width;
440 int irq;
441
442 u16 rc_rxqcr;
443 u16 rc_txcr;
444 u16 rc_ier;
445 u16 sharedbus;
446 u16 cmd_reg_cache;
447 u16 cmd_reg_cache_int;
448 u16 promiscuous;
449 u16 all_mcast;
450 u16 mcast_lst_size;
451 u8 mcast_lst[MAX_MCAST_LST][MAC_ADDR_LEN];
452 u8 mcast_bits[HW_MCAST_SIZE];
453 u8 mac_addr[6];
454 u8 fid;
455 u8 extra_byte;
456 u8 enabled;
457};
458
459static int msg_enable;
460
461#define ks_info(_ks, _msg...) dev_info(&(_ks)->pdev->dev, _msg)
462#define ks_warn(_ks, _msg...) dev_warn(&(_ks)->pdev->dev, _msg)
463#define ks_dbg(_ks, _msg...) dev_dbg(&(_ks)->pdev->dev, _msg)
464#define ks_err(_ks, _msg...) dev_err(&(_ks)->pdev->dev, _msg)
465
466#define BE3 0x8000 /* Byte Enable 3 */
467#define BE2 0x4000 /* Byte Enable 2 */
468#define BE1 0x2000 /* Byte Enable 1 */
469#define BE0 0x1000 /* Byte Enable 0 */
470
471/**
472 * register read/write calls.
473 *
474 * All these calls issue transactions to access the chip's registers. They
475 * all require that the necessary lock is held to prevent accesses when the
476 * chip is busy transfering packet data (RX/TX FIFO accesses).
477 */
478
479/**
480 * ks_rdreg8 - read 8 bit register from device
481 * @ks : The chip information
482 * @offset: The register address
483 *
484 * Read a 8bit register from the chip, returning the result
485 */
486static u8 ks_rdreg8(struct ks_net *ks, int offset)
487{
488 u16 data;
489 u8 shift_bit = offset & 0x03;
490 u8 shift_data = (offset & 1) << 3;
491 ks->cmd_reg_cache = (u16) offset | (u16)(BE0 << shift_bit);
492 iowrite16(ks->cmd_reg_cache, ks->hw_addr_cmd);
493 data = ioread16(ks->hw_addr);
494 return (u8)(data >> shift_data);
495}
496
497/**
498 * ks_rdreg16 - read 16 bit register from device
499 * @ks : The chip information
500 * @offset: The register address
501 *
502 * Read a 16bit register from the chip, returning the result
503 */
504
505static u16 ks_rdreg16(struct ks_net *ks, int offset)
506{
507 ks->cmd_reg_cache = (u16)offset | ((BE1 | BE0) << (offset & 0x02));
508 iowrite16(ks->cmd_reg_cache, ks->hw_addr_cmd);
509 return ioread16(ks->hw_addr);
510}
511
512/**
513 * ks_wrreg8 - write 8bit register value to chip
514 * @ks: The chip information
515 * @offset: The register address
516 * @value: The value to write
517 *
518 */
519static void ks_wrreg8(struct ks_net *ks, int offset, u8 value)
520{
521 u8 shift_bit = (offset & 0x03);
522 u16 value_write = (u16)(value << ((offset & 1) << 3));
523 ks->cmd_reg_cache = (u16)offset | (BE0 << shift_bit);
524 iowrite16(ks->cmd_reg_cache, ks->hw_addr_cmd);
525 iowrite16(value_write, ks->hw_addr);
526}
527
528/**
529 * ks_wrreg16 - write 16bit register value to chip
530 * @ks: The chip information
531 * @offset: The register address
532 * @value: The value to write
533 *
534 */
535
536static void ks_wrreg16(struct ks_net *ks, int offset, u16 value)
537{
538 ks->cmd_reg_cache = (u16)offset | ((BE1 | BE0) << (offset & 0x02));
539 iowrite16(ks->cmd_reg_cache, ks->hw_addr_cmd);
540 iowrite16(value, ks->hw_addr);
541}
542
543/**
544 * ks_inblk - read a block of data from QMU. This is called after sudo DMA mode enabled.
545 * @ks: The chip state
546 * @wptr: buffer address to save data
547 * @len: length in byte to read
548 *
549 */
550static inline void ks_inblk(struct ks_net *ks, u16 *wptr, u32 len)
551{
552 len >>= 1;
553 while (len--)
554 *wptr++ = (u16)ioread16(ks->hw_addr);
555}
556
557/**
558 * ks_outblk - write data to QMU. This is called after sudo DMA mode enabled.
559 * @ks: The chip information
560 * @wptr: buffer address
561 * @len: length in byte to write
562 *
563 */
564static inline void ks_outblk(struct ks_net *ks, u16 *wptr, u32 len)
565{
566 len >>= 1;
567 while (len--)
568 iowrite16(*wptr++, ks->hw_addr);
569}
570
571/**
572 * ks_tx_fifo_space - return the available hardware buffer size.
573 * @ks: The chip information
574 *
575 */
576static inline u16 ks_tx_fifo_space(struct ks_net *ks)
577{
578 return ks_rdreg16(ks, KS_TXMIR) & 0x1fff;
579}
580
581/**
582 * ks_save_cmd_reg - save the command register from the cache.
583 * @ks: The chip information
584 *
585 */
586static inline void ks_save_cmd_reg(struct ks_net *ks)
587{
588 /*ks8851 MLL has a bug to read back the command register.
589 * So rely on software to save the content of command register.
590 */
591 ks->cmd_reg_cache_int = ks->cmd_reg_cache;
592}
593
594/**
595 * ks_restore_cmd_reg - restore the command register from the cache and
596 * write to hardware register.
597 * @ks: The chip information
598 *
599 */
600static inline void ks_restore_cmd_reg(struct ks_net *ks)
601{
602 ks->cmd_reg_cache = ks->cmd_reg_cache_int;
603 iowrite16(ks->cmd_reg_cache, ks->hw_addr_cmd);
604}
605
606/**
607 * ks_set_powermode - set power mode of the device
608 * @ks: The chip information
609 * @pwrmode: The power mode value to write to KS_PMECR.
610 *
611 * Change the power mode of the chip.
612 */
613static void ks_set_powermode(struct ks_net *ks, unsigned pwrmode)
614{
615 unsigned pmecr;
616
617 if (netif_msg_hw(ks))
618 ks_dbg(ks, "setting power mode %d\n", pwrmode);
619
620 ks_rdreg16(ks, KS_GRR);
621 pmecr = ks_rdreg16(ks, KS_PMECR);
622 pmecr &= ~PMECR_PM_MASK;
623 pmecr |= pwrmode;
624
625 ks_wrreg16(ks, KS_PMECR, pmecr);
626}
627
628/**
629 * ks_read_config - read chip configuration of bus width.
630 * @ks: The chip information
631 *
632 */
633static void ks_read_config(struct ks_net *ks)
634{
635 u16 reg_data = 0;
636
637 /* Regardless of bus width, 8 bit read should always work.*/
638 reg_data = ks_rdreg8(ks, KS_CCR) & 0x00FF;
639 reg_data |= ks_rdreg8(ks, KS_CCR+1) << 8;
640
641 /* addr/data bus are multiplexed */
642 ks->sharedbus = (reg_data & CCR_SHARED) == CCR_SHARED;
643
644 /* There are garbage data when reading data from QMU,
645 depending on bus-width.
646 */
647
648 if (reg_data & CCR_8BIT) {
649 ks->bus_width = ENUM_BUS_8BIT;
650 ks->extra_byte = 1;
651 } else if (reg_data & CCR_16BIT) {
652 ks->bus_width = ENUM_BUS_16BIT;
653 ks->extra_byte = 2;
654 } else {
655 ks->bus_width = ENUM_BUS_32BIT;
656 ks->extra_byte = 4;
657 }
658}
659
660/**
661 * ks_soft_reset - issue one of the soft reset to the device
662 * @ks: The device state.
663 * @op: The bit(s) to set in the GRR
664 *
665 * Issue the relevant soft-reset command to the device's GRR register
666 * specified by @op.
667 *
668 * Note, the delays are in there as a caution to ensure that the reset
669 * has time to take effect and then complete. Since the datasheet does
670 * not currently specify the exact sequence, we have chosen something
671 * that seems to work with our device.
672 */
673static void ks_soft_reset(struct ks_net *ks, unsigned op)
674{
675 /* Disable interrupt first */
676 ks_wrreg16(ks, KS_IER, 0x0000);
677 ks_wrreg16(ks, KS_GRR, op);
678 mdelay(10); /* wait a short time to effect reset */
679 ks_wrreg16(ks, KS_GRR, 0);
680 mdelay(1); /* wait for condition to clear */
681}
682
683
684/**
685 * ks_read_qmu - read 1 pkt data from the QMU.
686 * @ks: The chip information
687 * @buf: buffer address to save 1 pkt
688 * @len: Pkt length
689 * Here is the sequence to read 1 pkt:
690 * 1. set sudo DMA mode
691 * 2. read prepend data
692 * 3. read pkt data
693 * 4. reset sudo DMA Mode
694 */
695static inline void ks_read_qmu(struct ks_net *ks, u16 *buf, u32 len)
696{
697 u32 r = ks->extra_byte & 0x1 ;
698 u32 w = ks->extra_byte - r;
699
700 /* 1. set sudo DMA mode */
701 ks_wrreg16(ks, KS_RXFDPR, RXFDPR_RXFPAI);
702 ks_wrreg8(ks, KS_RXQCR, (ks->rc_rxqcr | RXQCR_SDA) & 0xff);
703
704 /* 2. read prepend data */
705 /**
706 * read 4 + extra bytes and discard them.
707 * extra bytes for dummy, 2 for status, 2 for len
708 */
709
710 /* use likely(r) for 8 bit access for performance */
711 if (unlikely(r))
712 ioread8(ks->hw_addr);
713 ks_inblk(ks, buf, w + 2 + 2);
714
715 /* 3. read pkt data */
716 ks_inblk(ks, buf, ALIGN(len, 4));
717
718 /* 4. reset sudo DMA Mode */
719 ks_wrreg8(ks, KS_RXQCR, ks->rc_rxqcr);
720}
721
722/**
723 * ks_rcv - read multiple pkts data from the QMU.
724 * @ks: The chip information
725 * @netdev: The network device being opened.
726 *
727 * Read all of header information before reading pkt content.
728 * It is not allowed only port of pkts in QMU after issuing
729 * interrupt ack.
730 */
731static void ks_rcv(struct ks_net *ks, struct net_device *netdev)
732{
733 u32 i;
734 struct type_frame_head *frame_hdr = ks->frame_head_info;
735 struct sk_buff *skb;
736
737 ks->frame_cnt = ks_rdreg16(ks, KS_RXFCTR) >> 8;
738
739 /* read all header information */
740 for (i = 0; i < ks->frame_cnt; i++) {
741 /* Checking Received packet status */
742 frame_hdr->sts = ks_rdreg16(ks, KS_RXFHSR);
743 /* Get packet len from hardware */
744 frame_hdr->len = ks_rdreg16(ks, KS_RXFHBCR);
745 frame_hdr++;
746 }
747
748 frame_hdr = ks->frame_head_info;
749 while (ks->frame_cnt--) {
750 skb = dev_alloc_skb(frame_hdr->len + 16);
751 if (likely(skb && (frame_hdr->sts & RXFSHR_RXFV) &&
752 (frame_hdr->len < RX_BUF_SIZE) && frame_hdr->len)) {
753 skb_reserve(skb, 2);
754 /* read data block including CRC 4 bytes */
755 ks_read_qmu(ks, (u16 *)skb->data, frame_hdr->len + 4);
756 skb_put(skb, frame_hdr->len);
757 skb->dev = netdev;
758 skb->protocol = eth_type_trans(skb, netdev);
759 netif_rx(skb);
760 } else {
761 printk(KERN_ERR "%s: err:skb alloc\n", __func__);
762 ks_wrreg16(ks, KS_RXQCR, (ks->rc_rxqcr | RXQCR_RRXEF));
763 if (skb)
764 dev_kfree_skb_irq(skb);
765 }
766 frame_hdr++;
767 }
768}
769
770/**
771 * ks_update_link_status - link status update.
772 * @netdev: The network device being opened.
773 * @ks: The chip information
774 *
775 */
776
777static void ks_update_link_status(struct net_device *netdev, struct ks_net *ks)
778{
779 /* check the status of the link */
780 u32 link_up_status;
781 if (ks_rdreg16(ks, KS_P1SR) & P1SR_LINK_GOOD) {
782 netif_carrier_on(netdev);
783 link_up_status = true;
784 } else {
785 netif_carrier_off(netdev);
786 link_up_status = false;
787 }
788 if (netif_msg_link(ks))
789 ks_dbg(ks, "%s: %s\n",
790 __func__, link_up_status ? "UP" : "DOWN");
791}
792
793/**
794 * ks_irq - device interrupt handler
795 * @irq: Interrupt number passed from the IRQ hnalder.
796 * @pw: The private word passed to register_irq(), our struct ks_net.
797 *
798 * This is the handler invoked to find out what happened
799 *
800 * Read the interrupt status, work out what needs to be done and then clear
801 * any of the interrupts that are not needed.
802 */
803
804static irqreturn_t ks_irq(int irq, void *pw)
805{
806 struct ks_net *ks = pw;
807 struct net_device *netdev = ks->netdev;
808 u16 status;
809
810 /*this should be the first in IRQ handler */
811 ks_save_cmd_reg(ks);
812
813 status = ks_rdreg16(ks, KS_ISR);
814 if (unlikely(!status)) {
815 ks_restore_cmd_reg(ks);
816 return IRQ_NONE;
817 }
818
819 ks_wrreg16(ks, KS_ISR, status);
820
821 if (likely(status & IRQ_RXI))
822 ks_rcv(ks, netdev);
823
824 if (unlikely(status & IRQ_LCI))
825 ks_update_link_status(netdev, ks);
826
827 if (unlikely(status & IRQ_TXI))
828 netif_wake_queue(netdev);
829
830 if (unlikely(status & IRQ_LDI)) {
831
832 u16 pmecr = ks_rdreg16(ks, KS_PMECR);
833 pmecr &= ~PMECR_WKEVT_MASK;
834 ks_wrreg16(ks, KS_PMECR, pmecr | PMECR_WKEVT_LINK);
835 }
836
837 /* this should be the last in IRQ handler*/
838 ks_restore_cmd_reg(ks);
839 return IRQ_HANDLED;
840}
841
842
843/**
844 * ks_net_open - open network device
845 * @netdev: The network device being opened.
846 *
847 * Called when the network device is marked active, such as a user executing
848 * 'ifconfig up' on the device.
849 */
850static int ks_net_open(struct net_device *netdev)
851{
852 struct ks_net *ks = netdev_priv(netdev);
853 int err;
854
855#define KS_INT_FLAGS (IRQF_DISABLED|IRQF_TRIGGER_LOW)
856 /* lock the card, even if we may not actually do anything
857 * else at the moment.
858 */
859
860 if (netif_msg_ifup(ks))
861 ks_dbg(ks, "%s - entry\n", __func__);
862
863 /* reset the HW */
864 err = request_irq(ks->irq, ks_irq, KS_INT_FLAGS, DRV_NAME, ks);
865
866 if (err) {
867 printk(KERN_ERR "Failed to request IRQ: %d: %d\n",
868 ks->irq, err);
869 return err;
870 }
871
872 if (netif_msg_ifup(ks))
873 ks_dbg(ks, "network device %s up\n", netdev->name);
874
875 return 0;
876}
877
878/**
879 * ks_net_stop - close network device
880 * @netdev: The device being closed.
881 *
882 * Called to close down a network device which has been active. Cancell any
883 * work, shutdown the RX and TX process and then place the chip into a low
884 * power state whilst it is not being used.
885 */
886static int ks_net_stop(struct net_device *netdev)
887{
888 struct ks_net *ks = netdev_priv(netdev);
889
890 if (netif_msg_ifdown(ks))
891 ks_info(ks, "%s: shutting down\n", netdev->name);
892
893 netif_stop_queue(netdev);
894
895 kfree(ks->frame_head_info);
896
897 mutex_lock(&ks->lock);
898
899 /* turn off the IRQs and ack any outstanding */
900 ks_wrreg16(ks, KS_IER, 0x0000);
901 ks_wrreg16(ks, KS_ISR, 0xffff);
902
903 /* shutdown RX process */
904 ks_wrreg16(ks, KS_RXCR1, 0x0000);
905
906 /* shutdown TX process */
907 ks_wrreg16(ks, KS_TXCR, 0x0000);
908
909 /* set powermode to soft power down to save power */
910 ks_set_powermode(ks, PMECR_PM_SOFTDOWN);
911 free_irq(ks->irq, netdev);
912 mutex_unlock(&ks->lock);
913 return 0;
914}
915
916
917/**
918 * ks_write_qmu - write 1 pkt data to the QMU.
919 * @ks: The chip information
920 * @pdata: buffer address to save 1 pkt
921 * @len: Pkt length in byte
922 * Here is the sequence to write 1 pkt:
923 * 1. set sudo DMA mode
924 * 2. write status/length
925 * 3. write pkt data
926 * 4. reset sudo DMA Mode
927 * 5. reset sudo DMA mode
928 * 6. Wait until pkt is out
929 */
930static void ks_write_qmu(struct ks_net *ks, u8 *pdata, u16 len)
931{
932 unsigned fid = ks->fid;
933
934 fid = ks->fid;
935 ks->fid = (ks->fid + 1) & TXFR_TXFID_MASK;
936
937 /* reduce the tx interrupt occurrances. */
938 if (!fid)
939 fid |= TXFR_TXIC; /* irq on completion */
940
941 /* start header at txb[0] to align txw entries */
942 ks->txh.txw[0] = cpu_to_le16(fid);
943 ks->txh.txw[1] = cpu_to_le16(len);
944
945 /* 1. set sudo-DMA mode */
946 ks_wrreg8(ks, KS_RXQCR, (ks->rc_rxqcr | RXQCR_SDA) & 0xff);
947 /* 2. write status/lenth info */
948 ks_outblk(ks, ks->txh.txw, 4);
949 /* 3. write pkt data */
950 ks_outblk(ks, (u16 *)pdata, ALIGN(len, 4));
951 /* 4. reset sudo-DMA mode */
952 ks_wrreg8(ks, KS_RXQCR, ks->rc_rxqcr);
953 /* 5. Enqueue Tx(move the pkt from TX buffer into TXQ) */
954 ks_wrreg16(ks, KS_TXQCR, TXQCR_METFE);
955 /* 6. wait until TXQCR_METFE is auto-cleared */
956 while (ks_rdreg16(ks, KS_TXQCR) & TXQCR_METFE)
957 ;
958}
959
960static void ks_disable_int(struct ks_net *ks)
961{
962 ks_wrreg16(ks, KS_IER, 0x0000);
963} /* ks_disable_int */
964
965static void ks_enable_int(struct ks_net *ks)
966{
967 ks_wrreg16(ks, KS_IER, ks->rc_ier);
968} /* ks_enable_int */
969
970/**
971 * ks_start_xmit - transmit packet
972 * @skb : The buffer to transmit
973 * @netdev : The device used to transmit the packet.
974 *
975 * Called by the network layer to transmit the @skb.
976 * spin_lock_irqsave is required because tx and rx should be mutual exclusive.
977 * So while tx is in-progress, prevent IRQ interrupt from happenning.
978 */
979static int ks_start_xmit(struct sk_buff *skb, struct net_device *netdev)
980{
981 int retv = NETDEV_TX_OK;
982 struct ks_net *ks = netdev_priv(netdev);
983
984 disable_irq(netdev->irq);
985 ks_disable_int(ks);
986 spin_lock(&ks->statelock);
987
988 /* Extra space are required:
989 * 4 byte for alignment, 4 for status/length, 4 for CRC
990 */
991
992 if (likely(ks_tx_fifo_space(ks) >= skb->len + 12)) {
993 ks_write_qmu(ks, skb->data, skb->len);
994 dev_kfree_skb(skb);
995 } else
996 retv = NETDEV_TX_BUSY;
997 spin_unlock(&ks->statelock);
998 ks_enable_int(ks);
999 enable_irq(netdev->irq);
1000 return retv;
1001}
1002
1003/**
1004 * ks_start_rx - ready to serve pkts
1005 * @ks : The chip information
1006 *
1007 */
1008static void ks_start_rx(struct ks_net *ks)
1009{
1010 u16 cntl;
1011
1012 /* Enables QMU Receive (RXCR1). */
1013 cntl = ks_rdreg16(ks, KS_RXCR1);
1014 cntl |= RXCR1_RXE ;
1015 ks_wrreg16(ks, KS_RXCR1, cntl);
1016} /* ks_start_rx */
1017
1018/**
1019 * ks_stop_rx - stop to serve pkts
1020 * @ks : The chip information
1021 *
1022 */
1023static void ks_stop_rx(struct ks_net *ks)
1024{
1025 u16 cntl;
1026
1027 /* Disables QMU Receive (RXCR1). */
1028 cntl = ks_rdreg16(ks, KS_RXCR1);
1029 cntl &= ~RXCR1_RXE ;
1030 ks_wrreg16(ks, KS_RXCR1, cntl);
1031
1032} /* ks_stop_rx */
1033
1034static unsigned long const ethernet_polynomial = 0x04c11db7U;
1035
1036static unsigned long ether_gen_crc(int length, u8 *data)
1037{
1038 long crc = -1;
1039 while (--length >= 0) {
1040 u8 current_octet = *data++;
1041 int bit;
1042
1043 for (bit = 0; bit < 8; bit++, current_octet >>= 1) {
1044 crc = (crc << 1) ^
1045 ((crc < 0) ^ (current_octet & 1) ?
1046 ethernet_polynomial : 0);
1047 }
1048 }
1049 return (unsigned long)crc;
1050} /* ether_gen_crc */
1051
1052/**
1053* ks_set_grpaddr - set multicast information
1054* @ks : The chip information
1055*/
1056
1057static void ks_set_grpaddr(struct ks_net *ks)
1058{
1059 u8 i;
1060 u32 index, position, value;
1061
1062 memset(ks->mcast_bits, 0, sizeof(u8) * HW_MCAST_SIZE);
1063
1064 for (i = 0; i < ks->mcast_lst_size; i++) {
1065 position = (ether_gen_crc(6, ks->mcast_lst[i]) >> 26) & 0x3f;
1066 index = position >> 3;
1067 value = 1 << (position & 7);
1068 ks->mcast_bits[index] |= (u8)value;
1069 }
1070
1071 for (i = 0; i < HW_MCAST_SIZE; i++) {
1072 if (i & 1) {
1073 ks_wrreg16(ks, (u16)((KS_MAHTR0 + i) & ~1),
1074 (ks->mcast_bits[i] << 8) |
1075 ks->mcast_bits[i - 1]);
1076 }
1077 }
1078} /* ks_set_grpaddr */
1079
1080/*
1081* ks_clear_mcast - clear multicast information
1082*
1083* @ks : The chip information
1084* This routine removes all mcast addresses set in the hardware.
1085*/
1086
1087static void ks_clear_mcast(struct ks_net *ks)
1088{
1089 u16 i, mcast_size;
1090 for (i = 0; i < HW_MCAST_SIZE; i++)
1091 ks->mcast_bits[i] = 0;
1092
1093 mcast_size = HW_MCAST_SIZE >> 2;
1094 for (i = 0; i < mcast_size; i++)
1095 ks_wrreg16(ks, KS_MAHTR0 + (2*i), 0);
1096}
1097
1098static void ks_set_promis(struct ks_net *ks, u16 promiscuous_mode)
1099{
1100 u16 cntl;
1101 ks->promiscuous = promiscuous_mode;
1102 ks_stop_rx(ks); /* Stop receiving for reconfiguration */
1103 cntl = ks_rdreg16(ks, KS_RXCR1);
1104
1105 cntl &= ~RXCR1_FILTER_MASK;
1106 if (promiscuous_mode)
1107 /* Enable Promiscuous mode */
1108 cntl |= RXCR1_RXAE | RXCR1_RXINVF;
1109 else
1110 /* Disable Promiscuous mode (default normal mode) */
1111 cntl |= RXCR1_RXPAFMA;
1112
1113 ks_wrreg16(ks, KS_RXCR1, cntl);
1114
1115 if (ks->enabled)
1116 ks_start_rx(ks);
1117
1118} /* ks_set_promis */
1119
1120static void ks_set_mcast(struct ks_net *ks, u16 mcast)
1121{
1122 u16 cntl;
1123
1124 ks->all_mcast = mcast;
1125 ks_stop_rx(ks); /* Stop receiving for reconfiguration */
1126 cntl = ks_rdreg16(ks, KS_RXCR1);
1127 cntl &= ~RXCR1_FILTER_MASK;
1128 if (mcast)
1129 /* Enable "Perfect with Multicast address passed mode" */
1130 cntl |= (RXCR1_RXAE | RXCR1_RXMAFMA | RXCR1_RXPAFMA);
1131 else
1132 /**
1133 * Disable "Perfect with Multicast address passed
1134 * mode" (normal mode).
1135 */
1136 cntl |= RXCR1_RXPAFMA;
1137
1138 ks_wrreg16(ks, KS_RXCR1, cntl);
1139
1140 if (ks->enabled)
1141 ks_start_rx(ks);
1142} /* ks_set_mcast */
1143
1144static void ks_set_rx_mode(struct net_device *netdev)
1145{
1146 struct ks_net *ks = netdev_priv(netdev);
1147 struct dev_mc_list *ptr;
1148
1149 /* Turn on/off promiscuous mode. */
1150 if ((netdev->flags & IFF_PROMISC) == IFF_PROMISC)
1151 ks_set_promis(ks,
1152 (u16)((netdev->flags & IFF_PROMISC) == IFF_PROMISC));
1153 /* Turn on/off all mcast mode. */
1154 else if ((netdev->flags & IFF_ALLMULTI) == IFF_ALLMULTI)
1155 ks_set_mcast(ks,
1156 (u16)((netdev->flags & IFF_ALLMULTI) == IFF_ALLMULTI));
1157 else
1158 ks_set_promis(ks, false);
1159
1160 if ((netdev->flags & IFF_MULTICAST) && netdev->mc_count) {
1161 if (netdev->mc_count <= MAX_MCAST_LST) {
1162 int i = 0;
1163 for (ptr = netdev->mc_list; ptr; ptr = ptr->next) {
1164 if (!(*ptr->dmi_addr & 1))
1165 continue;
1166 if (i >= MAX_MCAST_LST)
1167 break;
1168 memcpy(ks->mcast_lst[i++], ptr->dmi_addr,
1169 MAC_ADDR_LEN);
1170 }
1171 ks->mcast_lst_size = (u8)i;
1172 ks_set_grpaddr(ks);
1173 } else {
1174 /**
1175 * List too big to support so
1176 * turn on all mcast mode.
1177 */
1178 ks->mcast_lst_size = MAX_MCAST_LST;
1179 ks_set_mcast(ks, true);
1180 }
1181 } else {
1182 ks->mcast_lst_size = 0;
1183 ks_clear_mcast(ks);
1184 }
1185} /* ks_set_rx_mode */
1186
1187static void ks_set_mac(struct ks_net *ks, u8 *data)
1188{
1189 u16 *pw = (u16 *)data;
1190 u16 w, u;
1191
1192 ks_stop_rx(ks); /* Stop receiving for reconfiguration */
1193
1194 u = *pw++;
1195 w = ((u & 0xFF) << 8) | ((u >> 8) & 0xFF);
1196 ks_wrreg16(ks, KS_MARH, w);
1197
1198 u = *pw++;
1199 w = ((u & 0xFF) << 8) | ((u >> 8) & 0xFF);
1200 ks_wrreg16(ks, KS_MARM, w);
1201
1202 u = *pw;
1203 w = ((u & 0xFF) << 8) | ((u >> 8) & 0xFF);
1204 ks_wrreg16(ks, KS_MARL, w);
1205
1206 memcpy(ks->mac_addr, data, 6);
1207
1208 if (ks->enabled)
1209 ks_start_rx(ks);
1210}
1211
1212static int ks_set_mac_address(struct net_device *netdev, void *paddr)
1213{
1214 struct ks_net *ks = netdev_priv(netdev);
1215 struct sockaddr *addr = paddr;
1216 u8 *da;
1217
1218 memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
1219
1220 da = (u8 *)netdev->dev_addr;
1221
1222 ks_set_mac(ks, da);
1223 return 0;
1224}
1225
1226static int ks_net_ioctl(struct net_device *netdev, struct ifreq *req, int cmd)
1227{
1228 struct ks_net *ks = netdev_priv(netdev);
1229
1230 if (!netif_running(netdev))
1231 return -EINVAL;
1232
1233 return generic_mii_ioctl(&ks->mii, if_mii(req), cmd, NULL);
1234}
1235
1236static const struct net_device_ops ks_netdev_ops = {
1237 .ndo_open = ks_net_open,
1238 .ndo_stop = ks_net_stop,
1239 .ndo_do_ioctl = ks_net_ioctl,
1240 .ndo_start_xmit = ks_start_xmit,
1241 .ndo_set_mac_address = ks_set_mac_address,
1242 .ndo_set_rx_mode = ks_set_rx_mode,
1243 .ndo_change_mtu = eth_change_mtu,
1244 .ndo_validate_addr = eth_validate_addr,
1245};
1246
1247/* ethtool support */
1248
1249static void ks_get_drvinfo(struct net_device *netdev,
1250 struct ethtool_drvinfo *di)
1251{
1252 strlcpy(di->driver, DRV_NAME, sizeof(di->driver));
1253 strlcpy(di->version, "1.00", sizeof(di->version));
1254 strlcpy(di->bus_info, dev_name(netdev->dev.parent),
1255 sizeof(di->bus_info));
1256}
1257
1258static u32 ks_get_msglevel(struct net_device *netdev)
1259{
1260 struct ks_net *ks = netdev_priv(netdev);
1261 return ks->msg_enable;
1262}
1263
1264static void ks_set_msglevel(struct net_device *netdev, u32 to)
1265{
1266 struct ks_net *ks = netdev_priv(netdev);
1267 ks->msg_enable = to;
1268}
1269
1270static int ks_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd)
1271{
1272 struct ks_net *ks = netdev_priv(netdev);
1273 return mii_ethtool_gset(&ks->mii, cmd);
1274}
1275
1276static int ks_set_settings(struct net_device *netdev, struct ethtool_cmd *cmd)
1277{
1278 struct ks_net *ks = netdev_priv(netdev);
1279 return mii_ethtool_sset(&ks->mii, cmd);
1280}
1281
1282static u32 ks_get_link(struct net_device *netdev)
1283{
1284 struct ks_net *ks = netdev_priv(netdev);
1285 return mii_link_ok(&ks->mii);
1286}
1287
1288static int ks_nway_reset(struct net_device *netdev)
1289{
1290 struct ks_net *ks = netdev_priv(netdev);
1291 return mii_nway_restart(&ks->mii);
1292}
1293
1294static const struct ethtool_ops ks_ethtool_ops = {
1295 .get_drvinfo = ks_get_drvinfo,
1296 .get_msglevel = ks_get_msglevel,
1297 .set_msglevel = ks_set_msglevel,
1298 .get_settings = ks_get_settings,
1299 .set_settings = ks_set_settings,
1300 .get_link = ks_get_link,
1301 .nway_reset = ks_nway_reset,
1302};
1303
1304/* MII interface controls */
1305
1306/**
1307 * ks_phy_reg - convert MII register into a KS8851 register
1308 * @reg: MII register number.
1309 *
1310 * Return the KS8851 register number for the corresponding MII PHY register
1311 * if possible. Return zero if the MII register has no direct mapping to the
1312 * KS8851 register set.
1313 */
1314static int ks_phy_reg(int reg)
1315{
1316 switch (reg) {
1317 case MII_BMCR:
1318 return KS_P1MBCR;
1319 case MII_BMSR:
1320 return KS_P1MBSR;
1321 case MII_PHYSID1:
1322 return KS_PHY1ILR;
1323 case MII_PHYSID2:
1324 return KS_PHY1IHR;
1325 case MII_ADVERTISE:
1326 return KS_P1ANAR;
1327 case MII_LPA:
1328 return KS_P1ANLPR;
1329 }
1330
1331 return 0x0;
1332}
1333
1334/**
1335 * ks_phy_read - MII interface PHY register read.
1336 * @netdev: The network device the PHY is on.
1337 * @phy_addr: Address of PHY (ignored as we only have one)
1338 * @reg: The register to read.
1339 *
1340 * This call reads data from the PHY register specified in @reg. Since the
1341 * device does not support all the MII registers, the non-existant values
1342 * are always returned as zero.
1343 *
1344 * We return zero for unsupported registers as the MII code does not check
1345 * the value returned for any error status, and simply returns it to the
1346 * caller. The mii-tool that the driver was tested with takes any -ve error
1347 * as real PHY capabilities, thus displaying incorrect data to the user.
1348 */
1349static int ks_phy_read(struct net_device *netdev, int phy_addr, int reg)
1350{
1351 struct ks_net *ks = netdev_priv(netdev);
1352 int ksreg;
1353 int result;
1354
1355 ksreg = ks_phy_reg(reg);
1356 if (!ksreg)
1357 return 0x0; /* no error return allowed, so use zero */
1358
1359 mutex_lock(&ks->lock);
1360 result = ks_rdreg16(ks, ksreg);
1361 mutex_unlock(&ks->lock);
1362
1363 return result;
1364}
1365
1366static void ks_phy_write(struct net_device *netdev,
1367 int phy, int reg, int value)
1368{
1369 struct ks_net *ks = netdev_priv(netdev);
1370 int ksreg;
1371
1372 ksreg = ks_phy_reg(reg);
1373 if (ksreg) {
1374 mutex_lock(&ks->lock);
1375 ks_wrreg16(ks, ksreg, value);
1376 mutex_unlock(&ks->lock);
1377 }
1378}
1379
1380/**
1381 * ks_read_selftest - read the selftest memory info.
1382 * @ks: The device state
1383 *
1384 * Read and check the TX/RX memory selftest information.
1385 */
1386static int ks_read_selftest(struct ks_net *ks)
1387{
1388 unsigned both_done = MBIR_TXMBF | MBIR_RXMBF;
1389 int ret = 0;
1390 unsigned rd;
1391
1392 rd = ks_rdreg16(ks, KS_MBIR);
1393
1394 if ((rd & both_done) != both_done) {
1395 ks_warn(ks, "Memory selftest not finished\n");
1396 return 0;
1397 }
1398
1399 if (rd & MBIR_TXMBFA) {
1400 ks_err(ks, "TX memory selftest fails\n");
1401 ret |= 1;
1402 }
1403
1404 if (rd & MBIR_RXMBFA) {
1405 ks_err(ks, "RX memory selftest fails\n");
1406 ret |= 2;
1407 }
1408
1409 ks_info(ks, "the selftest passes\n");
1410 return ret;
1411}
1412
1413static void ks_disable(struct ks_net *ks)
1414{
1415 u16 w;
1416
1417 w = ks_rdreg16(ks, KS_TXCR);
1418
1419 /* Disables QMU Transmit (TXCR). */
1420 w &= ~TXCR_TXE;
1421 ks_wrreg16(ks, KS_TXCR, w);
1422
1423 /* Disables QMU Receive (RXCR1). */
1424 w = ks_rdreg16(ks, KS_RXCR1);
1425 w &= ~RXCR1_RXE ;
1426 ks_wrreg16(ks, KS_RXCR1, w);
1427
1428 ks->enabled = false;
1429
1430} /* ks_disable */
1431
1432static void ks_setup(struct ks_net *ks)
1433{
1434 u16 w;
1435
1436 /**
1437 * Configure QMU Transmit
1438 */
1439
1440 /* Setup Transmit Frame Data Pointer Auto-Increment (TXFDPR) */
1441 ks_wrreg16(ks, KS_TXFDPR, TXFDPR_TXFPAI);
1442
1443 /* Setup Receive Frame Data Pointer Auto-Increment */
1444 ks_wrreg16(ks, KS_RXFDPR, RXFDPR_RXFPAI);
1445
1446 /* Setup Receive Frame Threshold - 1 frame (RXFCTFC) */
1447 ks_wrreg16(ks, KS_RXFCTR, 1 & RXFCTR_THRESHOLD_MASK);
1448
1449 /* Setup RxQ Command Control (RXQCR) */
1450 ks->rc_rxqcr = RXQCR_CMD_CNTL;
1451 ks_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr);
1452
1453 /**
1454 * set the force mode to half duplex, default is full duplex
1455 * because if the auto-negotiation fails, most switch uses
1456 * half-duplex.
1457 */
1458
1459 w = ks_rdreg16(ks, KS_P1MBCR);
1460 w &= ~P1MBCR_FORCE_FDX;
1461 ks_wrreg16(ks, KS_P1MBCR, w);
1462
1463 w = TXCR_TXFCE | TXCR_TXPE | TXCR_TXCRC | TXCR_TCGIP;
1464 ks_wrreg16(ks, KS_TXCR, w);
1465
1466 w = RXCR1_RXFCE | RXCR1_RXBE | RXCR1_RXUE;
1467
1468 if (ks->promiscuous) /* bPromiscuous */
1469 w |= (RXCR1_RXAE | RXCR1_RXINVF);
1470 else if (ks->all_mcast) /* Multicast address passed mode */
1471 w |= (RXCR1_RXAE | RXCR1_RXMAFMA | RXCR1_RXPAFMA);
1472 else /* Normal mode */
1473 w |= RXCR1_RXPAFMA;
1474
1475 ks_wrreg16(ks, KS_RXCR1, w);
1476} /*ks_setup */
1477
1478
1479static void ks_setup_int(struct ks_net *ks)
1480{
1481 ks->rc_ier = 0x00;
1482 /* Clear the interrupts status of the hardware. */
1483 ks_wrreg16(ks, KS_ISR, 0xffff);
1484
1485 /* Enables the interrupts of the hardware. */
1486 ks->rc_ier = (IRQ_LCI | IRQ_TXI | IRQ_RXI);
1487} /* ks_setup_int */
1488
1489void ks_enable(struct ks_net *ks)
1490{
1491 u16 w;
1492
1493 w = ks_rdreg16(ks, KS_TXCR);
1494 /* Enables QMU Transmit (TXCR). */
1495 ks_wrreg16(ks, KS_TXCR, w | TXCR_TXE);
1496
1497 /*
1498 * RX Frame Count Threshold Enable and Auto-Dequeue RXQ Frame
1499 * Enable
1500 */
1501
1502 w = ks_rdreg16(ks, KS_RXQCR);
1503 ks_wrreg16(ks, KS_RXQCR, w | RXQCR_RXFCTE);
1504
1505 /* Enables QMU Receive (RXCR1). */
1506 w = ks_rdreg16(ks, KS_RXCR1);
1507 ks_wrreg16(ks, KS_RXCR1, w | RXCR1_RXE);
1508 ks->enabled = true;
1509} /* ks_enable */
1510
1511static int ks_hw_init(struct ks_net *ks)
1512{
1513#define MHEADER_SIZE (sizeof(struct type_frame_head) * MAX_RECV_FRAMES)
1514 ks->promiscuous = 0;
1515 ks->all_mcast = 0;
1516 ks->mcast_lst_size = 0;
1517
1518 ks->frame_head_info = (struct type_frame_head *) \
1519 kmalloc(MHEADER_SIZE, GFP_KERNEL);
1520 if (!ks->frame_head_info) {
1521 printk(KERN_ERR "Error: Fail to allocate frame memory\n");
1522 return false;
1523 }
1524
1525 ks_set_mac(ks, KS_DEFAULT_MAC_ADDRESS);
1526 return true;
1527}
1528
1529
1530static int __devinit ks8851_probe(struct platform_device *pdev)
1531{
1532 int err = -ENOMEM;
1533 struct resource *io_d, *io_c;
1534 struct net_device *netdev;
1535 struct ks_net *ks;
1536 u16 id, data;
1537
1538 io_d = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1539 io_c = platform_get_resource(pdev, IORESOURCE_MEM, 1);
1540
1541 if (!request_mem_region(io_d->start, resource_size(io_d), DRV_NAME))
1542 goto err_mem_region;
1543
1544 if (!request_mem_region(io_c->start, resource_size(io_c), DRV_NAME))
1545 goto err_mem_region1;
1546
1547 netdev = alloc_etherdev(sizeof(struct ks_net));
1548 if (!netdev)
1549 goto err_alloc_etherdev;
1550
1551 SET_NETDEV_DEV(netdev, &pdev->dev);
1552
1553 ks = netdev_priv(netdev);
1554 ks->netdev = netdev;
1555 ks->hw_addr = ioremap(io_d->start, resource_size(io_d));
1556
1557 if (!ks->hw_addr)
1558 goto err_ioremap;
1559
1560 ks->hw_addr_cmd = ioremap(io_c->start, resource_size(io_c));
1561 if (!ks->hw_addr_cmd)
1562 goto err_ioremap1;
1563
1564 ks->irq = platform_get_irq(pdev, 0);
1565
1566 if (ks->irq < 0) {
1567 err = ks->irq;
1568 goto err_get_irq;
1569 }
1570
1571 ks->pdev = pdev;
1572
1573 mutex_init(&ks->lock);
1574 spin_lock_init(&ks->statelock);
1575
1576 netdev->netdev_ops = &ks_netdev_ops;
1577 netdev->ethtool_ops = &ks_ethtool_ops;
1578
1579 /* setup mii state */
1580 ks->mii.dev = netdev;
1581 ks->mii.phy_id = 1,
1582 ks->mii.phy_id_mask = 1;
1583 ks->mii.reg_num_mask = 0xf;
1584 ks->mii.mdio_read = ks_phy_read;
1585 ks->mii.mdio_write = ks_phy_write;
1586
1587 ks_info(ks, "message enable is %d\n", msg_enable);
1588 /* set the default message enable */
1589 ks->msg_enable = netif_msg_init(msg_enable, (NETIF_MSG_DRV |
1590 NETIF_MSG_PROBE |
1591 NETIF_MSG_LINK));
1592 ks_read_config(ks);
1593
1594 /* simple check for a valid chip being connected to the bus */
1595 if ((ks_rdreg16(ks, KS_CIDER) & ~CIDER_REV_MASK) != CIDER_ID) {
1596 ks_err(ks, "failed to read device ID\n");
1597 err = -ENODEV;
1598 goto err_register;
1599 }
1600
1601 if (ks_read_selftest(ks)) {
1602 ks_err(ks, "failed to read device ID\n");
1603 err = -ENODEV;
1604 goto err_register;
1605 }
1606
1607 err = register_netdev(netdev);
1608 if (err)
1609 goto err_register;
1610
1611 platform_set_drvdata(pdev, netdev);
1612
1613 ks_soft_reset(ks, GRR_GSR);
1614 ks_hw_init(ks);
1615 ks_disable(ks);
1616 ks_setup(ks);
1617 ks_setup_int(ks);
1618 ks_enable_int(ks);
1619 ks_enable(ks);
1620 memcpy(netdev->dev_addr, ks->mac_addr, 6);
1621
1622 data = ks_rdreg16(ks, KS_OBCR);
1623 ks_wrreg16(ks, KS_OBCR, data | OBCR_ODS_16MA);
1624
1625 /**
1626 * If you want to use the default MAC addr,
1627 * comment out the 2 functions below.
1628 */
1629
1630 random_ether_addr(netdev->dev_addr);
1631 ks_set_mac(ks, netdev->dev_addr);
1632
1633 id = ks_rdreg16(ks, KS_CIDER);
1634
1635 printk(KERN_INFO DRV_NAME
1636 " Found chip, family: 0x%x, id: 0x%x, rev: 0x%x\n",
1637 (id >> 8) & 0xff, (id >> 4) & 0xf, (id >> 1) & 0x7);
1638 return 0;
1639
1640err_register:
1641err_get_irq:
1642 iounmap(ks->hw_addr_cmd);
1643err_ioremap1:
1644 iounmap(ks->hw_addr);
1645err_ioremap:
1646 free_netdev(netdev);
1647err_alloc_etherdev:
1648 release_mem_region(io_c->start, resource_size(io_c));
1649err_mem_region1:
1650 release_mem_region(io_d->start, resource_size(io_d));
1651err_mem_region:
1652 return err;
1653}
1654
1655static int __devexit ks8851_remove(struct platform_device *pdev)
1656{
1657 struct net_device *netdev = platform_get_drvdata(pdev);
1658 struct ks_net *ks = netdev_priv(netdev);
1659 struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1660
1661 unregister_netdev(netdev);
1662 iounmap(ks->hw_addr);
1663 free_netdev(netdev);
1664 release_mem_region(iomem->start, resource_size(iomem));
1665 platform_set_drvdata(pdev, NULL);
1666 return 0;
1667
1668}
1669
1670static struct platform_driver ks8851_platform_driver = {
1671 .driver = {
1672 .name = DRV_NAME,
1673 .owner = THIS_MODULE,
1674 },
1675 .probe = ks8851_probe,
1676 .remove = __devexit_p(ks8851_remove),
1677};
1678
1679static int __init ks8851_init(void)
1680{
1681 return platform_driver_register(&ks8851_platform_driver);
1682}
1683
1684static void __exit ks8851_exit(void)
1685{
1686 platform_driver_unregister(&ks8851_platform_driver);
1687}
1688
1689module_init(ks8851_init);
1690module_exit(ks8851_exit);
1691
1692MODULE_DESCRIPTION("KS8851 MLL Network driver");
1693MODULE_AUTHOR("David Choi <david.choi@micrel.com>");
1694MODULE_LICENSE("GPL");
1695module_param_named(message, msg_enable, int, 0);
1696MODULE_PARM_DESC(message, "Message verbosity level (0=none, 31=all)");
1697
diff --git a/drivers/net/meth.c b/drivers/net/meth.c
index 92ceb689b4d4..2af81735386b 100644
--- a/drivers/net/meth.c
+++ b/drivers/net/meth.c
@@ -828,7 +828,7 @@ static int __exit meth_remove(struct platform_device *pdev)
828 828
829static struct platform_driver meth_driver = { 829static struct platform_driver meth_driver = {
830 .probe = meth_probe, 830 .probe = meth_probe,
831 .remove = __devexit_p(meth_remove), 831 .remove = __exit_p(meth_remove),
832 .driver = { 832 .driver = {
833 .name = "meth", 833 .name = "meth",
834 .owner = THIS_MODULE, 834 .owner = THIS_MODULE,
diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c
index 3dd481e77f92..5dd7225b178e 100644
--- a/drivers/net/mlx4/main.c
+++ b/drivers/net/mlx4/main.c
@@ -1282,6 +1282,7 @@ static struct pci_device_id mlx4_pci_table[] = {
1282 { PCI_VDEVICE(MELLANOX, 0x6372) }, /* MT25458 ConnectX EN 10GBASE-T 10GigE */ 1282 { PCI_VDEVICE(MELLANOX, 0x6372) }, /* MT25458 ConnectX EN 10GBASE-T 10GigE */
1283 { PCI_VDEVICE(MELLANOX, 0x675a) }, /* MT25458 ConnectX EN 10GBASE-T+Gen2 10GigE */ 1283 { PCI_VDEVICE(MELLANOX, 0x675a) }, /* MT25458 ConnectX EN 10GBASE-T+Gen2 10GigE */
1284 { PCI_VDEVICE(MELLANOX, 0x6764) }, /* MT26468 ConnectX EN 10GigE PCIe gen2*/ 1284 { PCI_VDEVICE(MELLANOX, 0x6764) }, /* MT26468 ConnectX EN 10GigE PCIe gen2*/
1285 { PCI_VDEVICE(MELLANOX, 0x676e) }, /* MT26478 ConnectX2 40GigE PCIe gen2 */
1285 { 0, } 1286 { 0, }
1286}; 1287};
1287 1288
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index b5aa974827e5..7fc15e9e8adb 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -595,7 +595,8 @@ netxen_setup_pci_map(struct netxen_adapter *adapter)
595 void __iomem *mem_ptr2 = NULL; 595 void __iomem *mem_ptr2 = NULL;
596 void __iomem *db_ptr = NULL; 596 void __iomem *db_ptr = NULL;
597 597
598 unsigned long mem_base, mem_len, db_base, db_len = 0, pci_len0 = 0; 598 resource_size_t mem_base, db_base;
599 unsigned long mem_len, db_len = 0, pci_len0 = 0;
599 600
600 struct pci_dev *pdev = adapter->pdev; 601 struct pci_dev *pdev = adapter->pdev;
601 int pci_func = adapter->ahw.pci_func; 602 int pci_func = adapter->ahw.pci_func;
@@ -1714,7 +1715,7 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
1714 /* 4 fragments per cmd des */ 1715 /* 4 fragments per cmd des */
1715 no_of_desc = (frag_count + 3) >> 2; 1716 no_of_desc = (frag_count + 3) >> 2;
1716 1717
1717 if (unlikely(no_of_desc + 2) > netxen_tx_avail(tx_ring)) { 1718 if (unlikely(no_of_desc + 2 > netxen_tx_avail(tx_ring))) {
1718 netif_stop_queue(netdev); 1719 netif_stop_queue(netdev);
1719 return NETDEV_TX_BUSY; 1720 return NETDEV_TX_BUSY;
1720 } 1721 }
diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c
index c594e1946476..57fd483dbb1f 100644
--- a/drivers/net/ns83820.c
+++ b/drivers/net/ns83820.c
@@ -111,6 +111,7 @@
111#include <linux/compiler.h> 111#include <linux/compiler.h>
112#include <linux/prefetch.h> 112#include <linux/prefetch.h>
113#include <linux/ethtool.h> 113#include <linux/ethtool.h>
114#include <linux/sched.h>
114#include <linux/timer.h> 115#include <linux/timer.h>
115#include <linux/if_vlan.h> 116#include <linux/if_vlan.h>
116#include <linux/rtnetlink.h> 117#include <linux/rtnetlink.h>
diff --git a/drivers/net/pasemi_mac_ethtool.c b/drivers/net/pasemi_mac_ethtool.c
index 064a4fe1dd90..28a86224879d 100644
--- a/drivers/net/pasemi_mac_ethtool.c
+++ b/drivers/net/pasemi_mac_ethtool.c
@@ -71,6 +71,9 @@ pasemi_mac_ethtool_get_settings(struct net_device *netdev,
71 struct pasemi_mac *mac = netdev_priv(netdev); 71 struct pasemi_mac *mac = netdev_priv(netdev);
72 struct phy_device *phydev = mac->phydev; 72 struct phy_device *phydev = mac->phydev;
73 73
74 if (!phydev)
75 return -EOPNOTSUPP;
76
74 return phy_ethtool_gset(phydev, cmd); 77 return phy_ethtool_gset(phydev, cmd);
75} 78}
76 79
diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c
index ee8ad3e180dd..b58965a2b3ae 100644
--- a/drivers/net/pcmcia/3c574_cs.c
+++ b/drivers/net/pcmcia/3c574_cs.c
@@ -251,6 +251,7 @@ static void el3_tx_timeout(struct net_device *dev);
251static int el3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); 251static int el3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
252static const struct ethtool_ops netdev_ethtool_ops; 252static const struct ethtool_ops netdev_ethtool_ops;
253static void set_rx_mode(struct net_device *dev); 253static void set_rx_mode(struct net_device *dev);
254static void set_multicast_list(struct net_device *dev);
254 255
255static void tc574_detach(struct pcmcia_device *p_dev); 256static void tc574_detach(struct pcmcia_device *p_dev);
256 257
@@ -266,7 +267,7 @@ static const struct net_device_ops el3_netdev_ops = {
266 .ndo_tx_timeout = el3_tx_timeout, 267 .ndo_tx_timeout = el3_tx_timeout,
267 .ndo_get_stats = el3_get_stats, 268 .ndo_get_stats = el3_get_stats,
268 .ndo_do_ioctl = el3_ioctl, 269 .ndo_do_ioctl = el3_ioctl,
269 .ndo_set_multicast_list = set_rx_mode, 270 .ndo_set_multicast_list = set_multicast_list,
270 .ndo_change_mtu = eth_change_mtu, 271 .ndo_change_mtu = eth_change_mtu,
271 .ndo_set_mac_address = eth_mac_addr, 272 .ndo_set_mac_address = eth_mac_addr,
272 .ndo_validate_addr = eth_validate_addr, 273 .ndo_validate_addr = eth_validate_addr,
@@ -1161,6 +1162,16 @@ static void set_rx_mode(struct net_device *dev)
1161 outw(SetRxFilter | RxStation | RxBroadcast, ioaddr + EL3_CMD); 1162 outw(SetRxFilter | RxStation | RxBroadcast, ioaddr + EL3_CMD);
1162} 1163}
1163 1164
1165static void set_multicast_list(struct net_device *dev)
1166{
1167 struct el3_private *lp = netdev_priv(dev);
1168 unsigned long flags;
1169
1170 spin_lock_irqsave(&lp->window_lock, flags);
1171 set_rx_mode(dev);
1172 spin_unlock_irqrestore(&lp->window_lock, flags);
1173}
1174
1164static int el3_close(struct net_device *dev) 1175static int el3_close(struct net_device *dev)
1165{ 1176{
1166 unsigned int ioaddr = dev->base_addr; 1177 unsigned int ioaddr = dev->base_addr;
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index 474876c879cb..bd3447f04902 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -1754,14 +1754,14 @@ static struct pcmcia_device_id pcnet_ids[] = {
1754 PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "cis/PCMLM28.cis"), 1754 PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "cis/PCMLM28.cis"),
1755 PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "Psion Dacom", "Gold Card V34 Ethernet GSM", 0xf5f025c2, 0x4ae85d35, "cis/PCMLM28.cis"), 1755 PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "Psion Dacom", "Gold Card V34 Ethernet GSM", 0xf5f025c2, 0x4ae85d35, "cis/PCMLM28.cis"),
1756 PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "LINKSYS", "PCMLM28", 0xf7cb0b07, 0x66881874, "cis/PCMLM28.cis"), 1756 PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "LINKSYS", "PCMLM28", 0xf7cb0b07, 0x66881874, "cis/PCMLM28.cis"),
1757 PCMCIA_MFC_DEVICE_CIS_PROD_ID12(0, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "DP83903.cis"), 1757 PCMCIA_MFC_DEVICE_CIS_PROD_ID12(0, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "cis/DP83903.cis"),
1758 PCMCIA_MFC_DEVICE_CIS_PROD_ID4(0, "NSC MF LAN/Modem", 0x58fc6056, "DP83903.cis"), 1758 PCMCIA_MFC_DEVICE_CIS_PROD_ID4(0, "NSC MF LAN/Modem", 0x58fc6056, "cis/DP83903.cis"),
1759 PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0175, 0x0000, "DP83903.cis"), 1759 PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0175, 0x0000, "cis/DP83903.cis"),
1760 PCMCIA_DEVICE_CIS_MANF_CARD(0xc00f, 0x0002, "cis/LA-PCM.cis"), 1760 PCMCIA_DEVICE_CIS_MANF_CARD(0xc00f, 0x0002, "cis/LA-PCM.cis"),
1761 PCMCIA_DEVICE_CIS_PROD_ID12("KTI", "PE520 PLUS", 0xad180345, 0x9d58d392, "PE520.cis"), 1761 PCMCIA_DEVICE_CIS_PROD_ID12("KTI", "PE520 PLUS", 0xad180345, 0x9d58d392, "PE520.cis"),
1762 PCMCIA_DEVICE_CIS_PROD_ID12("NDC", "Ethernet", 0x01c43ae1, 0x00b2e941, "NE2K.cis"), 1762 PCMCIA_DEVICE_CIS_PROD_ID12("NDC", "Ethernet", 0x01c43ae1, 0x00b2e941, "cis/NE2K.cis"),
1763 PCMCIA_DEVICE_CIS_PROD_ID12("PMX ", "PE-200", 0x34f3f1c8, 0x10b59f8c, "PE-200.cis"), 1763 PCMCIA_DEVICE_CIS_PROD_ID12("PMX ", "PE-200", 0x34f3f1c8, 0x10b59f8c, "PE-200.cis"),
1764 PCMCIA_DEVICE_CIS_PROD_ID12("TAMARACK", "Ethernet", 0xcf434fba, 0x00b2e941, "tamarack.cis"), 1764 PCMCIA_DEVICE_CIS_PROD_ID12("TAMARACK", "Ethernet", 0xcf434fba, 0x00b2e941, "cis/tamarack.cis"),
1765 PCMCIA_DEVICE_PROD_ID12("Ethernet", "CF Size PC Card", 0x00b2e941, 0x43ac239b), 1765 PCMCIA_DEVICE_PROD_ID12("Ethernet", "CF Size PC Card", 0x00b2e941, 0x43ac239b),
1766 PCMCIA_DEVICE_PROD_ID123("Fast Ethernet", "CF Size PC Card", "1.0", 1766 PCMCIA_DEVICE_PROD_ID123("Fast Ethernet", "CF Size PC Card", "1.0",
1767 0xb4be14e3, 0x43ac239b, 0x0877b627), 1767 0xb4be14e3, 0x43ac239b, 0x0877b627),
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
index 6d28b18e7e28..c1b3f09f452c 100644
--- a/drivers/net/pcnet32.c
+++ b/drivers/net/pcnet32.c
@@ -31,6 +31,7 @@ static const char *const version =
31 31
32#include <linux/module.h> 32#include <linux/module.h>
33#include <linux/kernel.h> 33#include <linux/kernel.h>
34#include <linux/sched.h>
34#include <linux/string.h> 35#include <linux/string.h>
35#include <linux/errno.h> 36#include <linux/errno.h>
36#include <linux/ioport.h> 37#include <linux/ioport.h>
diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c
index 250e10f2c35b..8659d341e769 100644
--- a/drivers/net/phy/mdio-gpio.c
+++ b/drivers/net/phy/mdio-gpio.c
@@ -238,6 +238,7 @@ static struct of_device_id mdio_ofgpio_match[] = {
238 }, 238 },
239 {}, 239 {},
240}; 240};
241MODULE_DEVICE_TABLE(of, mdio_ofgpio_match);
241 242
242static struct of_platform_driver mdio_ofgpio_driver = { 243static struct of_platform_driver mdio_ofgpio_driver = {
243 .name = "mdio-gpio", 244 .name = "mdio-gpio",
diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c
index cc394d073755..5910df60c93e 100644
--- a/drivers/net/pppol2tp.c
+++ b/drivers/net/pppol2tp.c
@@ -2179,7 +2179,7 @@ static int pppol2tp_session_setsockopt(struct sock *sk,
2179 * session or the special tunnel type. 2179 * session or the special tunnel type.
2180 */ 2180 */
2181static int pppol2tp_setsockopt(struct socket *sock, int level, int optname, 2181static int pppol2tp_setsockopt(struct socket *sock, int level, int optname,
2182 char __user *optval, int optlen) 2182 char __user *optval, unsigned int optlen)
2183{ 2183{
2184 struct sock *sk = sock->sk; 2184 struct sock *sk = sock->sk;
2185 struct pppol2tp_session *session = sk->sk_user_data; 2185 struct pppol2tp_session *session = sk->sk_user_data;
diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h
index a9845a2f243f..e7285f01bd04 100644
--- a/drivers/net/qlge/qlge.h
+++ b/drivers/net/qlge/qlge.h
@@ -9,6 +9,7 @@
9 9
10#include <linux/pci.h> 10#include <linux/pci.h>
11#include <linux/netdevice.h> 11#include <linux/netdevice.h>
12#include <linux/rtnetlink.h>
12 13
13/* 14/*
14 * General definitions... 15 * General definitions...
@@ -135,9 +136,9 @@ enum {
135 RST_FO_TFO = (1 << 0), 136 RST_FO_TFO = (1 << 0),
136 RST_FO_RR_MASK = 0x00060000, 137 RST_FO_RR_MASK = 0x00060000,
137 RST_FO_RR_CQ_CAM = 0x00000000, 138 RST_FO_RR_CQ_CAM = 0x00000000,
138 RST_FO_RR_DROP = 0x00000001, 139 RST_FO_RR_DROP = 0x00000002,
139 RST_FO_RR_DQ = 0x00000002, 140 RST_FO_RR_DQ = 0x00000004,
140 RST_FO_RR_RCV_FUNC_CQ = 0x00000003, 141 RST_FO_RR_RCV_FUNC_CQ = 0x00000006,
141 RST_FO_FRB = (1 << 12), 142 RST_FO_FRB = (1 << 12),
142 RST_FO_MOP = (1 << 13), 143 RST_FO_MOP = (1 << 13),
143 RST_FO_REG = (1 << 14), 144 RST_FO_REG = (1 << 14),
@@ -802,6 +803,12 @@ enum {
802 MB_CMD_SET_PORT_CFG = 0x00000122, 803 MB_CMD_SET_PORT_CFG = 0x00000122,
803 MB_CMD_GET_PORT_CFG = 0x00000123, 804 MB_CMD_GET_PORT_CFG = 0x00000123,
804 MB_CMD_GET_LINK_STS = 0x00000124, 805 MB_CMD_GET_LINK_STS = 0x00000124,
806 MB_CMD_SET_MGMNT_TFK_CTL = 0x00000160, /* Set Mgmnt Traffic Control */
807 MB_SET_MPI_TFK_STOP = (1 << 0),
808 MB_SET_MPI_TFK_RESUME = (1 << 1),
809 MB_CMD_GET_MGMNT_TFK_CTL = 0x00000161, /* Get Mgmnt Traffic Control */
810 MB_GET_MPI_TFK_STOPPED = (1 << 0),
811 MB_GET_MPI_TFK_FIFO_EMPTY = (1 << 1),
805 812
806 /* Mailbox Command Status. */ 813 /* Mailbox Command Status. */
807 MB_CMD_STS_GOOD = 0x00004000, /* Success. */ 814 MB_CMD_STS_GOOD = 0x00004000, /* Success. */
@@ -1167,7 +1174,7 @@ struct ricb {
1167#define RSS_RI6 0x40 1174#define RSS_RI6 0x40
1168#define RSS_RT6 0x80 1175#define RSS_RT6 0x80
1169 __le16 mask; 1176 __le16 mask;
1170 __le32 hash_cq_id[256]; 1177 u8 hash_cq_id[1024];
1171 __le32 ipv6_hash_key[10]; 1178 __le32 ipv6_hash_key[10];
1172 __le32 ipv4_hash_key[4]; 1179 __le32 ipv4_hash_key[4];
1173} __attribute((packed)); 1180} __attribute((packed));
@@ -1381,15 +1388,15 @@ struct intr_context {
1381 1388
1382/* adapter flags definitions. */ 1389/* adapter flags definitions. */
1383enum { 1390enum {
1384 QL_ADAPTER_UP = (1 << 0), /* Adapter has been brought up. */ 1391 QL_ADAPTER_UP = 0, /* Adapter has been brought up. */
1385 QL_LEGACY_ENABLED = (1 << 3), 1392 QL_LEGACY_ENABLED = 1,
1386 QL_MSI_ENABLED = (1 << 3), 1393 QL_MSI_ENABLED = 2,
1387 QL_MSIX_ENABLED = (1 << 4), 1394 QL_MSIX_ENABLED = 3,
1388 QL_DMA64 = (1 << 5), 1395 QL_DMA64 = 4,
1389 QL_PROMISCUOUS = (1 << 6), 1396 QL_PROMISCUOUS = 5,
1390 QL_ALLMULTI = (1 << 7), 1397 QL_ALLMULTI = 6,
1391 QL_PORT_CFG = (1 << 8), 1398 QL_PORT_CFG = 7,
1392 QL_CAM_RT_SET = (1 << 9), 1399 QL_CAM_RT_SET = 8,
1393}; 1400};
1394 1401
1395/* link_status bit definitions */ 1402/* link_status bit definitions */
@@ -1477,7 +1484,6 @@ struct ql_adapter {
1477 u32 mailbox_in; 1484 u32 mailbox_in;
1478 u32 mailbox_out; 1485 u32 mailbox_out;
1479 struct mbox_params idc_mbc; 1486 struct mbox_params idc_mbc;
1480 struct mutex mpi_mutex;
1481 1487
1482 int tx_ring_size; 1488 int tx_ring_size;
1483 int rx_ring_size; 1489 int rx_ring_size;
@@ -1606,6 +1612,8 @@ int ql_read_mpi_reg(struct ql_adapter *qdev, u32 reg, u32 *data);
1606int ql_mb_about_fw(struct ql_adapter *qdev); 1612int ql_mb_about_fw(struct ql_adapter *qdev);
1607void ql_link_on(struct ql_adapter *qdev); 1613void ql_link_on(struct ql_adapter *qdev);
1608void ql_link_off(struct ql_adapter *qdev); 1614void ql_link_off(struct ql_adapter *qdev);
1615int ql_mb_set_mgmnt_traffic_ctl(struct ql_adapter *qdev, u32 control);
1616int ql_wait_fifo_empty(struct ql_adapter *qdev);
1609 1617
1610#if 1 1618#if 1
1611#define QL_ALL_DUMP 1619#define QL_ALL_DUMP
diff --git a/drivers/net/qlge/qlge_ethtool.c b/drivers/net/qlge/qlge_ethtool.c
index 68f9bd280f86..52073946bce3 100644
--- a/drivers/net/qlge/qlge_ethtool.c
+++ b/drivers/net/qlge/qlge_ethtool.c
@@ -45,7 +45,6 @@ static int ql_update_ring_coalescing(struct ql_adapter *qdev)
45 if (!netif_running(qdev->ndev)) 45 if (!netif_running(qdev->ndev))
46 return status; 46 return status;
47 47
48 spin_lock(&qdev->hw_lock);
49 /* Skip the default queue, and update the outbound handler 48 /* Skip the default queue, and update the outbound handler
50 * queues if they changed. 49 * queues if they changed.
51 */ 50 */
@@ -92,7 +91,6 @@ static int ql_update_ring_coalescing(struct ql_adapter *qdev)
92 } 91 }
93 } 92 }
94exit: 93exit:
95 spin_unlock(&qdev->hw_lock);
96 return status; 94 return status;
97} 95}
98 96
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index 7783c5db81dc..48b45df85ec9 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -34,7 +34,6 @@
34#include <linux/etherdevice.h> 34#include <linux/etherdevice.h>
35#include <linux/ethtool.h> 35#include <linux/ethtool.h>
36#include <linux/skbuff.h> 36#include <linux/skbuff.h>
37#include <linux/rtnetlink.h>
38#include <linux/if_vlan.h> 37#include <linux/if_vlan.h>
39#include <linux/delay.h> 38#include <linux/delay.h>
40#include <linux/mm.h> 39#include <linux/mm.h>
@@ -321,6 +320,37 @@ static int ql_set_mac_addr_reg(struct ql_adapter *qdev, u8 *addr, u32 type,
321 320
322 switch (type) { 321 switch (type) {
323 case MAC_ADDR_TYPE_MULTI_MAC: 322 case MAC_ADDR_TYPE_MULTI_MAC:
323 {
324 u32 upper = (addr[0] << 8) | addr[1];
325 u32 lower = (addr[2] << 24) | (addr[3] << 16) |
326 (addr[4] << 8) | (addr[5]);
327
328 status =
329 ql_wait_reg_rdy(qdev,
330 MAC_ADDR_IDX, MAC_ADDR_MW, 0);
331 if (status)
332 goto exit;
333 ql_write32(qdev, MAC_ADDR_IDX, (offset++) |
334 (index << MAC_ADDR_IDX_SHIFT) |
335 type | MAC_ADDR_E);
336 ql_write32(qdev, MAC_ADDR_DATA, lower);
337 status =
338 ql_wait_reg_rdy(qdev,
339 MAC_ADDR_IDX, MAC_ADDR_MW, 0);
340 if (status)
341 goto exit;
342 ql_write32(qdev, MAC_ADDR_IDX, (offset++) |
343 (index << MAC_ADDR_IDX_SHIFT) |
344 type | MAC_ADDR_E);
345
346 ql_write32(qdev, MAC_ADDR_DATA, upper);
347 status =
348 ql_wait_reg_rdy(qdev,
349 MAC_ADDR_IDX, MAC_ADDR_MW, 0);
350 if (status)
351 goto exit;
352 break;
353 }
324 case MAC_ADDR_TYPE_CAM_MAC: 354 case MAC_ADDR_TYPE_CAM_MAC:
325 { 355 {
326 u32 cam_output; 356 u32 cam_output;
@@ -366,16 +396,14 @@ static int ql_set_mac_addr_reg(struct ql_adapter *qdev, u8 *addr, u32 type,
366 and possibly the function id. Right now we hardcode 396 and possibly the function id. Right now we hardcode
367 the route field to NIC core. 397 the route field to NIC core.
368 */ 398 */
369 if (type == MAC_ADDR_TYPE_CAM_MAC) { 399 cam_output = (CAM_OUT_ROUTE_NIC |
370 cam_output = (CAM_OUT_ROUTE_NIC | 400 (qdev->
371 (qdev-> 401 func << CAM_OUT_FUNC_SHIFT) |
372 func << CAM_OUT_FUNC_SHIFT) | 402 (0 << CAM_OUT_CQ_ID_SHIFT));
373 (0 << CAM_OUT_CQ_ID_SHIFT)); 403 if (qdev->vlgrp)
374 if (qdev->vlgrp) 404 cam_output |= CAM_OUT_RV;
375 cam_output |= CAM_OUT_RV; 405 /* route to NIC core */
376 /* route to NIC core */ 406 ql_write32(qdev, MAC_ADDR_DATA, cam_output);
377 ql_write32(qdev, MAC_ADDR_DATA, cam_output);
378 }
379 break; 407 break;
380 } 408 }
381 case MAC_ADDR_TYPE_VLAN: 409 case MAC_ADDR_TYPE_VLAN:
@@ -547,14 +575,14 @@ static int ql_set_routing_reg(struct ql_adapter *qdev, u32 index, u32 mask,
547 } 575 }
548 case RT_IDX_MCAST: /* Pass up All Multicast frames. */ 576 case RT_IDX_MCAST: /* Pass up All Multicast frames. */
549 { 577 {
550 value = RT_IDX_DST_CAM_Q | /* dest */ 578 value = RT_IDX_DST_DFLT_Q | /* dest */
551 RT_IDX_TYPE_NICQ | /* type */ 579 RT_IDX_TYPE_NICQ | /* type */
552 (RT_IDX_ALLMULTI_SLOT << RT_IDX_IDX_SHIFT);/* index */ 580 (RT_IDX_ALLMULTI_SLOT << RT_IDX_IDX_SHIFT);/* index */
553 break; 581 break;
554 } 582 }
555 case RT_IDX_MCAST_MATCH: /* Pass up matched Multicast frames. */ 583 case RT_IDX_MCAST_MATCH: /* Pass up matched Multicast frames. */
556 { 584 {
557 value = RT_IDX_DST_CAM_Q | /* dest */ 585 value = RT_IDX_DST_DFLT_Q | /* dest */
558 RT_IDX_TYPE_NICQ | /* type */ 586 RT_IDX_TYPE_NICQ | /* type */
559 (RT_IDX_MCAST_MATCH_SLOT << RT_IDX_IDX_SHIFT);/* index */ 587 (RT_IDX_MCAST_MATCH_SLOT << RT_IDX_IDX_SHIFT);/* index */
560 break; 588 break;
@@ -1926,12 +1954,10 @@ static void ql_vlan_rx_add_vid(struct net_device *ndev, u16 vid)
1926 status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK); 1954 status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK);
1927 if (status) 1955 if (status)
1928 return; 1956 return;
1929 spin_lock(&qdev->hw_lock);
1930 if (ql_set_mac_addr_reg 1957 if (ql_set_mac_addr_reg
1931 (qdev, (u8 *) &enable_bit, MAC_ADDR_TYPE_VLAN, vid)) { 1958 (qdev, (u8 *) &enable_bit, MAC_ADDR_TYPE_VLAN, vid)) {
1932 QPRINTK(qdev, IFUP, ERR, "Failed to init vlan address.\n"); 1959 QPRINTK(qdev, IFUP, ERR, "Failed to init vlan address.\n");
1933 } 1960 }
1934 spin_unlock(&qdev->hw_lock);
1935 ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK); 1961 ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
1936} 1962}
1937 1963
@@ -1945,12 +1971,10 @@ static void ql_vlan_rx_kill_vid(struct net_device *ndev, u16 vid)
1945 if (status) 1971 if (status)
1946 return; 1972 return;
1947 1973
1948 spin_lock(&qdev->hw_lock);
1949 if (ql_set_mac_addr_reg 1974 if (ql_set_mac_addr_reg
1950 (qdev, (u8 *) &enable_bit, MAC_ADDR_TYPE_VLAN, vid)) { 1975 (qdev, (u8 *) &enable_bit, MAC_ADDR_TYPE_VLAN, vid)) {
1951 QPRINTK(qdev, IFUP, ERR, "Failed to clear vlan address.\n"); 1976 QPRINTK(qdev, IFUP, ERR, "Failed to clear vlan address.\n");
1952 } 1977 }
1953 spin_unlock(&qdev->hw_lock);
1954 ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK); 1978 ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
1955 1979
1956} 1980}
@@ -2001,15 +2025,17 @@ static irqreturn_t qlge_isr(int irq, void *dev_id)
2001 /* 2025 /*
2002 * Check MPI processor activity. 2026 * Check MPI processor activity.
2003 */ 2027 */
2004 if (var & STS_PI) { 2028 if ((var & STS_PI) &&
2029 (ql_read32(qdev, INTR_MASK) & INTR_MASK_PI)) {
2005 /* 2030 /*
2006 * We've got an async event or mailbox completion. 2031 * We've got an async event or mailbox completion.
2007 * Handle it and clear the source of the interrupt. 2032 * Handle it and clear the source of the interrupt.
2008 */ 2033 */
2009 QPRINTK(qdev, INTR, ERR, "Got MPI processor interrupt.\n"); 2034 QPRINTK(qdev, INTR, ERR, "Got MPI processor interrupt.\n");
2010 ql_disable_completion_interrupt(qdev, intr_context->intr); 2035 ql_disable_completion_interrupt(qdev, intr_context->intr);
2011 queue_delayed_work_on(smp_processor_id(), qdev->workqueue, 2036 ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16));
2012 &qdev->mpi_work, 0); 2037 queue_delayed_work_on(smp_processor_id(),
2038 qdev->workqueue, &qdev->mpi_work, 0);
2013 work_done++; 2039 work_done++;
2014 } 2040 }
2015 2041
@@ -3080,6 +3106,12 @@ err_irq:
3080 3106
3081static int ql_start_rss(struct ql_adapter *qdev) 3107static int ql_start_rss(struct ql_adapter *qdev)
3082{ 3108{
3109 u8 init_hash_seed[] = {0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2,
3110 0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f,
3111 0xb0, 0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b,
3112 0x30, 0xb4, 0x77, 0xcb, 0x2d, 0xa3, 0x80,
3113 0x30, 0xf2, 0x0c, 0x6a, 0x42, 0xb7, 0x3b,
3114 0xbe, 0xac, 0x01, 0xfa};
3083 struct ricb *ricb = &qdev->ricb; 3115 struct ricb *ricb = &qdev->ricb;
3084 int status = 0; 3116 int status = 0;
3085 int i; 3117 int i;
@@ -3089,21 +3121,17 @@ static int ql_start_rss(struct ql_adapter *qdev)
3089 3121
3090 ricb->base_cq = RSS_L4K; 3122 ricb->base_cq = RSS_L4K;
3091 ricb->flags = 3123 ricb->flags =
3092 (RSS_L6K | RSS_LI | RSS_LB | RSS_LM | RSS_RI4 | RSS_RI6 | RSS_RT4 | 3124 (RSS_L6K | RSS_LI | RSS_LB | RSS_LM | RSS_RT4 | RSS_RT6);
3093 RSS_RT6); 3125 ricb->mask = cpu_to_le16((u16)(0x3ff));
3094 ricb->mask = cpu_to_le16(qdev->rss_ring_count - 1);
3095 3126
3096 /* 3127 /*
3097 * Fill out the Indirection Table. 3128 * Fill out the Indirection Table.
3098 */ 3129 */
3099 for (i = 0; i < 256; i++) 3130 for (i = 0; i < 1024; i++)
3100 hash_id[i] = i & (qdev->rss_ring_count - 1); 3131 hash_id[i] = (i & (qdev->rss_ring_count - 1));
3101 3132
3102 /* 3133 memcpy((void *)&ricb->ipv6_hash_key[0], init_hash_seed, 40);
3103 * Random values for the IPv6 and IPv4 Hash Keys. 3134 memcpy((void *)&ricb->ipv4_hash_key[0], init_hash_seed, 16);
3104 */
3105 get_random_bytes((void *)&ricb->ipv6_hash_key[0], 40);
3106 get_random_bytes((void *)&ricb->ipv4_hash_key[0], 16);
3107 3135
3108 QPRINTK(qdev, IFUP, DEBUG, "Initializing RSS.\n"); 3136 QPRINTK(qdev, IFUP, DEBUG, "Initializing RSS.\n");
3109 3137
@@ -3142,14 +3170,14 @@ static int ql_route_initialize(struct ql_adapter *qdev)
3142{ 3170{
3143 int status = 0; 3171 int status = 0;
3144 3172
3145 status = ql_sem_spinlock(qdev, SEM_RT_IDX_MASK); 3173 /* Clear all the entries in the routing table. */
3174 status = ql_clear_routing_entries(qdev);
3146 if (status) 3175 if (status)
3147 return status; 3176 return status;
3148 3177
3149 /* Clear all the entries in the routing table. */ 3178 status = ql_sem_spinlock(qdev, SEM_RT_IDX_MASK);
3150 status = ql_clear_routing_entries(qdev);
3151 if (status) 3179 if (status)
3152 goto exit; 3180 return status;
3153 3181
3154 status = ql_set_routing_reg(qdev, RT_IDX_ALL_ERR_SLOT, RT_IDX_ERR, 1); 3182 status = ql_set_routing_reg(qdev, RT_IDX_ALL_ERR_SLOT, RT_IDX_ERR, 1);
3155 if (status) { 3183 if (status) {
@@ -3242,6 +3270,13 @@ static int ql_adapter_initialize(struct ql_adapter *qdev)
3242 ql_write32(qdev, SPLT_HDR, SPLT_HDR_EP | 3270 ql_write32(qdev, SPLT_HDR, SPLT_HDR_EP |
3243 min(SMALL_BUFFER_SIZE, MAX_SPLIT_SIZE)); 3271 min(SMALL_BUFFER_SIZE, MAX_SPLIT_SIZE));
3244 3272
3273 /* Set RX packet routing to use port/pci function on which the
3274 * packet arrived on in addition to usual frame routing.
3275 * This is helpful on bonding where both interfaces can have
3276 * the same MAC address.
3277 */
3278 ql_write32(qdev, RST_FO, RST_FO_RR_MASK | RST_FO_RR_RCV_FUNC_CQ);
3279
3245 /* Start up the rx queues. */ 3280 /* Start up the rx queues. */
3246 for (i = 0; i < qdev->rx_ring_count; i++) { 3281 for (i = 0; i < qdev->rx_ring_count; i++) {
3247 status = ql_start_rx_ring(qdev, &qdev->rx_ring[i]); 3282 status = ql_start_rx_ring(qdev, &qdev->rx_ring[i]);
@@ -3314,6 +3349,13 @@ static int ql_adapter_reset(struct ql_adapter *qdev)
3314 3349
3315 end_jiffies = jiffies + 3350 end_jiffies = jiffies +
3316 max((unsigned long)1, usecs_to_jiffies(30)); 3351 max((unsigned long)1, usecs_to_jiffies(30));
3352
3353 /* Stop management traffic. */
3354 ql_mb_set_mgmnt_traffic_ctl(qdev, MB_SET_MPI_TFK_STOP);
3355
3356 /* Wait for the NIC and MGMNT FIFOs to empty. */
3357 ql_wait_fifo_empty(qdev);
3358
3317 ql_write32(qdev, RST_FO, (RST_FO_FR << 16) | RST_FO_FR); 3359 ql_write32(qdev, RST_FO, (RST_FO_FR << 16) | RST_FO_FR);
3318 3360
3319 do { 3361 do {
@@ -3329,6 +3371,8 @@ static int ql_adapter_reset(struct ql_adapter *qdev)
3329 status = -ETIMEDOUT; 3371 status = -ETIMEDOUT;
3330 } 3372 }
3331 3373
3374 /* Resume management traffic. */
3375 ql_mb_set_mgmnt_traffic_ctl(qdev, MB_SET_MPI_TFK_RESUME);
3332 return status; 3376 return status;
3333} 3377}
3334 3378
@@ -3380,12 +3424,10 @@ static int ql_adapter_down(struct ql_adapter *qdev)
3380 3424
3381 ql_free_rx_buffers(qdev); 3425 ql_free_rx_buffers(qdev);
3382 3426
3383 spin_lock(&qdev->hw_lock);
3384 status = ql_adapter_reset(qdev); 3427 status = ql_adapter_reset(qdev);
3385 if (status) 3428 if (status)
3386 QPRINTK(qdev, IFDOWN, ERR, "reset(func #%d) FAILED!\n", 3429 QPRINTK(qdev, IFDOWN, ERR, "reset(func #%d) FAILED!\n",
3387 qdev->func); 3430 qdev->func);
3388 spin_unlock(&qdev->hw_lock);
3389 return status; 3431 return status;
3390} 3432}
3391 3433
@@ -3587,7 +3629,6 @@ static void qlge_set_multicast_list(struct net_device *ndev)
3587 status = ql_sem_spinlock(qdev, SEM_RT_IDX_MASK); 3629 status = ql_sem_spinlock(qdev, SEM_RT_IDX_MASK);
3588 if (status) 3630 if (status)
3589 return; 3631 return;
3590 spin_lock(&qdev->hw_lock);
3591 /* 3632 /*
3592 * Set or clear promiscuous mode if a 3633 * Set or clear promiscuous mode if a
3593 * transition is taking place. 3634 * transition is taking place.
@@ -3664,7 +3705,6 @@ static void qlge_set_multicast_list(struct net_device *ndev)
3664 } 3705 }
3665 } 3706 }
3666exit: 3707exit:
3667 spin_unlock(&qdev->hw_lock);
3668 ql_sem_unlock(qdev, SEM_RT_IDX_MASK); 3708 ql_sem_unlock(qdev, SEM_RT_IDX_MASK);
3669} 3709}
3670 3710
@@ -3684,10 +3724,8 @@ static int qlge_set_mac_address(struct net_device *ndev, void *p)
3684 status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK); 3724 status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK);
3685 if (status) 3725 if (status)
3686 return status; 3726 return status;
3687 spin_lock(&qdev->hw_lock);
3688 status = ql_set_mac_addr_reg(qdev, (u8 *) ndev->dev_addr, 3727 status = ql_set_mac_addr_reg(qdev, (u8 *) ndev->dev_addr,
3689 MAC_ADDR_TYPE_CAM_MAC, qdev->func * MAX_CQ); 3728 MAC_ADDR_TYPE_CAM_MAC, qdev->func * MAX_CQ);
3690 spin_unlock(&qdev->hw_lock);
3691 if (status) 3729 if (status)
3692 QPRINTK(qdev, HW, ERR, "Failed to load MAC address.\n"); 3730 QPRINTK(qdev, HW, ERR, "Failed to load MAC address.\n");
3693 ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK); 3731 ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
@@ -3705,7 +3743,7 @@ static void ql_asic_reset_work(struct work_struct *work)
3705 struct ql_adapter *qdev = 3743 struct ql_adapter *qdev =
3706 container_of(work, struct ql_adapter, asic_reset_work.work); 3744 container_of(work, struct ql_adapter, asic_reset_work.work);
3707 int status; 3745 int status;
3708 3746 rtnl_lock();
3709 status = ql_adapter_down(qdev); 3747 status = ql_adapter_down(qdev);
3710 if (status) 3748 if (status)
3711 goto error; 3749 goto error;
@@ -3714,11 +3752,17 @@ static void ql_asic_reset_work(struct work_struct *work)
3714 if (status) 3752 if (status)
3715 goto error; 3753 goto error;
3716 3754
3755 /* Restore rx mode. */
3756 clear_bit(QL_ALLMULTI, &qdev->flags);
3757 clear_bit(QL_PROMISCUOUS, &qdev->flags);
3758 qlge_set_multicast_list(qdev->ndev);
3759
3760 rtnl_unlock();
3717 return; 3761 return;
3718error: 3762error:
3719 QPRINTK(qdev, IFUP, ALERT, 3763 QPRINTK(qdev, IFUP, ALERT,
3720 "Driver up/down cycle failed, closing device\n"); 3764 "Driver up/down cycle failed, closing device\n");
3721 rtnl_lock(); 3765
3722 set_bit(QL_ADAPTER_UP, &qdev->flags); 3766 set_bit(QL_ADAPTER_UP, &qdev->flags);
3723 dev_close(qdev->ndev); 3767 dev_close(qdev->ndev);
3724 rtnl_unlock(); 3768 rtnl_unlock();
@@ -3834,11 +3878,14 @@ static int __devinit ql_init_device(struct pci_dev *pdev,
3834 return err; 3878 return err;
3835 } 3879 }
3836 3880
3881 qdev->ndev = ndev;
3882 qdev->pdev = pdev;
3883 pci_set_drvdata(pdev, ndev);
3837 pos = pci_find_capability(pdev, PCI_CAP_ID_EXP); 3884 pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
3838 if (pos <= 0) { 3885 if (pos <= 0) {
3839 dev_err(&pdev->dev, PFX "Cannot find PCI Express capability, " 3886 dev_err(&pdev->dev, PFX "Cannot find PCI Express capability, "
3840 "aborting.\n"); 3887 "aborting.\n");
3841 goto err_out; 3888 return pos;
3842 } else { 3889 } else {
3843 pci_read_config_word(pdev, pos + PCI_EXP_DEVCTL, &val16); 3890 pci_read_config_word(pdev, pos + PCI_EXP_DEVCTL, &val16);
3844 val16 &= ~PCI_EXP_DEVCTL_NOSNOOP_EN; 3891 val16 &= ~PCI_EXP_DEVCTL_NOSNOOP_EN;
@@ -3851,7 +3898,7 @@ static int __devinit ql_init_device(struct pci_dev *pdev,
3851 err = pci_request_regions(pdev, DRV_NAME); 3898 err = pci_request_regions(pdev, DRV_NAME);
3852 if (err) { 3899 if (err) {
3853 dev_err(&pdev->dev, "PCI region request failed.\n"); 3900 dev_err(&pdev->dev, "PCI region request failed.\n");
3854 goto err_out; 3901 return err;
3855 } 3902 }
3856 3903
3857 pci_set_master(pdev); 3904 pci_set_master(pdev);
@@ -3869,7 +3916,6 @@ static int __devinit ql_init_device(struct pci_dev *pdev,
3869 goto err_out; 3916 goto err_out;
3870 } 3917 }
3871 3918
3872 pci_set_drvdata(pdev, ndev);
3873 qdev->reg_base = 3919 qdev->reg_base =
3874 ioremap_nocache(pci_resource_start(pdev, 1), 3920 ioremap_nocache(pci_resource_start(pdev, 1),
3875 pci_resource_len(pdev, 1)); 3921 pci_resource_len(pdev, 1));
@@ -3889,8 +3935,6 @@ static int __devinit ql_init_device(struct pci_dev *pdev,
3889 goto err_out; 3935 goto err_out;
3890 } 3936 }
3891 3937
3892 qdev->ndev = ndev;
3893 qdev->pdev = pdev;
3894 err = ql_get_board_info(qdev); 3938 err = ql_get_board_info(qdev);
3895 if (err) { 3939 if (err) {
3896 dev_err(&pdev->dev, "Register access failed.\n"); 3940 dev_err(&pdev->dev, "Register access failed.\n");
@@ -3930,7 +3974,6 @@ static int __devinit ql_init_device(struct pci_dev *pdev,
3930 INIT_DELAYED_WORK(&qdev->mpi_work, ql_mpi_work); 3974 INIT_DELAYED_WORK(&qdev->mpi_work, ql_mpi_work);
3931 INIT_DELAYED_WORK(&qdev->mpi_port_cfg_work, ql_mpi_port_cfg_work); 3975 INIT_DELAYED_WORK(&qdev->mpi_port_cfg_work, ql_mpi_port_cfg_work);
3932 INIT_DELAYED_WORK(&qdev->mpi_idc_work, ql_mpi_idc_work); 3976 INIT_DELAYED_WORK(&qdev->mpi_idc_work, ql_mpi_idc_work);
3933 mutex_init(&qdev->mpi_mutex);
3934 init_completion(&qdev->ide_completion); 3977 init_completion(&qdev->ide_completion);
3935 3978
3936 if (!cards_found) { 3979 if (!cards_found) {
diff --git a/drivers/net/qlge/qlge_mpi.c b/drivers/net/qlge/qlge_mpi.c
index 6685bd97da91..99e58e3f8e22 100644
--- a/drivers/net/qlge/qlge_mpi.c
+++ b/drivers/net/qlge/qlge_mpi.c
@@ -472,7 +472,6 @@ static int ql_mailbox_command(struct ql_adapter *qdev, struct mbox_params *mbcp)
472{ 472{
473 int status, count; 473 int status, count;
474 474
475 mutex_lock(&qdev->mpi_mutex);
476 475
477 /* Begin polled mode for MPI */ 476 /* Begin polled mode for MPI */
478 ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16)); 477 ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16));
@@ -541,7 +540,6 @@ static int ql_mailbox_command(struct ql_adapter *qdev, struct mbox_params *mbcp)
541 status = -EIO; 540 status = -EIO;
542 } 541 }
543end: 542end:
544 mutex_unlock(&qdev->mpi_mutex);
545 /* End polled mode for MPI */ 543 /* End polled mode for MPI */
546 ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16) | INTR_MASK_PI); 544 ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16) | INTR_MASK_PI);
547 return status; 545 return status;
@@ -770,13 +768,104 @@ static int ql_idc_wait(struct ql_adapter *qdev)
770 return status; 768 return status;
771} 769}
772 770
771int ql_mb_set_mgmnt_traffic_ctl(struct ql_adapter *qdev, u32 control)
772{
773 struct mbox_params mbc;
774 struct mbox_params *mbcp = &mbc;
775 int status;
776
777 memset(mbcp, 0, sizeof(struct mbox_params));
778
779 mbcp->in_count = 1;
780 mbcp->out_count = 2;
781
782 mbcp->mbox_in[0] = MB_CMD_SET_MGMNT_TFK_CTL;
783 mbcp->mbox_in[1] = control;
784
785 status = ql_mailbox_command(qdev, mbcp);
786 if (status)
787 return status;
788
789 if (mbcp->mbox_out[0] == MB_CMD_STS_GOOD)
790 return status;
791
792 if (mbcp->mbox_out[0] == MB_CMD_STS_INVLD_CMD) {
793 QPRINTK(qdev, DRV, ERR,
794 "Command not supported by firmware.\n");
795 status = -EINVAL;
796 } else if (mbcp->mbox_out[0] == MB_CMD_STS_ERR) {
797 /* This indicates that the firmware is
798 * already in the state we are trying to
799 * change it to.
800 */
801 QPRINTK(qdev, DRV, ERR,
802 "Command parameters make no change.\n");
803 }
804 return status;
805}
806
807/* Returns a negative error code or the mailbox command status. */
808static int ql_mb_get_mgmnt_traffic_ctl(struct ql_adapter *qdev, u32 *control)
809{
810 struct mbox_params mbc;
811 struct mbox_params *mbcp = &mbc;
812 int status;
813
814 memset(mbcp, 0, sizeof(struct mbox_params));
815 *control = 0;
816
817 mbcp->in_count = 1;
818 mbcp->out_count = 1;
819
820 mbcp->mbox_in[0] = MB_CMD_GET_MGMNT_TFK_CTL;
821
822 status = ql_mailbox_command(qdev, mbcp);
823 if (status)
824 return status;
825
826 if (mbcp->mbox_out[0] == MB_CMD_STS_GOOD) {
827 *control = mbcp->mbox_in[1];
828 return status;
829 }
830
831 if (mbcp->mbox_out[0] == MB_CMD_STS_INVLD_CMD) {
832 QPRINTK(qdev, DRV, ERR,
833 "Command not supported by firmware.\n");
834 status = -EINVAL;
835 } else if (mbcp->mbox_out[0] == MB_CMD_STS_ERR) {
836 QPRINTK(qdev, DRV, ERR,
837 "Failed to get MPI traffic control.\n");
838 status = -EIO;
839 }
840 return status;
841}
842
843int ql_wait_fifo_empty(struct ql_adapter *qdev)
844{
845 int count = 5;
846 u32 mgmnt_fifo_empty;
847 u32 nic_fifo_empty;
848
849 do {
850 nic_fifo_empty = ql_read32(qdev, STS) & STS_NFE;
851 ql_mb_get_mgmnt_traffic_ctl(qdev, &mgmnt_fifo_empty);
852 mgmnt_fifo_empty &= MB_GET_MPI_TFK_FIFO_EMPTY;
853 if (nic_fifo_empty && mgmnt_fifo_empty)
854 return 0;
855 msleep(100);
856 } while (count-- > 0);
857 return -ETIMEDOUT;
858}
859
773/* API called in work thread context to set new TX/RX 860/* API called in work thread context to set new TX/RX
774 * maximum frame size values to match MTU. 861 * maximum frame size values to match MTU.
775 */ 862 */
776static int ql_set_port_cfg(struct ql_adapter *qdev) 863static int ql_set_port_cfg(struct ql_adapter *qdev)
777{ 864{
778 int status; 865 int status;
866 rtnl_lock();
779 status = ql_mb_set_port_cfg(qdev); 867 status = ql_mb_set_port_cfg(qdev);
868 rtnl_unlock();
780 if (status) 869 if (status)
781 return status; 870 return status;
782 status = ql_idc_wait(qdev); 871 status = ql_idc_wait(qdev);
@@ -797,7 +886,9 @@ void ql_mpi_port_cfg_work(struct work_struct *work)
797 container_of(work, struct ql_adapter, mpi_port_cfg_work.work); 886 container_of(work, struct ql_adapter, mpi_port_cfg_work.work);
798 int status; 887 int status;
799 888
889 rtnl_lock();
800 status = ql_mb_get_port_cfg(qdev); 890 status = ql_mb_get_port_cfg(qdev);
891 rtnl_unlock();
801 if (status) { 892 if (status) {
802 QPRINTK(qdev, DRV, ERR, 893 QPRINTK(qdev, DRV, ERR,
803 "Bug: Failed to get port config data.\n"); 894 "Bug: Failed to get port config data.\n");
@@ -855,7 +946,9 @@ void ql_mpi_idc_work(struct work_struct *work)
855 * needs to be set. 946 * needs to be set.
856 * */ 947 * */
857 set_bit(QL_CAM_RT_SET, &qdev->flags); 948 set_bit(QL_CAM_RT_SET, &qdev->flags);
949 rtnl_lock();
858 status = ql_mb_idc_ack(qdev); 950 status = ql_mb_idc_ack(qdev);
951 rtnl_unlock();
859 if (status) { 952 if (status) {
860 QPRINTK(qdev, DRV, ERR, 953 QPRINTK(qdev, DRV, ERR,
861 "Bug: No pending IDC!\n"); 954 "Bug: No pending IDC!\n");
@@ -871,7 +964,9 @@ void ql_mpi_work(struct work_struct *work)
871 struct mbox_params *mbcp = &mbc; 964 struct mbox_params *mbcp = &mbc;
872 int err = 0; 965 int err = 0;
873 966
874 mutex_lock(&qdev->mpi_mutex); 967 rtnl_lock();
968 /* Begin polled mode for MPI */
969 ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16));
875 970
876 while (ql_read32(qdev, STS) & STS_PI) { 971 while (ql_read32(qdev, STS) & STS_PI) {
877 memset(mbcp, 0, sizeof(struct mbox_params)); 972 memset(mbcp, 0, sizeof(struct mbox_params));
@@ -884,7 +979,9 @@ void ql_mpi_work(struct work_struct *work)
884 break; 979 break;
885 } 980 }
886 981
887 mutex_unlock(&qdev->mpi_mutex); 982 /* End polled mode for MPI */
983 ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16) | INTR_MASK_PI);
984 rtnl_unlock();
888 ql_enable_completion_interrupt(qdev, 0); 985 ql_enable_completion_interrupt(qdev, 0);
889} 986}
890 987
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 50c6a3cfe439..83c47d95c3aa 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -115,7 +115,9 @@ enum mac_version {
115 RTL_GIGA_MAC_VER_22 = 0x16, // 8168C 115 RTL_GIGA_MAC_VER_22 = 0x16, // 8168C
116 RTL_GIGA_MAC_VER_23 = 0x17, // 8168CP 116 RTL_GIGA_MAC_VER_23 = 0x17, // 8168CP
117 RTL_GIGA_MAC_VER_24 = 0x18, // 8168CP 117 RTL_GIGA_MAC_VER_24 = 0x18, // 8168CP
118 RTL_GIGA_MAC_VER_25 = 0x19 // 8168D 118 RTL_GIGA_MAC_VER_25 = 0x19, // 8168D
119 RTL_GIGA_MAC_VER_26 = 0x1a, // 8168D
120 RTL_GIGA_MAC_VER_27 = 0x1b // 8168DP
119}; 121};
120 122
121#define _R(NAME,MAC,MASK) \ 123#define _R(NAME,MAC,MASK) \
@@ -150,7 +152,9 @@ static const struct {
150 _R("RTL8168c/8111c", RTL_GIGA_MAC_VER_22, 0xff7e1880), // PCI-E 152 _R("RTL8168c/8111c", RTL_GIGA_MAC_VER_22, 0xff7e1880), // PCI-E
151 _R("RTL8168cp/8111cp", RTL_GIGA_MAC_VER_23, 0xff7e1880), // PCI-E 153 _R("RTL8168cp/8111cp", RTL_GIGA_MAC_VER_23, 0xff7e1880), // PCI-E
152 _R("RTL8168cp/8111cp", RTL_GIGA_MAC_VER_24, 0xff7e1880), // PCI-E 154 _R("RTL8168cp/8111cp", RTL_GIGA_MAC_VER_24, 0xff7e1880), // PCI-E
153 _R("RTL8168d/8111d", RTL_GIGA_MAC_VER_25, 0xff7e1880) // PCI-E 155 _R("RTL8168d/8111d", RTL_GIGA_MAC_VER_25, 0xff7e1880), // PCI-E
156 _R("RTL8168d/8111d", RTL_GIGA_MAC_VER_26, 0xff7e1880), // PCI-E
157 _R("RTL8168dp/8111dp", RTL_GIGA_MAC_VER_27, 0xff7e1880) // PCI-E
154}; 158};
155#undef _R 159#undef _R
156 160
@@ -253,6 +257,13 @@ enum rtl8168_8101_registers {
253 DBG_REG = 0xd1, 257 DBG_REG = 0xd1,
254#define FIX_NAK_1 (1 << 4) 258#define FIX_NAK_1 (1 << 4)
255#define FIX_NAK_2 (1 << 3) 259#define FIX_NAK_2 (1 << 3)
260 EFUSEAR = 0xdc,
261#define EFUSEAR_FLAG 0x80000000
262#define EFUSEAR_WRITE_CMD 0x80000000
263#define EFUSEAR_READ_CMD 0x00000000
264#define EFUSEAR_REG_MASK 0x03ff
265#define EFUSEAR_REG_SHIFT 8
266#define EFUSEAR_DATA_MASK 0xff
256}; 267};
257 268
258enum rtl_register_content { 269enum rtl_register_content {
@@ -568,6 +579,14 @@ static void mdio_patch(void __iomem *ioaddr, int reg_addr, int value)
568 mdio_write(ioaddr, reg_addr, mdio_read(ioaddr, reg_addr) | value); 579 mdio_write(ioaddr, reg_addr, mdio_read(ioaddr, reg_addr) | value);
569} 580}
570 581
582static void mdio_plus_minus(void __iomem *ioaddr, int reg_addr, int p, int m)
583{
584 int val;
585
586 val = mdio_read(ioaddr, reg_addr);
587 mdio_write(ioaddr, reg_addr, (val | p) & ~m);
588}
589
571static void rtl_mdio_write(struct net_device *dev, int phy_id, int location, 590static void rtl_mdio_write(struct net_device *dev, int phy_id, int location,
572 int val) 591 int val)
573{ 592{
@@ -651,6 +670,24 @@ static u32 rtl_csi_read(void __iomem *ioaddr, int addr)
651 return value; 670 return value;
652} 671}
653 672
673static u8 rtl8168d_efuse_read(void __iomem *ioaddr, int reg_addr)
674{
675 u8 value = 0xff;
676 unsigned int i;
677
678 RTL_W32(EFUSEAR, (reg_addr & EFUSEAR_REG_MASK) << EFUSEAR_REG_SHIFT);
679
680 for (i = 0; i < 300; i++) {
681 if (RTL_R32(EFUSEAR) & EFUSEAR_FLAG) {
682 value = RTL_R32(EFUSEAR) & EFUSEAR_DATA_MASK;
683 break;
684 }
685 udelay(100);
686 }
687
688 return value;
689}
690
654static void rtl8169_irq_mask_and_ack(void __iomem *ioaddr) 691static void rtl8169_irq_mask_and_ack(void __iomem *ioaddr)
655{ 692{
656 RTL_W16(IntrMask, 0x0000); 693 RTL_W16(IntrMask, 0x0000);
@@ -1243,7 +1280,10 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp,
1243 int mac_version; 1280 int mac_version;
1244 } mac_info[] = { 1281 } mac_info[] = {
1245 /* 8168D family. */ 1282 /* 8168D family. */
1246 { 0x7c800000, 0x28000000, RTL_GIGA_MAC_VER_25 }, 1283 { 0x7cf00000, 0x28300000, RTL_GIGA_MAC_VER_26 },
1284 { 0x7cf00000, 0x28100000, RTL_GIGA_MAC_VER_25 },
1285 { 0x7c800000, 0x28800000, RTL_GIGA_MAC_VER_27 },
1286 { 0x7c800000, 0x28000000, RTL_GIGA_MAC_VER_26 },
1247 1287
1248 /* 8168C family. */ 1288 /* 8168C family. */
1249 { 0x7cf00000, 0x3ca00000, RTL_GIGA_MAC_VER_24 }, 1289 { 0x7cf00000, 0x3ca00000, RTL_GIGA_MAC_VER_24 },
@@ -1648,74 +1688,903 @@ static void rtl8168c_4_hw_phy_config(void __iomem *ioaddr)
1648 rtl8168c_3_hw_phy_config(ioaddr); 1688 rtl8168c_3_hw_phy_config(ioaddr);
1649} 1689}
1650 1690
1651static void rtl8168d_hw_phy_config(void __iomem *ioaddr) 1691static void rtl8168d_1_hw_phy_config(void __iomem *ioaddr)
1652{ 1692{
1653 struct phy_reg phy_reg_init_0[] = { 1693 static struct phy_reg phy_reg_init_0[] = {
1654 { 0x1f, 0x0001 }, 1694 { 0x1f, 0x0001 },
1655 { 0x09, 0x2770 }, 1695 { 0x06, 0x4064 },
1656 { 0x08, 0x04d0 }, 1696 { 0x07, 0x2863 },
1657 { 0x0b, 0xad15 }, 1697 { 0x08, 0x059c },
1658 { 0x0c, 0x5bf0 }, 1698 { 0x09, 0x26b4 },
1659 { 0x1c, 0xf101 }, 1699 { 0x0a, 0x6a19 },
1700 { 0x0b, 0xdcc8 },
1701 { 0x10, 0xf06d },
1702 { 0x14, 0x7f68 },
1703 { 0x18, 0x7fd9 },
1704 { 0x1c, 0xf0ff },
1705 { 0x1d, 0x3d9c },
1660 { 0x1f, 0x0003 }, 1706 { 0x1f, 0x0003 },
1661 { 0x14, 0x94d7 }, 1707 { 0x12, 0xf49f },
1662 { 0x12, 0xf4d6 }, 1708 { 0x13, 0x070b },
1663 { 0x09, 0xca0f }, 1709 { 0x1a, 0x05ad },
1664 { 0x1f, 0x0002 }, 1710 { 0x14, 0x94c0 }
1665 { 0x0b, 0x0b10 }, 1711 };
1666 { 0x0c, 0xd1f7 }, 1712 static struct phy_reg phy_reg_init_1[] = {
1667 { 0x1f, 0x0002 },
1668 { 0x06, 0x5461 },
1669 { 0x1f, 0x0002 }, 1713 { 0x1f, 0x0002 },
1670 { 0x05, 0x6662 }, 1714 { 0x06, 0x5561 },
1715 { 0x1f, 0x0005 },
1716 { 0x05, 0x8332 },
1717 { 0x06, 0x5561 }
1718 };
1719 static struct phy_reg phy_reg_init_2[] = {
1720 { 0x1f, 0x0005 },
1721 { 0x05, 0xffc2 },
1722 { 0x1f, 0x0005 },
1723 { 0x05, 0x8000 },
1724 { 0x06, 0xf8f9 },
1725 { 0x06, 0xfaef },
1726 { 0x06, 0x59ee },
1727 { 0x06, 0xf8ea },
1728 { 0x06, 0x00ee },
1729 { 0x06, 0xf8eb },
1730 { 0x06, 0x00e0 },
1731 { 0x06, 0xf87c },
1732 { 0x06, 0xe1f8 },
1733 { 0x06, 0x7d59 },
1734 { 0x06, 0x0fef },
1735 { 0x06, 0x0139 },
1736 { 0x06, 0x029e },
1737 { 0x06, 0x06ef },
1738 { 0x06, 0x1039 },
1739 { 0x06, 0x089f },
1740 { 0x06, 0x2aee },
1741 { 0x06, 0xf8ea },
1742 { 0x06, 0x00ee },
1743 { 0x06, 0xf8eb },
1744 { 0x06, 0x01e0 },
1745 { 0x06, 0xf87c },
1746 { 0x06, 0xe1f8 },
1747 { 0x06, 0x7d58 },
1748 { 0x06, 0x409e },
1749 { 0x06, 0x0f39 },
1750 { 0x06, 0x46aa },
1751 { 0x06, 0x0bbf },
1752 { 0x06, 0x8290 },
1753 { 0x06, 0xd682 },
1754 { 0x06, 0x9802 },
1755 { 0x06, 0x014f },
1756 { 0x06, 0xae09 },
1757 { 0x06, 0xbf82 },
1758 { 0x06, 0x98d6 },
1759 { 0x06, 0x82a0 },
1760 { 0x06, 0x0201 },
1761 { 0x06, 0x4fef },
1762 { 0x06, 0x95fe },
1763 { 0x06, 0xfdfc },
1764 { 0x06, 0x05f8 },
1765 { 0x06, 0xf9fa },
1766 { 0x06, 0xeef8 },
1767 { 0x06, 0xea00 },
1768 { 0x06, 0xeef8 },
1769 { 0x06, 0xeb00 },
1770 { 0x06, 0xe2f8 },
1771 { 0x06, 0x7ce3 },
1772 { 0x06, 0xf87d },
1773 { 0x06, 0xa511 },
1774 { 0x06, 0x1112 },
1775 { 0x06, 0xd240 },
1776 { 0x06, 0xd644 },
1777 { 0x06, 0x4402 },
1778 { 0x06, 0x8217 },
1779 { 0x06, 0xd2a0 },
1780 { 0x06, 0xd6aa },
1781 { 0x06, 0xaa02 },
1782 { 0x06, 0x8217 },
1783 { 0x06, 0xae0f },
1784 { 0x06, 0xa544 },
1785 { 0x06, 0x4402 },
1786 { 0x06, 0xae4d },
1787 { 0x06, 0xa5aa },
1788 { 0x06, 0xaa02 },
1789 { 0x06, 0xae47 },
1790 { 0x06, 0xaf82 },
1791 { 0x06, 0x13ee },
1792 { 0x06, 0x834e },
1793 { 0x06, 0x00ee },
1794 { 0x06, 0x834d },
1795 { 0x06, 0x0fee },
1796 { 0x06, 0x834c },
1797 { 0x06, 0x0fee },
1798 { 0x06, 0x834f },
1799 { 0x06, 0x00ee },
1800 { 0x06, 0x8351 },
1801 { 0x06, 0x00ee },
1802 { 0x06, 0x834a },
1803 { 0x06, 0xffee },
1804 { 0x06, 0x834b },
1805 { 0x06, 0xffe0 },
1806 { 0x06, 0x8330 },
1807 { 0x06, 0xe183 },
1808 { 0x06, 0x3158 },
1809 { 0x06, 0xfee4 },
1810 { 0x06, 0xf88a },
1811 { 0x06, 0xe5f8 },
1812 { 0x06, 0x8be0 },
1813 { 0x06, 0x8332 },
1814 { 0x06, 0xe183 },
1815 { 0x06, 0x3359 },
1816 { 0x06, 0x0fe2 },
1817 { 0x06, 0x834d },
1818 { 0x06, 0x0c24 },
1819 { 0x06, 0x5af0 },
1820 { 0x06, 0x1e12 },
1821 { 0x06, 0xe4f8 },
1822 { 0x06, 0x8ce5 },
1823 { 0x06, 0xf88d },
1824 { 0x06, 0xaf82 },
1825 { 0x06, 0x13e0 },
1826 { 0x06, 0x834f },
1827 { 0x06, 0x10e4 },
1828 { 0x06, 0x834f },
1829 { 0x06, 0xe083 },
1830 { 0x06, 0x4e78 },
1831 { 0x06, 0x009f },
1832 { 0x06, 0x0ae0 },
1833 { 0x06, 0x834f },
1834 { 0x06, 0xa010 },
1835 { 0x06, 0xa5ee },
1836 { 0x06, 0x834e },
1837 { 0x06, 0x01e0 },
1838 { 0x06, 0x834e },
1839 { 0x06, 0x7805 },
1840 { 0x06, 0x9e9a },
1841 { 0x06, 0xe083 },
1842 { 0x06, 0x4e78 },
1843 { 0x06, 0x049e },
1844 { 0x06, 0x10e0 },
1845 { 0x06, 0x834e },
1846 { 0x06, 0x7803 },
1847 { 0x06, 0x9e0f },
1848 { 0x06, 0xe083 },
1849 { 0x06, 0x4e78 },
1850 { 0x06, 0x019e },
1851 { 0x06, 0x05ae },
1852 { 0x06, 0x0caf },
1853 { 0x06, 0x81f8 },
1854 { 0x06, 0xaf81 },
1855 { 0x06, 0xa3af },
1856 { 0x06, 0x81dc },
1857 { 0x06, 0xaf82 },
1858 { 0x06, 0x13ee },
1859 { 0x06, 0x8348 },
1860 { 0x06, 0x00ee },
1861 { 0x06, 0x8349 },
1862 { 0x06, 0x00e0 },
1863 { 0x06, 0x8351 },
1864 { 0x06, 0x10e4 },
1865 { 0x06, 0x8351 },
1866 { 0x06, 0x5801 },
1867 { 0x06, 0x9fea },
1868 { 0x06, 0xd000 },
1869 { 0x06, 0xd180 },
1870 { 0x06, 0x1f66 },
1871 { 0x06, 0xe2f8 },
1872 { 0x06, 0xeae3 },
1873 { 0x06, 0xf8eb },
1874 { 0x06, 0x5af8 },
1875 { 0x06, 0x1e20 },
1876 { 0x06, 0xe6f8 },
1877 { 0x06, 0xeae5 },
1878 { 0x06, 0xf8eb },
1879 { 0x06, 0xd302 },
1880 { 0x06, 0xb3fe },
1881 { 0x06, 0xe2f8 },
1882 { 0x06, 0x7cef },
1883 { 0x06, 0x325b },
1884 { 0x06, 0x80e3 },
1885 { 0x06, 0xf87d },
1886 { 0x06, 0x9e03 },
1887 { 0x06, 0x7dff },
1888 { 0x06, 0xff0d },
1889 { 0x06, 0x581c },
1890 { 0x06, 0x551a },
1891 { 0x06, 0x6511 },
1892 { 0x06, 0xa190 },
1893 { 0x06, 0xd3e2 },
1894 { 0x06, 0x8348 },
1895 { 0x06, 0xe383 },
1896 { 0x06, 0x491b },
1897 { 0x06, 0x56ab },
1898 { 0x06, 0x08ef },
1899 { 0x06, 0x56e6 },
1900 { 0x06, 0x8348 },
1901 { 0x06, 0xe783 },
1902 { 0x06, 0x4910 },
1903 { 0x06, 0xd180 },
1904 { 0x06, 0x1f66 },
1905 { 0x06, 0xa004 },
1906 { 0x06, 0xb9e2 },
1907 { 0x06, 0x8348 },
1908 { 0x06, 0xe383 },
1909 { 0x06, 0x49ef },
1910 { 0x06, 0x65e2 },
1911 { 0x06, 0x834a },
1912 { 0x06, 0xe383 },
1913 { 0x06, 0x4b1b },
1914 { 0x06, 0x56aa },
1915 { 0x06, 0x0eef },
1916 { 0x06, 0x56e6 },
1917 { 0x06, 0x834a },
1918 { 0x06, 0xe783 },
1919 { 0x06, 0x4be2 },
1920 { 0x06, 0x834d },
1921 { 0x06, 0xe683 },
1922 { 0x06, 0x4ce0 },
1923 { 0x06, 0x834d },
1924 { 0x06, 0xa000 },
1925 { 0x06, 0x0caf },
1926 { 0x06, 0x81dc },
1927 { 0x06, 0xe083 },
1928 { 0x06, 0x4d10 },
1929 { 0x06, 0xe483 },
1930 { 0x06, 0x4dae },
1931 { 0x06, 0x0480 },
1932 { 0x06, 0xe483 },
1933 { 0x06, 0x4de0 },
1934 { 0x06, 0x834e },
1935 { 0x06, 0x7803 },
1936 { 0x06, 0x9e0b },
1937 { 0x06, 0xe083 },
1938 { 0x06, 0x4e78 },
1939 { 0x06, 0x049e },
1940 { 0x06, 0x04ee },
1941 { 0x06, 0x834e },
1942 { 0x06, 0x02e0 },
1943 { 0x06, 0x8332 },
1944 { 0x06, 0xe183 },
1945 { 0x06, 0x3359 },
1946 { 0x06, 0x0fe2 },
1947 { 0x06, 0x834d },
1948 { 0x06, 0x0c24 },
1949 { 0x06, 0x5af0 },
1950 { 0x06, 0x1e12 },
1951 { 0x06, 0xe4f8 },
1952 { 0x06, 0x8ce5 },
1953 { 0x06, 0xf88d },
1954 { 0x06, 0xe083 },
1955 { 0x06, 0x30e1 },
1956 { 0x06, 0x8331 },
1957 { 0x06, 0x6801 },
1958 { 0x06, 0xe4f8 },
1959 { 0x06, 0x8ae5 },
1960 { 0x06, 0xf88b },
1961 { 0x06, 0xae37 },
1962 { 0x06, 0xee83 },
1963 { 0x06, 0x4e03 },
1964 { 0x06, 0xe083 },
1965 { 0x06, 0x4ce1 },
1966 { 0x06, 0x834d },
1967 { 0x06, 0x1b01 },
1968 { 0x06, 0x9e04 },
1969 { 0x06, 0xaaa1 },
1970 { 0x06, 0xaea8 },
1971 { 0x06, 0xee83 },
1972 { 0x06, 0x4e04 },
1973 { 0x06, 0xee83 },
1974 { 0x06, 0x4f00 },
1975 { 0x06, 0xaeab },
1976 { 0x06, 0xe083 },
1977 { 0x06, 0x4f78 },
1978 { 0x06, 0x039f },
1979 { 0x06, 0x14ee },
1980 { 0x06, 0x834e },
1981 { 0x06, 0x05d2 },
1982 { 0x06, 0x40d6 },
1983 { 0x06, 0x5554 },
1984 { 0x06, 0x0282 },
1985 { 0x06, 0x17d2 },
1986 { 0x06, 0xa0d6 },
1987 { 0x06, 0xba00 },
1988 { 0x06, 0x0282 },
1989 { 0x06, 0x17fe },
1990 { 0x06, 0xfdfc },
1991 { 0x06, 0x05f8 },
1992 { 0x06, 0xe0f8 },
1993 { 0x06, 0x60e1 },
1994 { 0x06, 0xf861 },
1995 { 0x06, 0x6802 },
1996 { 0x06, 0xe4f8 },
1997 { 0x06, 0x60e5 },
1998 { 0x06, 0xf861 },
1999 { 0x06, 0xe0f8 },
2000 { 0x06, 0x48e1 },
2001 { 0x06, 0xf849 },
2002 { 0x06, 0x580f },
2003 { 0x06, 0x1e02 },
2004 { 0x06, 0xe4f8 },
2005 { 0x06, 0x48e5 },
2006 { 0x06, 0xf849 },
2007 { 0x06, 0xd000 },
2008 { 0x06, 0x0282 },
2009 { 0x06, 0x5bbf },
2010 { 0x06, 0x8350 },
2011 { 0x06, 0xef46 },
2012 { 0x06, 0xdc19 },
2013 { 0x06, 0xddd0 },
2014 { 0x06, 0x0102 },
2015 { 0x06, 0x825b },
2016 { 0x06, 0x0282 },
2017 { 0x06, 0x77e0 },
2018 { 0x06, 0xf860 },
2019 { 0x06, 0xe1f8 },
2020 { 0x06, 0x6158 },
2021 { 0x06, 0xfde4 },
2022 { 0x06, 0xf860 },
2023 { 0x06, 0xe5f8 },
2024 { 0x06, 0x61fc },
2025 { 0x06, 0x04f9 },
2026 { 0x06, 0xfafb },
2027 { 0x06, 0xc6bf },
2028 { 0x06, 0xf840 },
2029 { 0x06, 0xbe83 },
2030 { 0x06, 0x50a0 },
2031 { 0x06, 0x0101 },
2032 { 0x06, 0x071b },
2033 { 0x06, 0x89cf },
2034 { 0x06, 0xd208 },
2035 { 0x06, 0xebdb },
2036 { 0x06, 0x19b2 },
2037 { 0x06, 0xfbff },
2038 { 0x06, 0xfefd },
2039 { 0x06, 0x04f8 },
2040 { 0x06, 0xe0f8 },
2041 { 0x06, 0x48e1 },
2042 { 0x06, 0xf849 },
2043 { 0x06, 0x6808 },
2044 { 0x06, 0xe4f8 },
2045 { 0x06, 0x48e5 },
2046 { 0x06, 0xf849 },
2047 { 0x06, 0x58f7 },
2048 { 0x06, 0xe4f8 },
2049 { 0x06, 0x48e5 },
2050 { 0x06, 0xf849 },
2051 { 0x06, 0xfc04 },
2052 { 0x06, 0x4d20 },
2053 { 0x06, 0x0002 },
2054 { 0x06, 0x4e22 },
2055 { 0x06, 0x0002 },
2056 { 0x06, 0x4ddf },
2057 { 0x06, 0xff01 },
2058 { 0x06, 0x4edd },
2059 { 0x06, 0xff01 },
2060 { 0x05, 0x83d4 },
2061 { 0x06, 0x8000 },
2062 { 0x05, 0x83d8 },
2063 { 0x06, 0x8051 },
2064 { 0x02, 0x6010 },
2065 { 0x03, 0xdc00 },
2066 { 0x05, 0xfff6 },
2067 { 0x06, 0x00fc },
1671 { 0x1f, 0x0000 }, 2068 { 0x1f, 0x0000 },
1672 { 0x14, 0x0060 }, 2069
1673 { 0x1f, 0x0000 }, 2070 { 0x1f, 0x0000 },
1674 { 0x0d, 0xf8a0 }, 2071 { 0x0d, 0xf880 },
2072 { 0x1f, 0x0000 }
2073 };
2074
2075 rtl_phy_write(ioaddr, phy_reg_init_0, ARRAY_SIZE(phy_reg_init_0));
2076
2077 mdio_write(ioaddr, 0x1f, 0x0002);
2078 mdio_plus_minus(ioaddr, 0x0b, 0x0010, 0x00ef);
2079 mdio_plus_minus(ioaddr, 0x0c, 0xa200, 0x5d00);
2080
2081 rtl_phy_write(ioaddr, phy_reg_init_1, ARRAY_SIZE(phy_reg_init_1));
2082
2083 if (rtl8168d_efuse_read(ioaddr, 0x01) == 0xb1) {
2084 struct phy_reg phy_reg_init[] = {
2085 { 0x1f, 0x0002 },
2086 { 0x05, 0x669a },
2087 { 0x1f, 0x0005 },
2088 { 0x05, 0x8330 },
2089 { 0x06, 0x669a },
2090 { 0x1f, 0x0002 }
2091 };
2092 int val;
2093
2094 rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
2095
2096 val = mdio_read(ioaddr, 0x0d);
2097
2098 if ((val & 0x00ff) != 0x006c) {
2099 u32 set[] = {
2100 0x0065, 0x0066, 0x0067, 0x0068,
2101 0x0069, 0x006a, 0x006b, 0x006c
2102 };
2103 int i;
2104
2105 mdio_write(ioaddr, 0x1f, 0x0002);
2106
2107 val &= 0xff00;
2108 for (i = 0; i < ARRAY_SIZE(set); i++)
2109 mdio_write(ioaddr, 0x0d, val | set[i]);
2110 }
2111 } else {
2112 struct phy_reg phy_reg_init[] = {
2113 { 0x1f, 0x0002 },
2114 { 0x05, 0x6662 },
2115 { 0x1f, 0x0005 },
2116 { 0x05, 0x8330 },
2117 { 0x06, 0x6662 }
2118 };
2119
2120 rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
2121 }
2122
2123 mdio_write(ioaddr, 0x1f, 0x0002);
2124 mdio_patch(ioaddr, 0x0d, 0x0300);
2125 mdio_patch(ioaddr, 0x0f, 0x0010);
2126
2127 mdio_write(ioaddr, 0x1f, 0x0002);
2128 mdio_plus_minus(ioaddr, 0x02, 0x0100, 0x0600);
2129 mdio_plus_minus(ioaddr, 0x03, 0x0000, 0xe000);
2130
2131 rtl_phy_write(ioaddr, phy_reg_init_2, ARRAY_SIZE(phy_reg_init_2));
2132}
2133
2134static void rtl8168d_2_hw_phy_config(void __iomem *ioaddr)
2135{
2136 static struct phy_reg phy_reg_init_0[] = {
2137 { 0x1f, 0x0001 },
2138 { 0x06, 0x4064 },
2139 { 0x07, 0x2863 },
2140 { 0x08, 0x059c },
2141 { 0x09, 0x26b4 },
2142 { 0x0a, 0x6a19 },
2143 { 0x0b, 0xdcc8 },
2144 { 0x10, 0xf06d },
2145 { 0x14, 0x7f68 },
2146 { 0x18, 0x7fd9 },
2147 { 0x1c, 0xf0ff },
2148 { 0x1d, 0x3d9c },
2149 { 0x1f, 0x0003 },
2150 { 0x12, 0xf49f },
2151 { 0x13, 0x070b },
2152 { 0x1a, 0x05ad },
2153 { 0x14, 0x94c0 },
2154
2155 { 0x1f, 0x0002 },
2156 { 0x06, 0x5561 },
2157 { 0x1f, 0x0005 },
2158 { 0x05, 0x8332 },
2159 { 0x06, 0x5561 }
2160 };
2161 static struct phy_reg phy_reg_init_1[] = {
2162 { 0x1f, 0x0005 },
2163 { 0x05, 0xffc2 },
1675 { 0x1f, 0x0005 }, 2164 { 0x1f, 0x0005 },
1676 { 0x05, 0xffc2 } 2165 { 0x05, 0x8000 },
2166 { 0x06, 0xf8f9 },
2167 { 0x06, 0xfaee },
2168 { 0x06, 0xf8ea },
2169 { 0x06, 0x00ee },
2170 { 0x06, 0xf8eb },
2171 { 0x06, 0x00e2 },
2172 { 0x06, 0xf87c },
2173 { 0x06, 0xe3f8 },
2174 { 0x06, 0x7da5 },
2175 { 0x06, 0x1111 },
2176 { 0x06, 0x12d2 },
2177 { 0x06, 0x40d6 },
2178 { 0x06, 0x4444 },
2179 { 0x06, 0x0281 },
2180 { 0x06, 0xc6d2 },
2181 { 0x06, 0xa0d6 },
2182 { 0x06, 0xaaaa },
2183 { 0x06, 0x0281 },
2184 { 0x06, 0xc6ae },
2185 { 0x06, 0x0fa5 },
2186 { 0x06, 0x4444 },
2187 { 0x06, 0x02ae },
2188 { 0x06, 0x4da5 },
2189 { 0x06, 0xaaaa },
2190 { 0x06, 0x02ae },
2191 { 0x06, 0x47af },
2192 { 0x06, 0x81c2 },
2193 { 0x06, 0xee83 },
2194 { 0x06, 0x4e00 },
2195 { 0x06, 0xee83 },
2196 { 0x06, 0x4d0f },
2197 { 0x06, 0xee83 },
2198 { 0x06, 0x4c0f },
2199 { 0x06, 0xee83 },
2200 { 0x06, 0x4f00 },
2201 { 0x06, 0xee83 },
2202 { 0x06, 0x5100 },
2203 { 0x06, 0xee83 },
2204 { 0x06, 0x4aff },
2205 { 0x06, 0xee83 },
2206 { 0x06, 0x4bff },
2207 { 0x06, 0xe083 },
2208 { 0x06, 0x30e1 },
2209 { 0x06, 0x8331 },
2210 { 0x06, 0x58fe },
2211 { 0x06, 0xe4f8 },
2212 { 0x06, 0x8ae5 },
2213 { 0x06, 0xf88b },
2214 { 0x06, 0xe083 },
2215 { 0x06, 0x32e1 },
2216 { 0x06, 0x8333 },
2217 { 0x06, 0x590f },
2218 { 0x06, 0xe283 },
2219 { 0x06, 0x4d0c },
2220 { 0x06, 0x245a },
2221 { 0x06, 0xf01e },
2222 { 0x06, 0x12e4 },
2223 { 0x06, 0xf88c },
2224 { 0x06, 0xe5f8 },
2225 { 0x06, 0x8daf },
2226 { 0x06, 0x81c2 },
2227 { 0x06, 0xe083 },
2228 { 0x06, 0x4f10 },
2229 { 0x06, 0xe483 },
2230 { 0x06, 0x4fe0 },
2231 { 0x06, 0x834e },
2232 { 0x06, 0x7800 },
2233 { 0x06, 0x9f0a },
2234 { 0x06, 0xe083 },
2235 { 0x06, 0x4fa0 },
2236 { 0x06, 0x10a5 },
2237 { 0x06, 0xee83 },
2238 { 0x06, 0x4e01 },
2239 { 0x06, 0xe083 },
2240 { 0x06, 0x4e78 },
2241 { 0x06, 0x059e },
2242 { 0x06, 0x9ae0 },
2243 { 0x06, 0x834e },
2244 { 0x06, 0x7804 },
2245 { 0x06, 0x9e10 },
2246 { 0x06, 0xe083 },
2247 { 0x06, 0x4e78 },
2248 { 0x06, 0x039e },
2249 { 0x06, 0x0fe0 },
2250 { 0x06, 0x834e },
2251 { 0x06, 0x7801 },
2252 { 0x06, 0x9e05 },
2253 { 0x06, 0xae0c },
2254 { 0x06, 0xaf81 },
2255 { 0x06, 0xa7af },
2256 { 0x06, 0x8152 },
2257 { 0x06, 0xaf81 },
2258 { 0x06, 0x8baf },
2259 { 0x06, 0x81c2 },
2260 { 0x06, 0xee83 },
2261 { 0x06, 0x4800 },
2262 { 0x06, 0xee83 },
2263 { 0x06, 0x4900 },
2264 { 0x06, 0xe083 },
2265 { 0x06, 0x5110 },
2266 { 0x06, 0xe483 },
2267 { 0x06, 0x5158 },
2268 { 0x06, 0x019f },
2269 { 0x06, 0xead0 },
2270 { 0x06, 0x00d1 },
2271 { 0x06, 0x801f },
2272 { 0x06, 0x66e2 },
2273 { 0x06, 0xf8ea },
2274 { 0x06, 0xe3f8 },
2275 { 0x06, 0xeb5a },
2276 { 0x06, 0xf81e },
2277 { 0x06, 0x20e6 },
2278 { 0x06, 0xf8ea },
2279 { 0x06, 0xe5f8 },
2280 { 0x06, 0xebd3 },
2281 { 0x06, 0x02b3 },
2282 { 0x06, 0xfee2 },
2283 { 0x06, 0xf87c },
2284 { 0x06, 0xef32 },
2285 { 0x06, 0x5b80 },
2286 { 0x06, 0xe3f8 },
2287 { 0x06, 0x7d9e },
2288 { 0x06, 0x037d },
2289 { 0x06, 0xffff },
2290 { 0x06, 0x0d58 },
2291 { 0x06, 0x1c55 },
2292 { 0x06, 0x1a65 },
2293 { 0x06, 0x11a1 },
2294 { 0x06, 0x90d3 },
2295 { 0x06, 0xe283 },
2296 { 0x06, 0x48e3 },
2297 { 0x06, 0x8349 },
2298 { 0x06, 0x1b56 },
2299 { 0x06, 0xab08 },
2300 { 0x06, 0xef56 },
2301 { 0x06, 0xe683 },
2302 { 0x06, 0x48e7 },
2303 { 0x06, 0x8349 },
2304 { 0x06, 0x10d1 },
2305 { 0x06, 0x801f },
2306 { 0x06, 0x66a0 },
2307 { 0x06, 0x04b9 },
2308 { 0x06, 0xe283 },
2309 { 0x06, 0x48e3 },
2310 { 0x06, 0x8349 },
2311 { 0x06, 0xef65 },
2312 { 0x06, 0xe283 },
2313 { 0x06, 0x4ae3 },
2314 { 0x06, 0x834b },
2315 { 0x06, 0x1b56 },
2316 { 0x06, 0xaa0e },
2317 { 0x06, 0xef56 },
2318 { 0x06, 0xe683 },
2319 { 0x06, 0x4ae7 },
2320 { 0x06, 0x834b },
2321 { 0x06, 0xe283 },
2322 { 0x06, 0x4de6 },
2323 { 0x06, 0x834c },
2324 { 0x06, 0xe083 },
2325 { 0x06, 0x4da0 },
2326 { 0x06, 0x000c },
2327 { 0x06, 0xaf81 },
2328 { 0x06, 0x8be0 },
2329 { 0x06, 0x834d },
2330 { 0x06, 0x10e4 },
2331 { 0x06, 0x834d },
2332 { 0x06, 0xae04 },
2333 { 0x06, 0x80e4 },
2334 { 0x06, 0x834d },
2335 { 0x06, 0xe083 },
2336 { 0x06, 0x4e78 },
2337 { 0x06, 0x039e },
2338 { 0x06, 0x0be0 },
2339 { 0x06, 0x834e },
2340 { 0x06, 0x7804 },
2341 { 0x06, 0x9e04 },
2342 { 0x06, 0xee83 },
2343 { 0x06, 0x4e02 },
2344 { 0x06, 0xe083 },
2345 { 0x06, 0x32e1 },
2346 { 0x06, 0x8333 },
2347 { 0x06, 0x590f },
2348 { 0x06, 0xe283 },
2349 { 0x06, 0x4d0c },
2350 { 0x06, 0x245a },
2351 { 0x06, 0xf01e },
2352 { 0x06, 0x12e4 },
2353 { 0x06, 0xf88c },
2354 { 0x06, 0xe5f8 },
2355 { 0x06, 0x8de0 },
2356 { 0x06, 0x8330 },
2357 { 0x06, 0xe183 },
2358 { 0x06, 0x3168 },
2359 { 0x06, 0x01e4 },
2360 { 0x06, 0xf88a },
2361 { 0x06, 0xe5f8 },
2362 { 0x06, 0x8bae },
2363 { 0x06, 0x37ee },
2364 { 0x06, 0x834e },
2365 { 0x06, 0x03e0 },
2366 { 0x06, 0x834c },
2367 { 0x06, 0xe183 },
2368 { 0x06, 0x4d1b },
2369 { 0x06, 0x019e },
2370 { 0x06, 0x04aa },
2371 { 0x06, 0xa1ae },
2372 { 0x06, 0xa8ee },
2373 { 0x06, 0x834e },
2374 { 0x06, 0x04ee },
2375 { 0x06, 0x834f },
2376 { 0x06, 0x00ae },
2377 { 0x06, 0xabe0 },
2378 { 0x06, 0x834f },
2379 { 0x06, 0x7803 },
2380 { 0x06, 0x9f14 },
2381 { 0x06, 0xee83 },
2382 { 0x06, 0x4e05 },
2383 { 0x06, 0xd240 },
2384 { 0x06, 0xd655 },
2385 { 0x06, 0x5402 },
2386 { 0x06, 0x81c6 },
2387 { 0x06, 0xd2a0 },
2388 { 0x06, 0xd6ba },
2389 { 0x06, 0x0002 },
2390 { 0x06, 0x81c6 },
2391 { 0x06, 0xfefd },
2392 { 0x06, 0xfc05 },
2393 { 0x06, 0xf8e0 },
2394 { 0x06, 0xf860 },
2395 { 0x06, 0xe1f8 },
2396 { 0x06, 0x6168 },
2397 { 0x06, 0x02e4 },
2398 { 0x06, 0xf860 },
2399 { 0x06, 0xe5f8 },
2400 { 0x06, 0x61e0 },
2401 { 0x06, 0xf848 },
2402 { 0x06, 0xe1f8 },
2403 { 0x06, 0x4958 },
2404 { 0x06, 0x0f1e },
2405 { 0x06, 0x02e4 },
2406 { 0x06, 0xf848 },
2407 { 0x06, 0xe5f8 },
2408 { 0x06, 0x49d0 },
2409 { 0x06, 0x0002 },
2410 { 0x06, 0x820a },
2411 { 0x06, 0xbf83 },
2412 { 0x06, 0x50ef },
2413 { 0x06, 0x46dc },
2414 { 0x06, 0x19dd },
2415 { 0x06, 0xd001 },
2416 { 0x06, 0x0282 },
2417 { 0x06, 0x0a02 },
2418 { 0x06, 0x8226 },
2419 { 0x06, 0xe0f8 },
2420 { 0x06, 0x60e1 },
2421 { 0x06, 0xf861 },
2422 { 0x06, 0x58fd },
2423 { 0x06, 0xe4f8 },
2424 { 0x06, 0x60e5 },
2425 { 0x06, 0xf861 },
2426 { 0x06, 0xfc04 },
2427 { 0x06, 0xf9fa },
2428 { 0x06, 0xfbc6 },
2429 { 0x06, 0xbff8 },
2430 { 0x06, 0x40be },
2431 { 0x06, 0x8350 },
2432 { 0x06, 0xa001 },
2433 { 0x06, 0x0107 },
2434 { 0x06, 0x1b89 },
2435 { 0x06, 0xcfd2 },
2436 { 0x06, 0x08eb },
2437 { 0x06, 0xdb19 },
2438 { 0x06, 0xb2fb },
2439 { 0x06, 0xfffe },
2440 { 0x06, 0xfd04 },
2441 { 0x06, 0xf8e0 },
2442 { 0x06, 0xf848 },
2443 { 0x06, 0xe1f8 },
2444 { 0x06, 0x4968 },
2445 { 0x06, 0x08e4 },
2446 { 0x06, 0xf848 },
2447 { 0x06, 0xe5f8 },
2448 { 0x06, 0x4958 },
2449 { 0x06, 0xf7e4 },
2450 { 0x06, 0xf848 },
2451 { 0x06, 0xe5f8 },
2452 { 0x06, 0x49fc },
2453 { 0x06, 0x044d },
2454 { 0x06, 0x2000 },
2455 { 0x06, 0x024e },
2456 { 0x06, 0x2200 },
2457 { 0x06, 0x024d },
2458 { 0x06, 0xdfff },
2459 { 0x06, 0x014e },
2460 { 0x06, 0xddff },
2461 { 0x06, 0x0100 },
2462 { 0x05, 0x83d8 },
2463 { 0x06, 0x8000 },
2464 { 0x03, 0xdc00 },
2465 { 0x05, 0xfff6 },
2466 { 0x06, 0x00fc },
2467 { 0x1f, 0x0000 },
2468
2469 { 0x1f, 0x0000 },
2470 { 0x0d, 0xf880 },
2471 { 0x1f, 0x0000 }
1677 }; 2472 };
1678 2473
1679 rtl_phy_write(ioaddr, phy_reg_init_0, ARRAY_SIZE(phy_reg_init_0)); 2474 rtl_phy_write(ioaddr, phy_reg_init_0, ARRAY_SIZE(phy_reg_init_0));
1680 2475
1681 if (mdio_read(ioaddr, 0x06) == 0xc400) { 2476 if (rtl8168d_efuse_read(ioaddr, 0x01) == 0xb1) {
1682 struct phy_reg phy_reg_init_1[] = { 2477 struct phy_reg phy_reg_init[] = {
2478 { 0x1f, 0x0002 },
2479 { 0x05, 0x669a },
1683 { 0x1f, 0x0005 }, 2480 { 0x1f, 0x0005 },
1684 { 0x01, 0x0300 }, 2481 { 0x05, 0x8330 },
1685 { 0x1f, 0x0000 }, 2482 { 0x06, 0x669a },
1686 { 0x11, 0x401c }, 2483
1687 { 0x16, 0x4100 }, 2484 { 0x1f, 0x0002 }
2485 };
2486 int val;
2487
2488 rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
2489
2490 val = mdio_read(ioaddr, 0x0d);
2491 if ((val & 0x00ff) != 0x006c) {
2492 u32 set[] = {
2493 0x0065, 0x0066, 0x0067, 0x0068,
2494 0x0069, 0x006a, 0x006b, 0x006c
2495 };
2496 int i;
2497
2498 mdio_write(ioaddr, 0x1f, 0x0002);
2499
2500 val &= 0xff00;
2501 for (i = 0; i < ARRAY_SIZE(set); i++)
2502 mdio_write(ioaddr, 0x0d, val | set[i]);
2503 }
2504 } else {
2505 struct phy_reg phy_reg_init[] = {
2506 { 0x1f, 0x0002 },
2507 { 0x05, 0x2642 },
1688 { 0x1f, 0x0005 }, 2508 { 0x1f, 0x0005 },
1689 { 0x07, 0x0010 }, 2509 { 0x05, 0x8330 },
1690 { 0x05, 0x83dc }, 2510 { 0x06, 0x2642 }
1691 { 0x06, 0x087d },
1692 { 0x05, 0x8300 },
1693 { 0x06, 0x0101 },
1694 { 0x06, 0x05f8 },
1695 { 0x06, 0xf9fa },
1696 { 0x06, 0xfbef },
1697 { 0x06, 0x79e2 },
1698 { 0x06, 0x835f },
1699 { 0x06, 0xe0f8 },
1700 { 0x06, 0x9ae1 },
1701 { 0x06, 0xf89b },
1702 { 0x06, 0xef31 },
1703 { 0x06, 0x3b65 },
1704 { 0x06, 0xaa07 },
1705 { 0x06, 0x81e4 },
1706 { 0x06, 0xf89a },
1707 { 0x06, 0xe5f8 },
1708 { 0x06, 0x9baf },
1709 { 0x06, 0x06ae },
1710 { 0x05, 0x83dc },
1711 { 0x06, 0x8300 },
1712 }; 2511 };
1713 2512
1714 rtl_phy_write(ioaddr, phy_reg_init_1, 2513 rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
1715 ARRAY_SIZE(phy_reg_init_1));
1716 } 2514 }
1717 2515
1718 mdio_write(ioaddr, 0x1f, 0x0000); 2516 mdio_write(ioaddr, 0x1f, 0x0002);
2517 mdio_plus_minus(ioaddr, 0x02, 0x0100, 0x0600);
2518 mdio_plus_minus(ioaddr, 0x03, 0x0000, 0xe000);
2519
2520 mdio_write(ioaddr, 0x1f, 0x0001);
2521 mdio_write(ioaddr, 0x17, 0x0cc0);
2522
2523 mdio_write(ioaddr, 0x1f, 0x0002);
2524 mdio_patch(ioaddr, 0x0f, 0x0017);
2525
2526 rtl_phy_write(ioaddr, phy_reg_init_1, ARRAY_SIZE(phy_reg_init_1));
2527}
2528
2529static void rtl8168d_3_hw_phy_config(void __iomem *ioaddr)
2530{
2531 struct phy_reg phy_reg_init[] = {
2532 { 0x1f, 0x0002 },
2533 { 0x10, 0x0008 },
2534 { 0x0d, 0x006c },
2535
2536 { 0x1f, 0x0000 },
2537 { 0x0d, 0xf880 },
2538
2539 { 0x1f, 0x0001 },
2540 { 0x17, 0x0cc0 },
2541
2542 { 0x1f, 0x0001 },
2543 { 0x0b, 0xa4d8 },
2544 { 0x09, 0x281c },
2545 { 0x07, 0x2883 },
2546 { 0x0a, 0x6b35 },
2547 { 0x1d, 0x3da4 },
2548 { 0x1c, 0xeffd },
2549 { 0x14, 0x7f52 },
2550 { 0x18, 0x7fc6 },
2551 { 0x08, 0x0601 },
2552 { 0x06, 0x4063 },
2553 { 0x10, 0xf074 },
2554 { 0x1f, 0x0003 },
2555 { 0x13, 0x0789 },
2556 { 0x12, 0xf4bd },
2557 { 0x1a, 0x04fd },
2558 { 0x14, 0x84b0 },
2559 { 0x1f, 0x0000 },
2560 { 0x00, 0x9200 },
2561
2562 { 0x1f, 0x0005 },
2563 { 0x01, 0x0340 },
2564 { 0x1f, 0x0001 },
2565 { 0x04, 0x4000 },
2566 { 0x03, 0x1d21 },
2567 { 0x02, 0x0c32 },
2568 { 0x01, 0x0200 },
2569 { 0x00, 0x5554 },
2570 { 0x04, 0x4800 },
2571 { 0x04, 0x4000 },
2572 { 0x04, 0xf000 },
2573 { 0x03, 0xdf01 },
2574 { 0x02, 0xdf20 },
2575 { 0x01, 0x101a },
2576 { 0x00, 0xa0ff },
2577 { 0x04, 0xf800 },
2578 { 0x04, 0xf000 },
2579 { 0x1f, 0x0000 },
2580
2581 { 0x1f, 0x0007 },
2582 { 0x1e, 0x0023 },
2583 { 0x16, 0x0000 },
2584 { 0x1f, 0x0000 }
2585 };
2586
2587 rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
1719} 2588}
1720 2589
1721static void rtl8102e_hw_phy_config(void __iomem *ioaddr) 2590static void rtl8102e_hw_phy_config(void __iomem *ioaddr)
@@ -1792,7 +2661,13 @@ static void rtl_hw_phy_config(struct net_device *dev)
1792 rtl8168cp_2_hw_phy_config(ioaddr); 2661 rtl8168cp_2_hw_phy_config(ioaddr);
1793 break; 2662 break;
1794 case RTL_GIGA_MAC_VER_25: 2663 case RTL_GIGA_MAC_VER_25:
1795 rtl8168d_hw_phy_config(ioaddr); 2664 rtl8168d_1_hw_phy_config(ioaddr);
2665 break;
2666 case RTL_GIGA_MAC_VER_26:
2667 rtl8168d_2_hw_phy_config(ioaddr);
2668 break;
2669 case RTL_GIGA_MAC_VER_27:
2670 rtl8168d_3_hw_phy_config(ioaddr);
1796 break; 2671 break;
1797 2672
1798 default: 2673 default:
@@ -2863,6 +3738,8 @@ static void rtl_hw_start_8168(struct net_device *dev)
2863 break; 3738 break;
2864 3739
2865 case RTL_GIGA_MAC_VER_25: 3740 case RTL_GIGA_MAC_VER_25:
3741 case RTL_GIGA_MAC_VER_26:
3742 case RTL_GIGA_MAC_VER_27:
2866 rtl_hw_start_8168d(ioaddr, pdev); 3743 rtl_hw_start_8168d(ioaddr, pdev);
2867 break; 3744 break;
2868 3745
diff --git a/drivers/net/sb1000.c b/drivers/net/sb1000.c
index ee366c5a8fa3..c9c70ab0cce0 100644
--- a/drivers/net/sb1000.c
+++ b/drivers/net/sb1000.c
@@ -36,6 +36,7 @@ static char version[] = "sb1000.c:v1.1.2 6/01/98 (fventuri@mediaone.net)\n";
36 36
37#include <linux/module.h> 37#include <linux/module.h>
38#include <linux/kernel.h> 38#include <linux/kernel.h>
39#include <linux/sched.h>
39#include <linux/string.h> 40#include <linux/string.h>
40#include <linux/interrupt.h> 41#include <linux/interrupt.h>
41#include <linux/errno.h> 42#include <linux/errno.h>
diff --git a/drivers/net/sgiseeq.c b/drivers/net/sgiseeq.c
index ecf3279fbef5..f4dfd1f679a9 100644
--- a/drivers/net/sgiseeq.c
+++ b/drivers/net/sgiseeq.c
@@ -826,7 +826,7 @@ static int __exit sgiseeq_remove(struct platform_device *pdev)
826 826
827static struct platform_driver sgiseeq_driver = { 827static struct platform_driver sgiseeq_driver = {
828 .probe = sgiseeq_probe, 828 .probe = sgiseeq_probe,
829 .remove = __devexit_p(sgiseeq_remove), 829 .remove = __exit_p(sgiseeq_remove),
830 .driver = { 830 .driver = {
831 .name = "sgiseeq", 831 .name = "sgiseeq",
832 .owner = THIS_MODULE, 832 .owner = THIS_MODULE,
diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c
index 97949d0a699b..c072f7f36acf 100644
--- a/drivers/net/sis900.c
+++ b/drivers/net/sis900.c
@@ -52,6 +52,7 @@
52#include <linux/module.h> 52#include <linux/module.h>
53#include <linux/moduleparam.h> 53#include <linux/moduleparam.h>
54#include <linux/kernel.h> 54#include <linux/kernel.h>
55#include <linux/sched.h>
55#include <linux/string.h> 56#include <linux/string.h>
56#include <linux/timer.h> 57#include <linux/timer.h>
57#include <linux/errno.h> 58#include <linux/errno.h>
diff --git a/drivers/net/skfp/skfddi.c b/drivers/net/skfp/skfddi.c
index 38a508b4aad9..b27156eaf267 100644
--- a/drivers/net/skfp/skfddi.c
+++ b/drivers/net/skfp/skfddi.c
@@ -73,6 +73,7 @@ static const char * const boot_msg =
73 73
74/* Include files */ 74/* Include files */
75 75
76#include <linux/capability.h>
76#include <linux/module.h> 77#include <linux/module.h>
77#include <linux/kernel.h> 78#include <linux/kernel.h>
78#include <linux/errno.h> 79#include <linux/errno.h>
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index 55bad4081966..8f5414348e86 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -37,6 +37,7 @@
37#include <linux/crc32.h> 37#include <linux/crc32.h>
38#include <linux/dma-mapping.h> 38#include <linux/dma-mapping.h>
39#include <linux/debugfs.h> 39#include <linux/debugfs.h>
40#include <linux/sched.h>
40#include <linux/seq_file.h> 41#include <linux/seq_file.h>
41#include <linux/mii.h> 42#include <linux/mii.h>
42#include <asm/irq.h> 43#include <asm/irq.h>
@@ -3935,11 +3936,14 @@ static int __devinit skge_probe(struct pci_dev *pdev,
3935#endif 3936#endif
3936 3937
3937 err = -ENOMEM; 3938 err = -ENOMEM;
3938 hw = kzalloc(sizeof(*hw), GFP_KERNEL); 3939 /* space for skge@pci:0000:04:00.0 */
3940 hw = kzalloc(sizeof(*hw) + strlen(DRV_NAME "@pci:" )
3941 + strlen(pci_name(pdev)) + 1, GFP_KERNEL);
3939 if (!hw) { 3942 if (!hw) {
3940 dev_err(&pdev->dev, "cannot allocate hardware struct\n"); 3943 dev_err(&pdev->dev, "cannot allocate hardware struct\n");
3941 goto err_out_free_regions; 3944 goto err_out_free_regions;
3942 } 3945 }
3946 sprintf(hw->irq_name, DRV_NAME "@pci:%s", pci_name(pdev));
3943 3947
3944 hw->pdev = pdev; 3948 hw->pdev = pdev;
3945 spin_lock_init(&hw->hw_lock); 3949 spin_lock_init(&hw->hw_lock);
@@ -3974,7 +3978,7 @@ static int __devinit skge_probe(struct pci_dev *pdev,
3974 goto err_out_free_netdev; 3978 goto err_out_free_netdev;
3975 } 3979 }
3976 3980
3977 err = request_irq(pdev->irq, skge_intr, IRQF_SHARED, dev->name, hw); 3981 err = request_irq(pdev->irq, skge_intr, IRQF_SHARED, hw->irq_name, hw);
3978 if (err) { 3982 if (err) {
3979 dev_err(&pdev->dev, "%s: cannot assign irq %d\n", 3983 dev_err(&pdev->dev, "%s: cannot assign irq %d\n",
3980 dev->name, pdev->irq); 3984 dev->name, pdev->irq);
@@ -3982,14 +3986,17 @@ static int __devinit skge_probe(struct pci_dev *pdev,
3982 } 3986 }
3983 skge_show_addr(dev); 3987 skge_show_addr(dev);
3984 3988
3985 if (hw->ports > 1 && (dev1 = skge_devinit(hw, 1, using_dac))) { 3989 if (hw->ports > 1) {
3986 if (register_netdev(dev1) == 0) 3990 dev1 = skge_devinit(hw, 1, using_dac);
3991 if (dev1 && register_netdev(dev1) == 0)
3987 skge_show_addr(dev1); 3992 skge_show_addr(dev1);
3988 else { 3993 else {
3989 /* Failure to register second port need not be fatal */ 3994 /* Failure to register second port need not be fatal */
3990 dev_warn(&pdev->dev, "register of second port failed\n"); 3995 dev_warn(&pdev->dev, "register of second port failed\n");
3991 hw->dev[1] = NULL; 3996 hw->dev[1] = NULL;
3992 free_netdev(dev1); 3997 hw->ports = 1;
3998 if (dev1)
3999 free_netdev(dev1);
3993 } 4000 }
3994 } 4001 }
3995 pci_set_drvdata(pdev, hw); 4002 pci_set_drvdata(pdev, hw);
diff --git a/drivers/net/skge.h b/drivers/net/skge.h
index 17caccbb7685..831de1b6e96e 100644
--- a/drivers/net/skge.h
+++ b/drivers/net/skge.h
@@ -2423,6 +2423,8 @@ struct skge_hw {
2423 u16 phy_addr; 2423 u16 phy_addr;
2424 spinlock_t phy_lock; 2424 spinlock_t phy_lock;
2425 struct tasklet_struct phy_task; 2425 struct tasklet_struct phy_task;
2426
2427 char irq_name[0]; /* skge@pci:000:04:00.0 */
2426}; 2428};
2427 2429
2428enum pause_control { 2430enum pause_control {
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index ef1165718dd7..2ab5c39f33ca 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -4487,13 +4487,16 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
4487 wol_default = device_may_wakeup(&pdev->dev) ? WAKE_MAGIC : 0; 4487 wol_default = device_may_wakeup(&pdev->dev) ? WAKE_MAGIC : 0;
4488 4488
4489 err = -ENOMEM; 4489 err = -ENOMEM;
4490 hw = kzalloc(sizeof(*hw), GFP_KERNEL); 4490
4491 hw = kzalloc(sizeof(*hw) + strlen(DRV_NAME "@pci:")
4492 + strlen(pci_name(pdev)) + 1, GFP_KERNEL);
4491 if (!hw) { 4493 if (!hw) {
4492 dev_err(&pdev->dev, "cannot allocate hardware struct\n"); 4494 dev_err(&pdev->dev, "cannot allocate hardware struct\n");
4493 goto err_out_free_regions; 4495 goto err_out_free_regions;
4494 } 4496 }
4495 4497
4496 hw->pdev = pdev; 4498 hw->pdev = pdev;
4499 sprintf(hw->irq_name, DRV_NAME "@pci:%s", pci_name(pdev));
4497 4500
4498 hw->regs = ioremap_nocache(pci_resource_start(pdev, 0), 0x4000); 4501 hw->regs = ioremap_nocache(pci_resource_start(pdev, 0), 0x4000);
4499 if (!hw->regs) { 4502 if (!hw->regs) {
@@ -4539,7 +4542,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
4539 4542
4540 err = request_irq(pdev->irq, sky2_intr, 4543 err = request_irq(pdev->irq, sky2_intr,
4541 (hw->flags & SKY2_HW_USE_MSI) ? 0 : IRQF_SHARED, 4544 (hw->flags & SKY2_HW_USE_MSI) ? 0 : IRQF_SHARED,
4542 dev->name, hw); 4545 hw->irq_name, hw);
4543 if (err) { 4546 if (err) {
4544 dev_err(&pdev->dev, "cannot assign irq %d\n", pdev->irq); 4547 dev_err(&pdev->dev, "cannot assign irq %d\n", pdev->irq);
4545 goto err_out_unregister; 4548 goto err_out_unregister;
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h
index e0f23a101043..ed54129698b4 100644
--- a/drivers/net/sky2.h
+++ b/drivers/net/sky2.h
@@ -2085,6 +2085,8 @@ struct sky2_hw {
2085 struct timer_list watchdog_timer; 2085 struct timer_list watchdog_timer;
2086 struct work_struct restart_work; 2086 struct work_struct restart_work;
2087 wait_queue_head_t msi_wait; 2087 wait_queue_head_t msi_wait;
2088
2089 char irq_name[0];
2088}; 2090};
2089 2091
2090static inline int sky2_is_copper(const struct sky2_hw *hw) 2092static inline int sky2_is_copper(const struct sky2_hw *hw)
diff --git a/drivers/net/slip.c b/drivers/net/slip.c
index e17c535a577e..fe3cebb984de 100644
--- a/drivers/net/slip.c
+++ b/drivers/net/slip.c
@@ -67,6 +67,7 @@
67#include <asm/system.h> 67#include <asm/system.h>
68#include <asm/uaccess.h> 68#include <asm/uaccess.h>
69#include <linux/bitops.h> 69#include <linux/bitops.h>
70#include <linux/sched.h>
70#include <linux/string.h> 71#include <linux/string.h>
71#include <linux/mm.h> 72#include <linux/mm.h>
72#include <linux/interrupt.h> 73#include <linux/interrupt.h>
diff --git a/drivers/net/stmmac/Kconfig b/drivers/net/stmmac/Kconfig
new file mode 100644
index 000000000000..35eaa5251d7f
--- /dev/null
+++ b/drivers/net/stmmac/Kconfig
@@ -0,0 +1,53 @@
1config STMMAC_ETH
2 tristate "STMicroelectronics 10/100/1000 Ethernet driver"
3 select MII
4 select PHYLIB
5 depends on NETDEVICES && CPU_SUBTYPE_ST40
6 help
7 This is the driver for the ST MAC 10/100/1000 on-chip Ethernet
8 controllers. ST Ethernet IPs are built around a Synopsys IP Core.
9
10if STMMAC_ETH
11
12config STMMAC_DA
13 bool "STMMAC DMA arbitration scheme"
14 default n
15 help
16 Selecting this option, rx has priority over Tx (only for Giga
17 Ethernet device).
18 By default, the DMA arbitration scheme is based on Round-robin
19 (rx:tx priority is 1:1).
20
21config STMMAC_DUAL_MAC
22 bool "STMMAC: dual mac support (EXPERIMENTAL)"
23 default n
24 depends on EXPERIMENTAL && STMMAC_ETH && !STMMAC_TIMER
25 help
26 Some ST SoCs (for example the stx7141 and stx7200c2) have two
27 Ethernet Controllers. This option turns on the second Ethernet
28 device on this kind of platforms.
29
30config STMMAC_TIMER
31 bool "STMMAC Timer optimisation"
32 default n
33 help
34 Use an external timer for mitigating the number of network
35 interrupts.
36
37choice
38 prompt "Select Timer device"
39 depends on STMMAC_TIMER
40
41config STMMAC_TMU_TIMER
42 bool "TMU channel 2"
43 depends on CPU_SH4
44 help
45
46config STMMAC_RTC_TIMER
47 bool "Real time clock"
48 depends on RTC_CLASS
49 help
50
51endchoice
52
53endif
diff --git a/drivers/net/stmmac/Makefile b/drivers/net/stmmac/Makefile
new file mode 100644
index 000000000000..b2d7a5564dfa
--- /dev/null
+++ b/drivers/net/stmmac/Makefile
@@ -0,0 +1,4 @@
1obj-$(CONFIG_STMMAC_ETH) += stmmac.o
2stmmac-$(CONFIG_STMMAC_TIMER) += stmmac_timer.o
3stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o \
4 mac100.o gmac.o $(stmmac-y)
diff --git a/drivers/net/stmmac/common.h b/drivers/net/stmmac/common.h
new file mode 100644
index 000000000000..e49e5188e887
--- /dev/null
+++ b/drivers/net/stmmac/common.h
@@ -0,0 +1,330 @@
1/*******************************************************************************
2 STMMAC Common Header File
3
4 Copyright (C) 2007-2009 STMicroelectronics Ltd
5
6 This program is free software; you can redistribute it and/or modify it
7 under the terms and conditions of the GNU General Public License,
8 version 2, as published by the Free Software Foundation.
9
10 This program is distributed in the hope it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 more details.
14
15 You should have received a copy of the GNU General Public License along with
16 this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18
19 The full GNU General Public License is included in this distribution in
20 the file called "COPYING".
21
22 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
23*******************************************************************************/
24
25#include "descs.h"
26#include <linux/io.h>
27
28/* *********************************************
29 DMA CRS Control and Status Register Mapping
30 * *********************************************/
31#define DMA_BUS_MODE 0x00001000 /* Bus Mode */
32#define DMA_XMT_POLL_DEMAND 0x00001004 /* Transmit Poll Demand */
33#define DMA_RCV_POLL_DEMAND 0x00001008 /* Received Poll Demand */
34#define DMA_RCV_BASE_ADDR 0x0000100c /* Receive List Base */
35#define DMA_TX_BASE_ADDR 0x00001010 /* Transmit List Base */
36#define DMA_STATUS 0x00001014 /* Status Register */
37#define DMA_CONTROL 0x00001018 /* Ctrl (Operational Mode) */
38#define DMA_INTR_ENA 0x0000101c /* Interrupt Enable */
39#define DMA_MISSED_FRAME_CTR 0x00001020 /* Missed Frame Counter */
40#define DMA_CUR_TX_BUF_ADDR 0x00001050 /* Current Host Tx Buffer */
41#define DMA_CUR_RX_BUF_ADDR 0x00001054 /* Current Host Rx Buffer */
42
43/* ********************************
44 DMA Control register defines
45 * ********************************/
46#define DMA_CONTROL_ST 0x00002000 /* Start/Stop Transmission */
47#define DMA_CONTROL_SR 0x00000002 /* Start/Stop Receive */
48
49/* **************************************
50 DMA Interrupt Enable register defines
51 * **************************************/
52/**** NORMAL INTERRUPT ****/
53#define DMA_INTR_ENA_NIE 0x00010000 /* Normal Summary */
54#define DMA_INTR_ENA_TIE 0x00000001 /* Transmit Interrupt */
55#define DMA_INTR_ENA_TUE 0x00000004 /* Transmit Buffer Unavailable */
56#define DMA_INTR_ENA_RIE 0x00000040 /* Receive Interrupt */
57#define DMA_INTR_ENA_ERE 0x00004000 /* Early Receive */
58
59#define DMA_INTR_NORMAL (DMA_INTR_ENA_NIE | DMA_INTR_ENA_RIE | \
60 DMA_INTR_ENA_TIE)
61
62/**** ABNORMAL INTERRUPT ****/
63#define DMA_INTR_ENA_AIE 0x00008000 /* Abnormal Summary */
64#define DMA_INTR_ENA_FBE 0x00002000 /* Fatal Bus Error */
65#define DMA_INTR_ENA_ETE 0x00000400 /* Early Transmit */
66#define DMA_INTR_ENA_RWE 0x00000200 /* Receive Watchdog */
67#define DMA_INTR_ENA_RSE 0x00000100 /* Receive Stopped */
68#define DMA_INTR_ENA_RUE 0x00000080 /* Receive Buffer Unavailable */
69#define DMA_INTR_ENA_UNE 0x00000020 /* Tx Underflow */
70#define DMA_INTR_ENA_OVE 0x00000010 /* Receive Overflow */
71#define DMA_INTR_ENA_TJE 0x00000008 /* Transmit Jabber */
72#define DMA_INTR_ENA_TSE 0x00000002 /* Transmit Stopped */
73
74#define DMA_INTR_ABNORMAL (DMA_INTR_ENA_AIE | DMA_INTR_ENA_FBE | \
75 DMA_INTR_ENA_UNE)
76
77/* DMA default interrupt mask */
78#define DMA_INTR_DEFAULT_MASK (DMA_INTR_NORMAL | DMA_INTR_ABNORMAL)
79
80/* ****************************
81 * DMA Status register defines
82 * ****************************/
83#define DMA_STATUS_GPI 0x10000000 /* PMT interrupt */
84#define DMA_STATUS_GMI 0x08000000 /* MMC interrupt */
85#define DMA_STATUS_GLI 0x04000000 /* GMAC Line interface int. */
86#define DMA_STATUS_GMI 0x08000000
87#define DMA_STATUS_GLI 0x04000000
88#define DMA_STATUS_EB_MASK 0x00380000 /* Error Bits Mask */
89#define DMA_STATUS_EB_TX_ABORT 0x00080000 /* Error Bits - TX Abort */
90#define DMA_STATUS_EB_RX_ABORT 0x00100000 /* Error Bits - RX Abort */
91#define DMA_STATUS_TS_MASK 0x00700000 /* Transmit Process State */
92#define DMA_STATUS_TS_SHIFT 20
93#define DMA_STATUS_RS_MASK 0x000e0000 /* Receive Process State */
94#define DMA_STATUS_RS_SHIFT 17
95#define DMA_STATUS_NIS 0x00010000 /* Normal Interrupt Summary */
96#define DMA_STATUS_AIS 0x00008000 /* Abnormal Interrupt Summary */
97#define DMA_STATUS_ERI 0x00004000 /* Early Receive Interrupt */
98#define DMA_STATUS_FBI 0x00002000 /* Fatal Bus Error Interrupt */
99#define DMA_STATUS_ETI 0x00000400 /* Early Transmit Interrupt */
100#define DMA_STATUS_RWT 0x00000200 /* Receive Watchdog Timeout */
101#define DMA_STATUS_RPS 0x00000100 /* Receive Process Stopped */
102#define DMA_STATUS_RU 0x00000080 /* Receive Buffer Unavailable */
103#define DMA_STATUS_RI 0x00000040 /* Receive Interrupt */
104#define DMA_STATUS_UNF 0x00000020 /* Transmit Underflow */
105#define DMA_STATUS_OVF 0x00000010 /* Receive Overflow */
106#define DMA_STATUS_TJT 0x00000008 /* Transmit Jabber Timeout */
107#define DMA_STATUS_TU 0x00000004 /* Transmit Buffer Unavailable */
108#define DMA_STATUS_TPS 0x00000002 /* Transmit Process Stopped */
109#define DMA_STATUS_TI 0x00000001 /* Transmit Interrupt */
110
111/* Other defines */
112#define HASH_TABLE_SIZE 64
113#define PAUSE_TIME 0x200
114
115/* Flow Control defines */
116#define FLOW_OFF 0
117#define FLOW_RX 1
118#define FLOW_TX 2
119#define FLOW_AUTO (FLOW_TX | FLOW_RX)
120
121/* DMA STORE-AND-FORWARD Operation Mode */
122#define SF_DMA_MODE 1
123
124#define HW_CSUM 1
125#define NO_HW_CSUM 0
126
127/* GMAC TX FIFO is 8K, Rx FIFO is 16K */
128#define BUF_SIZE_16KiB 16384
129#define BUF_SIZE_8KiB 8192
130#define BUF_SIZE_4KiB 4096
131#define BUF_SIZE_2KiB 2048
132
133/* Power Down and WOL */
134#define PMT_NOT_SUPPORTED 0
135#define PMT_SUPPORTED 1
136
137/* Common MAC defines */
138#define MAC_CTRL_REG 0x00000000 /* MAC Control */
139#define MAC_ENABLE_TX 0x00000008 /* Transmitter Enable */
140#define MAC_RNABLE_RX 0x00000004 /* Receiver Enable */
141
142/* MAC Management Counters register */
143#define MMC_CONTROL 0x00000100 /* MMC Control */
144#define MMC_HIGH_INTR 0x00000104 /* MMC High Interrupt */
145#define MMC_LOW_INTR 0x00000108 /* MMC Low Interrupt */
146#define MMC_HIGH_INTR_MASK 0x0000010c /* MMC High Interrupt Mask */
147#define MMC_LOW_INTR_MASK 0x00000110 /* MMC Low Interrupt Mask */
148
149#define MMC_CONTROL_MAX_FRM_MASK 0x0003ff8 /* Maximum Frame Size */
150#define MMC_CONTROL_MAX_FRM_SHIFT 3
151#define MMC_CONTROL_MAX_FRAME 0x7FF
152
153struct stmmac_extra_stats {
154 /* Transmit errors */
155 unsigned long tx_underflow ____cacheline_aligned;
156 unsigned long tx_carrier;
157 unsigned long tx_losscarrier;
158 unsigned long tx_heartbeat;
159 unsigned long tx_deferred;
160 unsigned long tx_vlan;
161 unsigned long tx_jabber;
162 unsigned long tx_frame_flushed;
163 unsigned long tx_payload_error;
164 unsigned long tx_ip_header_error;
165 /* Receive errors */
166 unsigned long rx_desc;
167 unsigned long rx_partial;
168 unsigned long rx_runt;
169 unsigned long rx_toolong;
170 unsigned long rx_collision;
171 unsigned long rx_crc;
172 unsigned long rx_lenght;
173 unsigned long rx_mii;
174 unsigned long rx_multicast;
175 unsigned long rx_gmac_overflow;
176 unsigned long rx_watchdog;
177 unsigned long da_rx_filter_fail;
178 unsigned long sa_rx_filter_fail;
179 unsigned long rx_missed_cntr;
180 unsigned long rx_overflow_cntr;
181 unsigned long rx_vlan;
182 /* Tx/Rx IRQ errors */
183 unsigned long tx_undeflow_irq;
184 unsigned long tx_process_stopped_irq;
185 unsigned long tx_jabber_irq;
186 unsigned long rx_overflow_irq;
187 unsigned long rx_buf_unav_irq;
188 unsigned long rx_process_stopped_irq;
189 unsigned long rx_watchdog_irq;
190 unsigned long tx_early_irq;
191 unsigned long fatal_bus_error_irq;
192 /* Extra info */
193 unsigned long threshold;
194 unsigned long tx_pkt_n;
195 unsigned long rx_pkt_n;
196 unsigned long poll_n;
197 unsigned long sched_timer_n;
198 unsigned long normal_irq_n;
199};
200
201/* GMAC core can compute the checksums in HW. */
202enum rx_frame_status {
203 good_frame = 0,
204 discard_frame = 1,
205 csum_none = 2,
206};
207
208static inline void stmmac_set_mac_addr(unsigned long ioaddr, u8 addr[6],
209 unsigned int high, unsigned int low)
210{
211 unsigned long data;
212
213 data = (addr[5] << 8) | addr[4];
214 writel(data, ioaddr + high);
215 data = (addr[3] << 24) | (addr[2] << 16) | (addr[1] << 8) | addr[0];
216 writel(data, ioaddr + low);
217
218 return;
219}
220
221static inline void stmmac_get_mac_addr(unsigned long ioaddr,
222 unsigned char *addr, unsigned int high,
223 unsigned int low)
224{
225 unsigned int hi_addr, lo_addr;
226
227 /* Read the MAC address from the hardware */
228 hi_addr = readl(ioaddr + high);
229 lo_addr = readl(ioaddr + low);
230
231 /* Extract the MAC address from the high and low words */
232 addr[0] = lo_addr & 0xff;
233 addr[1] = (lo_addr >> 8) & 0xff;
234 addr[2] = (lo_addr >> 16) & 0xff;
235 addr[3] = (lo_addr >> 24) & 0xff;
236 addr[4] = hi_addr & 0xff;
237 addr[5] = (hi_addr >> 8) & 0xff;
238
239 return;
240}
241
242struct stmmac_ops {
243 /* MAC core initialization */
244 void (*core_init) (unsigned long ioaddr) ____cacheline_aligned;
245 /* DMA core initialization */
246 int (*dma_init) (unsigned long ioaddr, int pbl, u32 dma_tx, u32 dma_rx);
247 /* Dump MAC registers */
248 void (*dump_mac_regs) (unsigned long ioaddr);
249 /* Dump DMA registers */
250 void (*dump_dma_regs) (unsigned long ioaddr);
251 /* Set tx/rx threshold in the csr6 register
252 * An invalid value enables the store-and-forward mode */
253 void (*dma_mode) (unsigned long ioaddr, int txmode, int rxmode);
254 /* To track extra statistic (if supported) */
255 void (*dma_diagnostic_fr) (void *data, struct stmmac_extra_stats *x,
256 unsigned long ioaddr);
257 /* RX descriptor ring initialization */
258 void (*init_rx_desc) (struct dma_desc *p, unsigned int ring_size,
259 int disable_rx_ic);
260 /* TX descriptor ring initialization */
261 void (*init_tx_desc) (struct dma_desc *p, unsigned int ring_size);
262
263 /* Invoked by the xmit function to prepare the tx descriptor */
264 void (*prepare_tx_desc) (struct dma_desc *p, int is_fs, int len,
265 int csum_flag);
266 /* Set/get the owner of the descriptor */
267 void (*set_tx_owner) (struct dma_desc *p);
268 int (*get_tx_owner) (struct dma_desc *p);
269 /* Invoked by the xmit function to close the tx descriptor */
270 void (*close_tx_desc) (struct dma_desc *p);
271 /* Clean the tx descriptor as soon as the tx irq is received */
272 void (*release_tx_desc) (struct dma_desc *p);
273 /* Clear interrupt on tx frame completion. When this bit is
274 * set an interrupt happens as soon as the frame is transmitted */
275 void (*clear_tx_ic) (struct dma_desc *p);
276 /* Last tx segment reports the transmit status */
277 int (*get_tx_ls) (struct dma_desc *p);
278 /* Return the transmit status looking at the TDES1 */
279 int (*tx_status) (void *data, struct stmmac_extra_stats *x,
280 struct dma_desc *p, unsigned long ioaddr);
281 /* Get the buffer size from the descriptor */
282 int (*get_tx_len) (struct dma_desc *p);
283 /* Handle extra events on specific interrupts hw dependent */
284 void (*host_irq_status) (unsigned long ioaddr);
285 int (*get_rx_owner) (struct dma_desc *p);
286 void (*set_rx_owner) (struct dma_desc *p);
287 /* Get the receive frame size */
288 int (*get_rx_frame_len) (struct dma_desc *p);
289 /* Return the reception status looking at the RDES1 */
290 int (*rx_status) (void *data, struct stmmac_extra_stats *x,
291 struct dma_desc *p);
292 /* Multicast filter setting */
293 void (*set_filter) (struct net_device *dev);
294 /* Flow control setting */
295 void (*flow_ctrl) (unsigned long ioaddr, unsigned int duplex,
296 unsigned int fc, unsigned int pause_time);
297 /* Set power management mode (e.g. magic frame) */
298 void (*pmt) (unsigned long ioaddr, unsigned long mode);
299 /* Set/Get Unicast MAC addresses */
300 void (*set_umac_addr) (unsigned long ioaddr, unsigned char *addr,
301 unsigned int reg_n);
302 void (*get_umac_addr) (unsigned long ioaddr, unsigned char *addr,
303 unsigned int reg_n);
304};
305
306struct mac_link {
307 int port;
308 int duplex;
309 int speed;
310};
311
312struct mii_regs {
313 unsigned int addr; /* MII Address */
314 unsigned int data; /* MII Data */
315};
316
317struct hw_cap {
318 unsigned int version; /* Core Version register (GMAC) */
319 unsigned int pmt; /* Power-Down mode (GMAC) */
320 struct mac_link link;
321 struct mii_regs mii;
322};
323
324struct mac_device_info {
325 struct hw_cap hw;
326 struct stmmac_ops *ops;
327};
328
329struct mac_device_info *gmac_setup(unsigned long addr);
330struct mac_device_info *mac100_setup(unsigned long addr);
diff --git a/drivers/net/stmmac/descs.h b/drivers/net/stmmac/descs.h
new file mode 100644
index 000000000000..6d2a0b2f5e57
--- /dev/null
+++ b/drivers/net/stmmac/descs.h
@@ -0,0 +1,163 @@
1/*******************************************************************************
2 Header File to describe the DMA descriptors
3 Use enhanced descriptors in case of GMAC Cores.
4
5 This program is free software; you can redistribute it and/or modify it
6 under the terms and conditions of the GNU General Public License,
7 version 2, as published by the Free Software Foundation.
8
9 This program is distributed in the hope it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 more details.
13
14 You should have received a copy of the GNU General Public License along with
15 this program; if not, write to the Free Software Foundation, Inc.,
16 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17
18 The full GNU General Public License is included in this distribution in
19 the file called "COPYING".
20
21 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
22*******************************************************************************/
23struct dma_desc {
24 /* Receive descriptor */
25 union {
26 struct {
27 /* RDES0 */
28 u32 reserved1:1;
29 u32 crc_error:1;
30 u32 dribbling:1;
31 u32 mii_error:1;
32 u32 receive_watchdog:1;
33 u32 frame_type:1;
34 u32 collision:1;
35 u32 frame_too_long:1;
36 u32 last_descriptor:1;
37 u32 first_descriptor:1;
38 u32 multicast_frame:1;
39 u32 run_frame:1;
40 u32 length_error:1;
41 u32 partial_frame_error:1;
42 u32 descriptor_error:1;
43 u32 error_summary:1;
44 u32 frame_length:14;
45 u32 filtering_fail:1;
46 u32 own:1;
47 /* RDES1 */
48 u32 buffer1_size:11;
49 u32 buffer2_size:11;
50 u32 reserved2:2;
51 u32 second_address_chained:1;
52 u32 end_ring:1;
53 u32 reserved3:5;
54 u32 disable_ic:1;
55 } rx;
56 struct {
57 /* RDES0 */
58 u32 payload_csum_error:1;
59 u32 crc_error:1;
60 u32 dribbling:1;
61 u32 error_gmii:1;
62 u32 receive_watchdog:1;
63 u32 frame_type:1;
64 u32 late_collision:1;
65 u32 ipc_csum_error:1;
66 u32 last_descriptor:1;
67 u32 first_descriptor:1;
68 u32 vlan_tag:1;
69 u32 overflow_error:1;
70 u32 length_error:1;
71 u32 sa_filter_fail:1;
72 u32 descriptor_error:1;
73 u32 error_summary:1;
74 u32 frame_length:14;
75 u32 da_filter_fail:1;
76 u32 own:1;
77 /* RDES1 */
78 u32 buffer1_size:13;
79 u32 reserved1:1;
80 u32 second_address_chained:1;
81 u32 end_ring:1;
82 u32 buffer2_size:13;
83 u32 reserved2:2;
84 u32 disable_ic:1;
85 } erx; /* -- enhanced -- */
86
87 /* Transmit descriptor */
88 struct {
89 /* TDES0 */
90 u32 deferred:1;
91 u32 underflow_error:1;
92 u32 excessive_deferral:1;
93 u32 collision_count:4;
94 u32 heartbeat_fail:1;
95 u32 excessive_collisions:1;
96 u32 late_collision:1;
97 u32 no_carrier:1;
98 u32 loss_carrier:1;
99 u32 reserved1:3;
100 u32 error_summary:1;
101 u32 reserved2:15;
102 u32 own:1;
103 /* TDES1 */
104 u32 buffer1_size:11;
105 u32 buffer2_size:11;
106 u32 reserved3:1;
107 u32 disable_padding:1;
108 u32 second_address_chained:1;
109 u32 end_ring:1;
110 u32 crc_disable:1;
111 u32 reserved4:2;
112 u32 first_segment:1;
113 u32 last_segment:1;
114 u32 interrupt:1;
115 } tx;
116 struct {
117 /* TDES0 */
118 u32 deferred:1;
119 u32 underflow_error:1;
120 u32 excessive_deferral:1;
121 u32 collision_count:4;
122 u32 vlan_frame:1;
123 u32 excessive_collisions:1;
124 u32 late_collision:1;
125 u32 no_carrier:1;
126 u32 loss_carrier:1;
127 u32 payload_error:1;
128 u32 frame_flushed:1;
129 u32 jabber_timeout:1;
130 u32 error_summary:1;
131 u32 ip_header_error:1;
132 u32 time_stamp_status:1;
133 u32 reserved1:2;
134 u32 second_address_chained:1;
135 u32 end_ring:1;
136 u32 checksum_insertion:2;
137 u32 reserved2:1;
138 u32 time_stamp_enable:1;
139 u32 disable_padding:1;
140 u32 crc_disable:1;
141 u32 first_segment:1;
142 u32 last_segment:1;
143 u32 interrupt:1;
144 u32 own:1;
145 /* TDES1 */
146 u32 buffer1_size:13;
147 u32 reserved3:3;
148 u32 buffer2_size:13;
149 u32 reserved4:3;
150 } etx; /* -- enhanced -- */
151 } des01;
152 unsigned int des2;
153 unsigned int des3;
154};
155
156/* Transmit checksum insertion control */
157enum tdes_csum_insertion {
158 cic_disabled = 0, /* Checksum Insertion Control */
159 cic_only_ip = 1, /* Only IP header */
160 cic_no_pseudoheader = 2, /* IP header but pseudoheader
161 * is not calculated */
162 cic_full = 3, /* IP header and pseudoheader */
163};
diff --git a/drivers/net/stmmac/gmac.c b/drivers/net/stmmac/gmac.c
new file mode 100644
index 000000000000..b624bb5bae0a
--- /dev/null
+++ b/drivers/net/stmmac/gmac.c
@@ -0,0 +1,693 @@
1/*******************************************************************************
2 This is the driver for the GMAC on-chip Ethernet controller for ST SoCs.
3 DWC Ether MAC 10/100/1000 Universal version 3.41a has been used for
4 developing this code.
5
6 Copyright (C) 2007-2009 STMicroelectronics Ltd
7
8 This program is free software; you can redistribute it and/or modify it
9 under the terms and conditions of the GNU General Public License,
10 version 2, as published by the Free Software Foundation.
11
12 This program is distributed in the hope it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 more details.
16
17 You should have received a copy of the GNU General Public License along with
18 this program; if not, write to the Free Software Foundation, Inc.,
19 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
20
21 The full GNU General Public License is included in this distribution in
22 the file called "COPYING".
23
24 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
25*******************************************************************************/
26
27#include <linux/netdevice.h>
28#include <linux/crc32.h>
29#include <linux/mii.h>
30#include <linux/phy.h>
31
32#include "stmmac.h"
33#include "gmac.h"
34
35#undef GMAC_DEBUG
36/*#define GMAC_DEBUG*/
37#undef FRAME_FILTER_DEBUG
38/*#define FRAME_FILTER_DEBUG*/
39#ifdef GMAC_DEBUG
40#define DBG(fmt, args...) printk(fmt, ## args)
41#else
42#define DBG(fmt, args...) do { } while (0)
43#endif
44
45static void gmac_dump_regs(unsigned long ioaddr)
46{
47 int i;
48 pr_info("\t----------------------------------------------\n"
49 "\t GMAC registers (base addr = 0x%8x)\n"
50 "\t----------------------------------------------\n",
51 (unsigned int)ioaddr);
52
53 for (i = 0; i < 55; i++) {
54 int offset = i * 4;
55 pr_info("\tReg No. %d (offset 0x%x): 0x%08x\n", i,
56 offset, readl(ioaddr + offset));
57 }
58 return;
59}
60
61static int gmac_dma_init(unsigned long ioaddr, int pbl, u32 dma_tx, u32 dma_rx)
62{
63 u32 value = readl(ioaddr + DMA_BUS_MODE);
64 /* DMA SW reset */
65 value |= DMA_BUS_MODE_SFT_RESET;
66 writel(value, ioaddr + DMA_BUS_MODE);
67 do {} while ((readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET));
68
69 value = /* DMA_BUS_MODE_FB | */ DMA_BUS_MODE_4PBL |
70 ((pbl << DMA_BUS_MODE_PBL_SHIFT) |
71 (pbl << DMA_BUS_MODE_RPBL_SHIFT));
72
73#ifdef CONFIG_STMMAC_DA
74 value |= DMA_BUS_MODE_DA; /* Rx has priority over tx */
75#endif
76 writel(value, ioaddr + DMA_BUS_MODE);
77
78 /* Mask interrupts by writing to CSR7 */
79 writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA);
80
81 /* The base address of the RX/TX descriptor lists must be written into
82 * DMA CSR3 and CSR4, respectively. */
83 writel(dma_tx, ioaddr + DMA_TX_BASE_ADDR);
84 writel(dma_rx, ioaddr + DMA_RCV_BASE_ADDR);
85
86 return 0;
87}
88
89/* Transmit FIFO flush operation */
90static void gmac_flush_tx_fifo(unsigned long ioaddr)
91{
92 u32 csr6 = readl(ioaddr + DMA_CONTROL);
93 writel((csr6 | DMA_CONTROL_FTF), ioaddr + DMA_CONTROL);
94
95 do {} while ((readl(ioaddr + DMA_CONTROL) & DMA_CONTROL_FTF));
96}
97
98static void gmac_dma_operation_mode(unsigned long ioaddr, int txmode,
99 int rxmode)
100{
101 u32 csr6 = readl(ioaddr + DMA_CONTROL);
102
103 if (txmode == SF_DMA_MODE) {
104 DBG(KERN_DEBUG "GMAC: enabling TX store and forward mode\n");
105 /* Transmit COE type 2 cannot be done in cut-through mode. */
106 csr6 |= DMA_CONTROL_TSF;
107 /* Operating on second frame increase the performance
108 * especially when transmit store-and-forward is used.*/
109 csr6 |= DMA_CONTROL_OSF;
110 } else {
111 DBG(KERN_DEBUG "GMAC: disabling TX store and forward mode"
112 " (threshold = %d)\n", txmode);
113 csr6 &= ~DMA_CONTROL_TSF;
114 csr6 &= DMA_CONTROL_TC_TX_MASK;
115 /* Set the transmit threashold */
116 if (txmode <= 32)
117 csr6 |= DMA_CONTROL_TTC_32;
118 else if (txmode <= 64)
119 csr6 |= DMA_CONTROL_TTC_64;
120 else if (txmode <= 128)
121 csr6 |= DMA_CONTROL_TTC_128;
122 else if (txmode <= 192)
123 csr6 |= DMA_CONTROL_TTC_192;
124 else
125 csr6 |= DMA_CONTROL_TTC_256;
126 }
127
128 if (rxmode == SF_DMA_MODE) {
129 DBG(KERN_DEBUG "GMAC: enabling RX store and forward mode\n");
130 csr6 |= DMA_CONTROL_RSF;
131 } else {
132 DBG(KERN_DEBUG "GMAC: disabling RX store and forward mode"
133 " (threshold = %d)\n", rxmode);
134 csr6 &= ~DMA_CONTROL_RSF;
135 csr6 &= DMA_CONTROL_TC_RX_MASK;
136 if (rxmode <= 32)
137 csr6 |= DMA_CONTROL_RTC_32;
138 else if (rxmode <= 64)
139 csr6 |= DMA_CONTROL_RTC_64;
140 else if (rxmode <= 96)
141 csr6 |= DMA_CONTROL_RTC_96;
142 else
143 csr6 |= DMA_CONTROL_RTC_128;
144 }
145
146 writel(csr6, ioaddr + DMA_CONTROL);
147 return;
148}
149
150/* Not yet implemented --- no RMON module */
151static void gmac_dma_diagnostic_fr(void *data, struct stmmac_extra_stats *x,
152 unsigned long ioaddr)
153{
154 return;
155}
156
157static void gmac_dump_dma_regs(unsigned long ioaddr)
158{
159 int i;
160 pr_info(" DMA registers\n");
161 for (i = 0; i < 22; i++) {
162 if ((i < 9) || (i > 17)) {
163 int offset = i * 4;
164 pr_err("\t Reg No. %d (offset 0x%x): 0x%08x\n", i,
165 (DMA_BUS_MODE + offset),
166 readl(ioaddr + DMA_BUS_MODE + offset));
167 }
168 }
169 return;
170}
171
172static int gmac_get_tx_frame_status(void *data, struct stmmac_extra_stats *x,
173 struct dma_desc *p, unsigned long ioaddr)
174{
175 int ret = 0;
176 struct net_device_stats *stats = (struct net_device_stats *)data;
177
178 if (unlikely(p->des01.etx.error_summary)) {
179 DBG(KERN_ERR "GMAC TX error... 0x%08x\n", p->des01.etx);
180 if (unlikely(p->des01.etx.jabber_timeout)) {
181 DBG(KERN_ERR "\tjabber_timeout error\n");
182 x->tx_jabber++;
183 }
184
185 if (unlikely(p->des01.etx.frame_flushed)) {
186 DBG(KERN_ERR "\tframe_flushed error\n");
187 x->tx_frame_flushed++;
188 gmac_flush_tx_fifo(ioaddr);
189 }
190
191 if (unlikely(p->des01.etx.loss_carrier)) {
192 DBG(KERN_ERR "\tloss_carrier error\n");
193 x->tx_losscarrier++;
194 stats->tx_carrier_errors++;
195 }
196 if (unlikely(p->des01.etx.no_carrier)) {
197 DBG(KERN_ERR "\tno_carrier error\n");
198 x->tx_carrier++;
199 stats->tx_carrier_errors++;
200 }
201 if (unlikely(p->des01.etx.late_collision)) {
202 DBG(KERN_ERR "\tlate_collision error\n");
203 stats->collisions += p->des01.etx.collision_count;
204 }
205 if (unlikely(p->des01.etx.excessive_collisions)) {
206 DBG(KERN_ERR "\texcessive_collisions\n");
207 stats->collisions += p->des01.etx.collision_count;
208 }
209 if (unlikely(p->des01.etx.excessive_deferral)) {
210 DBG(KERN_INFO "\texcessive tx_deferral\n");
211 x->tx_deferred++;
212 }
213
214 if (unlikely(p->des01.etx.underflow_error)) {
215 DBG(KERN_ERR "\tunderflow error\n");
216 gmac_flush_tx_fifo(ioaddr);
217 x->tx_underflow++;
218 }
219
220 if (unlikely(p->des01.etx.ip_header_error)) {
221 DBG(KERN_ERR "\tTX IP header csum error\n");
222 x->tx_ip_header_error++;
223 }
224
225 if (unlikely(p->des01.etx.payload_error)) {
226 DBG(KERN_ERR "\tAddr/Payload csum error\n");
227 x->tx_payload_error++;
228 gmac_flush_tx_fifo(ioaddr);
229 }
230
231 ret = -1;
232 }
233
234 if (unlikely(p->des01.etx.deferred)) {
235 DBG(KERN_INFO "GMAC TX status: tx deferred\n");
236 x->tx_deferred++;
237 }
238#ifdef STMMAC_VLAN_TAG_USED
239 if (p->des01.etx.vlan_frame) {
240 DBG(KERN_INFO "GMAC TX status: VLAN frame\n");
241 x->tx_vlan++;
242 }
243#endif
244
245 return ret;
246}
247
248static int gmac_get_tx_len(struct dma_desc *p)
249{
250 return p->des01.etx.buffer1_size;
251}
252
253static int gmac_coe_rdes0(int ipc_err, int type, int payload_err)
254{
255 int ret = good_frame;
256 u32 status = (type << 2 | ipc_err << 1 | payload_err) & 0x7;
257
258 /* bits 5 7 0 | Frame status
259 * ----------------------------------------------------------
260 * 0 0 0 | IEEE 802.3 Type frame (lenght < 1536 octects)
261 * 1 0 0 | IPv4/6 No CSUM errorS.
262 * 1 0 1 | IPv4/6 CSUM PAYLOAD error
263 * 1 1 0 | IPv4/6 CSUM IP HR error
264 * 1 1 1 | IPv4/6 IP PAYLOAD AND HEADER errorS
265 * 0 0 1 | IPv4/6 unsupported IP PAYLOAD
266 * 0 1 1 | COE bypassed.. no IPv4/6 frame
267 * 0 1 0 | Reserved.
268 */
269 if (status == 0x0) {
270 DBG(KERN_INFO "RX Des0 status: IEEE 802.3 Type frame.\n");
271 ret = good_frame;
272 } else if (status == 0x4) {
273 DBG(KERN_INFO "RX Des0 status: IPv4/6 No CSUM errorS.\n");
274 ret = good_frame;
275 } else if (status == 0x5) {
276 DBG(KERN_ERR "RX Des0 status: IPv4/6 Payload Error.\n");
277 ret = csum_none;
278 } else if (status == 0x6) {
279 DBG(KERN_ERR "RX Des0 status: IPv4/6 Header Error.\n");
280 ret = csum_none;
281 } else if (status == 0x7) {
282 DBG(KERN_ERR
283 "RX Des0 status: IPv4/6 Header and Payload Error.\n");
284 ret = csum_none;
285 } else if (status == 0x1) {
286 DBG(KERN_ERR
287 "RX Des0 status: IPv4/6 unsupported IP PAYLOAD.\n");
288 ret = discard_frame;
289 } else if (status == 0x3) {
290 DBG(KERN_ERR "RX Des0 status: No IPv4, IPv6 frame.\n");
291 ret = discard_frame;
292 }
293 return ret;
294}
295
296static int gmac_get_rx_frame_status(void *data, struct stmmac_extra_stats *x,
297 struct dma_desc *p)
298{
299 int ret = good_frame;
300 struct net_device_stats *stats = (struct net_device_stats *)data;
301
302 if (unlikely(p->des01.erx.error_summary)) {
303 DBG(KERN_ERR "GMAC RX Error Summary... 0x%08x\n", p->des01.erx);
304 if (unlikely(p->des01.erx.descriptor_error)) {
305 DBG(KERN_ERR "\tdescriptor error\n");
306 x->rx_desc++;
307 stats->rx_length_errors++;
308 }
309 if (unlikely(p->des01.erx.overflow_error)) {
310 DBG(KERN_ERR "\toverflow error\n");
311 x->rx_gmac_overflow++;
312 }
313
314 if (unlikely(p->des01.erx.ipc_csum_error))
315 DBG(KERN_ERR "\tIPC Csum Error/Giant frame\n");
316
317 if (unlikely(p->des01.erx.late_collision)) {
318 DBG(KERN_ERR "\tlate_collision error\n");
319 stats->collisions++;
320 stats->collisions++;
321 }
322 if (unlikely(p->des01.erx.receive_watchdog)) {
323 DBG(KERN_ERR "\treceive_watchdog error\n");
324 x->rx_watchdog++;
325 }
326 if (unlikely(p->des01.erx.error_gmii)) {
327 DBG(KERN_ERR "\tReceive Error\n");
328 x->rx_mii++;
329 }
330 if (unlikely(p->des01.erx.crc_error)) {
331 DBG(KERN_ERR "\tCRC error\n");
332 x->rx_crc++;
333 stats->rx_crc_errors++;
334 }
335 ret = discard_frame;
336 }
337
338 /* After a payload csum error, the ES bit is set.
339 * It doesn't match with the information reported into the databook.
340 * At any rate, we need to understand if the CSUM hw computation is ok
341 * and report this info to the upper layers. */
342 ret = gmac_coe_rdes0(p->des01.erx.ipc_csum_error,
343 p->des01.erx.frame_type, p->des01.erx.payload_csum_error);
344
345 if (unlikely(p->des01.erx.dribbling)) {
346 DBG(KERN_ERR "GMAC RX: dribbling error\n");
347 ret = discard_frame;
348 }
349 if (unlikely(p->des01.erx.sa_filter_fail)) {
350 DBG(KERN_ERR "GMAC RX : Source Address filter fail\n");
351 x->sa_rx_filter_fail++;
352 ret = discard_frame;
353 }
354 if (unlikely(p->des01.erx.da_filter_fail)) {
355 DBG(KERN_ERR "GMAC RX : Destination Address filter fail\n");
356 x->da_rx_filter_fail++;
357 ret = discard_frame;
358 }
359 if (unlikely(p->des01.erx.length_error)) {
360 DBG(KERN_ERR "GMAC RX: length_error error\n");
361 x->rx_lenght++;
362 ret = discard_frame;
363 }
364#ifdef STMMAC_VLAN_TAG_USED
365 if (p->des01.erx.vlan_tag) {
366 DBG(KERN_INFO "GMAC RX: VLAN frame tagged\n");
367 x->rx_vlan++;
368 }
369#endif
370 return ret;
371}
372
373static void gmac_irq_status(unsigned long ioaddr)
374{
375 u32 intr_status = readl(ioaddr + GMAC_INT_STATUS);
376
377 /* Not used events (e.g. MMC interrupts) are not handled. */
378 if ((intr_status & mmc_tx_irq))
379 DBG(KERN_DEBUG "GMAC: MMC tx interrupt: 0x%08x\n",
380 readl(ioaddr + GMAC_MMC_TX_INTR));
381 if (unlikely(intr_status & mmc_rx_irq))
382 DBG(KERN_DEBUG "GMAC: MMC rx interrupt: 0x%08x\n",
383 readl(ioaddr + GMAC_MMC_RX_INTR));
384 if (unlikely(intr_status & mmc_rx_csum_offload_irq))
385 DBG(KERN_DEBUG "GMAC: MMC rx csum offload: 0x%08x\n",
386 readl(ioaddr + GMAC_MMC_RX_CSUM_OFFLOAD));
387 if (unlikely(intr_status & pmt_irq)) {
388 DBG(KERN_DEBUG "GMAC: received Magic frame\n");
389 /* clear the PMT bits 5 and 6 by reading the PMT
390 * status register. */
391 readl(ioaddr + GMAC_PMT);
392 }
393
394 return;
395}
396
397static void gmac_core_init(unsigned long ioaddr)
398{
399 u32 value = readl(ioaddr + GMAC_CONTROL);
400 value |= GMAC_CORE_INIT;
401 writel(value, ioaddr + GMAC_CONTROL);
402
403 /* STBus Bridge Configuration */
404 /*writel(0xc5608, ioaddr + 0x00007000);*/
405
406 /* Freeze MMC counters */
407 writel(0x8, ioaddr + GMAC_MMC_CTRL);
408 /* Mask GMAC interrupts */
409 writel(0x207, ioaddr + GMAC_INT_MASK);
410
411#ifdef STMMAC_VLAN_TAG_USED
412 /* Tag detection without filtering */
413 writel(0x0, ioaddr + GMAC_VLAN_TAG);
414#endif
415 return;
416}
417
418static void gmac_set_umac_addr(unsigned long ioaddr, unsigned char *addr,
419 unsigned int reg_n)
420{
421 stmmac_set_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n),
422 GMAC_ADDR_LOW(reg_n));
423}
424
425static void gmac_get_umac_addr(unsigned long ioaddr, unsigned char *addr,
426 unsigned int reg_n)
427{
428 stmmac_get_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n),
429 GMAC_ADDR_LOW(reg_n));
430}
431
432static void gmac_set_filter(struct net_device *dev)
433{
434 unsigned long ioaddr = dev->base_addr;
435 unsigned int value = 0;
436
437 DBG(KERN_INFO "%s: # mcasts %d, # unicast %d\n",
438 __func__, dev->mc_count, dev->uc_count);
439
440 if (dev->flags & IFF_PROMISC)
441 value = GMAC_FRAME_FILTER_PR;
442 else if ((dev->mc_count > HASH_TABLE_SIZE)
443 || (dev->flags & IFF_ALLMULTI)) {
444 value = GMAC_FRAME_FILTER_PM; /* pass all multi */
445 writel(0xffffffff, ioaddr + GMAC_HASH_HIGH);
446 writel(0xffffffff, ioaddr + GMAC_HASH_LOW);
447 } else if (dev->mc_count > 0) {
448 int i;
449 u32 mc_filter[2];
450 struct dev_mc_list *mclist;
451
452 /* Hash filter for multicast */
453 value = GMAC_FRAME_FILTER_HMC;
454
455 memset(mc_filter, 0, sizeof(mc_filter));
456 for (i = 0, mclist = dev->mc_list;
457 mclist && i < dev->mc_count; i++, mclist = mclist->next) {
458 /* The upper 6 bits of the calculated CRC are used to
459 index the contens of the hash table */
460 int bit_nr =
461 bitrev32(~crc32_le(~0, mclist->dmi_addr, 6)) >> 26;
462 /* The most significant bit determines the register to
463 * use (H/L) while the other 5 bits determine the bit
464 * within the register. */
465 mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
466 }
467 writel(mc_filter[0], ioaddr + GMAC_HASH_LOW);
468 writel(mc_filter[1], ioaddr + GMAC_HASH_HIGH);
469 }
470
471 /* Handle multiple unicast addresses (perfect filtering)*/
472 if (dev->uc_count > GMAC_MAX_UNICAST_ADDRESSES)
473 /* Switch to promiscuous mode is more than 16 addrs
474 are required */
475 value |= GMAC_FRAME_FILTER_PR;
476 else {
477 int i;
478 struct dev_addr_list *uc_ptr = dev->uc_list;
479
480 for (i = 0; i < dev->uc_count; i++) {
481 gmac_set_umac_addr(ioaddr, uc_ptr->da_addr,
482 i + 1);
483
484 DBG(KERN_INFO "\t%d "
485 "- Unicast addr %02x:%02x:%02x:%02x:%02x:"
486 "%02x\n", i + 1,
487 uc_ptr->da_addr[0], uc_ptr->da_addr[1],
488 uc_ptr->da_addr[2], uc_ptr->da_addr[3],
489 uc_ptr->da_addr[4], uc_ptr->da_addr[5]);
490 uc_ptr = uc_ptr->next;
491 }
492 }
493
494#ifdef FRAME_FILTER_DEBUG
495 /* Enable Receive all mode (to debug filtering_fail errors) */
496 value |= GMAC_FRAME_FILTER_RA;
497#endif
498 writel(value, ioaddr + GMAC_FRAME_FILTER);
499
500 DBG(KERN_INFO "\tFrame Filter reg: 0x%08x\n\tHash regs: "
501 "HI 0x%08x, LO 0x%08x\n", readl(ioaddr + GMAC_FRAME_FILTER),
502 readl(ioaddr + GMAC_HASH_HIGH), readl(ioaddr + GMAC_HASH_LOW));
503
504 return;
505}
506
507static void gmac_flow_ctrl(unsigned long ioaddr, unsigned int duplex,
508 unsigned int fc, unsigned int pause_time)
509{
510 unsigned int flow = 0;
511
512 DBG(KERN_DEBUG "GMAC Flow-Control:\n");
513 if (fc & FLOW_RX) {
514 DBG(KERN_DEBUG "\tReceive Flow-Control ON\n");
515 flow |= GMAC_FLOW_CTRL_RFE;
516 }
517 if (fc & FLOW_TX) {
518 DBG(KERN_DEBUG "\tTransmit Flow-Control ON\n");
519 flow |= GMAC_FLOW_CTRL_TFE;
520 }
521
522 if (duplex) {
523 DBG(KERN_DEBUG "\tduplex mode: pause time: %d\n", pause_time);
524 flow |= (pause_time << GMAC_FLOW_CTRL_PT_SHIFT);
525 }
526
527 writel(flow, ioaddr + GMAC_FLOW_CTRL);
528 return;
529}
530
531static void gmac_pmt(unsigned long ioaddr, unsigned long mode)
532{
533 unsigned int pmt = 0;
534
535 if (mode == WAKE_MAGIC) {
536 DBG(KERN_DEBUG "GMAC: WOL Magic frame\n");
537 pmt |= power_down | magic_pkt_en;
538 } else if (mode == WAKE_UCAST) {
539 DBG(KERN_DEBUG "GMAC: WOL on global unicast\n");
540 pmt |= global_unicast;
541 }
542
543 writel(pmt, ioaddr + GMAC_PMT);
544 return;
545}
546
547static void gmac_init_rx_desc(struct dma_desc *p, unsigned int ring_size,
548 int disable_rx_ic)
549{
550 int i;
551 for (i = 0; i < ring_size; i++) {
552 p->des01.erx.own = 1;
553 p->des01.erx.buffer1_size = BUF_SIZE_8KiB - 1;
554 /* To support jumbo frames */
555 p->des01.erx.buffer2_size = BUF_SIZE_8KiB - 1;
556 if (i == ring_size - 1)
557 p->des01.erx.end_ring = 1;
558 if (disable_rx_ic)
559 p->des01.erx.disable_ic = 1;
560 p++;
561 }
562 return;
563}
564
565static void gmac_init_tx_desc(struct dma_desc *p, unsigned int ring_size)
566{
567 int i;
568
569 for (i = 0; i < ring_size; i++) {
570 p->des01.etx.own = 0;
571 if (i == ring_size - 1)
572 p->des01.etx.end_ring = 1;
573 p++;
574 }
575
576 return;
577}
578
579static int gmac_get_tx_owner(struct dma_desc *p)
580{
581 return p->des01.etx.own;
582}
583
584static int gmac_get_rx_owner(struct dma_desc *p)
585{
586 return p->des01.erx.own;
587}
588
589static void gmac_set_tx_owner(struct dma_desc *p)
590{
591 p->des01.etx.own = 1;
592}
593
594static void gmac_set_rx_owner(struct dma_desc *p)
595{
596 p->des01.erx.own = 1;
597}
598
599static int gmac_get_tx_ls(struct dma_desc *p)
600{
601 return p->des01.etx.last_segment;
602}
603
604static void gmac_release_tx_desc(struct dma_desc *p)
605{
606 int ter = p->des01.etx.end_ring;
607
608 memset(p, 0, sizeof(struct dma_desc));
609 p->des01.etx.end_ring = ter;
610
611 return;
612}
613
614static void gmac_prepare_tx_desc(struct dma_desc *p, int is_fs, int len,
615 int csum_flag)
616{
617 p->des01.etx.first_segment = is_fs;
618 if (unlikely(len > BUF_SIZE_4KiB)) {
619 p->des01.etx.buffer1_size = BUF_SIZE_4KiB;
620 p->des01.etx.buffer2_size = len - BUF_SIZE_4KiB;
621 } else {
622 p->des01.etx.buffer1_size = len;
623 }
624 if (likely(csum_flag))
625 p->des01.etx.checksum_insertion = cic_full;
626}
627
628static void gmac_clear_tx_ic(struct dma_desc *p)
629{
630 p->des01.etx.interrupt = 0;
631}
632
633static void gmac_close_tx_desc(struct dma_desc *p)
634{
635 p->des01.etx.last_segment = 1;
636 p->des01.etx.interrupt = 1;
637}
638
639static int gmac_get_rx_frame_len(struct dma_desc *p)
640{
641 return p->des01.erx.frame_length;
642}
643
644struct stmmac_ops gmac_driver = {
645 .core_init = gmac_core_init,
646 .dump_mac_regs = gmac_dump_regs,
647 .dma_init = gmac_dma_init,
648 .dump_dma_regs = gmac_dump_dma_regs,
649 .dma_mode = gmac_dma_operation_mode,
650 .dma_diagnostic_fr = gmac_dma_diagnostic_fr,
651 .tx_status = gmac_get_tx_frame_status,
652 .rx_status = gmac_get_rx_frame_status,
653 .get_tx_len = gmac_get_tx_len,
654 .set_filter = gmac_set_filter,
655 .flow_ctrl = gmac_flow_ctrl,
656 .pmt = gmac_pmt,
657 .init_rx_desc = gmac_init_rx_desc,
658 .init_tx_desc = gmac_init_tx_desc,
659 .get_tx_owner = gmac_get_tx_owner,
660 .get_rx_owner = gmac_get_rx_owner,
661 .release_tx_desc = gmac_release_tx_desc,
662 .prepare_tx_desc = gmac_prepare_tx_desc,
663 .clear_tx_ic = gmac_clear_tx_ic,
664 .close_tx_desc = gmac_close_tx_desc,
665 .get_tx_ls = gmac_get_tx_ls,
666 .set_tx_owner = gmac_set_tx_owner,
667 .set_rx_owner = gmac_set_rx_owner,
668 .get_rx_frame_len = gmac_get_rx_frame_len,
669 .host_irq_status = gmac_irq_status,
670 .set_umac_addr = gmac_set_umac_addr,
671 .get_umac_addr = gmac_get_umac_addr,
672};
673
674struct mac_device_info *gmac_setup(unsigned long ioaddr)
675{
676 struct mac_device_info *mac;
677 u32 uid = readl(ioaddr + GMAC_VERSION);
678
679 pr_info("\tGMAC - user ID: 0x%x, Synopsys ID: 0x%x\n",
680 ((uid & 0x0000ff00) >> 8), (uid & 0x000000ff));
681
682 mac = kzalloc(sizeof(const struct mac_device_info), GFP_KERNEL);
683
684 mac->ops = &gmac_driver;
685 mac->hw.pmt = PMT_SUPPORTED;
686 mac->hw.link.port = GMAC_CONTROL_PS;
687 mac->hw.link.duplex = GMAC_CONTROL_DM;
688 mac->hw.link.speed = GMAC_CONTROL_FES;
689 mac->hw.mii.addr = GMAC_MII_ADDR;
690 mac->hw.mii.data = GMAC_MII_DATA;
691
692 return mac;
693}
diff --git a/drivers/net/stmmac/gmac.h b/drivers/net/stmmac/gmac.h
new file mode 100644
index 000000000000..684a363120a9
--- /dev/null
+++ b/drivers/net/stmmac/gmac.h
@@ -0,0 +1,204 @@
1/*******************************************************************************
2 Copyright (C) 2007-2009 STMicroelectronics Ltd
3
4 This program is free software; you can redistribute it and/or modify it
5 under the terms and conditions of the GNU General Public License,
6 version 2, as published by the Free Software Foundation.
7
8 This program is distributed in the hope it will be useful, but WITHOUT
9 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 more details.
12
13 You should have received a copy of the GNU General Public License along with
14 this program; if not, write to the Free Software Foundation, Inc.,
15 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
16
17 The full GNU General Public License is included in this distribution in
18 the file called "COPYING".
19
20 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
21*******************************************************************************/
22
23#define GMAC_CONTROL 0x00000000 /* Configuration */
24#define GMAC_FRAME_FILTER 0x00000004 /* Frame Filter */
25#define GMAC_HASH_HIGH 0x00000008 /* Multicast Hash Table High */
26#define GMAC_HASH_LOW 0x0000000c /* Multicast Hash Table Low */
27#define GMAC_MII_ADDR 0x00000010 /* MII Address */
28#define GMAC_MII_DATA 0x00000014 /* MII Data */
29#define GMAC_FLOW_CTRL 0x00000018 /* Flow Control */
30#define GMAC_VLAN_TAG 0x0000001c /* VLAN Tag */
31#define GMAC_VERSION 0x00000020 /* GMAC CORE Version */
32#define GMAC_WAKEUP_FILTER 0x00000028 /* Wake-up Frame Filter */
33
34#define GMAC_INT_STATUS 0x00000038 /* interrupt status register */
35enum gmac_irq_status {
36 time_stamp_irq = 0x0200,
37 mmc_rx_csum_offload_irq = 0x0080,
38 mmc_tx_irq = 0x0040,
39 mmc_rx_irq = 0x0020,
40 mmc_irq = 0x0010,
41 pmt_irq = 0x0008,
42 pcs_ane_irq = 0x0004,
43 pcs_link_irq = 0x0002,
44 rgmii_irq = 0x0001,
45};
46#define GMAC_INT_MASK 0x0000003c /* interrupt mask register */
47
48/* PMT Control and Status */
49#define GMAC_PMT 0x0000002c
50enum power_event {
51 pointer_reset = 0x80000000,
52 global_unicast = 0x00000200,
53 wake_up_rx_frame = 0x00000040,
54 magic_frame = 0x00000020,
55 wake_up_frame_en = 0x00000004,
56 magic_pkt_en = 0x00000002,
57 power_down = 0x00000001,
58};
59
60/* GMAC HW ADDR regs */
61#define GMAC_ADDR_HIGH(reg) (0x00000040+(reg * 8))
62#define GMAC_ADDR_LOW(reg) (0x00000044+(reg * 8))
63#define GMAC_MAX_UNICAST_ADDRESSES 16
64
65#define GMAC_AN_CTRL 0x000000c0 /* AN control */
66#define GMAC_AN_STATUS 0x000000c4 /* AN status */
67#define GMAC_ANE_ADV 0x000000c8 /* Auto-Neg. Advertisement */
68#define GMAC_ANE_LINK 0x000000cc /* Auto-Neg. link partener ability */
69#define GMAC_ANE_EXP 0x000000d0 /* ANE expansion */
70#define GMAC_TBI 0x000000d4 /* TBI extend status */
71#define GMAC_GMII_STATUS 0x000000d8 /* S/R-GMII status */
72
73/* GMAC Configuration defines */
74#define GMAC_CONTROL_TC 0x01000000 /* Transmit Conf. in RGMII/SGMII */
75#define GMAC_CONTROL_WD 0x00800000 /* Disable Watchdog on receive */
76#define GMAC_CONTROL_JD 0x00400000 /* Jabber disable */
77#define GMAC_CONTROL_BE 0x00200000 /* Frame Burst Enable */
78#define GMAC_CONTROL_JE 0x00100000 /* Jumbo frame */
79enum inter_frame_gap {
80 GMAC_CONTROL_IFG_88 = 0x00040000,
81 GMAC_CONTROL_IFG_80 = 0x00020000,
82 GMAC_CONTROL_IFG_40 = 0x000e0000,
83};
84#define GMAC_CONTROL_DCRS 0x00010000 /* Disable carrier sense during tx */
85#define GMAC_CONTROL_PS 0x00008000 /* Port Select 0:GMI 1:MII */
86#define GMAC_CONTROL_FES 0x00004000 /* Speed 0:10 1:100 */
87#define GMAC_CONTROL_DO 0x00002000 /* Disable Rx Own */
88#define GMAC_CONTROL_LM 0x00001000 /* Loop-back mode */
89#define GMAC_CONTROL_DM 0x00000800 /* Duplex Mode */
90#define GMAC_CONTROL_IPC 0x00000400 /* Checksum Offload */
91#define GMAC_CONTROL_DR 0x00000200 /* Disable Retry */
92#define GMAC_CONTROL_LUD 0x00000100 /* Link up/down */
93#define GMAC_CONTROL_ACS 0x00000080 /* Automatic Pad Stripping */
94#define GMAC_CONTROL_DC 0x00000010 /* Deferral Check */
95#define GMAC_CONTROL_TE 0x00000008 /* Transmitter Enable */
96#define GMAC_CONTROL_RE 0x00000004 /* Receiver Enable */
97
98#define GMAC_CORE_INIT (GMAC_CONTROL_JD | GMAC_CONTROL_PS | GMAC_CONTROL_ACS | \
99 GMAC_CONTROL_IPC | GMAC_CONTROL_JE | GMAC_CONTROL_BE)
100
101/* GMAC Frame Filter defines */
102#define GMAC_FRAME_FILTER_PR 0x00000001 /* Promiscuous Mode */
103#define GMAC_FRAME_FILTER_HUC 0x00000002 /* Hash Unicast */
104#define GMAC_FRAME_FILTER_HMC 0x00000004 /* Hash Multicast */
105#define GMAC_FRAME_FILTER_DAIF 0x00000008 /* DA Inverse Filtering */
106#define GMAC_FRAME_FILTER_PM 0x00000010 /* Pass all multicast */
107#define GMAC_FRAME_FILTER_DBF 0x00000020 /* Disable Broadcast frames */
108#define GMAC_FRAME_FILTER_SAIF 0x00000100 /* Inverse Filtering */
109#define GMAC_FRAME_FILTER_SAF 0x00000200 /* Source Address Filter */
110#define GMAC_FRAME_FILTER_HPF 0x00000400 /* Hash or perfect Filter */
111#define GMAC_FRAME_FILTER_RA 0x80000000 /* Receive all mode */
112/* GMII ADDR defines */
113#define GMAC_MII_ADDR_WRITE 0x00000002 /* MII Write */
114#define GMAC_MII_ADDR_BUSY 0x00000001 /* MII Busy */
115/* GMAC FLOW CTRL defines */
116#define GMAC_FLOW_CTRL_PT_MASK 0xffff0000 /* Pause Time Mask */
117#define GMAC_FLOW_CTRL_PT_SHIFT 16
118#define GMAC_FLOW_CTRL_RFE 0x00000004 /* Rx Flow Control Enable */
119#define GMAC_FLOW_CTRL_TFE 0x00000002 /* Tx Flow Control Enable */
120#define GMAC_FLOW_CTRL_FCB_BPA 0x00000001 /* Flow Control Busy ... */
121
122/*--- DMA BLOCK defines ---*/
123/* DMA Bus Mode register defines */
124#define DMA_BUS_MODE_SFT_RESET 0x00000001 /* Software Reset */
125#define DMA_BUS_MODE_DA 0x00000002 /* Arbitration scheme */
126#define DMA_BUS_MODE_DSL_MASK 0x0000007c /* Descriptor Skip Length */
127#define DMA_BUS_MODE_DSL_SHIFT 2 /* (in DWORDS) */
128/* Programmable burst length (passed thorugh platform)*/
129#define DMA_BUS_MODE_PBL_MASK 0x00003f00 /* Programmable Burst Len */
130#define DMA_BUS_MODE_PBL_SHIFT 8
131
132enum rx_tx_priority_ratio {
133 double_ratio = 0x00004000, /*2:1 */
134 triple_ratio = 0x00008000, /*3:1 */
135 quadruple_ratio = 0x0000c000, /*4:1 */
136};
137
138#define DMA_BUS_MODE_FB 0x00010000 /* Fixed burst */
139#define DMA_BUS_MODE_RPBL_MASK 0x003e0000 /* Rx-Programmable Burst Len */
140#define DMA_BUS_MODE_RPBL_SHIFT 17
141#define DMA_BUS_MODE_USP 0x00800000
142#define DMA_BUS_MODE_4PBL 0x01000000
143#define DMA_BUS_MODE_AAL 0x02000000
144
145/* DMA CRS Control and Status Register Mapping */
146#define DMA_HOST_TX_DESC 0x00001048 /* Current Host Tx descriptor */
147#define DMA_HOST_RX_DESC 0x0000104c /* Current Host Rx descriptor */
148/* DMA Bus Mode register defines */
149#define DMA_BUS_PR_RATIO_MASK 0x0000c000 /* Rx/Tx priority ratio */
150#define DMA_BUS_PR_RATIO_SHIFT 14
151#define DMA_BUS_FB 0x00010000 /* Fixed Burst */
152
153/* DMA operation mode defines (start/stop tx/rx are placed in common header)*/
154#define DMA_CONTROL_DT 0x04000000 /* Disable Drop TCP/IP csum error */
155#define DMA_CONTROL_RSF 0x02000000 /* Receive Store and Forward */
156#define DMA_CONTROL_DFF 0x01000000 /* Disaable flushing */
157/* Theshold for Activating the FC */
158enum rfa {
159 act_full_minus_1 = 0x00800000,
160 act_full_minus_2 = 0x00800200,
161 act_full_minus_3 = 0x00800400,
162 act_full_minus_4 = 0x00800600,
163};
164/* Theshold for Deactivating the FC */
165enum rfd {
166 deac_full_minus_1 = 0x00400000,
167 deac_full_minus_2 = 0x00400800,
168 deac_full_minus_3 = 0x00401000,
169 deac_full_minus_4 = 0x00401800,
170};
171#define DMA_CONTROL_TSF 0x00200000 /* Transmit Store and Forward */
172#define DMA_CONTROL_FTF 0x00100000 /* Flush transmit FIFO */
173
174enum ttc_control {
175 DMA_CONTROL_TTC_64 = 0x00000000,
176 DMA_CONTROL_TTC_128 = 0x00004000,
177 DMA_CONTROL_TTC_192 = 0x00008000,
178 DMA_CONTROL_TTC_256 = 0x0000c000,
179 DMA_CONTROL_TTC_40 = 0x00010000,
180 DMA_CONTROL_TTC_32 = 0x00014000,
181 DMA_CONTROL_TTC_24 = 0x00018000,
182 DMA_CONTROL_TTC_16 = 0x0001c000,
183};
184#define DMA_CONTROL_TC_TX_MASK 0xfffe3fff
185
186#define DMA_CONTROL_EFC 0x00000100
187#define DMA_CONTROL_FEF 0x00000080
188#define DMA_CONTROL_FUF 0x00000040
189
190enum rtc_control {
191 DMA_CONTROL_RTC_64 = 0x00000000,
192 DMA_CONTROL_RTC_32 = 0x00000008,
193 DMA_CONTROL_RTC_96 = 0x00000010,
194 DMA_CONTROL_RTC_128 = 0x00000018,
195};
196#define DMA_CONTROL_TC_RX_MASK 0xffffffe7
197
198#define DMA_CONTROL_OSF 0x00000004 /* Operate on second frame */
199
200/* MMC registers offset */
201#define GMAC_MMC_CTRL 0x100
202#define GMAC_MMC_RX_INTR 0x104
203#define GMAC_MMC_TX_INTR 0x108
204#define GMAC_MMC_RX_CSUM_OFFLOAD 0x208
diff --git a/drivers/net/stmmac/mac100.c b/drivers/net/stmmac/mac100.c
new file mode 100644
index 000000000000..625171b6062b
--- /dev/null
+++ b/drivers/net/stmmac/mac100.c
@@ -0,0 +1,517 @@
1/*******************************************************************************
2 This is the driver for the MAC 10/100 on-chip Ethernet controller
3 currently tested on all the ST boards based on STb7109 and stx7200 SoCs.
4
5 DWC Ether MAC 10/100 Universal version 4.0 has been used for developing
6 this code.
7
8 Copyright (C) 2007-2009 STMicroelectronics Ltd
9
10 This program is free software; you can redistribute it and/or modify it
11 under the terms and conditions of the GNU General Public License,
12 version 2, as published by the Free Software Foundation.
13
14 This program is distributed in the hope it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 more details.
18
19 You should have received a copy of the GNU General Public License along with
20 this program; if not, write to the Free Software Foundation, Inc.,
21 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
22
23 The full GNU General Public License is included in this distribution in
24 the file called "COPYING".
25
26 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
27*******************************************************************************/
28
29#include <linux/netdevice.h>
30#include <linux/crc32.h>
31#include <linux/mii.h>
32#include <linux/phy.h>
33
34#include "common.h"
35#include "mac100.h"
36
37#undef MAC100_DEBUG
38/*#define MAC100_DEBUG*/
39#ifdef MAC100_DEBUG
40#define DBG(fmt, args...) printk(fmt, ## args)
41#else
42#define DBG(fmt, args...) do { } while (0)
43#endif
44
45static void mac100_core_init(unsigned long ioaddr)
46{
47 u32 value = readl(ioaddr + MAC_CONTROL);
48
49 writel((value | MAC_CORE_INIT), ioaddr + MAC_CONTROL);
50
51#ifdef STMMAC_VLAN_TAG_USED
52 writel(ETH_P_8021Q, ioaddr + MAC_VLAN1);
53#endif
54 return;
55}
56
57static void mac100_dump_mac_regs(unsigned long ioaddr)
58{
59 pr_info("\t----------------------------------------------\n"
60 "\t MAC100 CSR (base addr = 0x%8x)\n"
61 "\t----------------------------------------------\n",
62 (unsigned int)ioaddr);
63 pr_info("\tcontrol reg (offset 0x%x): 0x%08x\n", MAC_CONTROL,
64 readl(ioaddr + MAC_CONTROL));
65 pr_info("\taddr HI (offset 0x%x): 0x%08x\n ", MAC_ADDR_HIGH,
66 readl(ioaddr + MAC_ADDR_HIGH));
67 pr_info("\taddr LO (offset 0x%x): 0x%08x\n", MAC_ADDR_LOW,
68 readl(ioaddr + MAC_ADDR_LOW));
69 pr_info("\tmulticast hash HI (offset 0x%x): 0x%08x\n",
70 MAC_HASH_HIGH, readl(ioaddr + MAC_HASH_HIGH));
71 pr_info("\tmulticast hash LO (offset 0x%x): 0x%08x\n",
72 MAC_HASH_LOW, readl(ioaddr + MAC_HASH_LOW));
73 pr_info("\tflow control (offset 0x%x): 0x%08x\n",
74 MAC_FLOW_CTRL, readl(ioaddr + MAC_FLOW_CTRL));
75 pr_info("\tVLAN1 tag (offset 0x%x): 0x%08x\n", MAC_VLAN1,
76 readl(ioaddr + MAC_VLAN1));
77 pr_info("\tVLAN2 tag (offset 0x%x): 0x%08x\n", MAC_VLAN2,
78 readl(ioaddr + MAC_VLAN2));
79 pr_info("\n\tMAC management counter registers\n");
80 pr_info("\t MMC crtl (offset 0x%x): 0x%08x\n",
81 MMC_CONTROL, readl(ioaddr + MMC_CONTROL));
82 pr_info("\t MMC High Interrupt (offset 0x%x): 0x%08x\n",
83 MMC_HIGH_INTR, readl(ioaddr + MMC_HIGH_INTR));
84 pr_info("\t MMC Low Interrupt (offset 0x%x): 0x%08x\n",
85 MMC_LOW_INTR, readl(ioaddr + MMC_LOW_INTR));
86 pr_info("\t MMC High Interrupt Mask (offset 0x%x): 0x%08x\n",
87 MMC_HIGH_INTR_MASK, readl(ioaddr + MMC_HIGH_INTR_MASK));
88 pr_info("\t MMC Low Interrupt Mask (offset 0x%x): 0x%08x\n",
89 MMC_LOW_INTR_MASK, readl(ioaddr + MMC_LOW_INTR_MASK));
90 return;
91}
92
93static int mac100_dma_init(unsigned long ioaddr, int pbl, u32 dma_tx,
94 u32 dma_rx)
95{
96 u32 value = readl(ioaddr + DMA_BUS_MODE);
97 /* DMA SW reset */
98 value |= DMA_BUS_MODE_SFT_RESET;
99 writel(value, ioaddr + DMA_BUS_MODE);
100 do {} while ((readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET));
101
102 /* Enable Application Access by writing to DMA CSR0 */
103 writel(DMA_BUS_MODE_DEFAULT | (pbl << DMA_BUS_MODE_PBL_SHIFT),
104 ioaddr + DMA_BUS_MODE);
105
106 /* Mask interrupts by writing to CSR7 */
107 writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA);
108
109 /* The base address of the RX/TX descriptor lists must be written into
110 * DMA CSR3 and CSR4, respectively. */
111 writel(dma_tx, ioaddr + DMA_TX_BASE_ADDR);
112 writel(dma_rx, ioaddr + DMA_RCV_BASE_ADDR);
113
114 return 0;
115}
116
117/* Store and Forward capability is not used at all..
118 * The transmit threshold can be programmed by
119 * setting the TTC bits in the DMA control register.*/
120static void mac100_dma_operation_mode(unsigned long ioaddr, int txmode,
121 int rxmode)
122{
123 u32 csr6 = readl(ioaddr + DMA_CONTROL);
124
125 if (txmode <= 32)
126 csr6 |= DMA_CONTROL_TTC_32;
127 else if (txmode <= 64)
128 csr6 |= DMA_CONTROL_TTC_64;
129 else
130 csr6 |= DMA_CONTROL_TTC_128;
131
132 writel(csr6, ioaddr + DMA_CONTROL);
133
134 return;
135}
136
137static void mac100_dump_dma_regs(unsigned long ioaddr)
138{
139 int i;
140
141 DBG(KERN_DEBUG "MAC100 DMA CSR \n");
142 for (i = 0; i < 9; i++)
143 pr_debug("\t CSR%d (offset 0x%x): 0x%08x\n", i,
144 (DMA_BUS_MODE + i * 4),
145 readl(ioaddr + DMA_BUS_MODE + i * 4));
146 DBG(KERN_DEBUG "\t CSR20 (offset 0x%x): 0x%08x\n",
147 DMA_CUR_TX_BUF_ADDR, readl(ioaddr + DMA_CUR_TX_BUF_ADDR));
148 DBG(KERN_DEBUG "\t CSR21 (offset 0x%x): 0x%08x\n",
149 DMA_CUR_RX_BUF_ADDR, readl(ioaddr + DMA_CUR_RX_BUF_ADDR));
150 return;
151}
152
153/* DMA controller has two counters to track the number of
154 the receive missed frames. */
155static void mac100_dma_diagnostic_fr(void *data, struct stmmac_extra_stats *x,
156 unsigned long ioaddr)
157{
158 struct net_device_stats *stats = (struct net_device_stats *)data;
159 u32 csr8 = readl(ioaddr + DMA_MISSED_FRAME_CTR);
160
161 if (unlikely(csr8)) {
162 if (csr8 & DMA_MISSED_FRAME_OVE) {
163 stats->rx_over_errors += 0x800;
164 x->rx_overflow_cntr += 0x800;
165 } else {
166 unsigned int ove_cntr;
167 ove_cntr = ((csr8 & DMA_MISSED_FRAME_OVE_CNTR) >> 17);
168 stats->rx_over_errors += ove_cntr;
169 x->rx_overflow_cntr += ove_cntr;
170 }
171
172 if (csr8 & DMA_MISSED_FRAME_OVE_M) {
173 stats->rx_missed_errors += 0xffff;
174 x->rx_missed_cntr += 0xffff;
175 } else {
176 unsigned int miss_f = (csr8 & DMA_MISSED_FRAME_M_CNTR);
177 stats->rx_missed_errors += miss_f;
178 x->rx_missed_cntr += miss_f;
179 }
180 }
181 return;
182}
183
184static int mac100_get_tx_frame_status(void *data, struct stmmac_extra_stats *x,
185 struct dma_desc *p, unsigned long ioaddr)
186{
187 int ret = 0;
188 struct net_device_stats *stats = (struct net_device_stats *)data;
189
190 if (unlikely(p->des01.tx.error_summary)) {
191 if (unlikely(p->des01.tx.underflow_error)) {
192 x->tx_underflow++;
193 stats->tx_fifo_errors++;
194 }
195 if (unlikely(p->des01.tx.no_carrier)) {
196 x->tx_carrier++;
197 stats->tx_carrier_errors++;
198 }
199 if (unlikely(p->des01.tx.loss_carrier)) {
200 x->tx_losscarrier++;
201 stats->tx_carrier_errors++;
202 }
203 if (unlikely((p->des01.tx.excessive_deferral) ||
204 (p->des01.tx.excessive_collisions) ||
205 (p->des01.tx.late_collision)))
206 stats->collisions += p->des01.tx.collision_count;
207 ret = -1;
208 }
209 if (unlikely(p->des01.tx.heartbeat_fail)) {
210 x->tx_heartbeat++;
211 stats->tx_heartbeat_errors++;
212 ret = -1;
213 }
214 if (unlikely(p->des01.tx.deferred))
215 x->tx_deferred++;
216
217 return ret;
218}
219
220static int mac100_get_tx_len(struct dma_desc *p)
221{
222 return p->des01.tx.buffer1_size;
223}
224
225/* This function verifies if each incoming frame has some errors
226 * and, if required, updates the multicast statistics.
227 * In case of success, it returns csum_none becasue the device
228 * is not able to compute the csum in HW. */
229static int mac100_get_rx_frame_status(void *data, struct stmmac_extra_stats *x,
230 struct dma_desc *p)
231{
232 int ret = csum_none;
233 struct net_device_stats *stats = (struct net_device_stats *)data;
234
235 if (unlikely(p->des01.rx.last_descriptor == 0)) {
236 pr_warning("mac100 Error: Oversized Ethernet "
237 "frame spanned multiple buffers\n");
238 stats->rx_length_errors++;
239 return discard_frame;
240 }
241
242 if (unlikely(p->des01.rx.error_summary)) {
243 if (unlikely(p->des01.rx.descriptor_error))
244 x->rx_desc++;
245 if (unlikely(p->des01.rx.partial_frame_error))
246 x->rx_partial++;
247 if (unlikely(p->des01.rx.run_frame))
248 x->rx_runt++;
249 if (unlikely(p->des01.rx.frame_too_long))
250 x->rx_toolong++;
251 if (unlikely(p->des01.rx.collision)) {
252 x->rx_collision++;
253 stats->collisions++;
254 }
255 if (unlikely(p->des01.rx.crc_error)) {
256 x->rx_crc++;
257 stats->rx_crc_errors++;
258 }
259 ret = discard_frame;
260 }
261 if (unlikely(p->des01.rx.dribbling))
262 ret = discard_frame;
263
264 if (unlikely(p->des01.rx.length_error)) {
265 x->rx_lenght++;
266 ret = discard_frame;
267 }
268 if (unlikely(p->des01.rx.mii_error)) {
269 x->rx_mii++;
270 ret = discard_frame;
271 }
272 if (p->des01.rx.multicast_frame) {
273 x->rx_multicast++;
274 stats->multicast++;
275 }
276 return ret;
277}
278
279static void mac100_irq_status(unsigned long ioaddr)
280{
281 return;
282}
283
284static void mac100_set_umac_addr(unsigned long ioaddr, unsigned char *addr,
285 unsigned int reg_n)
286{
287 stmmac_set_mac_addr(ioaddr, addr, MAC_ADDR_HIGH, MAC_ADDR_LOW);
288}
289
290static void mac100_get_umac_addr(unsigned long ioaddr, unsigned char *addr,
291 unsigned int reg_n)
292{
293 stmmac_get_mac_addr(ioaddr, addr, MAC_ADDR_HIGH, MAC_ADDR_LOW);
294}
295
296static void mac100_set_filter(struct net_device *dev)
297{
298 unsigned long ioaddr = dev->base_addr;
299 u32 value = readl(ioaddr + MAC_CONTROL);
300
301 if (dev->flags & IFF_PROMISC) {
302 value |= MAC_CONTROL_PR;
303 value &= ~(MAC_CONTROL_PM | MAC_CONTROL_IF | MAC_CONTROL_HO |
304 MAC_CONTROL_HP);
305 } else if ((dev->mc_count > HASH_TABLE_SIZE)
306 || (dev->flags & IFF_ALLMULTI)) {
307 value |= MAC_CONTROL_PM;
308 value &= ~(MAC_CONTROL_PR | MAC_CONTROL_IF | MAC_CONTROL_HO);
309 writel(0xffffffff, ioaddr + MAC_HASH_HIGH);
310 writel(0xffffffff, ioaddr + MAC_HASH_LOW);
311 } else if (dev->mc_count == 0) { /* no multicast */
312 value &= ~(MAC_CONTROL_PM | MAC_CONTROL_PR | MAC_CONTROL_IF |
313 MAC_CONTROL_HO | MAC_CONTROL_HP);
314 } else {
315 int i;
316 u32 mc_filter[2];
317 struct dev_mc_list *mclist;
318
319 /* Perfect filter mode for physical address and Hash
320 filter for multicast */
321 value |= MAC_CONTROL_HP;
322 value &= ~(MAC_CONTROL_PM | MAC_CONTROL_PR | MAC_CONTROL_IF
323 | MAC_CONTROL_HO);
324
325 memset(mc_filter, 0, sizeof(mc_filter));
326 for (i = 0, mclist = dev->mc_list;
327 mclist && i < dev->mc_count; i++, mclist = mclist->next) {
328 /* The upper 6 bits of the calculated CRC are used to
329 * index the contens of the hash table */
330 int bit_nr =
331 ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
332 /* The most significant bit determines the register to
333 * use (H/L) while the other 5 bits determine the bit
334 * within the register. */
335 mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
336 }
337 writel(mc_filter[0], ioaddr + MAC_HASH_LOW);
338 writel(mc_filter[1], ioaddr + MAC_HASH_HIGH);
339 }
340
341 writel(value, ioaddr + MAC_CONTROL);
342
343 DBG(KERN_INFO "%s: CTRL reg: 0x%08x Hash regs: "
344 "HI 0x%08x, LO 0x%08x\n",
345 __func__, readl(ioaddr + MAC_CONTROL),
346 readl(ioaddr + MAC_HASH_HIGH), readl(ioaddr + MAC_HASH_LOW));
347 return;
348}
349
350static void mac100_flow_ctrl(unsigned long ioaddr, unsigned int duplex,
351 unsigned int fc, unsigned int pause_time)
352{
353 unsigned int flow = MAC_FLOW_CTRL_ENABLE;
354
355 if (duplex)
356 flow |= (pause_time << MAC_FLOW_CTRL_PT_SHIFT);
357 writel(flow, ioaddr + MAC_FLOW_CTRL);
358
359 return;
360}
361
362/* No PMT module supported in our SoC for the Ethernet Controller. */
363static void mac100_pmt(unsigned long ioaddr, unsigned long mode)
364{
365 return;
366}
367
368static void mac100_init_rx_desc(struct dma_desc *p, unsigned int ring_size,
369 int disable_rx_ic)
370{
371 int i;
372 for (i = 0; i < ring_size; i++) {
373 p->des01.rx.own = 1;
374 p->des01.rx.buffer1_size = BUF_SIZE_2KiB - 1;
375 if (i == ring_size - 1)
376 p->des01.rx.end_ring = 1;
377 if (disable_rx_ic)
378 p->des01.rx.disable_ic = 1;
379 p++;
380 }
381 return;
382}
383
384static void mac100_init_tx_desc(struct dma_desc *p, unsigned int ring_size)
385{
386 int i;
387 for (i = 0; i < ring_size; i++) {
388 p->des01.tx.own = 0;
389 if (i == ring_size - 1)
390 p->des01.tx.end_ring = 1;
391 p++;
392 }
393 return;
394}
395
396static int mac100_get_tx_owner(struct dma_desc *p)
397{
398 return p->des01.tx.own;
399}
400
401static int mac100_get_rx_owner(struct dma_desc *p)
402{
403 return p->des01.rx.own;
404}
405
406static void mac100_set_tx_owner(struct dma_desc *p)
407{
408 p->des01.tx.own = 1;
409}
410
411static void mac100_set_rx_owner(struct dma_desc *p)
412{
413 p->des01.rx.own = 1;
414}
415
416static int mac100_get_tx_ls(struct dma_desc *p)
417{
418 return p->des01.tx.last_segment;
419}
420
421static void mac100_release_tx_desc(struct dma_desc *p)
422{
423 int ter = p->des01.tx.end_ring;
424
425 /* clean field used within the xmit */
426 p->des01.tx.first_segment = 0;
427 p->des01.tx.last_segment = 0;
428 p->des01.tx.buffer1_size = 0;
429
430 /* clean status reported */
431 p->des01.tx.error_summary = 0;
432 p->des01.tx.underflow_error = 0;
433 p->des01.tx.no_carrier = 0;
434 p->des01.tx.loss_carrier = 0;
435 p->des01.tx.excessive_deferral = 0;
436 p->des01.tx.excessive_collisions = 0;
437 p->des01.tx.late_collision = 0;
438 p->des01.tx.heartbeat_fail = 0;
439 p->des01.tx.deferred = 0;
440
441 /* set termination field */
442 p->des01.tx.end_ring = ter;
443
444 return;
445}
446
447static void mac100_prepare_tx_desc(struct dma_desc *p, int is_fs, int len,
448 int csum_flag)
449{
450 p->des01.tx.first_segment = is_fs;
451 p->des01.tx.buffer1_size = len;
452}
453
454static void mac100_clear_tx_ic(struct dma_desc *p)
455{
456 p->des01.tx.interrupt = 0;
457}
458
459static void mac100_close_tx_desc(struct dma_desc *p)
460{
461 p->des01.tx.last_segment = 1;
462 p->des01.tx.interrupt = 1;
463}
464
465static int mac100_get_rx_frame_len(struct dma_desc *p)
466{
467 return p->des01.rx.frame_length;
468}
469
470struct stmmac_ops mac100_driver = {
471 .core_init = mac100_core_init,
472 .dump_mac_regs = mac100_dump_mac_regs,
473 .dma_init = mac100_dma_init,
474 .dump_dma_regs = mac100_dump_dma_regs,
475 .dma_mode = mac100_dma_operation_mode,
476 .dma_diagnostic_fr = mac100_dma_diagnostic_fr,
477 .tx_status = mac100_get_tx_frame_status,
478 .rx_status = mac100_get_rx_frame_status,
479 .get_tx_len = mac100_get_tx_len,
480 .set_filter = mac100_set_filter,
481 .flow_ctrl = mac100_flow_ctrl,
482 .pmt = mac100_pmt,
483 .init_rx_desc = mac100_init_rx_desc,
484 .init_tx_desc = mac100_init_tx_desc,
485 .get_tx_owner = mac100_get_tx_owner,
486 .get_rx_owner = mac100_get_rx_owner,
487 .release_tx_desc = mac100_release_tx_desc,
488 .prepare_tx_desc = mac100_prepare_tx_desc,
489 .clear_tx_ic = mac100_clear_tx_ic,
490 .close_tx_desc = mac100_close_tx_desc,
491 .get_tx_ls = mac100_get_tx_ls,
492 .set_tx_owner = mac100_set_tx_owner,
493 .set_rx_owner = mac100_set_rx_owner,
494 .get_rx_frame_len = mac100_get_rx_frame_len,
495 .host_irq_status = mac100_irq_status,
496 .set_umac_addr = mac100_set_umac_addr,
497 .get_umac_addr = mac100_get_umac_addr,
498};
499
500struct mac_device_info *mac100_setup(unsigned long ioaddr)
501{
502 struct mac_device_info *mac;
503
504 mac = kzalloc(sizeof(const struct mac_device_info), GFP_KERNEL);
505
506 pr_info("\tMAC 10/100\n");
507
508 mac->ops = &mac100_driver;
509 mac->hw.pmt = PMT_NOT_SUPPORTED;
510 mac->hw.link.port = MAC_CONTROL_PS;
511 mac->hw.link.duplex = MAC_CONTROL_F;
512 mac->hw.link.speed = 0;
513 mac->hw.mii.addr = MAC_MII_ADDR;
514 mac->hw.mii.data = MAC_MII_DATA;
515
516 return mac;
517}
diff --git a/drivers/net/stmmac/mac100.h b/drivers/net/stmmac/mac100.h
new file mode 100644
index 000000000000..0f8f110d004a
--- /dev/null
+++ b/drivers/net/stmmac/mac100.h
@@ -0,0 +1,116 @@
1/*******************************************************************************
2 MAC 10/100 Header File
3
4 Copyright (C) 2007-2009 STMicroelectronics Ltd
5
6 This program is free software; you can redistribute it and/or modify it
7 under the terms and conditions of the GNU General Public License,
8 version 2, as published by the Free Software Foundation.
9
10 This program is distributed in the hope it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 more details.
14
15 You should have received a copy of the GNU General Public License along with
16 this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18
19 The full GNU General Public License is included in this distribution in
20 the file called "COPYING".
21
22 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
23*******************************************************************************/
24
25/*----------------------------------------------------------------------------
26 * MAC BLOCK defines
27 *---------------------------------------------------------------------------*/
28/* MAC CSR offset */
29#define MAC_CONTROL 0x00000000 /* MAC Control */
30#define MAC_ADDR_HIGH 0x00000004 /* MAC Address High */
31#define MAC_ADDR_LOW 0x00000008 /* MAC Address Low */
32#define MAC_HASH_HIGH 0x0000000c /* Multicast Hash Table High */
33#define MAC_HASH_LOW 0x00000010 /* Multicast Hash Table Low */
34#define MAC_MII_ADDR 0x00000014 /* MII Address */
35#define MAC_MII_DATA 0x00000018 /* MII Data */
36#define MAC_FLOW_CTRL 0x0000001c /* Flow Control */
37#define MAC_VLAN1 0x00000020 /* VLAN1 Tag */
38#define MAC_VLAN2 0x00000024 /* VLAN2 Tag */
39
40/* MAC CTRL defines */
41#define MAC_CONTROL_RA 0x80000000 /* Receive All Mode */
42#define MAC_CONTROL_BLE 0x40000000 /* Endian Mode */
43#define MAC_CONTROL_HBD 0x10000000 /* Heartbeat Disable */
44#define MAC_CONTROL_PS 0x08000000 /* Port Select */
45#define MAC_CONTROL_DRO 0x00800000 /* Disable Receive Own */
46#define MAC_CONTROL_EXT_LOOPBACK 0x00400000 /* Reserved (ext loopback?) */
47#define MAC_CONTROL_OM 0x00200000 /* Loopback Operating Mode */
48#define MAC_CONTROL_F 0x00100000 /* Full Duplex Mode */
49#define MAC_CONTROL_PM 0x00080000 /* Pass All Multicast */
50#define MAC_CONTROL_PR 0x00040000 /* Promiscuous Mode */
51#define MAC_CONTROL_IF 0x00020000 /* Inverse Filtering */
52#define MAC_CONTROL_PB 0x00010000 /* Pass Bad Frames */
53#define MAC_CONTROL_HO 0x00008000 /* Hash Only Filtering Mode */
54#define MAC_CONTROL_HP 0x00002000 /* Hash/Perfect Filtering Mode */
55#define MAC_CONTROL_LCC 0x00001000 /* Late Collision Control */
56#define MAC_CONTROL_DBF 0x00000800 /* Disable Broadcast Frames */
57#define MAC_CONTROL_DRTY 0x00000400 /* Disable Retry */
58#define MAC_CONTROL_ASTP 0x00000100 /* Automatic Pad Stripping */
59#define MAC_CONTROL_BOLMT_10 0x00000000 /* Back Off Limit 10 */
60#define MAC_CONTROL_BOLMT_8 0x00000040 /* Back Off Limit 8 */
61#define MAC_CONTROL_BOLMT_4 0x00000080 /* Back Off Limit 4 */
62#define MAC_CONTROL_BOLMT_1 0x000000c0 /* Back Off Limit 1 */
63#define MAC_CONTROL_DC 0x00000020 /* Deferral Check */
64#define MAC_CONTROL_TE 0x00000008 /* Transmitter Enable */
65#define MAC_CONTROL_RE 0x00000004 /* Receiver Enable */
66
67#define MAC_CORE_INIT (MAC_CONTROL_HBD | MAC_CONTROL_ASTP)
68
69/* MAC FLOW CTRL defines */
70#define MAC_FLOW_CTRL_PT_MASK 0xffff0000 /* Pause Time Mask */
71#define MAC_FLOW_CTRL_PT_SHIFT 16
72#define MAC_FLOW_CTRL_PASS 0x00000004 /* Pass Control Frames */
73#define MAC_FLOW_CTRL_ENABLE 0x00000002 /* Flow Control Enable */
74#define MAC_FLOW_CTRL_PAUSE 0x00000001 /* Flow Control Busy ... */
75
76/* MII ADDR defines */
77#define MAC_MII_ADDR_WRITE 0x00000002 /* MII Write */
78#define MAC_MII_ADDR_BUSY 0x00000001 /* MII Busy */
79
80/*----------------------------------------------------------------------------
81 * DMA BLOCK defines
82 *---------------------------------------------------------------------------*/
83
84/* DMA Bus Mode register defines */
85#define DMA_BUS_MODE_DBO 0x00100000 /* Descriptor Byte Ordering */
86#define DMA_BUS_MODE_BLE 0x00000080 /* Big Endian/Little Endian */
87#define DMA_BUS_MODE_PBL_MASK 0x00003f00 /* Programmable Burst Len */
88#define DMA_BUS_MODE_PBL_SHIFT 8
89#define DMA_BUS_MODE_DSL_MASK 0x0000007c /* Descriptor Skip Length */
90#define DMA_BUS_MODE_DSL_SHIFT 2 /* (in DWORDS) */
91#define DMA_BUS_MODE_BAR_BUS 0x00000002 /* Bar-Bus Arbitration */
92#define DMA_BUS_MODE_SFT_RESET 0x00000001 /* Software Reset */
93#define DMA_BUS_MODE_DEFAULT 0x00000000
94
95/* DMA Control register defines */
96#define DMA_CONTROL_SF 0x00200000 /* Store And Forward */
97
98/* Transmit Threshold Control */
99enum ttc_control {
100 DMA_CONTROL_TTC_DEFAULT = 0x00000000, /* Threshold is 32 DWORDS */
101 DMA_CONTROL_TTC_64 = 0x00004000, /* Threshold is 64 DWORDS */
102 DMA_CONTROL_TTC_128 = 0x00008000, /* Threshold is 128 DWORDS */
103 DMA_CONTROL_TTC_256 = 0x0000c000, /* Threshold is 256 DWORDS */
104 DMA_CONTROL_TTC_18 = 0x00400000, /* Threshold is 18 DWORDS */
105 DMA_CONTROL_TTC_24 = 0x00404000, /* Threshold is 24 DWORDS */
106 DMA_CONTROL_TTC_32 = 0x00408000, /* Threshold is 32 DWORDS */
107 DMA_CONTROL_TTC_40 = 0x0040c000, /* Threshold is 40 DWORDS */
108 DMA_CONTROL_SE = 0x00000008, /* Stop On Empty */
109 DMA_CONTROL_OSF = 0x00000004, /* Operate On 2nd Frame */
110};
111
112/* STMAC110 DMA Missed Frame Counter register defines */
113#define DMA_MISSED_FRAME_OVE 0x10000000 /* FIFO Overflow Overflow */
114#define DMA_MISSED_FRAME_OVE_CNTR 0x0ffe0000 /* Overflow Frame Counter */
115#define DMA_MISSED_FRAME_OVE_M 0x00010000 /* Missed Frame Overflow */
116#define DMA_MISSED_FRAME_M_CNTR 0x0000ffff /* Missed Frame Couinter */
diff --git a/drivers/net/stmmac/stmmac.h b/drivers/net/stmmac/stmmac.h
new file mode 100644
index 000000000000..6d2eae3040e5
--- /dev/null
+++ b/drivers/net/stmmac/stmmac.h
@@ -0,0 +1,98 @@
1/*******************************************************************************
2 Copyright (C) 2007-2009 STMicroelectronics Ltd
3
4 This program is free software; you can redistribute it and/or modify it
5 under the terms and conditions of the GNU General Public License,
6 version 2, as published by the Free Software Foundation.
7
8 This program is distributed in the hope it will be useful, but WITHOUT
9 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 more details.
12
13 You should have received a copy of the GNU General Public License along with
14 this program; if not, write to the Free Software Foundation, Inc.,
15 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
16
17 The full GNU General Public License is included in this distribution in
18 the file called "COPYING".
19
20 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
21*******************************************************************************/
22
23#define DRV_MODULE_VERSION "Oct_09"
24
25#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
26#define STMMAC_VLAN_TAG_USED
27#include <linux/if_vlan.h>
28#endif
29
30#include "common.h"
31#ifdef CONFIG_STMMAC_TIMER
32#include "stmmac_timer.h"
33#endif
34
35struct stmmac_priv {
36 /* Frequently used values are kept adjacent for cache effect */
37 struct dma_desc *dma_tx ____cacheline_aligned;
38 dma_addr_t dma_tx_phy;
39 struct sk_buff **tx_skbuff;
40 unsigned int cur_tx;
41 unsigned int dirty_tx;
42 unsigned int dma_tx_size;
43 int tx_coe;
44 int tx_coalesce;
45
46 struct dma_desc *dma_rx ;
47 unsigned int cur_rx;
48 unsigned int dirty_rx;
49 struct sk_buff **rx_skbuff;
50 dma_addr_t *rx_skbuff_dma;
51 struct sk_buff_head rx_recycle;
52
53 struct net_device *dev;
54 int is_gmac;
55 dma_addr_t dma_rx_phy;
56 unsigned int dma_rx_size;
57 int rx_csum;
58 unsigned int dma_buf_sz;
59 struct device *device;
60 struct mac_device_info *mac_type;
61
62 struct stmmac_extra_stats xstats;
63 struct napi_struct napi;
64
65 phy_interface_t phy_interface;
66 int pbl;
67 int bus_id;
68 int phy_addr;
69 int phy_mask;
70 int (*phy_reset) (void *priv);
71 void (*fix_mac_speed) (void *priv, unsigned int speed);
72 void *bsp_priv;
73
74 int phy_irq;
75 struct phy_device *phydev;
76 int oldlink;
77 int speed;
78 int oldduplex;
79 unsigned int flow_ctrl;
80 unsigned int pause;
81 struct mii_bus *mii;
82
83 u32 msg_enable;
84 spinlock_t lock;
85 int wolopts;
86 int wolenabled;
87 int shutdown;
88#ifdef CONFIG_STMMAC_TIMER
89 struct stmmac_timer *tm;
90#endif
91#ifdef STMMAC_VLAN_TAG_USED
92 struct vlan_group *vlgrp;
93#endif
94};
95
96extern int stmmac_mdio_unregister(struct net_device *ndev);
97extern int stmmac_mdio_register(struct net_device *ndev);
98extern void stmmac_set_ethtool_ops(struct net_device *netdev);
diff --git a/drivers/net/stmmac/stmmac_ethtool.c b/drivers/net/stmmac/stmmac_ethtool.c
new file mode 100644
index 000000000000..694ebe6a0758
--- /dev/null
+++ b/drivers/net/stmmac/stmmac_ethtool.c
@@ -0,0 +1,395 @@
1/*******************************************************************************
2 STMMAC Ethtool support
3
4 Copyright (C) 2007-2009 STMicroelectronics Ltd
5
6 This program is free software; you can redistribute it and/or modify it
7 under the terms and conditions of the GNU General Public License,
8 version 2, as published by the Free Software Foundation.
9
10 This program is distributed in the hope it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 more details.
14
15 You should have received a copy of the GNU General Public License along with
16 this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18
19 The full GNU General Public License is included in this distribution in
20 the file called "COPYING".
21
22 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
23*******************************************************************************/
24
25#include <linux/etherdevice.h>
26#include <linux/ethtool.h>
27#include <linux/mii.h>
28#include <linux/phy.h>
29
30#include "stmmac.h"
31
32#define REG_SPACE_SIZE 0x1054
33#define MAC100_ETHTOOL_NAME "st_mac100"
34#define GMAC_ETHTOOL_NAME "st_gmac"
35
36struct stmmac_stats {
37 char stat_string[ETH_GSTRING_LEN];
38 int sizeof_stat;
39 int stat_offset;
40};
41
42#define STMMAC_STAT(m) \
43 { #m, FIELD_SIZEOF(struct stmmac_extra_stats, m), \
44 offsetof(struct stmmac_priv, xstats.m)}
45
46static const struct stmmac_stats stmmac_gstrings_stats[] = {
47 STMMAC_STAT(tx_underflow),
48 STMMAC_STAT(tx_carrier),
49 STMMAC_STAT(tx_losscarrier),
50 STMMAC_STAT(tx_heartbeat),
51 STMMAC_STAT(tx_deferred),
52 STMMAC_STAT(tx_vlan),
53 STMMAC_STAT(rx_vlan),
54 STMMAC_STAT(tx_jabber),
55 STMMAC_STAT(tx_frame_flushed),
56 STMMAC_STAT(tx_payload_error),
57 STMMAC_STAT(tx_ip_header_error),
58 STMMAC_STAT(rx_desc),
59 STMMAC_STAT(rx_partial),
60 STMMAC_STAT(rx_runt),
61 STMMAC_STAT(rx_toolong),
62 STMMAC_STAT(rx_collision),
63 STMMAC_STAT(rx_crc),
64 STMMAC_STAT(rx_lenght),
65 STMMAC_STAT(rx_mii),
66 STMMAC_STAT(rx_multicast),
67 STMMAC_STAT(rx_gmac_overflow),
68 STMMAC_STAT(rx_watchdog),
69 STMMAC_STAT(da_rx_filter_fail),
70 STMMAC_STAT(sa_rx_filter_fail),
71 STMMAC_STAT(rx_missed_cntr),
72 STMMAC_STAT(rx_overflow_cntr),
73 STMMAC_STAT(tx_undeflow_irq),
74 STMMAC_STAT(tx_process_stopped_irq),
75 STMMAC_STAT(tx_jabber_irq),
76 STMMAC_STAT(rx_overflow_irq),
77 STMMAC_STAT(rx_buf_unav_irq),
78 STMMAC_STAT(rx_process_stopped_irq),
79 STMMAC_STAT(rx_watchdog_irq),
80 STMMAC_STAT(tx_early_irq),
81 STMMAC_STAT(fatal_bus_error_irq),
82 STMMAC_STAT(threshold),
83 STMMAC_STAT(tx_pkt_n),
84 STMMAC_STAT(rx_pkt_n),
85 STMMAC_STAT(poll_n),
86 STMMAC_STAT(sched_timer_n),
87 STMMAC_STAT(normal_irq_n),
88};
89#define STMMAC_STATS_LEN ARRAY_SIZE(stmmac_gstrings_stats)
90
91void stmmac_ethtool_getdrvinfo(struct net_device *dev,
92 struct ethtool_drvinfo *info)
93{
94 struct stmmac_priv *priv = netdev_priv(dev);
95
96 if (!priv->is_gmac)
97 strcpy(info->driver, MAC100_ETHTOOL_NAME);
98 else
99 strcpy(info->driver, GMAC_ETHTOOL_NAME);
100
101 strcpy(info->version, DRV_MODULE_VERSION);
102 info->fw_version[0] = '\0';
103 info->n_stats = STMMAC_STATS_LEN;
104 return;
105}
106
107int stmmac_ethtool_getsettings(struct net_device *dev, struct ethtool_cmd *cmd)
108{
109 struct stmmac_priv *priv = netdev_priv(dev);
110 struct phy_device *phy = priv->phydev;
111 int rc;
112 if (phy == NULL) {
113 pr_err("%s: %s: PHY is not registered\n",
114 __func__, dev->name);
115 return -ENODEV;
116 }
117 if (!netif_running(dev)) {
118 pr_err("%s: interface is disabled: we cannot track "
119 "link speed / duplex setting\n", dev->name);
120 return -EBUSY;
121 }
122 cmd->transceiver = XCVR_INTERNAL;
123 spin_lock_irq(&priv->lock);
124 rc = phy_ethtool_gset(phy, cmd);
125 spin_unlock_irq(&priv->lock);
126 return rc;
127}
128
129int stmmac_ethtool_setsettings(struct net_device *dev, struct ethtool_cmd *cmd)
130{
131 struct stmmac_priv *priv = netdev_priv(dev);
132 struct phy_device *phy = priv->phydev;
133 int rc;
134
135 spin_lock(&priv->lock);
136 rc = phy_ethtool_sset(phy, cmd);
137 spin_unlock(&priv->lock);
138
139 return rc;
140}
141
142u32 stmmac_ethtool_getmsglevel(struct net_device *dev)
143{
144 struct stmmac_priv *priv = netdev_priv(dev);
145 return priv->msg_enable;
146}
147
148void stmmac_ethtool_setmsglevel(struct net_device *dev, u32 level)
149{
150 struct stmmac_priv *priv = netdev_priv(dev);
151 priv->msg_enable = level;
152
153}
154
155int stmmac_check_if_running(struct net_device *dev)
156{
157 if (!netif_running(dev))
158 return -EBUSY;
159 return 0;
160}
161
162int stmmac_ethtool_get_regs_len(struct net_device *dev)
163{
164 return REG_SPACE_SIZE;
165}
166
167void stmmac_ethtool_gregs(struct net_device *dev,
168 struct ethtool_regs *regs, void *space)
169{
170 int i;
171 u32 *reg_space = (u32 *) space;
172
173 struct stmmac_priv *priv = netdev_priv(dev);
174
175 memset(reg_space, 0x0, REG_SPACE_SIZE);
176
177 if (!priv->is_gmac) {
178 /* MAC registers */
179 for (i = 0; i < 12; i++)
180 reg_space[i] = readl(dev->base_addr + (i * 4));
181 /* DMA registers */
182 for (i = 0; i < 9; i++)
183 reg_space[i + 12] =
184 readl(dev->base_addr + (DMA_BUS_MODE + (i * 4)));
185 reg_space[22] = readl(dev->base_addr + DMA_CUR_TX_BUF_ADDR);
186 reg_space[23] = readl(dev->base_addr + DMA_CUR_RX_BUF_ADDR);
187 } else {
188 /* MAC registers */
189 for (i = 0; i < 55; i++)
190 reg_space[i] = readl(dev->base_addr + (i * 4));
191 /* DMA registers */
192 for (i = 0; i < 22; i++)
193 reg_space[i + 55] =
194 readl(dev->base_addr + (DMA_BUS_MODE + (i * 4)));
195 }
196
197 return;
198}
199
200int stmmac_ethtool_set_tx_csum(struct net_device *netdev, u32 data)
201{
202 if (data)
203 netdev->features |= NETIF_F_HW_CSUM;
204 else
205 netdev->features &= ~NETIF_F_HW_CSUM;
206
207 return 0;
208}
209
210u32 stmmac_ethtool_get_rx_csum(struct net_device *dev)
211{
212 struct stmmac_priv *priv = netdev_priv(dev);
213
214 return priv->rx_csum;
215}
216
217static void
218stmmac_get_pauseparam(struct net_device *netdev,
219 struct ethtool_pauseparam *pause)
220{
221 struct stmmac_priv *priv = netdev_priv(netdev);
222
223 spin_lock(&priv->lock);
224
225 pause->rx_pause = 0;
226 pause->tx_pause = 0;
227 pause->autoneg = priv->phydev->autoneg;
228
229 if (priv->flow_ctrl & FLOW_RX)
230 pause->rx_pause = 1;
231 if (priv->flow_ctrl & FLOW_TX)
232 pause->tx_pause = 1;
233
234 spin_unlock(&priv->lock);
235 return;
236}
237
238static int
239stmmac_set_pauseparam(struct net_device *netdev,
240 struct ethtool_pauseparam *pause)
241{
242 struct stmmac_priv *priv = netdev_priv(netdev);
243 struct phy_device *phy = priv->phydev;
244 int new_pause = FLOW_OFF;
245 int ret = 0;
246
247 spin_lock(&priv->lock);
248
249 if (pause->rx_pause)
250 new_pause |= FLOW_RX;
251 if (pause->tx_pause)
252 new_pause |= FLOW_TX;
253
254 priv->flow_ctrl = new_pause;
255
256 if (phy->autoneg) {
257 if (netif_running(netdev)) {
258 struct ethtool_cmd cmd;
259 /* auto-negotiation automatically restarted */
260 cmd.cmd = ETHTOOL_NWAY_RST;
261 cmd.supported = phy->supported;
262 cmd.advertising = phy->advertising;
263 cmd.autoneg = phy->autoneg;
264 cmd.speed = phy->speed;
265 cmd.duplex = phy->duplex;
266 cmd.phy_address = phy->addr;
267 ret = phy_ethtool_sset(phy, &cmd);
268 }
269 } else {
270 unsigned long ioaddr = netdev->base_addr;
271 priv->mac_type->ops->flow_ctrl(ioaddr, phy->duplex,
272 priv->flow_ctrl, priv->pause);
273 }
274 spin_unlock(&priv->lock);
275 return ret;
276}
277
278static void stmmac_get_ethtool_stats(struct net_device *dev,
279 struct ethtool_stats *dummy, u64 *data)
280{
281 struct stmmac_priv *priv = netdev_priv(dev);
282 unsigned long ioaddr = dev->base_addr;
283 int i;
284
285 /* Update HW stats if supported */
286 priv->mac_type->ops->dma_diagnostic_fr(&dev->stats, &priv->xstats,
287 ioaddr);
288
289 for (i = 0; i < STMMAC_STATS_LEN; i++) {
290 char *p = (char *)priv + stmmac_gstrings_stats[i].stat_offset;
291 data[i] = (stmmac_gstrings_stats[i].sizeof_stat ==
292 sizeof(u64)) ? (*(u64 *)p) : (*(u32 *)p);
293 }
294
295 return;
296}
297
298static int stmmac_get_sset_count(struct net_device *netdev, int sset)
299{
300 switch (sset) {
301 case ETH_SS_STATS:
302 return STMMAC_STATS_LEN;
303 default:
304 return -EOPNOTSUPP;
305 }
306}
307
308static void stmmac_get_strings(struct net_device *dev, u32 stringset, u8 *data)
309{
310 int i;
311 u8 *p = data;
312
313 switch (stringset) {
314 case ETH_SS_STATS:
315 for (i = 0; i < STMMAC_STATS_LEN; i++) {
316 memcpy(p, stmmac_gstrings_stats[i].stat_string,
317 ETH_GSTRING_LEN);
318 p += ETH_GSTRING_LEN;
319 }
320 break;
321 default:
322 WARN_ON(1);
323 break;
324 }
325 return;
326}
327
328/* Currently only support WOL through Magic packet. */
329static void stmmac_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
330{
331 struct stmmac_priv *priv = netdev_priv(dev);
332
333 spin_lock_irq(&priv->lock);
334 if (priv->wolenabled == PMT_SUPPORTED) {
335 wol->supported = WAKE_MAGIC;
336 wol->wolopts = priv->wolopts;
337 }
338 spin_unlock_irq(&priv->lock);
339}
340
341static int stmmac_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
342{
343 struct stmmac_priv *priv = netdev_priv(dev);
344 u32 support = WAKE_MAGIC;
345
346 if (priv->wolenabled == PMT_NOT_SUPPORTED)
347 return -EINVAL;
348
349 if (wol->wolopts & ~support)
350 return -EINVAL;
351
352 if (wol->wolopts == 0)
353 device_set_wakeup_enable(priv->device, 0);
354 else
355 device_set_wakeup_enable(priv->device, 1);
356
357 spin_lock_irq(&priv->lock);
358 priv->wolopts = wol->wolopts;
359 spin_unlock_irq(&priv->lock);
360
361 return 0;
362}
363
364static struct ethtool_ops stmmac_ethtool_ops = {
365 .begin = stmmac_check_if_running,
366 .get_drvinfo = stmmac_ethtool_getdrvinfo,
367 .get_settings = stmmac_ethtool_getsettings,
368 .set_settings = stmmac_ethtool_setsettings,
369 .get_msglevel = stmmac_ethtool_getmsglevel,
370 .set_msglevel = stmmac_ethtool_setmsglevel,
371 .get_regs = stmmac_ethtool_gregs,
372 .get_regs_len = stmmac_ethtool_get_regs_len,
373 .get_link = ethtool_op_get_link,
374 .get_rx_csum = stmmac_ethtool_get_rx_csum,
375 .get_tx_csum = ethtool_op_get_tx_csum,
376 .set_tx_csum = stmmac_ethtool_set_tx_csum,
377 .get_sg = ethtool_op_get_sg,
378 .set_sg = ethtool_op_set_sg,
379 .get_pauseparam = stmmac_get_pauseparam,
380 .set_pauseparam = stmmac_set_pauseparam,
381 .get_ethtool_stats = stmmac_get_ethtool_stats,
382 .get_strings = stmmac_get_strings,
383 .get_wol = stmmac_get_wol,
384 .set_wol = stmmac_set_wol,
385 .get_sset_count = stmmac_get_sset_count,
386#ifdef NETIF_F_TSO
387 .get_tso = ethtool_op_get_tso,
388 .set_tso = ethtool_op_set_tso,
389#endif
390};
391
392void stmmac_set_ethtool_ops(struct net_device *netdev)
393{
394 SET_ETHTOOL_OPS(netdev, &stmmac_ethtool_ops);
395}
diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c
new file mode 100644
index 000000000000..c2f14dc9ba28
--- /dev/null
+++ b/drivers/net/stmmac/stmmac_main.c
@@ -0,0 +1,2204 @@
1/*******************************************************************************
2 This is the driver for the ST MAC 10/100/1000 on-chip Ethernet controllers.
3 ST Ethernet IPs are built around a Synopsys IP Core.
4
5 Copyright (C) 2007-2009 STMicroelectronics Ltd
6
7 This program is free software; you can redistribute it and/or modify it
8 under the terms and conditions of the GNU General Public License,
9 version 2, as published by the Free Software Foundation.
10
11 This program is distributed in the hope it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 more details.
15
16 You should have received a copy of the GNU General Public License along with
17 this program; if not, write to the Free Software Foundation, Inc.,
18 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
19
20 The full GNU General Public License is included in this distribution in
21 the file called "COPYING".
22
23 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
24
25 Documentation available at:
26 http://www.stlinux.com
27 Support available at:
28 https://bugzilla.stlinux.com/
29*******************************************************************************/
30
31#include <linux/module.h>
32#include <linux/init.h>
33#include <linux/kernel.h>
34#include <linux/interrupt.h>
35#include <linux/netdevice.h>
36#include <linux/etherdevice.h>
37#include <linux/platform_device.h>
38#include <linux/ip.h>
39#include <linux/tcp.h>
40#include <linux/skbuff.h>
41#include <linux/ethtool.h>
42#include <linux/if_ether.h>
43#include <linux/crc32.h>
44#include <linux/mii.h>
45#include <linux/phy.h>
46#include <linux/if_vlan.h>
47#include <linux/dma-mapping.h>
48#include <linux/stm/soc.h>
49#include "stmmac.h"
50
51#define STMMAC_RESOURCE_NAME "stmmaceth"
52#define PHY_RESOURCE_NAME "stmmacphy"
53
54#undef STMMAC_DEBUG
55/*#define STMMAC_DEBUG*/
56#ifdef STMMAC_DEBUG
57#define DBG(nlevel, klevel, fmt, args...) \
58 ((void)(netif_msg_##nlevel(priv) && \
59 printk(KERN_##klevel fmt, ## args)))
60#else
61#define DBG(nlevel, klevel, fmt, args...) do { } while (0)
62#endif
63
64#undef STMMAC_RX_DEBUG
65/*#define STMMAC_RX_DEBUG*/
66#ifdef STMMAC_RX_DEBUG
67#define RX_DBG(fmt, args...) printk(fmt, ## args)
68#else
69#define RX_DBG(fmt, args...) do { } while (0)
70#endif
71
72#undef STMMAC_XMIT_DEBUG
73/*#define STMMAC_XMIT_DEBUG*/
74#ifdef STMMAC_TX_DEBUG
75#define TX_DBG(fmt, args...) printk(fmt, ## args)
76#else
77#define TX_DBG(fmt, args...) do { } while (0)
78#endif
79
80#define STMMAC_ALIGN(x) L1_CACHE_ALIGN(x)
81#define JUMBO_LEN 9000
82
83/* Module parameters */
84#define TX_TIMEO 5000 /* default 5 seconds */
85static int watchdog = TX_TIMEO;
86module_param(watchdog, int, S_IRUGO | S_IWUSR);
87MODULE_PARM_DESC(watchdog, "Transmit timeout in milliseconds");
88
89static int debug = -1; /* -1: default, 0: no output, 16: all */
90module_param(debug, int, S_IRUGO | S_IWUSR);
91MODULE_PARM_DESC(debug, "Message Level (0: no output, 16: all)");
92
93static int phyaddr = -1;
94module_param(phyaddr, int, S_IRUGO);
95MODULE_PARM_DESC(phyaddr, "Physical device address");
96
97#define DMA_TX_SIZE 256
98static int dma_txsize = DMA_TX_SIZE;
99module_param(dma_txsize, int, S_IRUGO | S_IWUSR);
100MODULE_PARM_DESC(dma_txsize, "Number of descriptors in the TX list");
101
102#define DMA_RX_SIZE 256
103static int dma_rxsize = DMA_RX_SIZE;
104module_param(dma_rxsize, int, S_IRUGO | S_IWUSR);
105MODULE_PARM_DESC(dma_rxsize, "Number of descriptors in the RX list");
106
107static int flow_ctrl = FLOW_OFF;
108module_param(flow_ctrl, int, S_IRUGO | S_IWUSR);
109MODULE_PARM_DESC(flow_ctrl, "Flow control ability [on/off]");
110
111static int pause = PAUSE_TIME;
112module_param(pause, int, S_IRUGO | S_IWUSR);
113MODULE_PARM_DESC(pause, "Flow Control Pause Time");
114
115#define TC_DEFAULT 64
116static int tc = TC_DEFAULT;
117module_param(tc, int, S_IRUGO | S_IWUSR);
118MODULE_PARM_DESC(tc, "DMA threshold control value");
119
120#define RX_NO_COALESCE 1 /* Always interrupt on completion */
121#define TX_NO_COALESCE -1 /* No moderation by default */
122
123/* Pay attention to tune this parameter; take care of both
124 * hardware capability and network stabitily/performance impact.
125 * Many tests showed that ~4ms latency seems to be good enough. */
126#ifdef CONFIG_STMMAC_TIMER
127#define DEFAULT_PERIODIC_RATE 256
128static int tmrate = DEFAULT_PERIODIC_RATE;
129module_param(tmrate, int, S_IRUGO | S_IWUSR);
130MODULE_PARM_DESC(tmrate, "External timer freq. (default: 256Hz)");
131#endif
132
133#define DMA_BUFFER_SIZE BUF_SIZE_2KiB
134static int buf_sz = DMA_BUFFER_SIZE;
135module_param(buf_sz, int, S_IRUGO | S_IWUSR);
136MODULE_PARM_DESC(buf_sz, "DMA buffer size");
137
138/* In case of Giga ETH, we can enable/disable the COE for the
139 * transmit HW checksum computation.
140 * Note that, if tx csum is off in HW, SG will be still supported. */
141static int tx_coe = HW_CSUM;
142module_param(tx_coe, int, S_IRUGO | S_IWUSR);
143MODULE_PARM_DESC(tx_coe, "GMAC COE type 2 [on/off]");
144
145static const u32 default_msg_level = (NETIF_MSG_DRV | NETIF_MSG_PROBE |
146 NETIF_MSG_LINK | NETIF_MSG_IFUP |
147 NETIF_MSG_IFDOWN | NETIF_MSG_TIMER);
148
149static irqreturn_t stmmac_interrupt(int irq, void *dev_id);
150static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev);
151
152/**
153 * stmmac_verify_args - verify the driver parameters.
154 * Description: it verifies if some wrong parameter is passed to the driver.
155 * Note that wrong parameters are replaced with the default values.
156 */
157static void stmmac_verify_args(void)
158{
159 if (unlikely(watchdog < 0))
160 watchdog = TX_TIMEO;
161 if (unlikely(dma_rxsize < 0))
162 dma_rxsize = DMA_RX_SIZE;
163 if (unlikely(dma_txsize < 0))
164 dma_txsize = DMA_TX_SIZE;
165 if (unlikely((buf_sz < DMA_BUFFER_SIZE) || (buf_sz > BUF_SIZE_16KiB)))
166 buf_sz = DMA_BUFFER_SIZE;
167 if (unlikely(flow_ctrl > 1))
168 flow_ctrl = FLOW_AUTO;
169 else if (likely(flow_ctrl < 0))
170 flow_ctrl = FLOW_OFF;
171 if (unlikely((pause < 0) || (pause > 0xffff)))
172 pause = PAUSE_TIME;
173
174 return;
175}
176
177#if defined(STMMAC_XMIT_DEBUG) || defined(STMMAC_RX_DEBUG)
178static void print_pkt(unsigned char *buf, int len)
179{
180 int j;
181 pr_info("len = %d byte, buf addr: 0x%p", len, buf);
182 for (j = 0; j < len; j++) {
183 if ((j % 16) == 0)
184 pr_info("\n %03x:", j);
185 pr_info(" %02x", buf[j]);
186 }
187 pr_info("\n");
188 return;
189}
190#endif
191
192/* minimum number of free TX descriptors required to wake up TX process */
193#define STMMAC_TX_THRESH(x) (x->dma_tx_size/4)
194
195static inline u32 stmmac_tx_avail(struct stmmac_priv *priv)
196{
197 return priv->dirty_tx + priv->dma_tx_size - priv->cur_tx - 1;
198}
199
200/**
201 * stmmac_adjust_link
202 * @dev: net device structure
203 * Description: it adjusts the link parameters.
204 */
205static void stmmac_adjust_link(struct net_device *dev)
206{
207 struct stmmac_priv *priv = netdev_priv(dev);
208 struct phy_device *phydev = priv->phydev;
209 unsigned long ioaddr = dev->base_addr;
210 unsigned long flags;
211 int new_state = 0;
212 unsigned int fc = priv->flow_ctrl, pause_time = priv->pause;
213
214 if (phydev == NULL)
215 return;
216
217 DBG(probe, DEBUG, "stmmac_adjust_link: called. address %d link %d\n",
218 phydev->addr, phydev->link);
219
220 spin_lock_irqsave(&priv->lock, flags);
221 if (phydev->link) {
222 u32 ctrl = readl(ioaddr + MAC_CTRL_REG);
223
224 /* Now we make sure that we can be in full duplex mode.
225 * If not, we operate in half-duplex mode. */
226 if (phydev->duplex != priv->oldduplex) {
227 new_state = 1;
228 if (!(phydev->duplex))
229 ctrl &= ~priv->mac_type->hw.link.duplex;
230 else
231 ctrl |= priv->mac_type->hw.link.duplex;
232 priv->oldduplex = phydev->duplex;
233 }
234 /* Flow Control operation */
235 if (phydev->pause)
236 priv->mac_type->ops->flow_ctrl(ioaddr, phydev->duplex,
237 fc, pause_time);
238
239 if (phydev->speed != priv->speed) {
240 new_state = 1;
241 switch (phydev->speed) {
242 case 1000:
243 if (likely(priv->is_gmac))
244 ctrl &= ~priv->mac_type->hw.link.port;
245 break;
246 case 100:
247 case 10:
248 if (priv->is_gmac) {
249 ctrl |= priv->mac_type->hw.link.port;
250 if (phydev->speed == SPEED_100) {
251 ctrl |=
252 priv->mac_type->hw.link.
253 speed;
254 } else {
255 ctrl &=
256 ~(priv->mac_type->hw.
257 link.speed);
258 }
259 } else {
260 ctrl &= ~priv->mac_type->hw.link.port;
261 }
262 priv->fix_mac_speed(priv->bsp_priv,
263 phydev->speed);
264 break;
265 default:
266 if (netif_msg_link(priv))
267 pr_warning("%s: Speed (%d) is not 10"
268 " or 100!\n", dev->name, phydev->speed);
269 break;
270 }
271
272 priv->speed = phydev->speed;
273 }
274
275 writel(ctrl, ioaddr + MAC_CTRL_REG);
276
277 if (!priv->oldlink) {
278 new_state = 1;
279 priv->oldlink = 1;
280 }
281 } else if (priv->oldlink) {
282 new_state = 1;
283 priv->oldlink = 0;
284 priv->speed = 0;
285 priv->oldduplex = -1;
286 }
287
288 if (new_state && netif_msg_link(priv))
289 phy_print_status(phydev);
290
291 spin_unlock_irqrestore(&priv->lock, flags);
292
293 DBG(probe, DEBUG, "stmmac_adjust_link: exiting\n");
294}
295
296/**
297 * stmmac_init_phy - PHY initialization
298 * @dev: net device structure
299 * Description: it initializes the driver's PHY state, and attaches the PHY
300 * to the mac driver.
301 * Return value:
302 * 0 on success
303 */
304static int stmmac_init_phy(struct net_device *dev)
305{
306 struct stmmac_priv *priv = netdev_priv(dev);
307 struct phy_device *phydev;
308 char phy_id[BUS_ID_SIZE]; /* PHY to connect */
309 char bus_id[BUS_ID_SIZE];
310
311 priv->oldlink = 0;
312 priv->speed = 0;
313 priv->oldduplex = -1;
314
315 if (priv->phy_addr == -1) {
316 /* We don't have a PHY, so do nothing */
317 return 0;
318 }
319
320 snprintf(bus_id, MII_BUS_ID_SIZE, "%x", priv->bus_id);
321 snprintf(phy_id, BUS_ID_SIZE, PHY_ID_FMT, bus_id, priv->phy_addr);
322 pr_debug("stmmac_init_phy: trying to attach to %s\n", phy_id);
323
324 phydev = phy_connect(dev, phy_id, &stmmac_adjust_link, 0,
325 priv->phy_interface);
326
327 if (IS_ERR(phydev)) {
328 pr_err("%s: Could not attach to PHY\n", dev->name);
329 return PTR_ERR(phydev);
330 }
331
332 /*
333 * Broken HW is sometimes missing the pull-up resistor on the
334 * MDIO line, which results in reads to non-existent devices returning
335 * 0 rather than 0xffff. Catch this here and treat 0 as a non-existent
336 * device as well.
337 * Note: phydev->phy_id is the result of reading the UID PHY registers.
338 */
339 if (phydev->phy_id == 0) {
340 phy_disconnect(phydev);
341 return -ENODEV;
342 }
343 pr_debug("stmmac_init_phy: %s: attached to PHY (UID 0x%x)"
344 " Link = %d\n", dev->name, phydev->phy_id, phydev->link);
345
346 priv->phydev = phydev;
347
348 return 0;
349}
350
351static inline void stmmac_mac_enable_rx(unsigned long ioaddr)
352{
353 u32 value = readl(ioaddr + MAC_CTRL_REG);
354 value |= MAC_RNABLE_RX;
355 /* Set the RE (receive enable bit into the MAC CTRL register). */
356 writel(value, ioaddr + MAC_CTRL_REG);
357}
358
359static inline void stmmac_mac_enable_tx(unsigned long ioaddr)
360{
361 u32 value = readl(ioaddr + MAC_CTRL_REG);
362 value |= MAC_ENABLE_TX;
363 /* Set the TE (transmit enable bit into the MAC CTRL register). */
364 writel(value, ioaddr + MAC_CTRL_REG);
365}
366
367static inline void stmmac_mac_disable_rx(unsigned long ioaddr)
368{
369 u32 value = readl(ioaddr + MAC_CTRL_REG);
370 value &= ~MAC_RNABLE_RX;
371 writel(value, ioaddr + MAC_CTRL_REG);
372}
373
374static inline void stmmac_mac_disable_tx(unsigned long ioaddr)
375{
376 u32 value = readl(ioaddr + MAC_CTRL_REG);
377 value &= ~MAC_ENABLE_TX;
378 writel(value, ioaddr + MAC_CTRL_REG);
379}
380
381/**
382 * display_ring
383 * @p: pointer to the ring.
384 * @size: size of the ring.
385 * Description: display all the descriptors within the ring.
386 */
387static void display_ring(struct dma_desc *p, int size)
388{
389 struct tmp_s {
390 u64 a;
391 unsigned int b;
392 unsigned int c;
393 };
394 int i;
395 for (i = 0; i < size; i++) {
396 struct tmp_s *x = (struct tmp_s *)(p + i);
397 pr_info("\t%d [0x%x]: DES0=0x%x DES1=0x%x BUF1=0x%x BUF2=0x%x",
398 i, (unsigned int)virt_to_phys(&p[i]),
399 (unsigned int)(x->a), (unsigned int)((x->a) >> 32),
400 x->b, x->c);
401 pr_info("\n");
402 }
403}
404
405/**
406 * init_dma_desc_rings - init the RX/TX descriptor rings
407 * @dev: net device structure
408 * Description: this function initializes the DMA RX/TX descriptors
409 * and allocates the socket buffers.
410 */
411static void init_dma_desc_rings(struct net_device *dev)
412{
413 int i;
414 struct stmmac_priv *priv = netdev_priv(dev);
415 struct sk_buff *skb;
416 unsigned int txsize = priv->dma_tx_size;
417 unsigned int rxsize = priv->dma_rx_size;
418 unsigned int bfsize = priv->dma_buf_sz;
419 int buff2_needed = 0;
420 int dis_ic = 0;
421
422#ifdef CONFIG_STMMAC_TIMER
423 /* Using Timers disable interrupts on completion for the reception */
424 dis_ic = 1;
425#endif
426 /* Set the Buffer size according to the MTU;
427 * indeed, in case of jumbo we need to bump-up the buffer sizes.
428 */
429 if (unlikely(dev->mtu >= BUF_SIZE_8KiB))
430 bfsize = BUF_SIZE_16KiB;
431 else if (unlikely(dev->mtu >= BUF_SIZE_4KiB))
432 bfsize = BUF_SIZE_8KiB;
433 else if (unlikely(dev->mtu >= BUF_SIZE_2KiB))
434 bfsize = BUF_SIZE_4KiB;
435 else if (unlikely(dev->mtu >= DMA_BUFFER_SIZE))
436 bfsize = BUF_SIZE_2KiB;
437 else
438 bfsize = DMA_BUFFER_SIZE;
439
440 /* If the MTU exceeds 8k so use the second buffer in the chain */
441 if (bfsize >= BUF_SIZE_8KiB)
442 buff2_needed = 1;
443
444 DBG(probe, INFO, "stmmac: txsize %d, rxsize %d, bfsize %d\n",
445 txsize, rxsize, bfsize);
446
447 priv->rx_skbuff_dma = kmalloc(rxsize * sizeof(dma_addr_t), GFP_KERNEL);
448 priv->rx_skbuff =
449 kmalloc(sizeof(struct sk_buff *) * rxsize, GFP_KERNEL);
450 priv->dma_rx =
451 (struct dma_desc *)dma_alloc_coherent(priv->device,
452 rxsize *
453 sizeof(struct dma_desc),
454 &priv->dma_rx_phy,
455 GFP_KERNEL);
456 priv->tx_skbuff = kmalloc(sizeof(struct sk_buff *) * txsize,
457 GFP_KERNEL);
458 priv->dma_tx =
459 (struct dma_desc *)dma_alloc_coherent(priv->device,
460 txsize *
461 sizeof(struct dma_desc),
462 &priv->dma_tx_phy,
463 GFP_KERNEL);
464
465 if ((priv->dma_rx == NULL) || (priv->dma_tx == NULL)) {
466 pr_err("%s:ERROR allocating the DMA Tx/Rx desc\n", __func__);
467 return;
468 }
469
470 DBG(probe, INFO, "stmmac (%s) DMA desc rings: virt addr (Rx %p, "
471 "Tx %p)\n\tDMA phy addr (Rx 0x%08x, Tx 0x%08x)\n",
472 dev->name, priv->dma_rx, priv->dma_tx,
473 (unsigned int)priv->dma_rx_phy, (unsigned int)priv->dma_tx_phy);
474
475 /* RX INITIALIZATION */
476 DBG(probe, INFO, "stmmac: SKB addresses:\n"
477 "skb\t\tskb data\tdma data\n");
478
479 for (i = 0; i < rxsize; i++) {
480 struct dma_desc *p = priv->dma_rx + i;
481
482 skb = netdev_alloc_skb_ip_align(dev, bfsize);
483 if (unlikely(skb == NULL)) {
484 pr_err("%s: Rx init fails; skb is NULL\n", __func__);
485 break;
486 }
487 priv->rx_skbuff[i] = skb;
488 priv->rx_skbuff_dma[i] = dma_map_single(priv->device, skb->data,
489 bfsize, DMA_FROM_DEVICE);
490
491 p->des2 = priv->rx_skbuff_dma[i];
492 if (unlikely(buff2_needed))
493 p->des3 = p->des2 + BUF_SIZE_8KiB;
494 DBG(probe, INFO, "[%p]\t[%p]\t[%x]\n", priv->rx_skbuff[i],
495 priv->rx_skbuff[i]->data, priv->rx_skbuff_dma[i]);
496 }
497 priv->cur_rx = 0;
498 priv->dirty_rx = (unsigned int)(i - rxsize);
499 priv->dma_buf_sz = bfsize;
500 buf_sz = bfsize;
501
502 /* TX INITIALIZATION */
503 for (i = 0; i < txsize; i++) {
504 priv->tx_skbuff[i] = NULL;
505 priv->dma_tx[i].des2 = 0;
506 }
507 priv->dirty_tx = 0;
508 priv->cur_tx = 0;
509
510 /* Clear the Rx/Tx descriptors */
511 priv->mac_type->ops->init_rx_desc(priv->dma_rx, rxsize, dis_ic);
512 priv->mac_type->ops->init_tx_desc(priv->dma_tx, txsize);
513
514 if (netif_msg_hw(priv)) {
515 pr_info("RX descriptor ring:\n");
516 display_ring(priv->dma_rx, rxsize);
517 pr_info("TX descriptor ring:\n");
518 display_ring(priv->dma_tx, txsize);
519 }
520 return;
521}
522
523static void dma_free_rx_skbufs(struct stmmac_priv *priv)
524{
525 int i;
526
527 for (i = 0; i < priv->dma_rx_size; i++) {
528 if (priv->rx_skbuff[i]) {
529 dma_unmap_single(priv->device, priv->rx_skbuff_dma[i],
530 priv->dma_buf_sz, DMA_FROM_DEVICE);
531 dev_kfree_skb_any(priv->rx_skbuff[i]);
532 }
533 priv->rx_skbuff[i] = NULL;
534 }
535 return;
536}
537
538static void dma_free_tx_skbufs(struct stmmac_priv *priv)
539{
540 int i;
541
542 for (i = 0; i < priv->dma_tx_size; i++) {
543 if (priv->tx_skbuff[i] != NULL) {
544 struct dma_desc *p = priv->dma_tx + i;
545 if (p->des2)
546 dma_unmap_single(priv->device, p->des2,
547 priv->mac_type->ops->get_tx_len(p),
548 DMA_TO_DEVICE);
549 dev_kfree_skb_any(priv->tx_skbuff[i]);
550 priv->tx_skbuff[i] = NULL;
551 }
552 }
553 return;
554}
555
556static void free_dma_desc_resources(struct stmmac_priv *priv)
557{
558 /* Release the DMA TX/RX socket buffers */
559 dma_free_rx_skbufs(priv);
560 dma_free_tx_skbufs(priv);
561
562 /* Free the region of consistent memory previously allocated for
563 * the DMA */
564 dma_free_coherent(priv->device,
565 priv->dma_tx_size * sizeof(struct dma_desc),
566 priv->dma_tx, priv->dma_tx_phy);
567 dma_free_coherent(priv->device,
568 priv->dma_rx_size * sizeof(struct dma_desc),
569 priv->dma_rx, priv->dma_rx_phy);
570 kfree(priv->rx_skbuff_dma);
571 kfree(priv->rx_skbuff);
572 kfree(priv->tx_skbuff);
573
574 return;
575}
576
577/**
578 * stmmac_dma_start_tx
579 * @ioaddr: device I/O address
580 * Description: this function starts the DMA tx process.
581 */
582static void stmmac_dma_start_tx(unsigned long ioaddr)
583{
584 u32 value = readl(ioaddr + DMA_CONTROL);
585 value |= DMA_CONTROL_ST;
586 writel(value, ioaddr + DMA_CONTROL);
587 return;
588}
589
590static void stmmac_dma_stop_tx(unsigned long ioaddr)
591{
592 u32 value = readl(ioaddr + DMA_CONTROL);
593 value &= ~DMA_CONTROL_ST;
594 writel(value, ioaddr + DMA_CONTROL);
595 return;
596}
597
598/**
599 * stmmac_dma_start_rx
600 * @ioaddr: device I/O address
601 * Description: this function starts the DMA rx process.
602 */
603static void stmmac_dma_start_rx(unsigned long ioaddr)
604{
605 u32 value = readl(ioaddr + DMA_CONTROL);
606 value |= DMA_CONTROL_SR;
607 writel(value, ioaddr + DMA_CONTROL);
608
609 return;
610}
611
612static void stmmac_dma_stop_rx(unsigned long ioaddr)
613{
614 u32 value = readl(ioaddr + DMA_CONTROL);
615 value &= ~DMA_CONTROL_SR;
616 writel(value, ioaddr + DMA_CONTROL);
617
618 return;
619}
620
621/**
622 * stmmac_dma_operation_mode - HW DMA operation mode
623 * @priv : pointer to the private device structure.
624 * Description: it sets the DMA operation mode: tx/rx DMA thresholds
625 * or Store-And-Forward capability. It also verifies the COE for the
626 * transmission in case of Giga ETH.
627 */
628static void stmmac_dma_operation_mode(struct stmmac_priv *priv)
629{
630 if (!priv->is_gmac) {
631 /* MAC 10/100 */
632 priv->mac_type->ops->dma_mode(priv->dev->base_addr, tc, 0);
633 priv->tx_coe = NO_HW_CSUM;
634 } else {
635 if ((priv->dev->mtu <= ETH_DATA_LEN) && (tx_coe)) {
636 priv->mac_type->ops->dma_mode(priv->dev->base_addr,
637 SF_DMA_MODE, SF_DMA_MODE);
638 tc = SF_DMA_MODE;
639 priv->tx_coe = HW_CSUM;
640 } else {
641 /* Checksum computation is performed in software. */
642 priv->mac_type->ops->dma_mode(priv->dev->base_addr, tc,
643 SF_DMA_MODE);
644 priv->tx_coe = NO_HW_CSUM;
645 }
646 }
647 tx_coe = priv->tx_coe;
648
649 return;
650}
651
652#ifdef STMMAC_DEBUG
653/**
654 * show_tx_process_state
655 * @status: tx descriptor status field
656 * Description: it shows the Transmit Process State for CSR5[22:20]
657 */
658static void show_tx_process_state(unsigned int status)
659{
660 unsigned int state;
661 state = (status & DMA_STATUS_TS_MASK) >> DMA_STATUS_TS_SHIFT;
662
663 switch (state) {
664 case 0:
665 pr_info("- TX (Stopped): Reset or Stop command\n");
666 break;
667 case 1:
668 pr_info("- TX (Running):Fetching the Tx desc\n");
669 break;
670 case 2:
671 pr_info("- TX (Running): Waiting for end of tx\n");
672 break;
673 case 3:
674 pr_info("- TX (Running): Reading the data "
675 "and queuing the data into the Tx buf\n");
676 break;
677 case 6:
678 pr_info("- TX (Suspended): Tx Buff Underflow "
679 "or an unavailable Transmit descriptor\n");
680 break;
681 case 7:
682 pr_info("- TX (Running): Closing Tx descriptor\n");
683 break;
684 default:
685 break;
686 }
687 return;
688}
689
690/**
691 * show_rx_process_state
692 * @status: rx descriptor status field
693 * Description: it shows the Receive Process State for CSR5[19:17]
694 */
695static void show_rx_process_state(unsigned int status)
696{
697 unsigned int state;
698 state = (status & DMA_STATUS_RS_MASK) >> DMA_STATUS_RS_SHIFT;
699
700 switch (state) {
701 case 0:
702 pr_info("- RX (Stopped): Reset or Stop command\n");
703 break;
704 case 1:
705 pr_info("- RX (Running): Fetching the Rx desc\n");
706 break;
707 case 2:
708 pr_info("- RX (Running):Checking for end of pkt\n");
709 break;
710 case 3:
711 pr_info("- RX (Running): Waiting for Rx pkt\n");
712 break;
713 case 4:
714 pr_info("- RX (Suspended): Unavailable Rx buf\n");
715 break;
716 case 5:
717 pr_info("- RX (Running): Closing Rx descriptor\n");
718 break;
719 case 6:
720 pr_info("- RX(Running): Flushing the current frame"
721 " from the Rx buf\n");
722 break;
723 case 7:
724 pr_info("- RX (Running): Queuing the Rx frame"
725 " from the Rx buf into memory\n");
726 break;
727 default:
728 break;
729 }
730 return;
731}
732#endif
733
734/**
735 * stmmac_tx:
736 * @priv: private driver structure
737 * Description: it reclaims resources after transmission completes.
738 */
739static void stmmac_tx(struct stmmac_priv *priv)
740{
741 unsigned int txsize = priv->dma_tx_size;
742 unsigned long ioaddr = priv->dev->base_addr;
743
744 while (priv->dirty_tx != priv->cur_tx) {
745 int last;
746 unsigned int entry = priv->dirty_tx % txsize;
747 struct sk_buff *skb = priv->tx_skbuff[entry];
748 struct dma_desc *p = priv->dma_tx + entry;
749
750 /* Check if the descriptor is owned by the DMA. */
751 if (priv->mac_type->ops->get_tx_owner(p))
752 break;
753
754 /* Verify tx error by looking at the last segment */
755 last = priv->mac_type->ops->get_tx_ls(p);
756 if (likely(last)) {
757 int tx_error =
758 priv->mac_type->ops->tx_status(&priv->dev->stats,
759 &priv->xstats,
760 p, ioaddr);
761 if (likely(tx_error == 0)) {
762 priv->dev->stats.tx_packets++;
763 priv->xstats.tx_pkt_n++;
764 } else
765 priv->dev->stats.tx_errors++;
766 }
767 TX_DBG("%s: curr %d, dirty %d\n", __func__,
768 priv->cur_tx, priv->dirty_tx);
769
770 if (likely(p->des2))
771 dma_unmap_single(priv->device, p->des2,
772 priv->mac_type->ops->get_tx_len(p),
773 DMA_TO_DEVICE);
774 if (unlikely(p->des3))
775 p->des3 = 0;
776
777 if (likely(skb != NULL)) {
778 /*
779 * If there's room in the queue (limit it to size)
780 * we add this skb back into the pool,
781 * if it's the right size.
782 */
783 if ((skb_queue_len(&priv->rx_recycle) <
784 priv->dma_rx_size) &&
785 skb_recycle_check(skb, priv->dma_buf_sz))
786 __skb_queue_head(&priv->rx_recycle, skb);
787 else
788 dev_kfree_skb(skb);
789
790 priv->tx_skbuff[entry] = NULL;
791 }
792
793 priv->mac_type->ops->release_tx_desc(p);
794
795 entry = (++priv->dirty_tx) % txsize;
796 }
797 if (unlikely(netif_queue_stopped(priv->dev) &&
798 stmmac_tx_avail(priv) > STMMAC_TX_THRESH(priv))) {
799 netif_tx_lock(priv->dev);
800 if (netif_queue_stopped(priv->dev) &&
801 stmmac_tx_avail(priv) > STMMAC_TX_THRESH(priv)) {
802 TX_DBG("%s: restart transmit\n", __func__);
803 netif_wake_queue(priv->dev);
804 }
805 netif_tx_unlock(priv->dev);
806 }
807 return;
808}
809
810static inline void stmmac_enable_irq(struct stmmac_priv *priv)
811{
812#ifndef CONFIG_STMMAC_TIMER
813 writel(DMA_INTR_DEFAULT_MASK, priv->dev->base_addr + DMA_INTR_ENA);
814#else
815 priv->tm->timer_start(tmrate);
816#endif
817}
818
819static inline void stmmac_disable_irq(struct stmmac_priv *priv)
820{
821#ifndef CONFIG_STMMAC_TIMER
822 writel(0, priv->dev->base_addr + DMA_INTR_ENA);
823#else
824 priv->tm->timer_stop();
825#endif
826}
827
828static int stmmac_has_work(struct stmmac_priv *priv)
829{
830 unsigned int has_work = 0;
831 int rxret, tx_work = 0;
832
833 rxret = priv->mac_type->ops->get_rx_owner(priv->dma_rx +
834 (priv->cur_rx % priv->dma_rx_size));
835
836 if (priv->dirty_tx != priv->cur_tx)
837 tx_work = 1;
838
839 if (likely(!rxret || tx_work))
840 has_work = 1;
841
842 return has_work;
843}
844
845static inline void _stmmac_schedule(struct stmmac_priv *priv)
846{
847 if (likely(stmmac_has_work(priv))) {
848 stmmac_disable_irq(priv);
849 napi_schedule(&priv->napi);
850 }
851}
852
853#ifdef CONFIG_STMMAC_TIMER
854void stmmac_schedule(struct net_device *dev)
855{
856 struct stmmac_priv *priv = netdev_priv(dev);
857
858 priv->xstats.sched_timer_n++;
859
860 _stmmac_schedule(priv);
861
862 return;
863}
864
865static void stmmac_no_timer_started(unsigned int x)
866{;
867};
868
869static void stmmac_no_timer_stopped(void)
870{;
871};
872#endif
873
874/**
875 * stmmac_tx_err:
876 * @priv: pointer to the private device structure
877 * Description: it cleans the descriptors and restarts the transmission
878 * in case of errors.
879 */
880static void stmmac_tx_err(struct stmmac_priv *priv)
881{
882 netif_stop_queue(priv->dev);
883
884 stmmac_dma_stop_tx(priv->dev->base_addr);
885 dma_free_tx_skbufs(priv);
886 priv->mac_type->ops->init_tx_desc(priv->dma_tx, priv->dma_tx_size);
887 priv->dirty_tx = 0;
888 priv->cur_tx = 0;
889 stmmac_dma_start_tx(priv->dev->base_addr);
890
891 priv->dev->stats.tx_errors++;
892 netif_wake_queue(priv->dev);
893
894 return;
895}
896
897/**
898 * stmmac_dma_interrupt - Interrupt handler for the driver
899 * @dev: net device structure
900 * Description: Interrupt handler for the driver (DMA).
901 */
902static void stmmac_dma_interrupt(struct net_device *dev)
903{
904 unsigned long ioaddr = dev->base_addr;
905 struct stmmac_priv *priv = netdev_priv(dev);
906 /* read the status register (CSR5) */
907 u32 intr_status = readl(ioaddr + DMA_STATUS);
908
909 DBG(intr, INFO, "%s: [CSR5: 0x%08x]\n", __func__, intr_status);
910
911#ifdef STMMAC_DEBUG
912 /* It displays the DMA transmit process state (CSR5 register) */
913 if (netif_msg_tx_done(priv))
914 show_tx_process_state(intr_status);
915 if (netif_msg_rx_status(priv))
916 show_rx_process_state(intr_status);
917#endif
918 /* ABNORMAL interrupts */
919 if (unlikely(intr_status & DMA_STATUS_AIS)) {
920 DBG(intr, INFO, "CSR5[15] DMA ABNORMAL IRQ: ");
921 if (unlikely(intr_status & DMA_STATUS_UNF)) {
922 DBG(intr, INFO, "transmit underflow\n");
923 if (unlikely(tc != SF_DMA_MODE)
924 && (tc <= 256)) {
925 /* Try to bump up the threshold */
926 tc += 64;
927 priv->mac_type->ops->dma_mode(ioaddr, tc,
928 SF_DMA_MODE);
929 priv->xstats.threshold = tc;
930 }
931 stmmac_tx_err(priv);
932 priv->xstats.tx_undeflow_irq++;
933 }
934 if (unlikely(intr_status & DMA_STATUS_TJT)) {
935 DBG(intr, INFO, "transmit jabber\n");
936 priv->xstats.tx_jabber_irq++;
937 }
938 if (unlikely(intr_status & DMA_STATUS_OVF)) {
939 DBG(intr, INFO, "recv overflow\n");
940 priv->xstats.rx_overflow_irq++;
941 }
942 if (unlikely(intr_status & DMA_STATUS_RU)) {
943 DBG(intr, INFO, "receive buffer unavailable\n");
944 priv->xstats.rx_buf_unav_irq++;
945 }
946 if (unlikely(intr_status & DMA_STATUS_RPS)) {
947 DBG(intr, INFO, "receive process stopped\n");
948 priv->xstats.rx_process_stopped_irq++;
949 }
950 if (unlikely(intr_status & DMA_STATUS_RWT)) {
951 DBG(intr, INFO, "receive watchdog\n");
952 priv->xstats.rx_watchdog_irq++;
953 }
954 if (unlikely(intr_status & DMA_STATUS_ETI)) {
955 DBG(intr, INFO, "transmit early interrupt\n");
956 priv->xstats.tx_early_irq++;
957 }
958 if (unlikely(intr_status & DMA_STATUS_TPS)) {
959 DBG(intr, INFO, "transmit process stopped\n");
960 priv->xstats.tx_process_stopped_irq++;
961 stmmac_tx_err(priv);
962 }
963 if (unlikely(intr_status & DMA_STATUS_FBI)) {
964 DBG(intr, INFO, "fatal bus error\n");
965 priv->xstats.fatal_bus_error_irq++;
966 stmmac_tx_err(priv);
967 }
968 }
969
970 /* TX/RX NORMAL interrupts */
971 if (intr_status & DMA_STATUS_NIS) {
972 priv->xstats.normal_irq_n++;
973 if (likely((intr_status & DMA_STATUS_RI) ||
974 (intr_status & (DMA_STATUS_TI))))
975 _stmmac_schedule(priv);
976 }
977
978 /* Optional hardware blocks, interrupts should be disabled */
979 if (unlikely(intr_status &
980 (DMA_STATUS_GPI | DMA_STATUS_GMI | DMA_STATUS_GLI)))
981 pr_info("%s: unexpected status %08x\n", __func__, intr_status);
982
983 /* Clear the interrupt by writing a logic 1 to the CSR5[15-0] */
984 writel((intr_status & 0x1ffff), ioaddr + DMA_STATUS);
985
986 DBG(intr, INFO, "\n\n");
987
988 return;
989}
990
991/**
992 * stmmac_open - open entry point of the driver
993 * @dev : pointer to the device structure.
994 * Description:
995 * This function is the open entry point of the driver.
996 * Return value:
997 * 0 on success and an appropriate (-)ve integer as defined in errno.h
998 * file on failure.
999 */
1000static int stmmac_open(struct net_device *dev)
1001{
1002 struct stmmac_priv *priv = netdev_priv(dev);
1003 unsigned long ioaddr = dev->base_addr;
1004 int ret;
1005
1006 /* Check that the MAC address is valid. If its not, refuse
1007 * to bring the device up. The user must specify an
1008 * address using the following linux command:
1009 * ifconfig eth0 hw ether xx:xx:xx:xx:xx:xx */
1010 if (!is_valid_ether_addr(dev->dev_addr)) {
1011 random_ether_addr(dev->dev_addr);
1012 pr_warning("%s: generated random MAC address %pM\n", dev->name,
1013 dev->dev_addr);
1014 }
1015
1016 stmmac_verify_args();
1017
1018 ret = stmmac_init_phy(dev);
1019 if (unlikely(ret)) {
1020 pr_err("%s: Cannot attach to PHY (error: %d)\n", __func__, ret);
1021 return ret;
1022 }
1023
1024 /* Request the IRQ lines */
1025 ret = request_irq(dev->irq, &stmmac_interrupt,
1026 IRQF_SHARED, dev->name, dev);
1027 if (unlikely(ret < 0)) {
1028 pr_err("%s: ERROR: allocating the IRQ %d (error: %d)\n",
1029 __func__, dev->irq, ret);
1030 return ret;
1031 }
1032
1033#ifdef CONFIG_STMMAC_TIMER
1034 priv->tm = kmalloc(sizeof(struct stmmac_timer *), GFP_KERNEL);
1035 if (unlikely(priv->tm == NULL)) {
1036 pr_err("%s: ERROR: timer memory alloc failed \n", __func__);
1037 return -ENOMEM;
1038 }
1039 priv->tm->freq = tmrate;
1040
1041 /* Test if the HW timer can be actually used.
1042 * In case of failure continue with no timer. */
1043 if (unlikely((stmmac_open_ext_timer(dev, priv->tm)) < 0)) {
1044 pr_warning("stmmaceth: cannot attach the HW timer\n");
1045 tmrate = 0;
1046 priv->tm->freq = 0;
1047 priv->tm->timer_start = stmmac_no_timer_started;
1048 priv->tm->timer_stop = stmmac_no_timer_stopped;
1049 }
1050#endif
1051
1052 /* Create and initialize the TX/RX descriptors chains. */
1053 priv->dma_tx_size = STMMAC_ALIGN(dma_txsize);
1054 priv->dma_rx_size = STMMAC_ALIGN(dma_rxsize);
1055 priv->dma_buf_sz = STMMAC_ALIGN(buf_sz);
1056 init_dma_desc_rings(dev);
1057
1058 /* DMA initialization and SW reset */
1059 if (unlikely(priv->mac_type->ops->dma_init(ioaddr,
1060 priv->pbl, priv->dma_tx_phy, priv->dma_rx_phy) < 0)) {
1061
1062 pr_err("%s: DMA initialization failed\n", __func__);
1063 return -1;
1064 }
1065
1066 /* Copy the MAC addr into the HW */
1067 priv->mac_type->ops->set_umac_addr(ioaddr, dev->dev_addr, 0);
1068 /* Initialize the MAC Core */
1069 priv->mac_type->ops->core_init(ioaddr);
1070
1071 priv->shutdown = 0;
1072
1073 /* Initialise the MMC (if present) to disable all interrupts. */
1074 writel(0xffffffff, ioaddr + MMC_HIGH_INTR_MASK);
1075 writel(0xffffffff, ioaddr + MMC_LOW_INTR_MASK);
1076
1077 /* Enable the MAC Rx/Tx */
1078 stmmac_mac_enable_rx(ioaddr);
1079 stmmac_mac_enable_tx(ioaddr);
1080
1081 /* Set the HW DMA mode and the COE */
1082 stmmac_dma_operation_mode(priv);
1083
1084 /* Extra statistics */
1085 memset(&priv->xstats, 0, sizeof(struct stmmac_extra_stats));
1086 priv->xstats.threshold = tc;
1087
1088 /* Start the ball rolling... */
1089 DBG(probe, DEBUG, "%s: DMA RX/TX processes started...\n", dev->name);
1090 stmmac_dma_start_tx(ioaddr);
1091 stmmac_dma_start_rx(ioaddr);
1092
1093#ifdef CONFIG_STMMAC_TIMER
1094 priv->tm->timer_start(tmrate);
1095#endif
1096 /* Dump DMA/MAC registers */
1097 if (netif_msg_hw(priv)) {
1098 priv->mac_type->ops->dump_mac_regs(ioaddr);
1099 priv->mac_type->ops->dump_dma_regs(ioaddr);
1100 }
1101
1102 if (priv->phydev)
1103 phy_start(priv->phydev);
1104
1105 napi_enable(&priv->napi);
1106 skb_queue_head_init(&priv->rx_recycle);
1107 netif_start_queue(dev);
1108 return 0;
1109}
1110
1111/**
1112 * stmmac_release - close entry point of the driver
1113 * @dev : device pointer.
1114 * Description:
1115 * This is the stop entry point of the driver.
1116 */
1117static int stmmac_release(struct net_device *dev)
1118{
1119 struct stmmac_priv *priv = netdev_priv(dev);
1120
1121 /* Stop and disconnect the PHY */
1122 if (priv->phydev) {
1123 phy_stop(priv->phydev);
1124 phy_disconnect(priv->phydev);
1125 priv->phydev = NULL;
1126 }
1127
1128 netif_stop_queue(dev);
1129
1130#ifdef CONFIG_STMMAC_TIMER
1131 /* Stop and release the timer */
1132 stmmac_close_ext_timer();
1133 if (priv->tm != NULL)
1134 kfree(priv->tm);
1135#endif
1136 napi_disable(&priv->napi);
1137 skb_queue_purge(&priv->rx_recycle);
1138
1139 /* Free the IRQ lines */
1140 free_irq(dev->irq, dev);
1141
1142 /* Stop TX/RX DMA and clear the descriptors */
1143 stmmac_dma_stop_tx(dev->base_addr);
1144 stmmac_dma_stop_rx(dev->base_addr);
1145
1146 /* Release and free the Rx/Tx resources */
1147 free_dma_desc_resources(priv);
1148
1149 /* Disable the MAC core */
1150 stmmac_mac_disable_tx(dev->base_addr);
1151 stmmac_mac_disable_rx(dev->base_addr);
1152
1153 netif_carrier_off(dev);
1154
1155 return 0;
1156}
1157
1158/*
1159 * To perform emulated hardware segmentation on skb.
1160 */
1161static int stmmac_sw_tso(struct stmmac_priv *priv, struct sk_buff *skb)
1162{
1163 struct sk_buff *segs, *curr_skb;
1164 int gso_segs = skb_shinfo(skb)->gso_segs;
1165
1166 /* Estimate the number of fragments in the worst case */
1167 if (unlikely(stmmac_tx_avail(priv) < gso_segs)) {
1168 netif_stop_queue(priv->dev);
1169 TX_DBG(KERN_ERR "%s: TSO BUG! Tx Ring full when queue awake\n",
1170 __func__);
1171 if (stmmac_tx_avail(priv) < gso_segs)
1172 return NETDEV_TX_BUSY;
1173
1174 netif_wake_queue(priv->dev);
1175 }
1176 TX_DBG("\tstmmac_sw_tso: segmenting: skb %p (len %d)\n",
1177 skb, skb->len);
1178
1179 segs = skb_gso_segment(skb, priv->dev->features & ~NETIF_F_TSO);
1180 if (unlikely(IS_ERR(segs)))
1181 goto sw_tso_end;
1182
1183 do {
1184 curr_skb = segs;
1185 segs = segs->next;
1186 TX_DBG("\t\tcurrent skb->len: %d, *curr %p,"
1187 "*next %p\n", curr_skb->len, curr_skb, segs);
1188 curr_skb->next = NULL;
1189 stmmac_xmit(curr_skb, priv->dev);
1190 } while (segs);
1191
1192sw_tso_end:
1193 dev_kfree_skb(skb);
1194
1195 return NETDEV_TX_OK;
1196}
1197
1198static unsigned int stmmac_handle_jumbo_frames(struct sk_buff *skb,
1199 struct net_device *dev,
1200 int csum_insertion)
1201{
1202 struct stmmac_priv *priv = netdev_priv(dev);
1203 unsigned int nopaged_len = skb_headlen(skb);
1204 unsigned int txsize = priv->dma_tx_size;
1205 unsigned int entry = priv->cur_tx % txsize;
1206 struct dma_desc *desc = priv->dma_tx + entry;
1207
1208 if (nopaged_len > BUF_SIZE_8KiB) {
1209
1210 int buf2_size = nopaged_len - BUF_SIZE_8KiB;
1211
1212 desc->des2 = dma_map_single(priv->device, skb->data,
1213 BUF_SIZE_8KiB, DMA_TO_DEVICE);
1214 desc->des3 = desc->des2 + BUF_SIZE_4KiB;
1215 priv->mac_type->ops->prepare_tx_desc(desc, 1, BUF_SIZE_8KiB,
1216 csum_insertion);
1217
1218 entry = (++priv->cur_tx) % txsize;
1219 desc = priv->dma_tx + entry;
1220
1221 desc->des2 = dma_map_single(priv->device,
1222 skb->data + BUF_SIZE_8KiB,
1223 buf2_size, DMA_TO_DEVICE);
1224 desc->des3 = desc->des2 + BUF_SIZE_4KiB;
1225 priv->mac_type->ops->prepare_tx_desc(desc, 0,
1226 buf2_size, csum_insertion);
1227 priv->mac_type->ops->set_tx_owner(desc);
1228 priv->tx_skbuff[entry] = NULL;
1229 } else {
1230 desc->des2 = dma_map_single(priv->device, skb->data,
1231 nopaged_len, DMA_TO_DEVICE);
1232 desc->des3 = desc->des2 + BUF_SIZE_4KiB;
1233 priv->mac_type->ops->prepare_tx_desc(desc, 1, nopaged_len,
1234 csum_insertion);
1235 }
1236 return entry;
1237}
1238
1239/**
1240 * stmmac_xmit:
1241 * @skb : the socket buffer
1242 * @dev : device pointer
1243 * Description : Tx entry point of the driver.
1244 */
1245static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
1246{
1247 struct stmmac_priv *priv = netdev_priv(dev);
1248 unsigned int txsize = priv->dma_tx_size;
1249 unsigned int entry;
1250 int i, csum_insertion = 0;
1251 int nfrags = skb_shinfo(skb)->nr_frags;
1252 struct dma_desc *desc, *first;
1253
1254 if (unlikely(stmmac_tx_avail(priv) < nfrags + 1)) {
1255 if (!netif_queue_stopped(dev)) {
1256 netif_stop_queue(dev);
1257 /* This is a hard error, log it. */
1258 pr_err("%s: BUG! Tx Ring full when queue awake\n",
1259 __func__);
1260 }
1261 return NETDEV_TX_BUSY;
1262 }
1263
1264 entry = priv->cur_tx % txsize;
1265
1266#ifdef STMMAC_XMIT_DEBUG
1267 if ((skb->len > ETH_FRAME_LEN) || nfrags)
1268 pr_info("stmmac xmit:\n"
1269 "\tskb addr %p - len: %d - nopaged_len: %d\n"
1270 "\tn_frags: %d - ip_summed: %d - %s gso\n",
1271 skb, skb->len, skb_headlen(skb), nfrags, skb->ip_summed,
1272 !skb_is_gso(skb) ? "isn't" : "is");
1273#endif
1274
1275 if (unlikely(skb_is_gso(skb)))
1276 return stmmac_sw_tso(priv, skb);
1277
1278 if (likely((skb->ip_summed == CHECKSUM_PARTIAL))) {
1279 if (likely(priv->tx_coe == NO_HW_CSUM))
1280 skb_checksum_help(skb);
1281 else
1282 csum_insertion = 1;
1283 }
1284
1285 desc = priv->dma_tx + entry;
1286 first = desc;
1287
1288#ifdef STMMAC_XMIT_DEBUG
1289 if ((nfrags > 0) || (skb->len > ETH_FRAME_LEN))
1290 pr_debug("stmmac xmit: skb len: %d, nopaged_len: %d,\n"
1291 "\t\tn_frags: %d, ip_summed: %d\n",
1292 skb->len, skb_headlen(skb), nfrags, skb->ip_summed);
1293#endif
1294 priv->tx_skbuff[entry] = skb;
1295 if (unlikely(skb->len >= BUF_SIZE_4KiB)) {
1296 entry = stmmac_handle_jumbo_frames(skb, dev, csum_insertion);
1297 desc = priv->dma_tx + entry;
1298 } else {
1299 unsigned int nopaged_len = skb_headlen(skb);
1300 desc->des2 = dma_map_single(priv->device, skb->data,
1301 nopaged_len, DMA_TO_DEVICE);
1302 priv->mac_type->ops->prepare_tx_desc(desc, 1, nopaged_len,
1303 csum_insertion);
1304 }
1305
1306 for (i = 0; i < nfrags; i++) {
1307 skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
1308 int len = frag->size;
1309
1310 entry = (++priv->cur_tx) % txsize;
1311 desc = priv->dma_tx + entry;
1312
1313 TX_DBG("\t[entry %d] segment len: %d\n", entry, len);
1314 desc->des2 = dma_map_page(priv->device, frag->page,
1315 frag->page_offset,
1316 len, DMA_TO_DEVICE);
1317 priv->tx_skbuff[entry] = NULL;
1318 priv->mac_type->ops->prepare_tx_desc(desc, 0, len,
1319 csum_insertion);
1320 priv->mac_type->ops->set_tx_owner(desc);
1321 }
1322
1323 /* Interrupt on completition only for the latest segment */
1324 priv->mac_type->ops->close_tx_desc(desc);
1325#ifdef CONFIG_STMMAC_TIMER
1326 /* Clean IC while using timers */
1327 priv->mac_type->ops->clear_tx_ic(desc);
1328#endif
1329 /* To avoid raise condition */
1330 priv->mac_type->ops->set_tx_owner(first);
1331
1332 priv->cur_tx++;
1333
1334#ifdef STMMAC_XMIT_DEBUG
1335 if (netif_msg_pktdata(priv)) {
1336 pr_info("stmmac xmit: current=%d, dirty=%d, entry=%d, "
1337 "first=%p, nfrags=%d\n",
1338 (priv->cur_tx % txsize), (priv->dirty_tx % txsize),
1339 entry, first, nfrags);
1340 display_ring(priv->dma_tx, txsize);
1341 pr_info(">>> frame to be transmitted: ");
1342 print_pkt(skb->data, skb->len);
1343 }
1344#endif
1345 if (unlikely(stmmac_tx_avail(priv) <= (MAX_SKB_FRAGS + 1))) {
1346 TX_DBG("%s: stop transmitted packets\n", __func__);
1347 netif_stop_queue(dev);
1348 }
1349
1350 dev->stats.tx_bytes += skb->len;
1351
1352 /* CSR1 enables the transmit DMA to check for new descriptor */
1353 writel(1, dev->base_addr + DMA_XMT_POLL_DEMAND);
1354
1355 return NETDEV_TX_OK;
1356}
1357
1358static inline void stmmac_rx_refill(struct stmmac_priv *priv)
1359{
1360 unsigned int rxsize = priv->dma_rx_size;
1361 int bfsize = priv->dma_buf_sz;
1362 struct dma_desc *p = priv->dma_rx;
1363
1364 for (; priv->cur_rx - priv->dirty_rx > 0; priv->dirty_rx++) {
1365 unsigned int entry = priv->dirty_rx % rxsize;
1366 if (likely(priv->rx_skbuff[entry] == NULL)) {
1367 struct sk_buff *skb;
1368
1369 skb = __skb_dequeue(&priv->rx_recycle);
1370 if (skb == NULL)
1371 skb = netdev_alloc_skb_ip_align(priv->dev,
1372 bfsize);
1373
1374 if (unlikely(skb == NULL))
1375 break;
1376
1377 priv->rx_skbuff[entry] = skb;
1378 priv->rx_skbuff_dma[entry] =
1379 dma_map_single(priv->device, skb->data, bfsize,
1380 DMA_FROM_DEVICE);
1381
1382 (p + entry)->des2 = priv->rx_skbuff_dma[entry];
1383 if (unlikely(priv->is_gmac)) {
1384 if (bfsize >= BUF_SIZE_8KiB)
1385 (p + entry)->des3 =
1386 (p + entry)->des2 + BUF_SIZE_8KiB;
1387 }
1388 RX_DBG(KERN_INFO "\trefill entry #%d\n", entry);
1389 }
1390 priv->mac_type->ops->set_rx_owner(p + entry);
1391 }
1392 return;
1393}
1394
1395static int stmmac_rx(struct stmmac_priv *priv, int limit)
1396{
1397 unsigned int rxsize = priv->dma_rx_size;
1398 unsigned int entry = priv->cur_rx % rxsize;
1399 unsigned int next_entry;
1400 unsigned int count = 0;
1401 struct dma_desc *p = priv->dma_rx + entry;
1402 struct dma_desc *p_next;
1403
1404#ifdef STMMAC_RX_DEBUG
1405 if (netif_msg_hw(priv)) {
1406 pr_debug(">>> stmmac_rx: descriptor ring:\n");
1407 display_ring(priv->dma_rx, rxsize);
1408 }
1409#endif
1410 count = 0;
1411 while (!priv->mac_type->ops->get_rx_owner(p)) {
1412 int status;
1413
1414 if (count >= limit)
1415 break;
1416
1417 count++;
1418
1419 next_entry = (++priv->cur_rx) % rxsize;
1420 p_next = priv->dma_rx + next_entry;
1421 prefetch(p_next);
1422
1423 /* read the status of the incoming frame */
1424 status = (priv->mac_type->ops->rx_status(&priv->dev->stats,
1425 &priv->xstats, p));
1426 if (unlikely(status == discard_frame))
1427 priv->dev->stats.rx_errors++;
1428 else {
1429 struct sk_buff *skb;
1430 /* Length should omit the CRC */
1431 int frame_len =
1432 priv->mac_type->ops->get_rx_frame_len(p) - 4;
1433
1434#ifdef STMMAC_RX_DEBUG
1435 if (frame_len > ETH_FRAME_LEN)
1436 pr_debug("\tRX frame size %d, COE status: %d\n",
1437 frame_len, status);
1438
1439 if (netif_msg_hw(priv))
1440 pr_debug("\tdesc: %p [entry %d] buff=0x%x\n",
1441 p, entry, p->des2);
1442#endif
1443 skb = priv->rx_skbuff[entry];
1444 if (unlikely(!skb)) {
1445 pr_err("%s: Inconsistent Rx descriptor chain\n",
1446 priv->dev->name);
1447 priv->dev->stats.rx_dropped++;
1448 break;
1449 }
1450 prefetch(skb->data - NET_IP_ALIGN);
1451 priv->rx_skbuff[entry] = NULL;
1452
1453 skb_put(skb, frame_len);
1454 dma_unmap_single(priv->device,
1455 priv->rx_skbuff_dma[entry],
1456 priv->dma_buf_sz, DMA_FROM_DEVICE);
1457#ifdef STMMAC_RX_DEBUG
1458 if (netif_msg_pktdata(priv)) {
1459 pr_info(" frame received (%dbytes)", frame_len);
1460 print_pkt(skb->data, frame_len);
1461 }
1462#endif
1463 skb->protocol = eth_type_trans(skb, priv->dev);
1464
1465 if (unlikely(status == csum_none)) {
1466 /* always for the old mac 10/100 */
1467 skb->ip_summed = CHECKSUM_NONE;
1468 netif_receive_skb(skb);
1469 } else {
1470 skb->ip_summed = CHECKSUM_UNNECESSARY;
1471 napi_gro_receive(&priv->napi, skb);
1472 }
1473
1474 priv->dev->stats.rx_packets++;
1475 priv->dev->stats.rx_bytes += frame_len;
1476 priv->dev->last_rx = jiffies;
1477 }
1478 entry = next_entry;
1479 p = p_next; /* use prefetched values */
1480 }
1481
1482 stmmac_rx_refill(priv);
1483
1484 priv->xstats.rx_pkt_n += count;
1485
1486 return count;
1487}
1488
1489/**
1490 * stmmac_poll - stmmac poll method (NAPI)
1491 * @napi : pointer to the napi structure.
1492 * @budget : maximum number of packets that the current CPU can receive from
1493 * all interfaces.
1494 * Description :
1495 * This function implements the the reception process.
1496 * Also it runs the TX completion thread
1497 */
1498static int stmmac_poll(struct napi_struct *napi, int budget)
1499{
1500 struct stmmac_priv *priv = container_of(napi, struct stmmac_priv, napi);
1501 int work_done = 0;
1502
1503 priv->xstats.poll_n++;
1504 stmmac_tx(priv);
1505 work_done = stmmac_rx(priv, budget);
1506
1507 if (work_done < budget) {
1508 napi_complete(napi);
1509 stmmac_enable_irq(priv);
1510 }
1511 return work_done;
1512}
1513
1514/**
1515 * stmmac_tx_timeout
1516 * @dev : Pointer to net device structure
1517 * Description: this function is called when a packet transmission fails to
1518 * complete within a reasonable tmrate. The driver will mark the error in the
1519 * netdev structure and arrange for the device to be reset to a sane state
1520 * in order to transmit a new packet.
1521 */
1522static void stmmac_tx_timeout(struct net_device *dev)
1523{
1524 struct stmmac_priv *priv = netdev_priv(dev);
1525
1526 /* Clear Tx resources and restart transmitting again */
1527 stmmac_tx_err(priv);
1528 return;
1529}
1530
1531/* Configuration changes (passed on by ifconfig) */
1532static int stmmac_config(struct net_device *dev, struct ifmap *map)
1533{
1534 if (dev->flags & IFF_UP) /* can't act on a running interface */
1535 return -EBUSY;
1536
1537 /* Don't allow changing the I/O address */
1538 if (map->base_addr != dev->base_addr) {
1539 pr_warning("%s: can't change I/O address\n", dev->name);
1540 return -EOPNOTSUPP;
1541 }
1542
1543 /* Don't allow changing the IRQ */
1544 if (map->irq != dev->irq) {
1545 pr_warning("%s: can't change IRQ number %d\n",
1546 dev->name, dev->irq);
1547 return -EOPNOTSUPP;
1548 }
1549
1550 /* ignore other fields */
1551 return 0;
1552}
1553
1554/**
1555 * stmmac_multicast_list - entry point for multicast addressing
1556 * @dev : pointer to the device structure
1557 * Description:
1558 * This function is a driver entry point which gets called by the kernel
1559 * whenever multicast addresses must be enabled/disabled.
1560 * Return value:
1561 * void.
1562 */
1563static void stmmac_multicast_list(struct net_device *dev)
1564{
1565 struct stmmac_priv *priv = netdev_priv(dev);
1566
1567 spin_lock(&priv->lock);
1568 priv->mac_type->ops->set_filter(dev);
1569 spin_unlock(&priv->lock);
1570 return;
1571}
1572
1573/**
1574 * stmmac_change_mtu - entry point to change MTU size for the device.
1575 * @dev : device pointer.
1576 * @new_mtu : the new MTU size for the device.
1577 * Description: the Maximum Transfer Unit (MTU) is used by the network layer
1578 * to drive packet transmission. Ethernet has an MTU of 1500 octets
1579 * (ETH_DATA_LEN). This value can be changed with ifconfig.
1580 * Return value:
1581 * 0 on success and an appropriate (-)ve integer as defined in errno.h
1582 * file on failure.
1583 */
1584static int stmmac_change_mtu(struct net_device *dev, int new_mtu)
1585{
1586 struct stmmac_priv *priv = netdev_priv(dev);
1587 int max_mtu;
1588
1589 if (netif_running(dev)) {
1590 pr_err("%s: must be stopped to change its MTU\n", dev->name);
1591 return -EBUSY;
1592 }
1593
1594 if (priv->is_gmac)
1595 max_mtu = JUMBO_LEN;
1596 else
1597 max_mtu = ETH_DATA_LEN;
1598
1599 if ((new_mtu < 46) || (new_mtu > max_mtu)) {
1600 pr_err("%s: invalid MTU, max MTU is: %d\n", dev->name, max_mtu);
1601 return -EINVAL;
1602 }
1603
1604 dev->mtu = new_mtu;
1605
1606 return 0;
1607}
1608
1609static irqreturn_t stmmac_interrupt(int irq, void *dev_id)
1610{
1611 struct net_device *dev = (struct net_device *)dev_id;
1612 struct stmmac_priv *priv = netdev_priv(dev);
1613
1614 if (unlikely(!dev)) {
1615 pr_err("%s: invalid dev pointer\n", __func__);
1616 return IRQ_NONE;
1617 }
1618
1619 if (priv->is_gmac) {
1620 unsigned long ioaddr = dev->base_addr;
1621 /* To handle GMAC own interrupts */
1622 priv->mac_type->ops->host_irq_status(ioaddr);
1623 }
1624 stmmac_dma_interrupt(dev);
1625
1626 return IRQ_HANDLED;
1627}
1628
1629#ifdef CONFIG_NET_POLL_CONTROLLER
1630/* Polling receive - used by NETCONSOLE and other diagnostic tools
1631 * to allow network I/O with interrupts disabled. */
1632static void stmmac_poll_controller(struct net_device *dev)
1633{
1634 disable_irq(dev->irq);
1635 stmmac_interrupt(dev->irq, dev);
1636 enable_irq(dev->irq);
1637}
1638#endif
1639
1640/**
1641 * stmmac_ioctl - Entry point for the Ioctl
1642 * @dev: Device pointer.
1643 * @rq: An IOCTL specefic structure, that can contain a pointer to
1644 * a proprietary structure used to pass information to the driver.
1645 * @cmd: IOCTL command
1646 * Description:
1647 * Currently there are no special functionality supported in IOCTL, just the
1648 * phy_mii_ioctl(...) can be invoked.
1649 */
1650static int stmmac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
1651{
1652 struct stmmac_priv *priv = netdev_priv(dev);
1653 int ret = -EOPNOTSUPP;
1654
1655 if (!netif_running(dev))
1656 return -EINVAL;
1657
1658 switch (cmd) {
1659 case SIOCGMIIPHY:
1660 case SIOCGMIIREG:
1661 case SIOCSMIIREG:
1662 if (!priv->phydev)
1663 return -EINVAL;
1664
1665 spin_lock(&priv->lock);
1666 ret = phy_mii_ioctl(priv->phydev, if_mii(rq), cmd);
1667 spin_unlock(&priv->lock);
1668 default:
1669 break;
1670 }
1671 return ret;
1672}
1673
1674#ifdef STMMAC_VLAN_TAG_USED
1675static void stmmac_vlan_rx_register(struct net_device *dev,
1676 struct vlan_group *grp)
1677{
1678 struct stmmac_priv *priv = netdev_priv(dev);
1679
1680 DBG(probe, INFO, "%s: Setting vlgrp to %p\n", dev->name, grp);
1681
1682 spin_lock(&priv->lock);
1683 priv->vlgrp = grp;
1684 spin_unlock(&priv->lock);
1685
1686 return;
1687}
1688#endif
1689
1690static const struct net_device_ops stmmac_netdev_ops = {
1691 .ndo_open = stmmac_open,
1692 .ndo_start_xmit = stmmac_xmit,
1693 .ndo_stop = stmmac_release,
1694 .ndo_change_mtu = stmmac_change_mtu,
1695 .ndo_set_multicast_list = stmmac_multicast_list,
1696 .ndo_tx_timeout = stmmac_tx_timeout,
1697 .ndo_do_ioctl = stmmac_ioctl,
1698 .ndo_set_config = stmmac_config,
1699#ifdef STMMAC_VLAN_TAG_USED
1700 .ndo_vlan_rx_register = stmmac_vlan_rx_register,
1701#endif
1702#ifdef CONFIG_NET_POLL_CONTROLLER
1703 .ndo_poll_controller = stmmac_poll_controller,
1704#endif
1705 .ndo_set_mac_address = eth_mac_addr,
1706};
1707
1708/**
1709 * stmmac_probe - Initialization of the adapter .
1710 * @dev : device pointer
1711 * Description: The function initializes the network device structure for
1712 * the STMMAC driver. It also calls the low level routines
1713 * in order to init the HW (i.e. the DMA engine)
1714 */
1715static int stmmac_probe(struct net_device *dev)
1716{
1717 int ret = 0;
1718 struct stmmac_priv *priv = netdev_priv(dev);
1719
1720 ether_setup(dev);
1721
1722 dev->netdev_ops = &stmmac_netdev_ops;
1723 stmmac_set_ethtool_ops(dev);
1724
1725 dev->features |= (NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_HIGHDMA);
1726 dev->watchdog_timeo = msecs_to_jiffies(watchdog);
1727#ifdef STMMAC_VLAN_TAG_USED
1728 /* Both mac100 and gmac support receive VLAN tag detection */
1729 dev->features |= NETIF_F_HW_VLAN_RX;
1730#endif
1731 priv->msg_enable = netif_msg_init(debug, default_msg_level);
1732
1733 if (priv->is_gmac)
1734 priv->rx_csum = 1;
1735
1736 if (flow_ctrl)
1737 priv->flow_ctrl = FLOW_AUTO; /* RX/TX pause on */
1738
1739 priv->pause = pause;
1740 netif_napi_add(dev, &priv->napi, stmmac_poll, 64);
1741
1742 /* Get the MAC address */
1743 priv->mac_type->ops->get_umac_addr(dev->base_addr, dev->dev_addr, 0);
1744
1745 if (!is_valid_ether_addr(dev->dev_addr))
1746 pr_warning("\tno valid MAC address;"
1747 "please, use ifconfig or nwhwconfig!\n");
1748
1749 ret = register_netdev(dev);
1750 if (ret) {
1751 pr_err("%s: ERROR %i registering the device\n",
1752 __func__, ret);
1753 return -ENODEV;
1754 }
1755
1756 DBG(probe, DEBUG, "%s: Scatter/Gather: %s - HW checksums: %s\n",
1757 dev->name, (dev->features & NETIF_F_SG) ? "on" : "off",
1758 (dev->features & NETIF_F_HW_CSUM) ? "on" : "off");
1759
1760 spin_lock_init(&priv->lock);
1761
1762 return ret;
1763}
1764
1765/**
1766 * stmmac_mac_device_setup
1767 * @dev : device pointer
1768 * Description: select and initialise the mac device (mac100 or Gmac).
1769 */
1770static int stmmac_mac_device_setup(struct net_device *dev)
1771{
1772 struct stmmac_priv *priv = netdev_priv(dev);
1773 unsigned long ioaddr = dev->base_addr;
1774
1775 struct mac_device_info *device;
1776
1777 if (priv->is_gmac)
1778 device = gmac_setup(ioaddr);
1779 else
1780 device = mac100_setup(ioaddr);
1781
1782 if (!device)
1783 return -ENOMEM;
1784
1785 priv->mac_type = device;
1786
1787 priv->wolenabled = priv->mac_type->hw.pmt; /* PMT supported */
1788 if (priv->wolenabled == PMT_SUPPORTED)
1789 priv->wolopts = WAKE_MAGIC; /* Magic Frame */
1790
1791 return 0;
1792}
1793
1794static int stmmacphy_dvr_probe(struct platform_device *pdev)
1795{
1796 struct plat_stmmacphy_data *plat_dat;
1797 plat_dat = (struct plat_stmmacphy_data *)((pdev->dev).platform_data);
1798
1799 pr_debug("stmmacphy_dvr_probe: added phy for bus %d\n",
1800 plat_dat->bus_id);
1801
1802 return 0;
1803}
1804
1805static int stmmacphy_dvr_remove(struct platform_device *pdev)
1806{
1807 return 0;
1808}
1809
1810static struct platform_driver stmmacphy_driver = {
1811 .driver = {
1812 .name = PHY_RESOURCE_NAME,
1813 },
1814 .probe = stmmacphy_dvr_probe,
1815 .remove = stmmacphy_dvr_remove,
1816};
1817
1818/**
1819 * stmmac_associate_phy
1820 * @dev: pointer to device structure
1821 * @data: points to the private structure.
1822 * Description: Scans through all the PHYs we have registered and checks if
1823 * any are associated with our MAC. If so, then just fill in
1824 * the blanks in our local context structure
1825 */
1826static int stmmac_associate_phy(struct device *dev, void *data)
1827{
1828 struct stmmac_priv *priv = (struct stmmac_priv *)data;
1829 struct plat_stmmacphy_data *plat_dat;
1830
1831 plat_dat = (struct plat_stmmacphy_data *)(dev->platform_data);
1832
1833 DBG(probe, DEBUG, "%s: checking phy for bus %d\n", __func__,
1834 plat_dat->bus_id);
1835
1836 /* Check that this phy is for the MAC being initialised */
1837 if (priv->bus_id != plat_dat->bus_id)
1838 return 0;
1839
1840 /* OK, this PHY is connected to the MAC.
1841 Go ahead and get the parameters */
1842 DBG(probe, DEBUG, "%s: OK. Found PHY config\n", __func__);
1843 priv->phy_irq =
1844 platform_get_irq_byname(to_platform_device(dev), "phyirq");
1845 DBG(probe, DEBUG, "%s: PHY irq on bus %d is %d\n", __func__,
1846 plat_dat->bus_id, priv->phy_irq);
1847
1848 /* Override with kernel parameters if supplied XXX CRS XXX
1849 * this needs to have multiple instances */
1850 if ((phyaddr >= 0) && (phyaddr <= 31))
1851 plat_dat->phy_addr = phyaddr;
1852
1853 priv->phy_addr = plat_dat->phy_addr;
1854 priv->phy_mask = plat_dat->phy_mask;
1855 priv->phy_interface = plat_dat->interface;
1856 priv->phy_reset = plat_dat->phy_reset;
1857
1858 DBG(probe, DEBUG, "%s: exiting\n", __func__);
1859 return 1; /* forces exit of driver_for_each_device() */
1860}
1861
1862/**
1863 * stmmac_dvr_probe
1864 * @pdev: platform device pointer
1865 * Description: the driver is initialized through platform_device.
1866 */
1867static int stmmac_dvr_probe(struct platform_device *pdev)
1868{
1869 int ret = 0;
1870 struct resource *res;
1871 unsigned int *addr = NULL;
1872 struct net_device *ndev = NULL;
1873 struct stmmac_priv *priv;
1874 struct plat_stmmacenet_data *plat_dat;
1875
1876 pr_info("STMMAC driver:\n\tplatform registration... ");
1877 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1878 if (!res) {
1879 ret = -ENODEV;
1880 goto out;
1881 }
1882 pr_info("done!\n");
1883
1884 if (!request_mem_region(res->start, (res->end - res->start),
1885 pdev->name)) {
1886 pr_err("%s: ERROR: memory allocation failed"
1887 "cannot get the I/O addr 0x%x\n",
1888 __func__, (unsigned int)res->start);
1889 ret = -EBUSY;
1890 goto out;
1891 }
1892
1893 addr = ioremap(res->start, (res->end - res->start));
1894 if (!addr) {
1895 pr_err("%s: ERROR: memory mapping failed \n", __func__);
1896 ret = -ENOMEM;
1897 goto out;
1898 }
1899
1900 ndev = alloc_etherdev(sizeof(struct stmmac_priv));
1901 if (!ndev) {
1902 pr_err("%s: ERROR: allocating the device\n", __func__);
1903 ret = -ENOMEM;
1904 goto out;
1905 }
1906
1907 SET_NETDEV_DEV(ndev, &pdev->dev);
1908
1909 /* Get the MAC information */
1910 ndev->irq = platform_get_irq_byname(pdev, "macirq");
1911 if (ndev->irq == -ENXIO) {
1912 pr_err("%s: ERROR: MAC IRQ configuration "
1913 "information not found\n", __func__);
1914 ret = -ENODEV;
1915 goto out;
1916 }
1917
1918 priv = netdev_priv(ndev);
1919 priv->device = &(pdev->dev);
1920 priv->dev = ndev;
1921 plat_dat = (struct plat_stmmacenet_data *)((pdev->dev).platform_data);
1922 priv->bus_id = plat_dat->bus_id;
1923 priv->pbl = plat_dat->pbl; /* TLI */
1924 priv->is_gmac = plat_dat->has_gmac; /* GMAC is on board */
1925
1926 platform_set_drvdata(pdev, ndev);
1927
1928 /* Set the I/O base addr */
1929 ndev->base_addr = (unsigned long)addr;
1930
1931 /* MAC HW revice detection */
1932 ret = stmmac_mac_device_setup(ndev);
1933 if (ret < 0)
1934 goto out;
1935
1936 /* Network Device Registration */
1937 ret = stmmac_probe(ndev);
1938 if (ret < 0)
1939 goto out;
1940
1941 /* associate a PHY - it is provided by another platform bus */
1942 if (!driver_for_each_device
1943 (&(stmmacphy_driver.driver), NULL, (void *)priv,
1944 stmmac_associate_phy)) {
1945 pr_err("No PHY device is associated with this MAC!\n");
1946 ret = -ENODEV;
1947 goto out;
1948 }
1949
1950 priv->fix_mac_speed = plat_dat->fix_mac_speed;
1951 priv->bsp_priv = plat_dat->bsp_priv;
1952
1953 pr_info("\t%s - (dev. name: %s - id: %d, IRQ #%d\n"
1954 "\tIO base addr: 0x%08x)\n", ndev->name, pdev->name,
1955 pdev->id, ndev->irq, (unsigned int)addr);
1956
1957 /* MDIO bus Registration */
1958 pr_debug("\tMDIO bus (id: %d)...", priv->bus_id);
1959 ret = stmmac_mdio_register(ndev);
1960 if (ret < 0)
1961 goto out;
1962 pr_debug("registered!\n");
1963
1964out:
1965 if (ret < 0) {
1966 platform_set_drvdata(pdev, NULL);
1967 release_mem_region(res->start, (res->end - res->start));
1968 if (addr != NULL)
1969 iounmap(addr);
1970 }
1971
1972 return ret;
1973}
1974
1975/**
1976 * stmmac_dvr_remove
1977 * @pdev: platform device pointer
1978 * Description: this function resets the TX/RX processes, disables the MAC RX/TX
1979 * changes the link status, releases the DMA descriptor rings,
1980 * unregisters the MDIO bus and unmaps the allocated memory.
1981 */
1982static int stmmac_dvr_remove(struct platform_device *pdev)
1983{
1984 struct net_device *ndev = platform_get_drvdata(pdev);
1985 struct resource *res;
1986
1987 pr_info("%s:\n\tremoving driver", __func__);
1988
1989 stmmac_dma_stop_rx(ndev->base_addr);
1990 stmmac_dma_stop_tx(ndev->base_addr);
1991
1992 stmmac_mac_disable_rx(ndev->base_addr);
1993 stmmac_mac_disable_tx(ndev->base_addr);
1994
1995 netif_carrier_off(ndev);
1996
1997 stmmac_mdio_unregister(ndev);
1998
1999 platform_set_drvdata(pdev, NULL);
2000 unregister_netdev(ndev);
2001
2002 iounmap((void *)ndev->base_addr);
2003 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2004 release_mem_region(res->start, (res->end - res->start));
2005
2006 free_netdev(ndev);
2007
2008 return 0;
2009}
2010
2011#ifdef CONFIG_PM
2012static int stmmac_suspend(struct platform_device *pdev, pm_message_t state)
2013{
2014 struct net_device *dev = platform_get_drvdata(pdev);
2015 struct stmmac_priv *priv = netdev_priv(dev);
2016 int dis_ic = 0;
2017
2018 if (!dev || !netif_running(dev))
2019 return 0;
2020
2021 spin_lock(&priv->lock);
2022
2023 if (state.event == PM_EVENT_SUSPEND) {
2024 netif_device_detach(dev);
2025 netif_stop_queue(dev);
2026 if (priv->phydev)
2027 phy_stop(priv->phydev);
2028
2029#ifdef CONFIG_STMMAC_TIMER
2030 priv->tm->timer_stop();
2031 dis_ic = 1;
2032#endif
2033 napi_disable(&priv->napi);
2034
2035 /* Stop TX/RX DMA */
2036 stmmac_dma_stop_tx(dev->base_addr);
2037 stmmac_dma_stop_rx(dev->base_addr);
2038 /* Clear the Rx/Tx descriptors */
2039 priv->mac_type->ops->init_rx_desc(priv->dma_rx,
2040 priv->dma_rx_size, dis_ic);
2041 priv->mac_type->ops->init_tx_desc(priv->dma_tx,
2042 priv->dma_tx_size);
2043
2044 stmmac_mac_disable_tx(dev->base_addr);
2045
2046 if (device_may_wakeup(&(pdev->dev))) {
2047 /* Enable Power down mode by programming the PMT regs */
2048 if (priv->wolenabled == PMT_SUPPORTED)
2049 priv->mac_type->ops->pmt(dev->base_addr,
2050 priv->wolopts);
2051 } else {
2052 stmmac_mac_disable_rx(dev->base_addr);
2053 }
2054 } else {
2055 priv->shutdown = 1;
2056 /* Although this can appear slightly redundant it actually
2057 * makes fast the standby operation and guarantees the driver
2058 * working if hibernation is on media. */
2059 stmmac_release(dev);
2060 }
2061
2062 spin_unlock(&priv->lock);
2063 return 0;
2064}
2065
2066static int stmmac_resume(struct platform_device *pdev)
2067{
2068 struct net_device *dev = platform_get_drvdata(pdev);
2069 struct stmmac_priv *priv = netdev_priv(dev);
2070 unsigned long ioaddr = dev->base_addr;
2071
2072 if (!netif_running(dev))
2073 return 0;
2074
2075 spin_lock(&priv->lock);
2076
2077 if (priv->shutdown) {
2078 /* Re-open the interface and re-init the MAC/DMA
2079 and the rings. */
2080 stmmac_open(dev);
2081 goto out_resume;
2082 }
2083
2084 /* Power Down bit, into the PM register, is cleared
2085 * automatically as soon as a magic packet or a Wake-up frame
2086 * is received. Anyway, it's better to manually clear
2087 * this bit because it can generate problems while resuming
2088 * from another devices (e.g. serial console). */
2089 if (device_may_wakeup(&(pdev->dev)))
2090 if (priv->wolenabled == PMT_SUPPORTED)
2091 priv->mac_type->ops->pmt(dev->base_addr, 0);
2092
2093 netif_device_attach(dev);
2094
2095 /* Enable the MAC and DMA */
2096 stmmac_mac_enable_rx(ioaddr);
2097 stmmac_mac_enable_tx(ioaddr);
2098 stmmac_dma_start_tx(ioaddr);
2099 stmmac_dma_start_rx(ioaddr);
2100
2101#ifdef CONFIG_STMMAC_TIMER
2102 priv->tm->timer_start(tmrate);
2103#endif
2104 napi_enable(&priv->napi);
2105
2106 if (priv->phydev)
2107 phy_start(priv->phydev);
2108
2109 netif_start_queue(dev);
2110
2111out_resume:
2112 spin_unlock(&priv->lock);
2113 return 0;
2114}
2115#endif
2116
2117static struct platform_driver stmmac_driver = {
2118 .driver = {
2119 .name = STMMAC_RESOURCE_NAME,
2120 },
2121 .probe = stmmac_dvr_probe,
2122 .remove = stmmac_dvr_remove,
2123#ifdef CONFIG_PM
2124 .suspend = stmmac_suspend,
2125 .resume = stmmac_resume,
2126#endif
2127
2128};
2129
2130/**
2131 * stmmac_init_module - Entry point for the driver
2132 * Description: This function is the entry point for the driver.
2133 */
2134static int __init stmmac_init_module(void)
2135{
2136 int ret;
2137
2138 if (platform_driver_register(&stmmacphy_driver)) {
2139 pr_err("No PHY devices registered!\n");
2140 return -ENODEV;
2141 }
2142
2143 ret = platform_driver_register(&stmmac_driver);
2144 return ret;
2145}
2146
2147/**
2148 * stmmac_cleanup_module - Cleanup routine for the driver
2149 * Description: This function is the cleanup routine for the driver.
2150 */
2151static void __exit stmmac_cleanup_module(void)
2152{
2153 platform_driver_unregister(&stmmacphy_driver);
2154 platform_driver_unregister(&stmmac_driver);
2155}
2156
2157#ifndef MODULE
2158static int __init stmmac_cmdline_opt(char *str)
2159{
2160 char *opt;
2161
2162 if (!str || !*str)
2163 return -EINVAL;
2164 while ((opt = strsep(&str, ",")) != NULL) {
2165 if (!strncmp(opt, "debug:", 6))
2166 strict_strtoul(opt + 6, 0, (unsigned long *)&debug);
2167 else if (!strncmp(opt, "phyaddr:", 8))
2168 strict_strtoul(opt + 8, 0, (unsigned long *)&phyaddr);
2169 else if (!strncmp(opt, "dma_txsize:", 11))
2170 strict_strtoul(opt + 11, 0,
2171 (unsigned long *)&dma_txsize);
2172 else if (!strncmp(opt, "dma_rxsize:", 11))
2173 strict_strtoul(opt + 11, 0,
2174 (unsigned long *)&dma_rxsize);
2175 else if (!strncmp(opt, "buf_sz:", 7))
2176 strict_strtoul(opt + 7, 0, (unsigned long *)&buf_sz);
2177 else if (!strncmp(opt, "tc:", 3))
2178 strict_strtoul(opt + 3, 0, (unsigned long *)&tc);
2179 else if (!strncmp(opt, "tx_coe:", 7))
2180 strict_strtoul(opt + 7, 0, (unsigned long *)&tx_coe);
2181 else if (!strncmp(opt, "watchdog:", 9))
2182 strict_strtoul(opt + 9, 0, (unsigned long *)&watchdog);
2183 else if (!strncmp(opt, "flow_ctrl:", 10))
2184 strict_strtoul(opt + 10, 0,
2185 (unsigned long *)&flow_ctrl);
2186 else if (!strncmp(opt, "pause:", 6))
2187 strict_strtoul(opt + 6, 0, (unsigned long *)&pause);
2188#ifdef CONFIG_STMMAC_TIMER
2189 else if (!strncmp(opt, "tmrate:", 7))
2190 strict_strtoul(opt + 7, 0, (unsigned long *)&tmrate);
2191#endif
2192 }
2193 return 0;
2194}
2195
2196__setup("stmmaceth=", stmmac_cmdline_opt);
2197#endif
2198
2199module_init(stmmac_init_module);
2200module_exit(stmmac_cleanup_module);
2201
2202MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet driver");
2203MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>");
2204MODULE_LICENSE("GPL");
diff --git a/drivers/net/stmmac/stmmac_mdio.c b/drivers/net/stmmac/stmmac_mdio.c
new file mode 100644
index 000000000000..8498552a22fc
--- /dev/null
+++ b/drivers/net/stmmac/stmmac_mdio.c
@@ -0,0 +1,217 @@
1/*******************************************************************************
2 STMMAC Ethernet Driver -- MDIO bus implementation
3 Provides Bus interface for MII registers
4
5 Copyright (C) 2007-2009 STMicroelectronics Ltd
6
7 This program is free software; you can redistribute it and/or modify it
8 under the terms and conditions of the GNU General Public License,
9 version 2, as published by the Free Software Foundation.
10
11 This program is distributed in the hope it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 more details.
15
16 You should have received a copy of the GNU General Public License along with
17 this program; if not, write to the Free Software Foundation, Inc.,
18 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
19
20 The full GNU General Public License is included in this distribution in
21 the file called "COPYING".
22
23 Author: Carl Shaw <carl.shaw@st.com>
24 Maintainer: Giuseppe Cavallaro <peppe.cavallaro@st.com>
25*******************************************************************************/
26
27#include <linux/netdevice.h>
28#include <linux/mii.h>
29#include <linux/phy.h>
30
31#include "stmmac.h"
32
33#define MII_BUSY 0x00000001
34#define MII_WRITE 0x00000002
35
36/**
37 * stmmac_mdio_read
38 * @bus: points to the mii_bus structure
39 * @phyaddr: MII addr reg bits 15-11
40 * @phyreg: MII addr reg bits 10-6
41 * Description: it reads data from the MII register from within the phy device.
42 * For the 7111 GMAC, we must set the bit 0 in the MII address register while
43 * accessing the PHY registers.
44 * Fortunately, it seems this has no drawback for the 7109 MAC.
45 */
46static int stmmac_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
47{
48 struct net_device *ndev = bus->priv;
49 struct stmmac_priv *priv = netdev_priv(ndev);
50 unsigned long ioaddr = ndev->base_addr;
51 unsigned int mii_address = priv->mac_type->hw.mii.addr;
52 unsigned int mii_data = priv->mac_type->hw.mii.data;
53
54 int data;
55 u16 regValue = (((phyaddr << 11) & (0x0000F800)) |
56 ((phyreg << 6) & (0x000007C0)));
57 regValue |= MII_BUSY; /* in case of GMAC */
58
59 do {} while (((readl(ioaddr + mii_address)) & MII_BUSY) == 1);
60 writel(regValue, ioaddr + mii_address);
61 do {} while (((readl(ioaddr + mii_address)) & MII_BUSY) == 1);
62
63 /* Read the data from the MII data register */
64 data = (int)readl(ioaddr + mii_data);
65
66 return data;
67}
68
69/**
70 * stmmac_mdio_write
71 * @bus: points to the mii_bus structure
72 * @phyaddr: MII addr reg bits 15-11
73 * @phyreg: MII addr reg bits 10-6
74 * @phydata: phy data
75 * Description: it writes the data into the MII register from within the device.
76 */
77static int stmmac_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg,
78 u16 phydata)
79{
80 struct net_device *ndev = bus->priv;
81 struct stmmac_priv *priv = netdev_priv(ndev);
82 unsigned long ioaddr = ndev->base_addr;
83 unsigned int mii_address = priv->mac_type->hw.mii.addr;
84 unsigned int mii_data = priv->mac_type->hw.mii.data;
85
86 u16 value =
87 (((phyaddr << 11) & (0x0000F800)) | ((phyreg << 6) & (0x000007C0)))
88 | MII_WRITE;
89
90 value |= MII_BUSY;
91
92 /* Wait until any existing MII operation is complete */
93 do {} while (((readl(ioaddr + mii_address)) & MII_BUSY) == 1);
94
95 /* Set the MII address register to write */
96 writel(phydata, ioaddr + mii_data);
97 writel(value, ioaddr + mii_address);
98
99 /* Wait until any existing MII operation is complete */
100 do {} while (((readl(ioaddr + mii_address)) & MII_BUSY) == 1);
101
102 return 0;
103}
104
105/**
106 * stmmac_mdio_reset
107 * @bus: points to the mii_bus structure
108 * Description: reset the MII bus
109 */
110static int stmmac_mdio_reset(struct mii_bus *bus)
111{
112 struct net_device *ndev = bus->priv;
113 struct stmmac_priv *priv = netdev_priv(ndev);
114 unsigned long ioaddr = ndev->base_addr;
115 unsigned int mii_address = priv->mac_type->hw.mii.addr;
116
117 if (priv->phy_reset) {
118 pr_debug("stmmac_mdio_reset: calling phy_reset\n");
119 priv->phy_reset(priv->bsp_priv);
120 }
121
122 /* This is a workaround for problems with the STE101P PHY.
123 * It doesn't complete its reset until at least one clock cycle
124 * on MDC, so perform a dummy mdio read.
125 */
126 writel(0, ioaddr + mii_address);
127
128 return 0;
129}
130
131/**
132 * stmmac_mdio_register
133 * @ndev: net device structure
134 * Description: it registers the MII bus
135 */
136int stmmac_mdio_register(struct net_device *ndev)
137{
138 int err = 0;
139 struct mii_bus *new_bus;
140 int *irqlist;
141 struct stmmac_priv *priv = netdev_priv(ndev);
142 int addr, found;
143
144 new_bus = mdiobus_alloc();
145 if (new_bus == NULL)
146 return -ENOMEM;
147
148 irqlist = kzalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
149 if (irqlist == NULL) {
150 err = -ENOMEM;
151 goto irqlist_alloc_fail;
152 }
153
154 /* Assign IRQ to phy at address phy_addr */
155 if (priv->phy_addr != -1)
156 irqlist[priv->phy_addr] = priv->phy_irq;
157
158 new_bus->name = "STMMAC MII Bus";
159 new_bus->read = &stmmac_mdio_read;
160 new_bus->write = &stmmac_mdio_write;
161 new_bus->reset = &stmmac_mdio_reset;
162 snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", priv->bus_id);
163 new_bus->priv = ndev;
164 new_bus->irq = irqlist;
165 new_bus->phy_mask = priv->phy_mask;
166 new_bus->parent = priv->device;
167 err = mdiobus_register(new_bus);
168 if (err != 0) {
169 pr_err("%s: Cannot register as MDIO bus\n", new_bus->name);
170 goto bus_register_fail;
171 }
172
173 priv->mii = new_bus;
174
175 found = 0;
176 for (addr = 0; addr < 32; addr++) {
177 struct phy_device *phydev = new_bus->phy_map[addr];
178 if (phydev) {
179 if (priv->phy_addr == -1) {
180 priv->phy_addr = addr;
181 phydev->irq = priv->phy_irq;
182 irqlist[addr] = priv->phy_irq;
183 }
184 pr_info("%s: PHY ID %08x at %d IRQ %d (%s)%s\n",
185 ndev->name, phydev->phy_id, addr,
186 phydev->irq, dev_name(&phydev->dev),
187 (addr == priv->phy_addr) ? " active" : "");
188 found = 1;
189 }
190 }
191
192 if (!found)
193 pr_warning("%s: No PHY found\n", ndev->name);
194
195 return 0;
196bus_register_fail:
197 kfree(irqlist);
198irqlist_alloc_fail:
199 kfree(new_bus);
200 return err;
201}
202
203/**
204 * stmmac_mdio_unregister
205 * @ndev: net device structure
206 * Description: it unregisters the MII bus
207 */
208int stmmac_mdio_unregister(struct net_device *ndev)
209{
210 struct stmmac_priv *priv = netdev_priv(ndev);
211
212 mdiobus_unregister(priv->mii);
213 priv->mii->priv = NULL;
214 kfree(priv->mii);
215
216 return 0;
217}
diff --git a/drivers/net/stmmac/stmmac_timer.c b/drivers/net/stmmac/stmmac_timer.c
new file mode 100644
index 000000000000..b838c6582077
--- /dev/null
+++ b/drivers/net/stmmac/stmmac_timer.c
@@ -0,0 +1,140 @@
1/*******************************************************************************
2 STMMAC external timer support.
3
4 Copyright (C) 2007-2009 STMicroelectronics Ltd
5
6 This program is free software; you can redistribute it and/or modify it
7 under the terms and conditions of the GNU General Public License,
8 version 2, as published by the Free Software Foundation.
9
10 This program is distributed in the hope it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 more details.
14
15 You should have received a copy of the GNU General Public License along with
16 this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18
19 The full GNU General Public License is included in this distribution in
20 the file called "COPYING".
21
22 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
23*******************************************************************************/
24
25#include <linux/kernel.h>
26#include <linux/etherdevice.h>
27#include "stmmac_timer.h"
28
29static void stmmac_timer_handler(void *data)
30{
31 struct net_device *dev = (struct net_device *)data;
32
33 stmmac_schedule(dev);
34
35 return;
36}
37
38#define STMMAC_TIMER_MSG(timer, freq) \
39printk(KERN_INFO "stmmac_timer: %s Timer ON (freq %dHz)\n", timer, freq);
40
41#if defined(CONFIG_STMMAC_RTC_TIMER)
42#include <linux/rtc.h>
43static struct rtc_device *stmmac_rtc;
44static rtc_task_t stmmac_task;
45
46static void stmmac_rtc_start(unsigned int new_freq)
47{
48 rtc_irq_set_freq(stmmac_rtc, &stmmac_task, new_freq);
49 rtc_irq_set_state(stmmac_rtc, &stmmac_task, 1);
50 return;
51}
52
53static void stmmac_rtc_stop(void)
54{
55 rtc_irq_set_state(stmmac_rtc, &stmmac_task, 0);
56 return;
57}
58
59int stmmac_open_ext_timer(struct net_device *dev, struct stmmac_timer *tm)
60{
61 stmmac_task.private_data = dev;
62 stmmac_task.func = stmmac_timer_handler;
63
64 stmmac_rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
65 if (stmmac_rtc == NULL) {
66 pr_error("open rtc device failed\n");
67 return -ENODEV;
68 }
69
70 rtc_irq_register(stmmac_rtc, &stmmac_task);
71
72 /* Periodic mode is not supported */
73 if ((rtc_irq_set_freq(stmmac_rtc, &stmmac_task, tm->freq) < 0)) {
74 pr_error("set periodic failed\n");
75 rtc_irq_unregister(stmmac_rtc, &stmmac_task);
76 rtc_class_close(stmmac_rtc);
77 return -1;
78 }
79
80 STMMAC_TIMER_MSG(CONFIG_RTC_HCTOSYS_DEVICE, tm->freq);
81
82 tm->timer_start = stmmac_rtc_start;
83 tm->timer_stop = stmmac_rtc_stop;
84
85 return 0;
86}
87
88int stmmac_close_ext_timer(void)
89{
90 rtc_irq_set_state(stmmac_rtc, &stmmac_task, 0);
91 rtc_irq_unregister(stmmac_rtc, &stmmac_task);
92 rtc_class_close(stmmac_rtc);
93 return 0;
94}
95
96#elif defined(CONFIG_STMMAC_TMU_TIMER)
97#include <linux/clk.h>
98#define TMU_CHANNEL "tmu2_clk"
99static struct clk *timer_clock;
100
101static void stmmac_tmu_start(unsigned int new_freq)
102{
103 clk_set_rate(timer_clock, new_freq);
104 clk_enable(timer_clock);
105 return;
106}
107
108static void stmmac_tmu_stop(void)
109{
110 clk_disable(timer_clock);
111 return;
112}
113
114int stmmac_open_ext_timer(struct net_device *dev, struct stmmac_timer *tm)
115{
116 timer_clock = clk_get(NULL, TMU_CHANNEL);
117
118 if (timer_clock == NULL)
119 return -1;
120
121 if (tmu2_register_user(stmmac_timer_handler, (void *)dev) < 0) {
122 timer_clock = NULL;
123 return -1;
124 }
125
126 STMMAC_TIMER_MSG("TMU2", tm->freq);
127 tm->timer_start = stmmac_tmu_start;
128 tm->timer_stop = stmmac_tmu_stop;
129
130 return 0;
131}
132
133int stmmac_close_ext_timer(void)
134{
135 clk_disable(timer_clock);
136 tmu2_unregister_user();
137 clk_put(timer_clock);
138 return 0;
139}
140#endif
diff --git a/drivers/net/stmmac/stmmac_timer.h b/drivers/net/stmmac/stmmac_timer.h
new file mode 100644
index 000000000000..f795cae33725
--- /dev/null
+++ b/drivers/net/stmmac/stmmac_timer.h
@@ -0,0 +1,41 @@
1/*******************************************************************************
2 STMMAC external timer Header File.
3
4 Copyright (C) 2007-2009 STMicroelectronics Ltd
5
6 This program is free software; you can redistribute it and/or modify it
7 under the terms and conditions of the GNU General Public License,
8 version 2, as published by the Free Software Foundation.
9
10 This program is distributed in the hope it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 more details.
14
15 You should have received a copy of the GNU General Public License along with
16 this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18
19 The full GNU General Public License is included in this distribution in
20 the file called "COPYING".
21
22 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
23*******************************************************************************/
24
25struct stmmac_timer {
26 void (*timer_start) (unsigned int new_freq);
27 void (*timer_stop) (void);
28 unsigned int freq;
29};
30
31/* Open the HW timer device and return 0 in case of success */
32int stmmac_open_ext_timer(struct net_device *dev, struct stmmac_timer *tm);
33/* Stop the timer and release it */
34int stmmac_close_ext_timer(void);
35/* Function used for scheduling task within the stmmac */
36void stmmac_schedule(struct net_device *dev);
37
38#if defined(CONFIG_STMMAC_TMU_TIMER)
39extern int tmu2_register_user(void *fnt, void *data);
40extern void tmu2_unregister_user(void);
41#endif
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c
index 305ec3d783db..7019a0d1a82b 100644
--- a/drivers/net/sungem.c
+++ b/drivers/net/sungem.c
@@ -38,6 +38,7 @@
38#include <linux/interrupt.h> 38#include <linux/interrupt.h>
39#include <linux/ioport.h> 39#include <linux/ioport.h>
40#include <linux/in.h> 40#include <linux/in.h>
41#include <linux/sched.h>
41#include <linux/slab.h> 42#include <linux/slab.h>
42#include <linux/string.h> 43#include <linux/string.h>
43#include <linux/delay.h> 44#include <linux/delay.h>
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index f09bc5dfe8b2..ba5d3fe753b6 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -902,11 +902,12 @@ static int tg3_mdio_read(struct mii_bus *bp, int mii_id, int reg)
902 struct tg3 *tp = bp->priv; 902 struct tg3 *tp = bp->priv;
903 u32 val; 903 u32 val;
904 904
905 if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_PAUSED) 905 spin_lock_bh(&tp->lock);
906 return -EAGAIN;
907 906
908 if (tg3_readphy(tp, reg, &val)) 907 if (tg3_readphy(tp, reg, &val))
909 return -EIO; 908 val = -EIO;
909
910 spin_unlock_bh(&tp->lock);
910 911
911 return val; 912 return val;
912} 913}
@@ -914,14 +915,16 @@ static int tg3_mdio_read(struct mii_bus *bp, int mii_id, int reg)
914static int tg3_mdio_write(struct mii_bus *bp, int mii_id, int reg, u16 val) 915static int tg3_mdio_write(struct mii_bus *bp, int mii_id, int reg, u16 val)
915{ 916{
916 struct tg3 *tp = bp->priv; 917 struct tg3 *tp = bp->priv;
918 u32 ret = 0;
917 919
918 if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_PAUSED) 920 spin_lock_bh(&tp->lock);
919 return -EAGAIN;
920 921
921 if (tg3_writephy(tp, reg, val)) 922 if (tg3_writephy(tp, reg, val))
922 return -EIO; 923 ret = -EIO;
923 924
924 return 0; 925 spin_unlock_bh(&tp->lock);
926
927 return ret;
925} 928}
926 929
927static int tg3_mdio_reset(struct mii_bus *bp) 930static int tg3_mdio_reset(struct mii_bus *bp)
@@ -1011,12 +1014,6 @@ static void tg3_mdio_config_5785(struct tg3 *tp)
1011 1014
1012static void tg3_mdio_start(struct tg3 *tp) 1015static void tg3_mdio_start(struct tg3 *tp)
1013{ 1016{
1014 if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) {
1015 mutex_lock(&tp->mdio_bus->mdio_lock);
1016 tp->tg3_flags3 &= ~TG3_FLG3_MDIOBUS_PAUSED;
1017 mutex_unlock(&tp->mdio_bus->mdio_lock);
1018 }
1019
1020 tp->mi_mode &= ~MAC_MI_MODE_AUTO_POLL; 1017 tp->mi_mode &= ~MAC_MI_MODE_AUTO_POLL;
1021 tw32_f(MAC_MI_MODE, tp->mi_mode); 1018 tw32_f(MAC_MI_MODE, tp->mi_mode);
1022 udelay(80); 1019 udelay(80);
@@ -1041,15 +1038,6 @@ static void tg3_mdio_start(struct tg3 *tp)
1041 tg3_mdio_config_5785(tp); 1038 tg3_mdio_config_5785(tp);
1042} 1039}
1043 1040
1044static void tg3_mdio_stop(struct tg3 *tp)
1045{
1046 if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) {
1047 mutex_lock(&tp->mdio_bus->mdio_lock);
1048 tp->tg3_flags3 |= TG3_FLG3_MDIOBUS_PAUSED;
1049 mutex_unlock(&tp->mdio_bus->mdio_lock);
1050 }
1051}
1052
1053static int tg3_mdio_init(struct tg3 *tp) 1041static int tg3_mdio_init(struct tg3 *tp)
1054{ 1042{
1055 int i; 1043 int i;
@@ -1141,7 +1129,6 @@ static void tg3_mdio_fini(struct tg3 *tp)
1141 tp->tg3_flags3 &= ~TG3_FLG3_MDIOBUS_INITED; 1129 tp->tg3_flags3 &= ~TG3_FLG3_MDIOBUS_INITED;
1142 mdiobus_unregister(tp->mdio_bus); 1130 mdiobus_unregister(tp->mdio_bus);
1143 mdiobus_free(tp->mdio_bus); 1131 mdiobus_free(tp->mdio_bus);
1144 tp->tg3_flags3 &= ~TG3_FLG3_MDIOBUS_PAUSED;
1145 } 1132 }
1146} 1133}
1147 1134
@@ -1363,7 +1350,7 @@ static void tg3_adjust_link(struct net_device *dev)
1363 struct tg3 *tp = netdev_priv(dev); 1350 struct tg3 *tp = netdev_priv(dev);
1364 struct phy_device *phydev = tp->mdio_bus->phy_map[PHY_ADDR]; 1351 struct phy_device *phydev = tp->mdio_bus->phy_map[PHY_ADDR];
1365 1352
1366 spin_lock(&tp->lock); 1353 spin_lock_bh(&tp->lock);
1367 1354
1368 mac_mode = tp->mac_mode & ~(MAC_MODE_PORT_MODE_MASK | 1355 mac_mode = tp->mac_mode & ~(MAC_MODE_PORT_MODE_MASK |
1369 MAC_MODE_HALF_DUPLEX); 1356 MAC_MODE_HALF_DUPLEX);
@@ -1431,7 +1418,7 @@ static void tg3_adjust_link(struct net_device *dev)
1431 tp->link_config.active_speed = phydev->speed; 1418 tp->link_config.active_speed = phydev->speed;
1432 tp->link_config.active_duplex = phydev->duplex; 1419 tp->link_config.active_duplex = phydev->duplex;
1433 1420
1434 spin_unlock(&tp->lock); 1421 spin_unlock_bh(&tp->lock);
1435 1422
1436 if (linkmesg) 1423 if (linkmesg)
1437 tg3_link_report(tp); 1424 tg3_link_report(tp);
@@ -6392,8 +6379,6 @@ static int tg3_chip_reset(struct tg3 *tp)
6392 6379
6393 tg3_nvram_lock(tp); 6380 tg3_nvram_lock(tp);
6394 6381
6395 tg3_mdio_stop(tp);
6396
6397 tg3_ape_lock(tp, TG3_APE_LOCK_GRC); 6382 tg3_ape_lock(tp, TG3_APE_LOCK_GRC);
6398 6383
6399 /* No matching tg3_nvram_unlock() after this because 6384 /* No matching tg3_nvram_unlock() after this because
@@ -8698,6 +8683,8 @@ static int tg3_close(struct net_device *dev)
8698 8683
8699 del_timer_sync(&tp->timer); 8684 del_timer_sync(&tp->timer);
8700 8685
8686 tg3_phy_stop(tp);
8687
8701 tg3_full_lock(tp, 1); 8688 tg3_full_lock(tp, 1);
8702#if 0 8689#if 0
8703 tg3_dump_state(tp); 8690 tg3_dump_state(tp);
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index 82b45d8797b4..bab7940158e6 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -2412,7 +2412,6 @@ struct ring_info {
2412 2412
2413struct tx_ring_info { 2413struct tx_ring_info {
2414 struct sk_buff *skb; 2414 struct sk_buff *skb;
2415 u32 prev_vlan_tag;
2416}; 2415};
2417 2416
2418struct tg3_config_info { 2417struct tg3_config_info {
@@ -2749,7 +2748,6 @@ struct tg3 {
2749#define TG3_FLG3_5701_DMA_BUG 0x00000008 2748#define TG3_FLG3_5701_DMA_BUG 0x00000008
2750#define TG3_FLG3_USE_PHYLIB 0x00000010 2749#define TG3_FLG3_USE_PHYLIB 0x00000010
2751#define TG3_FLG3_MDIOBUS_INITED 0x00000020 2750#define TG3_FLG3_MDIOBUS_INITED 0x00000020
2752#define TG3_FLG3_MDIOBUS_PAUSED 0x00000040
2753#define TG3_FLG3_PHY_CONNECTED 0x00000080 2751#define TG3_FLG3_PHY_CONNECTED 0x00000080
2754#define TG3_FLG3_RGMII_STD_IBND_DISABLE 0x00000100 2752#define TG3_FLG3_RGMII_STD_IBND_DISABLE 0x00000100
2755#define TG3_FLG3_RGMII_EXT_IBND_RX_EN 0x00000200 2753#define TG3_FLG3_RGMII_EXT_IBND_RX_EN 0x00000200
diff --git a/drivers/net/tokenring/ibmtr.c b/drivers/net/tokenring/ibmtr.c
index 525bbc5b9c9d..36cb2423bcf1 100644
--- a/drivers/net/tokenring/ibmtr.c
+++ b/drivers/net/tokenring/ibmtr.c
@@ -108,6 +108,7 @@ in the event that chatty debug messages are desired - jjs 12/30/98 */
108#define IBMTR_DEBUG_MESSAGES 0 108#define IBMTR_DEBUG_MESSAGES 0
109 109
110#include <linux/module.h> 110#include <linux/module.h>
111#include <linux/sched.h>
111 112
112#ifdef PCMCIA /* required for ibmtr_cs.c to build */ 113#ifdef PCMCIA /* required for ibmtr_cs.c to build */
113#undef MODULE /* yes, really */ 114#undef MODULE /* yes, really */
diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c
index d6d345229fe9..5921f5bdd764 100644
--- a/drivers/net/typhoon.c
+++ b/drivers/net/typhoon.c
@@ -108,6 +108,7 @@ static const int multicast_filter_limit = 32;
108 108
109#include <linux/module.h> 109#include <linux/module.h>
110#include <linux/kernel.h> 110#include <linux/kernel.h>
111#include <linux/sched.h>
111#include <linux/string.h> 112#include <linux/string.h>
112#include <linux/timer.h> 113#include <linux/timer.h>
113#include <linux/errno.h> 114#include <linux/errno.h>
diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c
index 6fdaba8674b9..ed4a508ef262 100644
--- a/drivers/net/usb/pegasus.c
+++ b/drivers/net/usb/pegasus.c
@@ -62,8 +62,11 @@ static char *devid=NULL;
62static struct usb_eth_dev usb_dev_id[] = { 62static struct usb_eth_dev usb_dev_id[] = {
63#define PEGASUS_DEV(pn, vid, pid, flags) \ 63#define PEGASUS_DEV(pn, vid, pid, flags) \
64 {.name = pn, .vendor = vid, .device = pid, .private = flags}, 64 {.name = pn, .vendor = vid, .device = pid, .private = flags},
65#define PEGASUS_DEV_CLASS(pn, vid, pid, dclass, flags) \
66 PEGASUS_DEV(pn, vid, pid, flags)
65#include "pegasus.h" 67#include "pegasus.h"
66#undef PEGASUS_DEV 68#undef PEGASUS_DEV
69#undef PEGASUS_DEV_CLASS
67 {NULL, 0, 0, 0}, 70 {NULL, 0, 0, 0},
68 {NULL, 0, 0, 0} 71 {NULL, 0, 0, 0}
69}; 72};
@@ -71,8 +74,18 @@ static struct usb_eth_dev usb_dev_id[] = {
71static struct usb_device_id pegasus_ids[] = { 74static struct usb_device_id pegasus_ids[] = {
72#define PEGASUS_DEV(pn, vid, pid, flags) \ 75#define PEGASUS_DEV(pn, vid, pid, flags) \
73 {.match_flags = USB_DEVICE_ID_MATCH_DEVICE, .idVendor = vid, .idProduct = pid}, 76 {.match_flags = USB_DEVICE_ID_MATCH_DEVICE, .idVendor = vid, .idProduct = pid},
77/*
78 * The Belkin F8T012xx1 bluetooth adaptor has the same vendor and product
79 * IDs as the Belkin F5D5050, so we need to teach the pegasus driver to
80 * ignore adaptors belonging to the "Wireless" class 0xE0. For this one
81 * case anyway, seeing as the pegasus is for "Wired" adaptors.
82 */
83#define PEGASUS_DEV_CLASS(pn, vid, pid, dclass, flags) \
84 {.match_flags = (USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_DEV_CLASS), \
85 .idVendor = vid, .idProduct = pid, .bDeviceClass = dclass},
74#include "pegasus.h" 86#include "pegasus.h"
75#undef PEGASUS_DEV 87#undef PEGASUS_DEV
88#undef PEGASUS_DEV_CLASS
76 {}, 89 {},
77 {} 90 {}
78}; 91};
diff --git a/drivers/net/usb/pegasus.h b/drivers/net/usb/pegasus.h
index f968c834ff63..5d02f0200737 100644
--- a/drivers/net/usb/pegasus.h
+++ b/drivers/net/usb/pegasus.h
@@ -202,7 +202,11 @@ PEGASUS_DEV( "AEI USB Fast Ethernet Adapter", VENDOR_AEILAB, 0x1701,
202 DEFAULT_GPIO_RESET | PEGASUS_II ) 202 DEFAULT_GPIO_RESET | PEGASUS_II )
203PEGASUS_DEV( "Allied Telesyn Int. AT-USB100", VENDOR_ALLIEDTEL, 0xb100, 203PEGASUS_DEV( "Allied Telesyn Int. AT-USB100", VENDOR_ALLIEDTEL, 0xb100,
204 DEFAULT_GPIO_RESET | PEGASUS_II ) 204 DEFAULT_GPIO_RESET | PEGASUS_II )
205PEGASUS_DEV( "Belkin F5D5050 USB Ethernet", VENDOR_BELKIN, 0x0121, 205/*
206 * Distinguish between this Belkin adaptor and the Belkin bluetooth adaptors
207 * with the same product IDs by checking the device class too.
208 */
209PEGASUS_DEV_CLASS( "Belkin F5D5050 USB Ethernet", VENDOR_BELKIN, 0x0121, 0x00,
206 DEFAULT_GPIO_RESET | PEGASUS_II ) 210 DEFAULT_GPIO_RESET | PEGASUS_II )
207PEGASUS_DEV( "Billionton USB-100", VENDOR_BILLIONTON, 0x0986, 211PEGASUS_DEV( "Billionton USB-100", VENDOR_BILLIONTON, 0x0986,
208 DEFAULT_GPIO_RESET ) 212 DEFAULT_GPIO_RESET )
diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c
index d032bba9bc4c..0caa8008c51c 100644
--- a/drivers/net/usb/rndis_host.c
+++ b/drivers/net/usb/rndis_host.c
@@ -418,6 +418,7 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags)
418 goto halt_fail_and_release; 418 goto halt_fail_and_release;
419 } 419 }
420 memcpy(net->dev_addr, bp, ETH_ALEN); 420 memcpy(net->dev_addr, bp, ETH_ALEN);
421 memcpy(net->perm_addr, bp, ETH_ALEN);
421 422
422 /* set a nonzero filter to enable data transfers */ 423 /* set a nonzero filter to enable data transfers */
423 memset(u.set, 0, sizeof *u.set); 424 memset(u.set, 0, sizeof *u.set);
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index d445845f2779..8d009760277c 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -948,7 +948,7 @@ free:
948 return err; 948 return err;
949} 949}
950 950
951static void virtnet_remove(struct virtio_device *vdev) 951static void __devexit virtnet_remove(struct virtio_device *vdev)
952{ 952{
953 struct virtnet_info *vi = vdev->priv; 953 struct virtnet_info *vi = vdev->priv;
954 struct sk_buff *skb; 954 struct sk_buff *skb;
diff --git a/drivers/net/vmxnet3/Makefile b/drivers/net/vmxnet3/Makefile
new file mode 100644
index 000000000000..880f5098eac9
--- /dev/null
+++ b/drivers/net/vmxnet3/Makefile
@@ -0,0 +1,35 @@
1################################################################################
2#
3# Linux driver for VMware's vmxnet3 ethernet NIC.
4#
5# Copyright (C) 2007-2009, VMware, Inc. All Rights Reserved.
6#
7# This program is free software; you can redistribute it and/or modify it
8# under the terms of the GNU General Public License as published by the
9# Free Software Foundation; version 2 of the License and no later version.
10#
11# This program is distributed in the hope that it will be useful, but
12# WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
14# NON INFRINGEMENT. See the GNU General Public License for more
15# details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program; if not, write to the Free Software
19# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20#
21# The full GNU General Public License is included in this distribution in
22# the file called "COPYING".
23#
24# Maintained by: Shreyas Bhatewara <pv-drivers@vmware.com>
25#
26#
27################################################################################
28
29#
30# Makefile for the VMware vmxnet3 ethernet NIC driver
31#
32
33obj-$(CONFIG_VMXNET3) += vmxnet3.o
34
35vmxnet3-objs := vmxnet3_drv.o vmxnet3_ethtool.o
diff --git a/drivers/net/vmxnet3/upt1_defs.h b/drivers/net/vmxnet3/upt1_defs.h
new file mode 100644
index 000000000000..37108fb226d3
--- /dev/null
+++ b/drivers/net/vmxnet3/upt1_defs.h
@@ -0,0 +1,96 @@
1/*
2 * Linux driver for VMware's vmxnet3 ethernet NIC.
3 *
4 * Copyright (C) 2008-2009, VMware, Inc. All Rights Reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; version 2 of the License and no later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
13 * NON INFRINGEMENT. See the GNU General Public License for more
14 * details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * The full GNU General Public License is included in this distribution in
21 * the file called "COPYING".
22 *
23 * Maintained by: Shreyas Bhatewara <pv-drivers@vmware.com>
24 *
25 */
26
27#ifndef _UPT1_DEFS_H
28#define _UPT1_DEFS_H
29
30struct UPT1_TxStats {
31 u64 TSOPktsTxOK; /* TSO pkts post-segmentation */
32 u64 TSOBytesTxOK;
33 u64 ucastPktsTxOK;
34 u64 ucastBytesTxOK;
35 u64 mcastPktsTxOK;
36 u64 mcastBytesTxOK;
37 u64 bcastPktsTxOK;
38 u64 bcastBytesTxOK;
39 u64 pktsTxError;
40 u64 pktsTxDiscard;
41};
42
43struct UPT1_RxStats {
44 u64 LROPktsRxOK; /* LRO pkts */
45 u64 LROBytesRxOK; /* bytes from LRO pkts */
46 /* the following counters are for pkts from the wire, i.e., pre-LRO */
47 u64 ucastPktsRxOK;
48 u64 ucastBytesRxOK;
49 u64 mcastPktsRxOK;
50 u64 mcastBytesRxOK;
51 u64 bcastPktsRxOK;
52 u64 bcastBytesRxOK;
53 u64 pktsRxOutOfBuf;
54 u64 pktsRxError;
55};
56
57/* interrupt moderation level */
58enum {
59 UPT1_IML_NONE = 0, /* no interrupt moderation */
60 UPT1_IML_HIGHEST = 7, /* least intr generated */
61 UPT1_IML_ADAPTIVE = 8, /* adpative intr moderation */
62};
63/* values for UPT1_RSSConf.hashFunc */
64enum {
65 UPT1_RSS_HASH_TYPE_NONE = 0x0,
66 UPT1_RSS_HASH_TYPE_IPV4 = 0x01,
67 UPT1_RSS_HASH_TYPE_TCP_IPV4 = 0x02,
68 UPT1_RSS_HASH_TYPE_IPV6 = 0x04,
69 UPT1_RSS_HASH_TYPE_TCP_IPV6 = 0x08,
70};
71
72enum {
73 UPT1_RSS_HASH_FUNC_NONE = 0x0,
74 UPT1_RSS_HASH_FUNC_TOEPLITZ = 0x01,
75};
76
77#define UPT1_RSS_MAX_KEY_SIZE 40
78#define UPT1_RSS_MAX_IND_TABLE_SIZE 128
79
80struct UPT1_RSSConf {
81 u16 hashType;
82 u16 hashFunc;
83 u16 hashKeySize;
84 u16 indTableSize;
85 u8 hashKey[UPT1_RSS_MAX_KEY_SIZE];
86 u8 indTable[UPT1_RSS_MAX_IND_TABLE_SIZE];
87};
88
89/* features */
90enum {
91 UPT1_F_RXCSUM = 0x0001, /* rx csum verification */
92 UPT1_F_RSS = 0x0002,
93 UPT1_F_RXVLAN = 0x0004, /* VLAN tag stripping */
94 UPT1_F_LRO = 0x0008,
95};
96#endif
diff --git a/drivers/net/vmxnet3/vmxnet3_defs.h b/drivers/net/vmxnet3/vmxnet3_defs.h
new file mode 100644
index 000000000000..dc8ee4438a4f
--- /dev/null
+++ b/drivers/net/vmxnet3/vmxnet3_defs.h
@@ -0,0 +1,535 @@
1/*
2 * Linux driver for VMware's vmxnet3 ethernet NIC.
3 *
4 * Copyright (C) 2008-2009, VMware, Inc. All Rights Reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; version 2 of the License and no later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
13 * NON INFRINGEMENT. See the GNU General Public License for more
14 * details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * The full GNU General Public License is included in this distribution in
21 * the file called "COPYING".
22 *
23 * Maintained by: Shreyas Bhatewara <pv-drivers@vmware.com>
24 *
25 */
26
27#ifndef _VMXNET3_DEFS_H_
28#define _VMXNET3_DEFS_H_
29
30#include "upt1_defs.h"
31
32/* all registers are 32 bit wide */
33/* BAR 1 */
34enum {
35 VMXNET3_REG_VRRS = 0x0, /* Vmxnet3 Revision Report Selection */
36 VMXNET3_REG_UVRS = 0x8, /* UPT Version Report Selection */
37 VMXNET3_REG_DSAL = 0x10, /* Driver Shared Address Low */
38 VMXNET3_REG_DSAH = 0x18, /* Driver Shared Address High */
39 VMXNET3_REG_CMD = 0x20, /* Command */
40 VMXNET3_REG_MACL = 0x28, /* MAC Address Low */
41 VMXNET3_REG_MACH = 0x30, /* MAC Address High */
42 VMXNET3_REG_ICR = 0x38, /* Interrupt Cause Register */
43 VMXNET3_REG_ECR = 0x40 /* Event Cause Register */
44};
45
46/* BAR 0 */
47enum {
48 VMXNET3_REG_IMR = 0x0, /* Interrupt Mask Register */
49 VMXNET3_REG_TXPROD = 0x600, /* Tx Producer Index */
50 VMXNET3_REG_RXPROD = 0x800, /* Rx Producer Index for ring 1 */
51 VMXNET3_REG_RXPROD2 = 0xA00 /* Rx Producer Index for ring 2 */
52};
53
54#define VMXNET3_PT_REG_SIZE 4096 /* BAR 0 */
55#define VMXNET3_VD_REG_SIZE 4096 /* BAR 1 */
56
57#define VMXNET3_REG_ALIGN 8 /* All registers are 8-byte aligned. */
58#define VMXNET3_REG_ALIGN_MASK 0x7
59
60/* I/O Mapped access to registers */
61#define VMXNET3_IO_TYPE_PT 0
62#define VMXNET3_IO_TYPE_VD 1
63#define VMXNET3_IO_ADDR(type, reg) (((type) << 24) | ((reg) & 0xFFFFFF))
64#define VMXNET3_IO_TYPE(addr) ((addr) >> 24)
65#define VMXNET3_IO_REG(addr) ((addr) & 0xFFFFFF)
66
67enum {
68 VMXNET3_CMD_FIRST_SET = 0xCAFE0000,
69 VMXNET3_CMD_ACTIVATE_DEV = VMXNET3_CMD_FIRST_SET,
70 VMXNET3_CMD_QUIESCE_DEV,
71 VMXNET3_CMD_RESET_DEV,
72 VMXNET3_CMD_UPDATE_RX_MODE,
73 VMXNET3_CMD_UPDATE_MAC_FILTERS,
74 VMXNET3_CMD_UPDATE_VLAN_FILTERS,
75 VMXNET3_CMD_UPDATE_RSSIDT,
76 VMXNET3_CMD_UPDATE_IML,
77 VMXNET3_CMD_UPDATE_PMCFG,
78 VMXNET3_CMD_UPDATE_FEATURE,
79 VMXNET3_CMD_LOAD_PLUGIN,
80
81 VMXNET3_CMD_FIRST_GET = 0xF00D0000,
82 VMXNET3_CMD_GET_QUEUE_STATUS = VMXNET3_CMD_FIRST_GET,
83 VMXNET3_CMD_GET_STATS,
84 VMXNET3_CMD_GET_LINK,
85 VMXNET3_CMD_GET_PERM_MAC_LO,
86 VMXNET3_CMD_GET_PERM_MAC_HI,
87 VMXNET3_CMD_GET_DID_LO,
88 VMXNET3_CMD_GET_DID_HI,
89 VMXNET3_CMD_GET_DEV_EXTRA_INFO,
90 VMXNET3_CMD_GET_CONF_INTR
91};
92
93struct Vmxnet3_TxDesc {
94 u64 addr;
95
96 u32 len:14;
97 u32 gen:1; /* generation bit */
98 u32 rsvd:1;
99 u32 dtype:1; /* descriptor type */
100 u32 ext1:1;
101 u32 msscof:14; /* MSS, checksum offset, flags */
102
103 u32 hlen:10; /* header len */
104 u32 om:2; /* offload mode */
105 u32 eop:1; /* End Of Packet */
106 u32 cq:1; /* completion request */
107 u32 ext2:1;
108 u32 ti:1; /* VLAN Tag Insertion */
109 u32 tci:16; /* Tag to Insert */
110};
111
112/* TxDesc.OM values */
113#define VMXNET3_OM_NONE 0
114#define VMXNET3_OM_CSUM 2
115#define VMXNET3_OM_TSO 3
116
117/* fields in TxDesc we access w/o using bit fields */
118#define VMXNET3_TXD_EOP_SHIFT 12
119#define VMXNET3_TXD_CQ_SHIFT 13
120#define VMXNET3_TXD_GEN_SHIFT 14
121
122#define VMXNET3_TXD_CQ (1 << VMXNET3_TXD_CQ_SHIFT)
123#define VMXNET3_TXD_EOP (1 << VMXNET3_TXD_EOP_SHIFT)
124#define VMXNET3_TXD_GEN (1 << VMXNET3_TXD_GEN_SHIFT)
125
126#define VMXNET3_HDR_COPY_SIZE 128
127
128
129struct Vmxnet3_TxDataDesc {
130 u8 data[VMXNET3_HDR_COPY_SIZE];
131};
132
133
134struct Vmxnet3_TxCompDesc {
135 u32 txdIdx:12; /* Index of the EOP TxDesc */
136 u32 ext1:20;
137
138 u32 ext2;
139 u32 ext3;
140
141 u32 rsvd:24;
142 u32 type:7; /* completion type */
143 u32 gen:1; /* generation bit */
144};
145
146
147struct Vmxnet3_RxDesc {
148 u64 addr;
149
150 u32 len:14;
151 u32 btype:1; /* Buffer Type */
152 u32 dtype:1; /* Descriptor type */
153 u32 rsvd:15;
154 u32 gen:1; /* Generation bit */
155
156 u32 ext1;
157};
158
159/* values of RXD.BTYPE */
160#define VMXNET3_RXD_BTYPE_HEAD 0 /* head only */
161#define VMXNET3_RXD_BTYPE_BODY 1 /* body only */
162
163/* fields in RxDesc we access w/o using bit fields */
164#define VMXNET3_RXD_BTYPE_SHIFT 14
165#define VMXNET3_RXD_GEN_SHIFT 31
166
167
168struct Vmxnet3_RxCompDesc {
169 u32 rxdIdx:12; /* Index of the RxDesc */
170 u32 ext1:2;
171 u32 eop:1; /* End of Packet */
172 u32 sop:1; /* Start of Packet */
173 u32 rqID:10; /* rx queue/ring ID */
174 u32 rssType:4; /* RSS hash type used */
175 u32 cnc:1; /* Checksum Not Calculated */
176 u32 ext2:1;
177
178 u32 rssHash; /* RSS hash value */
179
180 u32 len:14; /* data length */
181 u32 err:1; /* Error */
182 u32 ts:1; /* Tag is stripped */
183 u32 tci:16; /* Tag stripped */
184
185 u32 csum:16;
186 u32 tuc:1; /* TCP/UDP Checksum Correct */
187 u32 udp:1; /* UDP packet */
188 u32 tcp:1; /* TCP packet */
189 u32 ipc:1; /* IP Checksum Correct */
190 u32 v6:1; /* IPv6 */
191 u32 v4:1; /* IPv4 */
192 u32 frg:1; /* IP Fragment */
193 u32 fcs:1; /* Frame CRC correct */
194 u32 type:7; /* completion type */
195 u32 gen:1; /* generation bit */
196};
197
198/* fields in RxCompDesc we access via Vmxnet3_GenericDesc.dword[3] */
199#define VMXNET3_RCD_TUC_SHIFT 16
200#define VMXNET3_RCD_IPC_SHIFT 19
201
202/* fields in RxCompDesc we access via Vmxnet3_GenericDesc.qword[1] */
203#define VMXNET3_RCD_TYPE_SHIFT 56
204#define VMXNET3_RCD_GEN_SHIFT 63
205
206/* csum OK for TCP/UDP pkts over IP */
207#define VMXNET3_RCD_CSUM_OK (1 << VMXNET3_RCD_TUC_SHIFT | \
208 1 << VMXNET3_RCD_IPC_SHIFT)
209
210/* value of RxCompDesc.rssType */
211enum {
212 VMXNET3_RCD_RSS_TYPE_NONE = 0,
213 VMXNET3_RCD_RSS_TYPE_IPV4 = 1,
214 VMXNET3_RCD_RSS_TYPE_TCPIPV4 = 2,
215 VMXNET3_RCD_RSS_TYPE_IPV6 = 3,
216 VMXNET3_RCD_RSS_TYPE_TCPIPV6 = 4,
217};
218
219
220/* a union for accessing all cmd/completion descriptors */
221union Vmxnet3_GenericDesc {
222 u64 qword[2];
223 u32 dword[4];
224 u16 word[8];
225 struct Vmxnet3_TxDesc txd;
226 struct Vmxnet3_RxDesc rxd;
227 struct Vmxnet3_TxCompDesc tcd;
228 struct Vmxnet3_RxCompDesc rcd;
229};
230
231#define VMXNET3_INIT_GEN 1
232
233/* Max size of a single tx buffer */
234#define VMXNET3_MAX_TX_BUF_SIZE (1 << 14)
235
236/* # of tx desc needed for a tx buffer size */
237#define VMXNET3_TXD_NEEDED(size) (((size) + VMXNET3_MAX_TX_BUF_SIZE - 1) / \
238 VMXNET3_MAX_TX_BUF_SIZE)
239
240/* max # of tx descs for a non-tso pkt */
241#define VMXNET3_MAX_TXD_PER_PKT 16
242
243/* Max size of a single rx buffer */
244#define VMXNET3_MAX_RX_BUF_SIZE ((1 << 14) - 1)
245/* Minimum size of a type 0 buffer */
246#define VMXNET3_MIN_T0_BUF_SIZE 128
247#define VMXNET3_MAX_CSUM_OFFSET 1024
248
249/* Ring base address alignment */
250#define VMXNET3_RING_BA_ALIGN 512
251#define VMXNET3_RING_BA_MASK (VMXNET3_RING_BA_ALIGN - 1)
252
253/* Ring size must be a multiple of 32 */
254#define VMXNET3_RING_SIZE_ALIGN 32
255#define VMXNET3_RING_SIZE_MASK (VMXNET3_RING_SIZE_ALIGN - 1)
256
257/* Max ring size */
258#define VMXNET3_TX_RING_MAX_SIZE 4096
259#define VMXNET3_TC_RING_MAX_SIZE 4096
260#define VMXNET3_RX_RING_MAX_SIZE 4096
261#define VMXNET3_RC_RING_MAX_SIZE 8192
262
263/* a list of reasons for queue stop */
264
265enum {
266 VMXNET3_ERR_NOEOP = 0x80000000, /* cannot find the EOP desc of a pkt */
267 VMXNET3_ERR_TXD_REUSE = 0x80000001, /* reuse TxDesc before tx completion */
268 VMXNET3_ERR_BIG_PKT = 0x80000002, /* too many TxDesc for a pkt */
269 VMXNET3_ERR_DESC_NOT_SPT = 0x80000003, /* descriptor type not supported */
270 VMXNET3_ERR_SMALL_BUF = 0x80000004, /* type 0 buffer too small */
271 VMXNET3_ERR_STRESS = 0x80000005, /* stress option firing in vmkernel */
272 VMXNET3_ERR_SWITCH = 0x80000006, /* mode switch failure */
273 VMXNET3_ERR_TXD_INVALID = 0x80000007, /* invalid TxDesc */
274};
275
276/* completion descriptor types */
277#define VMXNET3_CDTYPE_TXCOMP 0 /* Tx Completion Descriptor */
278#define VMXNET3_CDTYPE_RXCOMP 3 /* Rx Completion Descriptor */
279
280enum {
281 VMXNET3_GOS_BITS_UNK = 0, /* unknown */
282 VMXNET3_GOS_BITS_32 = 1,
283 VMXNET3_GOS_BITS_64 = 2,
284};
285
286#define VMXNET3_GOS_TYPE_LINUX 1
287
288
289struct Vmxnet3_GOSInfo {
290 u32 gosBits:2; /* 32-bit or 64-bit? */
291 u32 gosType:4; /* which guest */
292 u32 gosVer:16; /* gos version */
293 u32 gosMisc:10; /* other info about gos */
294};
295
296
297struct Vmxnet3_DriverInfo {
298 u32 version;
299 struct Vmxnet3_GOSInfo gos;
300 u32 vmxnet3RevSpt;
301 u32 uptVerSpt;
302};
303
304
305#define VMXNET3_REV1_MAGIC 0xbabefee1
306
307/*
308 * QueueDescPA must be 128 bytes aligned. It points to an array of
309 * Vmxnet3_TxQueueDesc followed by an array of Vmxnet3_RxQueueDesc.
310 * The number of Vmxnet3_TxQueueDesc/Vmxnet3_RxQueueDesc are specified by
311 * Vmxnet3_MiscConf.numTxQueues/numRxQueues, respectively.
312 */
313#define VMXNET3_QUEUE_DESC_ALIGN 128
314
315
316struct Vmxnet3_MiscConf {
317 struct Vmxnet3_DriverInfo driverInfo;
318 u64 uptFeatures;
319 u64 ddPA; /* driver data PA */
320 u64 queueDescPA; /* queue descriptor table PA */
321 u32 ddLen; /* driver data len */
322 u32 queueDescLen; /* queue desc. table len in bytes */
323 u32 mtu;
324 u16 maxNumRxSG;
325 u8 numTxQueues;
326 u8 numRxQueues;
327 u32 reserved[4];
328};
329
330
331struct Vmxnet3_TxQueueConf {
332 u64 txRingBasePA;
333 u64 dataRingBasePA;
334 u64 compRingBasePA;
335 u64 ddPA; /* driver data */
336 u64 reserved;
337 u32 txRingSize; /* # of tx desc */
338 u32 dataRingSize; /* # of data desc */
339 u32 compRingSize; /* # of comp desc */
340 u32 ddLen; /* size of driver data */
341 u8 intrIdx;
342 u8 _pad[7];
343};
344
345
346struct Vmxnet3_RxQueueConf {
347 u64 rxRingBasePA[2];
348 u64 compRingBasePA;
349 u64 ddPA; /* driver data */
350 u64 reserved;
351 u32 rxRingSize[2]; /* # of rx desc */
352 u32 compRingSize; /* # of rx comp desc */
353 u32 ddLen; /* size of driver data */
354 u8 intrIdx;
355 u8 _pad[7];
356};
357
358
359enum vmxnet3_intr_mask_mode {
360 VMXNET3_IMM_AUTO = 0,
361 VMXNET3_IMM_ACTIVE = 1,
362 VMXNET3_IMM_LAZY = 2
363};
364
365enum vmxnet3_intr_type {
366 VMXNET3_IT_AUTO = 0,
367 VMXNET3_IT_INTX = 1,
368 VMXNET3_IT_MSI = 2,
369 VMXNET3_IT_MSIX = 3
370};
371
372#define VMXNET3_MAX_TX_QUEUES 8
373#define VMXNET3_MAX_RX_QUEUES 16
374/* addition 1 for events */
375#define VMXNET3_MAX_INTRS 25
376
377
378struct Vmxnet3_IntrConf {
379 bool autoMask;
380 u8 numIntrs; /* # of interrupts */
381 u8 eventIntrIdx;
382 u8 modLevels[VMXNET3_MAX_INTRS]; /* moderation level for
383 * each intr */
384 u32 reserved[3];
385};
386
387/* one bit per VLAN ID, the size is in the units of u32 */
388#define VMXNET3_VFT_SIZE (4096 / (sizeof(u32) * 8))
389
390
391struct Vmxnet3_QueueStatus {
392 bool stopped;
393 u8 _pad[3];
394 u32 error;
395};
396
397
398struct Vmxnet3_TxQueueCtrl {
399 u32 txNumDeferred;
400 u32 txThreshold;
401 u64 reserved;
402};
403
404
405struct Vmxnet3_RxQueueCtrl {
406 bool updateRxProd;
407 u8 _pad[7];
408 u64 reserved;
409};
410
411enum {
412 VMXNET3_RXM_UCAST = 0x01, /* unicast only */
413 VMXNET3_RXM_MCAST = 0x02, /* multicast passing the filters */
414 VMXNET3_RXM_BCAST = 0x04, /* broadcast only */
415 VMXNET3_RXM_ALL_MULTI = 0x08, /* all multicast */
416 VMXNET3_RXM_PROMISC = 0x10 /* promiscuous */
417};
418
419struct Vmxnet3_RxFilterConf {
420 u32 rxMode; /* VMXNET3_RXM_xxx */
421 u16 mfTableLen; /* size of the multicast filter table */
422 u16 _pad1;
423 u64 mfTablePA; /* PA of the multicast filters table */
424 u32 vfTable[VMXNET3_VFT_SIZE]; /* vlan filter */
425};
426
427
428#define VMXNET3_PM_MAX_FILTERS 6
429#define VMXNET3_PM_MAX_PATTERN_SIZE 128
430#define VMXNET3_PM_MAX_MASK_SIZE (VMXNET3_PM_MAX_PATTERN_SIZE / 8)
431
432#define VMXNET3_PM_WAKEUP_MAGIC 0x01 /* wake up on magic pkts */
433#define VMXNET3_PM_WAKEUP_FILTER 0x02 /* wake up on pkts matching
434 * filters */
435
436
437struct Vmxnet3_PM_PktFilter {
438 u8 maskSize;
439 u8 patternSize;
440 u8 mask[VMXNET3_PM_MAX_MASK_SIZE];
441 u8 pattern[VMXNET3_PM_MAX_PATTERN_SIZE];
442 u8 pad[6];
443};
444
445
446struct Vmxnet3_PMConf {
447 u16 wakeUpEvents; /* VMXNET3_PM_WAKEUP_xxx */
448 u8 numFilters;
449 u8 pad[5];
450 struct Vmxnet3_PM_PktFilter filters[VMXNET3_PM_MAX_FILTERS];
451};
452
453
454struct Vmxnet3_VariableLenConfDesc {
455 u32 confVer;
456 u32 confLen;
457 u64 confPA;
458};
459
460
461struct Vmxnet3_TxQueueDesc {
462 struct Vmxnet3_TxQueueCtrl ctrl;
463 struct Vmxnet3_TxQueueConf conf;
464
465 /* Driver read after a GET command */
466 struct Vmxnet3_QueueStatus status;
467 struct UPT1_TxStats stats;
468 u8 _pad[88]; /* 128 aligned */
469};
470
471
472struct Vmxnet3_RxQueueDesc {
473 struct Vmxnet3_RxQueueCtrl ctrl;
474 struct Vmxnet3_RxQueueConf conf;
475 /* Driver read after a GET commad */
476 struct Vmxnet3_QueueStatus status;
477 struct UPT1_RxStats stats;
478 u8 __pad[88]; /* 128 aligned */
479};
480
481
482struct Vmxnet3_DSDevRead {
483 /* read-only region for device, read by dev in response to a SET cmd */
484 struct Vmxnet3_MiscConf misc;
485 struct Vmxnet3_IntrConf intrConf;
486 struct Vmxnet3_RxFilterConf rxFilterConf;
487 struct Vmxnet3_VariableLenConfDesc rssConfDesc;
488 struct Vmxnet3_VariableLenConfDesc pmConfDesc;
489 struct Vmxnet3_VariableLenConfDesc pluginConfDesc;
490};
491
492/* All structures in DriverShared are padded to multiples of 8 bytes */
493struct Vmxnet3_DriverShared {
494 u32 magic;
495 /* make devRead start at 64bit boundaries */
496 u32 pad;
497 struct Vmxnet3_DSDevRead devRead;
498 u32 ecr;
499 u32 reserved[5];
500};
501
502
503#define VMXNET3_ECR_RQERR (1 << 0)
504#define VMXNET3_ECR_TQERR (1 << 1)
505#define VMXNET3_ECR_LINK (1 << 2)
506#define VMXNET3_ECR_DIC (1 << 3)
507#define VMXNET3_ECR_DEBUG (1 << 4)
508
509/* flip the gen bit of a ring */
510#define VMXNET3_FLIP_RING_GEN(gen) ((gen) = (gen) ^ 0x1)
511
512/* only use this if moving the idx won't affect the gen bit */
513#define VMXNET3_INC_RING_IDX_ONLY(idx, ring_size) \
514 do {\
515 (idx)++;\
516 if (unlikely((idx) == (ring_size))) {\
517 (idx) = 0;\
518 } \
519 } while (0)
520
521#define VMXNET3_SET_VFTABLE_ENTRY(vfTable, vid) \
522 (vfTable[vid >> 5] |= (1 << (vid & 31)))
523#define VMXNET3_CLEAR_VFTABLE_ENTRY(vfTable, vid) \
524 (vfTable[vid >> 5] &= ~(1 << (vid & 31)))
525
526#define VMXNET3_VFTABLE_ENTRY_IS_SET(vfTable, vid) \
527 ((vfTable[vid >> 5] & (1 << (vid & 31))) != 0)
528
529#define VMXNET3_MAX_MTU 9000
530#define VMXNET3_MIN_MTU 60
531
532#define VMXNET3_LINK_UP (10000 << 16 | 1) /* 10 Gbps, up */
533#define VMXNET3_LINK_DOWN 0
534
535#endif /* _VMXNET3_DEFS_H_ */
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c
new file mode 100644
index 000000000000..6a16f76f277e
--- /dev/null
+++ b/drivers/net/vmxnet3/vmxnet3_drv.c
@@ -0,0 +1,2565 @@
1/*
2 * Linux driver for VMware's vmxnet3 ethernet NIC.
3 *
4 * Copyright (C) 2008-2009, VMware, Inc. All Rights Reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; version 2 of the License and no later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
13 * NON INFRINGEMENT. See the GNU General Public License for more
14 * details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * The full GNU General Public License is included in this distribution in
21 * the file called "COPYING".
22 *
23 * Maintained by: Shreyas Bhatewara <pv-drivers@vmware.com>
24 *
25 */
26
27#include "vmxnet3_int.h"
28
29char vmxnet3_driver_name[] = "vmxnet3";
30#define VMXNET3_DRIVER_DESC "VMware vmxnet3 virtual NIC driver"
31
32
33/*
34 * PCI Device ID Table
35 * Last entry must be all 0s
36 */
37static const struct pci_device_id vmxnet3_pciid_table[] = {
38 {PCI_VDEVICE(VMWARE, PCI_DEVICE_ID_VMWARE_VMXNET3)},
39 {0}
40};
41
42MODULE_DEVICE_TABLE(pci, vmxnet3_pciid_table);
43
44static atomic_t devices_found;
45
46
47/*
48 * Enable/Disable the given intr
49 */
50static void
51vmxnet3_enable_intr(struct vmxnet3_adapter *adapter, unsigned intr_idx)
52{
53 VMXNET3_WRITE_BAR0_REG(adapter, VMXNET3_REG_IMR + intr_idx * 8, 0);
54}
55
56
57static void
58vmxnet3_disable_intr(struct vmxnet3_adapter *adapter, unsigned intr_idx)
59{
60 VMXNET3_WRITE_BAR0_REG(adapter, VMXNET3_REG_IMR + intr_idx * 8, 1);
61}
62
63
64/*
65 * Enable/Disable all intrs used by the device
66 */
67static void
68vmxnet3_enable_all_intrs(struct vmxnet3_adapter *adapter)
69{
70 int i;
71
72 for (i = 0; i < adapter->intr.num_intrs; i++)
73 vmxnet3_enable_intr(adapter, i);
74}
75
76
77static void
78vmxnet3_disable_all_intrs(struct vmxnet3_adapter *adapter)
79{
80 int i;
81
82 for (i = 0; i < adapter->intr.num_intrs; i++)
83 vmxnet3_disable_intr(adapter, i);
84}
85
86
87static void
88vmxnet3_ack_events(struct vmxnet3_adapter *adapter, u32 events)
89{
90 VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_ECR, events);
91}
92
93
94static bool
95vmxnet3_tq_stopped(struct vmxnet3_tx_queue *tq, struct vmxnet3_adapter *adapter)
96{
97 return netif_queue_stopped(adapter->netdev);
98}
99
100
101static void
102vmxnet3_tq_start(struct vmxnet3_tx_queue *tq, struct vmxnet3_adapter *adapter)
103{
104 tq->stopped = false;
105 netif_start_queue(adapter->netdev);
106}
107
108
109static void
110vmxnet3_tq_wake(struct vmxnet3_tx_queue *tq, struct vmxnet3_adapter *adapter)
111{
112 tq->stopped = false;
113 netif_wake_queue(adapter->netdev);
114}
115
116
117static void
118vmxnet3_tq_stop(struct vmxnet3_tx_queue *tq, struct vmxnet3_adapter *adapter)
119{
120 tq->stopped = true;
121 tq->num_stop++;
122 netif_stop_queue(adapter->netdev);
123}
124
125
126/*
127 * Check the link state. This may start or stop the tx queue.
128 */
129static void
130vmxnet3_check_link(struct vmxnet3_adapter *adapter)
131{
132 u32 ret;
133
134 VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, VMXNET3_CMD_GET_LINK);
135 ret = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_CMD);
136 adapter->link_speed = ret >> 16;
137 if (ret & 1) { /* Link is up. */
138 printk(KERN_INFO "%s: NIC Link is Up %d Mbps\n",
139 adapter->netdev->name, adapter->link_speed);
140 if (!netif_carrier_ok(adapter->netdev))
141 netif_carrier_on(adapter->netdev);
142
143 vmxnet3_tq_start(&adapter->tx_queue, adapter);
144 } else {
145 printk(KERN_INFO "%s: NIC Link is Down\n",
146 adapter->netdev->name);
147 if (netif_carrier_ok(adapter->netdev))
148 netif_carrier_off(adapter->netdev);
149
150 vmxnet3_tq_stop(&adapter->tx_queue, adapter);
151 }
152}
153
154
155static void
156vmxnet3_process_events(struct vmxnet3_adapter *adapter)
157{
158 u32 events = adapter->shared->ecr;
159 if (!events)
160 return;
161
162 vmxnet3_ack_events(adapter, events);
163
164 /* Check if link state has changed */
165 if (events & VMXNET3_ECR_LINK)
166 vmxnet3_check_link(adapter);
167
168 /* Check if there is an error on xmit/recv queues */
169 if (events & (VMXNET3_ECR_TQERR | VMXNET3_ECR_RQERR)) {
170 VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
171 VMXNET3_CMD_GET_QUEUE_STATUS);
172
173 if (adapter->tqd_start->status.stopped) {
174 printk(KERN_ERR "%s: tq error 0x%x\n",
175 adapter->netdev->name,
176 adapter->tqd_start->status.error);
177 }
178 if (adapter->rqd_start->status.stopped) {
179 printk(KERN_ERR "%s: rq error 0x%x\n",
180 adapter->netdev->name,
181 adapter->rqd_start->status.error);
182 }
183
184 schedule_work(&adapter->work);
185 }
186}
187
188
189static void
190vmxnet3_unmap_tx_buf(struct vmxnet3_tx_buf_info *tbi,
191 struct pci_dev *pdev)
192{
193 if (tbi->map_type == VMXNET3_MAP_SINGLE)
194 pci_unmap_single(pdev, tbi->dma_addr, tbi->len,
195 PCI_DMA_TODEVICE);
196 else if (tbi->map_type == VMXNET3_MAP_PAGE)
197 pci_unmap_page(pdev, tbi->dma_addr, tbi->len,
198 PCI_DMA_TODEVICE);
199 else
200 BUG_ON(tbi->map_type != VMXNET3_MAP_NONE);
201
202 tbi->map_type = VMXNET3_MAP_NONE; /* to help debugging */
203}
204
205
206static int
207vmxnet3_unmap_pkt(u32 eop_idx, struct vmxnet3_tx_queue *tq,
208 struct pci_dev *pdev, struct vmxnet3_adapter *adapter)
209{
210 struct sk_buff *skb;
211 int entries = 0;
212
213 /* no out of order completion */
214 BUG_ON(tq->buf_info[eop_idx].sop_idx != tq->tx_ring.next2comp);
215 BUG_ON(tq->tx_ring.base[eop_idx].txd.eop != 1);
216
217 skb = tq->buf_info[eop_idx].skb;
218 BUG_ON(skb == NULL);
219 tq->buf_info[eop_idx].skb = NULL;
220
221 VMXNET3_INC_RING_IDX_ONLY(eop_idx, tq->tx_ring.size);
222
223 while (tq->tx_ring.next2comp != eop_idx) {
224 vmxnet3_unmap_tx_buf(tq->buf_info + tq->tx_ring.next2comp,
225 pdev);
226
227 /* update next2comp w/o tx_lock. Since we are marking more,
228 * instead of less, tx ring entries avail, the worst case is
229 * that the tx routine incorrectly re-queues a pkt due to
230 * insufficient tx ring entries.
231 */
232 vmxnet3_cmd_ring_adv_next2comp(&tq->tx_ring);
233 entries++;
234 }
235
236 dev_kfree_skb_any(skb);
237 return entries;
238}
239
240
241static int
242vmxnet3_tq_tx_complete(struct vmxnet3_tx_queue *tq,
243 struct vmxnet3_adapter *adapter)
244{
245 int completed = 0;
246 union Vmxnet3_GenericDesc *gdesc;
247
248 gdesc = tq->comp_ring.base + tq->comp_ring.next2proc;
249 while (gdesc->tcd.gen == tq->comp_ring.gen) {
250 completed += vmxnet3_unmap_pkt(gdesc->tcd.txdIdx, tq,
251 adapter->pdev, adapter);
252
253 vmxnet3_comp_ring_adv_next2proc(&tq->comp_ring);
254 gdesc = tq->comp_ring.base + tq->comp_ring.next2proc;
255 }
256
257 if (completed) {
258 spin_lock(&tq->tx_lock);
259 if (unlikely(vmxnet3_tq_stopped(tq, adapter) &&
260 vmxnet3_cmd_ring_desc_avail(&tq->tx_ring) >
261 VMXNET3_WAKE_QUEUE_THRESHOLD(tq) &&
262 netif_carrier_ok(adapter->netdev))) {
263 vmxnet3_tq_wake(tq, adapter);
264 }
265 spin_unlock(&tq->tx_lock);
266 }
267 return completed;
268}
269
270
271static void
272vmxnet3_tq_cleanup(struct vmxnet3_tx_queue *tq,
273 struct vmxnet3_adapter *adapter)
274{
275 int i;
276
277 while (tq->tx_ring.next2comp != tq->tx_ring.next2fill) {
278 struct vmxnet3_tx_buf_info *tbi;
279 union Vmxnet3_GenericDesc *gdesc;
280
281 tbi = tq->buf_info + tq->tx_ring.next2comp;
282 gdesc = tq->tx_ring.base + tq->tx_ring.next2comp;
283
284 vmxnet3_unmap_tx_buf(tbi, adapter->pdev);
285 if (tbi->skb) {
286 dev_kfree_skb_any(tbi->skb);
287 tbi->skb = NULL;
288 }
289 vmxnet3_cmd_ring_adv_next2comp(&tq->tx_ring);
290 }
291
292 /* sanity check, verify all buffers are indeed unmapped and freed */
293 for (i = 0; i < tq->tx_ring.size; i++) {
294 BUG_ON(tq->buf_info[i].skb != NULL ||
295 tq->buf_info[i].map_type != VMXNET3_MAP_NONE);
296 }
297
298 tq->tx_ring.gen = VMXNET3_INIT_GEN;
299 tq->tx_ring.next2fill = tq->tx_ring.next2comp = 0;
300
301 tq->comp_ring.gen = VMXNET3_INIT_GEN;
302 tq->comp_ring.next2proc = 0;
303}
304
305
306void
307vmxnet3_tq_destroy(struct vmxnet3_tx_queue *tq,
308 struct vmxnet3_adapter *adapter)
309{
310 if (tq->tx_ring.base) {
311 pci_free_consistent(adapter->pdev, tq->tx_ring.size *
312 sizeof(struct Vmxnet3_TxDesc),
313 tq->tx_ring.base, tq->tx_ring.basePA);
314 tq->tx_ring.base = NULL;
315 }
316 if (tq->data_ring.base) {
317 pci_free_consistent(adapter->pdev, tq->data_ring.size *
318 sizeof(struct Vmxnet3_TxDataDesc),
319 tq->data_ring.base, tq->data_ring.basePA);
320 tq->data_ring.base = NULL;
321 }
322 if (tq->comp_ring.base) {
323 pci_free_consistent(adapter->pdev, tq->comp_ring.size *
324 sizeof(struct Vmxnet3_TxCompDesc),
325 tq->comp_ring.base, tq->comp_ring.basePA);
326 tq->comp_ring.base = NULL;
327 }
328 kfree(tq->buf_info);
329 tq->buf_info = NULL;
330}
331
332
333static void
334vmxnet3_tq_init(struct vmxnet3_tx_queue *tq,
335 struct vmxnet3_adapter *adapter)
336{
337 int i;
338
339 /* reset the tx ring contents to 0 and reset the tx ring states */
340 memset(tq->tx_ring.base, 0, tq->tx_ring.size *
341 sizeof(struct Vmxnet3_TxDesc));
342 tq->tx_ring.next2fill = tq->tx_ring.next2comp = 0;
343 tq->tx_ring.gen = VMXNET3_INIT_GEN;
344
345 memset(tq->data_ring.base, 0, tq->data_ring.size *
346 sizeof(struct Vmxnet3_TxDataDesc));
347
348 /* reset the tx comp ring contents to 0 and reset comp ring states */
349 memset(tq->comp_ring.base, 0, tq->comp_ring.size *
350 sizeof(struct Vmxnet3_TxCompDesc));
351 tq->comp_ring.next2proc = 0;
352 tq->comp_ring.gen = VMXNET3_INIT_GEN;
353
354 /* reset the bookkeeping data */
355 memset(tq->buf_info, 0, sizeof(tq->buf_info[0]) * tq->tx_ring.size);
356 for (i = 0; i < tq->tx_ring.size; i++)
357 tq->buf_info[i].map_type = VMXNET3_MAP_NONE;
358
359 /* stats are not reset */
360}
361
362
363static int
364vmxnet3_tq_create(struct vmxnet3_tx_queue *tq,
365 struct vmxnet3_adapter *adapter)
366{
367 BUG_ON(tq->tx_ring.base || tq->data_ring.base ||
368 tq->comp_ring.base || tq->buf_info);
369
370 tq->tx_ring.base = pci_alloc_consistent(adapter->pdev, tq->tx_ring.size
371 * sizeof(struct Vmxnet3_TxDesc),
372 &tq->tx_ring.basePA);
373 if (!tq->tx_ring.base) {
374 printk(KERN_ERR "%s: failed to allocate tx ring\n",
375 adapter->netdev->name);
376 goto err;
377 }
378
379 tq->data_ring.base = pci_alloc_consistent(adapter->pdev,
380 tq->data_ring.size *
381 sizeof(struct Vmxnet3_TxDataDesc),
382 &tq->data_ring.basePA);
383 if (!tq->data_ring.base) {
384 printk(KERN_ERR "%s: failed to allocate data ring\n",
385 adapter->netdev->name);
386 goto err;
387 }
388
389 tq->comp_ring.base = pci_alloc_consistent(adapter->pdev,
390 tq->comp_ring.size *
391 sizeof(struct Vmxnet3_TxCompDesc),
392 &tq->comp_ring.basePA);
393 if (!tq->comp_ring.base) {
394 printk(KERN_ERR "%s: failed to allocate tx comp ring\n",
395 adapter->netdev->name);
396 goto err;
397 }
398
399 tq->buf_info = kcalloc(tq->tx_ring.size, sizeof(tq->buf_info[0]),
400 GFP_KERNEL);
401 if (!tq->buf_info) {
402 printk(KERN_ERR "%s: failed to allocate tx bufinfo\n",
403 adapter->netdev->name);
404 goto err;
405 }
406
407 return 0;
408
409err:
410 vmxnet3_tq_destroy(tq, adapter);
411 return -ENOMEM;
412}
413
414
415/*
416 * starting from ring->next2fill, allocate rx buffers for the given ring
417 * of the rx queue and update the rx desc. stop after @num_to_alloc buffers
418 * are allocated or allocation fails
419 */
420
421static int
422vmxnet3_rq_alloc_rx_buf(struct vmxnet3_rx_queue *rq, u32 ring_idx,
423 int num_to_alloc, struct vmxnet3_adapter *adapter)
424{
425 int num_allocated = 0;
426 struct vmxnet3_rx_buf_info *rbi_base = rq->buf_info[ring_idx];
427 struct vmxnet3_cmd_ring *ring = &rq->rx_ring[ring_idx];
428 u32 val;
429
430 while (num_allocated < num_to_alloc) {
431 struct vmxnet3_rx_buf_info *rbi;
432 union Vmxnet3_GenericDesc *gd;
433
434 rbi = rbi_base + ring->next2fill;
435 gd = ring->base + ring->next2fill;
436
437 if (rbi->buf_type == VMXNET3_RX_BUF_SKB) {
438 if (rbi->skb == NULL) {
439 rbi->skb = dev_alloc_skb(rbi->len +
440 NET_IP_ALIGN);
441 if (unlikely(rbi->skb == NULL)) {
442 rq->stats.rx_buf_alloc_failure++;
443 break;
444 }
445 rbi->skb->dev = adapter->netdev;
446
447 skb_reserve(rbi->skb, NET_IP_ALIGN);
448 rbi->dma_addr = pci_map_single(adapter->pdev,
449 rbi->skb->data, rbi->len,
450 PCI_DMA_FROMDEVICE);
451 } else {
452 /* rx buffer skipped by the device */
453 }
454 val = VMXNET3_RXD_BTYPE_HEAD << VMXNET3_RXD_BTYPE_SHIFT;
455 } else {
456 BUG_ON(rbi->buf_type != VMXNET3_RX_BUF_PAGE ||
457 rbi->len != PAGE_SIZE);
458
459 if (rbi->page == NULL) {
460 rbi->page = alloc_page(GFP_ATOMIC);
461 if (unlikely(rbi->page == NULL)) {
462 rq->stats.rx_buf_alloc_failure++;
463 break;
464 }
465 rbi->dma_addr = pci_map_page(adapter->pdev,
466 rbi->page, 0, PAGE_SIZE,
467 PCI_DMA_FROMDEVICE);
468 } else {
469 /* rx buffers skipped by the device */
470 }
471 val = VMXNET3_RXD_BTYPE_BODY << VMXNET3_RXD_BTYPE_SHIFT;
472 }
473
474 BUG_ON(rbi->dma_addr == 0);
475 gd->rxd.addr = rbi->dma_addr;
476 gd->dword[2] = (ring->gen << VMXNET3_RXD_GEN_SHIFT) | val |
477 rbi->len;
478
479 num_allocated++;
480 vmxnet3_cmd_ring_adv_next2fill(ring);
481 }
482 rq->uncommitted[ring_idx] += num_allocated;
483
484 dprintk(KERN_ERR "alloc_rx_buf: %d allocated, next2fill %u, next2comp "
485 "%u, uncommited %u\n", num_allocated, ring->next2fill,
486 ring->next2comp, rq->uncommitted[ring_idx]);
487
488 /* so that the device can distinguish a full ring and an empty ring */
489 BUG_ON(num_allocated != 0 && ring->next2fill == ring->next2comp);
490
491 return num_allocated;
492}
493
494
495static void
496vmxnet3_append_frag(struct sk_buff *skb, struct Vmxnet3_RxCompDesc *rcd,
497 struct vmxnet3_rx_buf_info *rbi)
498{
499 struct skb_frag_struct *frag = skb_shinfo(skb)->frags +
500 skb_shinfo(skb)->nr_frags;
501
502 BUG_ON(skb_shinfo(skb)->nr_frags >= MAX_SKB_FRAGS);
503
504 frag->page = rbi->page;
505 frag->page_offset = 0;
506 frag->size = rcd->len;
507 skb->data_len += frag->size;
508 skb_shinfo(skb)->nr_frags++;
509}
510
511
512static void
513vmxnet3_map_pkt(struct sk_buff *skb, struct vmxnet3_tx_ctx *ctx,
514 struct vmxnet3_tx_queue *tq, struct pci_dev *pdev,
515 struct vmxnet3_adapter *adapter)
516{
517 u32 dw2, len;
518 unsigned long buf_offset;
519 int i;
520 union Vmxnet3_GenericDesc *gdesc;
521 struct vmxnet3_tx_buf_info *tbi = NULL;
522
523 BUG_ON(ctx->copy_size > skb_headlen(skb));
524
525 /* use the previous gen bit for the SOP desc */
526 dw2 = (tq->tx_ring.gen ^ 0x1) << VMXNET3_TXD_GEN_SHIFT;
527
528 ctx->sop_txd = tq->tx_ring.base + tq->tx_ring.next2fill;
529 gdesc = ctx->sop_txd; /* both loops below can be skipped */
530
531 /* no need to map the buffer if headers are copied */
532 if (ctx->copy_size) {
533 ctx->sop_txd->txd.addr = tq->data_ring.basePA +
534 tq->tx_ring.next2fill *
535 sizeof(struct Vmxnet3_TxDataDesc);
536 ctx->sop_txd->dword[2] = dw2 | ctx->copy_size;
537 ctx->sop_txd->dword[3] = 0;
538
539 tbi = tq->buf_info + tq->tx_ring.next2fill;
540 tbi->map_type = VMXNET3_MAP_NONE;
541
542 dprintk(KERN_ERR "txd[%u]: 0x%Lx 0x%x 0x%x\n",
543 tq->tx_ring.next2fill, ctx->sop_txd->txd.addr,
544 ctx->sop_txd->dword[2], ctx->sop_txd->dword[3]);
545 vmxnet3_cmd_ring_adv_next2fill(&tq->tx_ring);
546
547 /* use the right gen for non-SOP desc */
548 dw2 = tq->tx_ring.gen << VMXNET3_TXD_GEN_SHIFT;
549 }
550
551 /* linear part can use multiple tx desc if it's big */
552 len = skb_headlen(skb) - ctx->copy_size;
553 buf_offset = ctx->copy_size;
554 while (len) {
555 u32 buf_size;
556
557 buf_size = len > VMXNET3_MAX_TX_BUF_SIZE ?
558 VMXNET3_MAX_TX_BUF_SIZE : len;
559
560 tbi = tq->buf_info + tq->tx_ring.next2fill;
561 tbi->map_type = VMXNET3_MAP_SINGLE;
562 tbi->dma_addr = pci_map_single(adapter->pdev,
563 skb->data + buf_offset, buf_size,
564 PCI_DMA_TODEVICE);
565
566 tbi->len = buf_size; /* this automatically convert 2^14 to 0 */
567
568 gdesc = tq->tx_ring.base + tq->tx_ring.next2fill;
569 BUG_ON(gdesc->txd.gen == tq->tx_ring.gen);
570
571 gdesc->txd.addr = tbi->dma_addr;
572 gdesc->dword[2] = dw2 | buf_size;
573 gdesc->dword[3] = 0;
574
575 dprintk(KERN_ERR "txd[%u]: 0x%Lx 0x%x 0x%x\n",
576 tq->tx_ring.next2fill, gdesc->txd.addr,
577 gdesc->dword[2], gdesc->dword[3]);
578 vmxnet3_cmd_ring_adv_next2fill(&tq->tx_ring);
579 dw2 = tq->tx_ring.gen << VMXNET3_TXD_GEN_SHIFT;
580
581 len -= buf_size;
582 buf_offset += buf_size;
583 }
584
585 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
586 struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i];
587
588 tbi = tq->buf_info + tq->tx_ring.next2fill;
589 tbi->map_type = VMXNET3_MAP_PAGE;
590 tbi->dma_addr = pci_map_page(adapter->pdev, frag->page,
591 frag->page_offset, frag->size,
592 PCI_DMA_TODEVICE);
593
594 tbi->len = frag->size;
595
596 gdesc = tq->tx_ring.base + tq->tx_ring.next2fill;
597 BUG_ON(gdesc->txd.gen == tq->tx_ring.gen);
598
599 gdesc->txd.addr = tbi->dma_addr;
600 gdesc->dword[2] = dw2 | frag->size;
601 gdesc->dword[3] = 0;
602
603 dprintk(KERN_ERR "txd[%u]: 0x%llu %u %u\n",
604 tq->tx_ring.next2fill, gdesc->txd.addr,
605 gdesc->dword[2], gdesc->dword[3]);
606 vmxnet3_cmd_ring_adv_next2fill(&tq->tx_ring);
607 dw2 = tq->tx_ring.gen << VMXNET3_TXD_GEN_SHIFT;
608 }
609
610 ctx->eop_txd = gdesc;
611
612 /* set the last buf_info for the pkt */
613 tbi->skb = skb;
614 tbi->sop_idx = ctx->sop_txd - tq->tx_ring.base;
615}
616
617
618/*
619 * parse and copy relevant protocol headers:
620 * For a tso pkt, relevant headers are L2/3/4 including options
621 * For a pkt requesting csum offloading, they are L2/3 and may include L4
622 * if it's a TCP/UDP pkt
623 *
624 * Returns:
625 * -1: error happens during parsing
626 * 0: protocol headers parsed, but too big to be copied
627 * 1: protocol headers parsed and copied
628 *
629 * Other effects:
630 * 1. related *ctx fields are updated.
631 * 2. ctx->copy_size is # of bytes copied
632 * 3. the portion copied is guaranteed to be in the linear part
633 *
634 */
635static int
636vmxnet3_parse_and_copy_hdr(struct sk_buff *skb, struct vmxnet3_tx_queue *tq,
637 struct vmxnet3_tx_ctx *ctx,
638 struct vmxnet3_adapter *adapter)
639{
640 struct Vmxnet3_TxDataDesc *tdd;
641
642 if (ctx->mss) {
643 ctx->eth_ip_hdr_size = skb_transport_offset(skb);
644 ctx->l4_hdr_size = ((struct tcphdr *)
645 skb_transport_header(skb))->doff * 4;
646 ctx->copy_size = ctx->eth_ip_hdr_size + ctx->l4_hdr_size;
647 } else {
648 unsigned int pull_size;
649
650 if (skb->ip_summed == CHECKSUM_PARTIAL) {
651 ctx->eth_ip_hdr_size = skb_transport_offset(skb);
652
653 if (ctx->ipv4) {
654 struct iphdr *iph = (struct iphdr *)
655 skb_network_header(skb);
656 if (iph->protocol == IPPROTO_TCP) {
657 pull_size = ctx->eth_ip_hdr_size +
658 sizeof(struct tcphdr);
659
660 if (unlikely(!pskb_may_pull(skb,
661 pull_size))) {
662 goto err;
663 }
664 ctx->l4_hdr_size = ((struct tcphdr *)
665 skb_transport_header(skb))->doff * 4;
666 } else if (iph->protocol == IPPROTO_UDP) {
667 ctx->l4_hdr_size =
668 sizeof(struct udphdr);
669 } else {
670 ctx->l4_hdr_size = 0;
671 }
672 } else {
673 /* for simplicity, don't copy L4 headers */
674 ctx->l4_hdr_size = 0;
675 }
676 ctx->copy_size = ctx->eth_ip_hdr_size +
677 ctx->l4_hdr_size;
678 } else {
679 ctx->eth_ip_hdr_size = 0;
680 ctx->l4_hdr_size = 0;
681 /* copy as much as allowed */
682 ctx->copy_size = min((unsigned int)VMXNET3_HDR_COPY_SIZE
683 , skb_headlen(skb));
684 }
685
686 /* make sure headers are accessible directly */
687 if (unlikely(!pskb_may_pull(skb, ctx->copy_size)))
688 goto err;
689 }
690
691 if (unlikely(ctx->copy_size > VMXNET3_HDR_COPY_SIZE)) {
692 tq->stats.oversized_hdr++;
693 ctx->copy_size = 0;
694 return 0;
695 }
696
697 tdd = tq->data_ring.base + tq->tx_ring.next2fill;
698
699 memcpy(tdd->data, skb->data, ctx->copy_size);
700 dprintk(KERN_ERR "copy %u bytes to dataRing[%u]\n",
701 ctx->copy_size, tq->tx_ring.next2fill);
702 return 1;
703
704err:
705 return -1;
706}
707
708
709static void
710vmxnet3_prepare_tso(struct sk_buff *skb,
711 struct vmxnet3_tx_ctx *ctx)
712{
713 struct tcphdr *tcph = (struct tcphdr *)skb_transport_header(skb);
714 if (ctx->ipv4) {
715 struct iphdr *iph = (struct iphdr *)skb_network_header(skb);
716 iph->check = 0;
717 tcph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, 0,
718 IPPROTO_TCP, 0);
719 } else {
720 struct ipv6hdr *iph = (struct ipv6hdr *)skb_network_header(skb);
721 tcph->check = ~csum_ipv6_magic(&iph->saddr, &iph->daddr, 0,
722 IPPROTO_TCP, 0);
723 }
724}
725
726
727/*
728 * Transmits a pkt thru a given tq
729 * Returns:
730 * NETDEV_TX_OK: descriptors are setup successfully
731 * NETDEV_TX_OK: error occured, the pkt is dropped
732 * NETDEV_TX_BUSY: tx ring is full, queue is stopped
733 *
734 * Side-effects:
735 * 1. tx ring may be changed
736 * 2. tq stats may be updated accordingly
737 * 3. shared->txNumDeferred may be updated
738 */
739
740static int
741vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq,
742 struct vmxnet3_adapter *adapter, struct net_device *netdev)
743{
744 int ret;
745 u32 count;
746 unsigned long flags;
747 struct vmxnet3_tx_ctx ctx;
748 union Vmxnet3_GenericDesc *gdesc;
749
750 /* conservatively estimate # of descriptors to use */
751 count = VMXNET3_TXD_NEEDED(skb_headlen(skb)) +
752 skb_shinfo(skb)->nr_frags + 1;
753
754 ctx.ipv4 = (skb->protocol == __constant_ntohs(ETH_P_IP));
755
756 ctx.mss = skb_shinfo(skb)->gso_size;
757 if (ctx.mss) {
758 if (skb_header_cloned(skb)) {
759 if (unlikely(pskb_expand_head(skb, 0, 0,
760 GFP_ATOMIC) != 0)) {
761 tq->stats.drop_tso++;
762 goto drop_pkt;
763 }
764 tq->stats.copy_skb_header++;
765 }
766 vmxnet3_prepare_tso(skb, &ctx);
767 } else {
768 if (unlikely(count > VMXNET3_MAX_TXD_PER_PKT)) {
769
770 /* non-tso pkts must not use more than
771 * VMXNET3_MAX_TXD_PER_PKT entries
772 */
773 if (skb_linearize(skb) != 0) {
774 tq->stats.drop_too_many_frags++;
775 goto drop_pkt;
776 }
777 tq->stats.linearized++;
778
779 /* recalculate the # of descriptors to use */
780 count = VMXNET3_TXD_NEEDED(skb_headlen(skb)) + 1;
781 }
782 }
783
784 ret = vmxnet3_parse_and_copy_hdr(skb, tq, &ctx, adapter);
785 if (ret >= 0) {
786 BUG_ON(ret <= 0 && ctx.copy_size != 0);
787 /* hdrs parsed, check against other limits */
788 if (ctx.mss) {
789 if (unlikely(ctx.eth_ip_hdr_size + ctx.l4_hdr_size >
790 VMXNET3_MAX_TX_BUF_SIZE)) {
791 goto hdr_too_big;
792 }
793 } else {
794 if (skb->ip_summed == CHECKSUM_PARTIAL) {
795 if (unlikely(ctx.eth_ip_hdr_size +
796 skb->csum_offset >
797 VMXNET3_MAX_CSUM_OFFSET)) {
798 goto hdr_too_big;
799 }
800 }
801 }
802 } else {
803 tq->stats.drop_hdr_inspect_err++;
804 goto drop_pkt;
805 }
806
807 spin_lock_irqsave(&tq->tx_lock, flags);
808
809 if (count > vmxnet3_cmd_ring_desc_avail(&tq->tx_ring)) {
810 tq->stats.tx_ring_full++;
811 dprintk(KERN_ERR "tx queue stopped on %s, next2comp %u"
812 " next2fill %u\n", adapter->netdev->name,
813 tq->tx_ring.next2comp, tq->tx_ring.next2fill);
814
815 vmxnet3_tq_stop(tq, adapter);
816 spin_unlock_irqrestore(&tq->tx_lock, flags);
817 return NETDEV_TX_BUSY;
818 }
819
820 /* fill tx descs related to addr & len */
821 vmxnet3_map_pkt(skb, &ctx, tq, adapter->pdev, adapter);
822
823 /* setup the EOP desc */
824 ctx.eop_txd->dword[3] = VMXNET3_TXD_CQ | VMXNET3_TXD_EOP;
825
826 /* setup the SOP desc */
827 gdesc = ctx.sop_txd;
828 if (ctx.mss) {
829 gdesc->txd.hlen = ctx.eth_ip_hdr_size + ctx.l4_hdr_size;
830 gdesc->txd.om = VMXNET3_OM_TSO;
831 gdesc->txd.msscof = ctx.mss;
832 tq->shared->txNumDeferred += (skb->len - gdesc->txd.hlen +
833 ctx.mss - 1) / ctx.mss;
834 } else {
835 if (skb->ip_summed == CHECKSUM_PARTIAL) {
836 gdesc->txd.hlen = ctx.eth_ip_hdr_size;
837 gdesc->txd.om = VMXNET3_OM_CSUM;
838 gdesc->txd.msscof = ctx.eth_ip_hdr_size +
839 skb->csum_offset;
840 } else {
841 gdesc->txd.om = 0;
842 gdesc->txd.msscof = 0;
843 }
844 tq->shared->txNumDeferred++;
845 }
846
847 if (vlan_tx_tag_present(skb)) {
848 gdesc->txd.ti = 1;
849 gdesc->txd.tci = vlan_tx_tag_get(skb);
850 }
851
852 wmb();
853
854 /* finally flips the GEN bit of the SOP desc */
855 gdesc->dword[2] ^= VMXNET3_TXD_GEN;
856 dprintk(KERN_ERR "txd[%u]: SOP 0x%Lx 0x%x 0x%x\n",
857 (u32)((union Vmxnet3_GenericDesc *)ctx.sop_txd -
858 tq->tx_ring.base), gdesc->txd.addr, gdesc->dword[2],
859 gdesc->dword[3]);
860
861 spin_unlock_irqrestore(&tq->tx_lock, flags);
862
863 if (tq->shared->txNumDeferred >= tq->shared->txThreshold) {
864 tq->shared->txNumDeferred = 0;
865 VMXNET3_WRITE_BAR0_REG(adapter, VMXNET3_REG_TXPROD,
866 tq->tx_ring.next2fill);
867 }
868 netdev->trans_start = jiffies;
869
870 return NETDEV_TX_OK;
871
872hdr_too_big:
873 tq->stats.drop_oversized_hdr++;
874drop_pkt:
875 tq->stats.drop_total++;
876 dev_kfree_skb(skb);
877 return NETDEV_TX_OK;
878}
879
880
881static netdev_tx_t
882vmxnet3_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
883{
884 struct vmxnet3_adapter *adapter = netdev_priv(netdev);
885 struct vmxnet3_tx_queue *tq = &adapter->tx_queue;
886
887 return vmxnet3_tq_xmit(skb, tq, adapter, netdev);
888}
889
890
891static void
892vmxnet3_rx_csum(struct vmxnet3_adapter *adapter,
893 struct sk_buff *skb,
894 union Vmxnet3_GenericDesc *gdesc)
895{
896 if (!gdesc->rcd.cnc && adapter->rxcsum) {
897 /* typical case: TCP/UDP over IP and both csums are correct */
898 if ((gdesc->dword[3] & VMXNET3_RCD_CSUM_OK) ==
899 VMXNET3_RCD_CSUM_OK) {
900 skb->ip_summed = CHECKSUM_UNNECESSARY;
901 BUG_ON(!(gdesc->rcd.tcp || gdesc->rcd.udp));
902 BUG_ON(!(gdesc->rcd.v4 || gdesc->rcd.v6));
903 BUG_ON(gdesc->rcd.frg);
904 } else {
905 if (gdesc->rcd.csum) {
906 skb->csum = htons(gdesc->rcd.csum);
907 skb->ip_summed = CHECKSUM_PARTIAL;
908 } else {
909 skb->ip_summed = CHECKSUM_NONE;
910 }
911 }
912 } else {
913 skb->ip_summed = CHECKSUM_NONE;
914 }
915}
916
917
918static void
919vmxnet3_rx_error(struct vmxnet3_rx_queue *rq, struct Vmxnet3_RxCompDesc *rcd,
920 struct vmxnet3_rx_ctx *ctx, struct vmxnet3_adapter *adapter)
921{
922 rq->stats.drop_err++;
923 if (!rcd->fcs)
924 rq->stats.drop_fcs++;
925
926 rq->stats.drop_total++;
927
928 /*
929 * We do not unmap and chain the rx buffer to the skb.
930 * We basically pretend this buffer is not used and will be recycled
931 * by vmxnet3_rq_alloc_rx_buf()
932 */
933
934 /*
935 * ctx->skb may be NULL if this is the first and the only one
936 * desc for the pkt
937 */
938 if (ctx->skb)
939 dev_kfree_skb_irq(ctx->skb);
940
941 ctx->skb = NULL;
942}
943
944
945static int
946vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
947 struct vmxnet3_adapter *adapter, int quota)
948{
949 static u32 rxprod_reg[2] = {VMXNET3_REG_RXPROD, VMXNET3_REG_RXPROD2};
950 u32 num_rxd = 0;
951 struct Vmxnet3_RxCompDesc *rcd;
952 struct vmxnet3_rx_ctx *ctx = &rq->rx_ctx;
953
954 rcd = &rq->comp_ring.base[rq->comp_ring.next2proc].rcd;
955 while (rcd->gen == rq->comp_ring.gen) {
956 struct vmxnet3_rx_buf_info *rbi;
957 struct sk_buff *skb;
958 int num_to_alloc;
959 struct Vmxnet3_RxDesc *rxd;
960 u32 idx, ring_idx;
961
962 if (num_rxd >= quota) {
963 /* we may stop even before we see the EOP desc of
964 * the current pkt
965 */
966 break;
967 }
968 num_rxd++;
969
970 idx = rcd->rxdIdx;
971 ring_idx = rcd->rqID == rq->qid ? 0 : 1;
972
973 rxd = &rq->rx_ring[ring_idx].base[idx].rxd;
974 rbi = rq->buf_info[ring_idx] + idx;
975
976 BUG_ON(rxd->addr != rbi->dma_addr || rxd->len != rbi->len);
977
978 if (unlikely(rcd->eop && rcd->err)) {
979 vmxnet3_rx_error(rq, rcd, ctx, adapter);
980 goto rcd_done;
981 }
982
983 if (rcd->sop) { /* first buf of the pkt */
984 BUG_ON(rxd->btype != VMXNET3_RXD_BTYPE_HEAD ||
985 rcd->rqID != rq->qid);
986
987 BUG_ON(rbi->buf_type != VMXNET3_RX_BUF_SKB);
988 BUG_ON(ctx->skb != NULL || rbi->skb == NULL);
989
990 if (unlikely(rcd->len == 0)) {
991 /* Pretend the rx buffer is skipped. */
992 BUG_ON(!(rcd->sop && rcd->eop));
993 dprintk(KERN_ERR "rxRing[%u][%u] 0 length\n",
994 ring_idx, idx);
995 goto rcd_done;
996 }
997
998 ctx->skb = rbi->skb;
999 rbi->skb = NULL;
1000
1001 pci_unmap_single(adapter->pdev, rbi->dma_addr, rbi->len,
1002 PCI_DMA_FROMDEVICE);
1003
1004 skb_put(ctx->skb, rcd->len);
1005 } else {
1006 BUG_ON(ctx->skb == NULL);
1007 /* non SOP buffer must be type 1 in most cases */
1008 if (rbi->buf_type == VMXNET3_RX_BUF_PAGE) {
1009 BUG_ON(rxd->btype != VMXNET3_RXD_BTYPE_BODY);
1010
1011 if (rcd->len) {
1012 pci_unmap_page(adapter->pdev,
1013 rbi->dma_addr, rbi->len,
1014 PCI_DMA_FROMDEVICE);
1015
1016 vmxnet3_append_frag(ctx->skb, rcd, rbi);
1017 rbi->page = NULL;
1018 }
1019 } else {
1020 /*
1021 * The only time a non-SOP buffer is type 0 is
1022 * when it's EOP and error flag is raised, which
1023 * has already been handled.
1024 */
1025 BUG_ON(true);
1026 }
1027 }
1028
1029 skb = ctx->skb;
1030 if (rcd->eop) {
1031 skb->len += skb->data_len;
1032 skb->truesize += skb->data_len;
1033
1034 vmxnet3_rx_csum(adapter, skb,
1035 (union Vmxnet3_GenericDesc *)rcd);
1036 skb->protocol = eth_type_trans(skb, adapter->netdev);
1037
1038 if (unlikely(adapter->vlan_grp && rcd->ts)) {
1039 vlan_hwaccel_receive_skb(skb,
1040 adapter->vlan_grp, rcd->tci);
1041 } else {
1042 netif_receive_skb(skb);
1043 }
1044
1045 adapter->netdev->last_rx = jiffies;
1046 ctx->skb = NULL;
1047 }
1048
1049rcd_done:
1050 /* device may skip some rx descs */
1051 rq->rx_ring[ring_idx].next2comp = idx;
1052 VMXNET3_INC_RING_IDX_ONLY(rq->rx_ring[ring_idx].next2comp,
1053 rq->rx_ring[ring_idx].size);
1054
1055 /* refill rx buffers frequently to avoid starving the h/w */
1056 num_to_alloc = vmxnet3_cmd_ring_desc_avail(rq->rx_ring +
1057 ring_idx);
1058 if (unlikely(num_to_alloc > VMXNET3_RX_ALLOC_THRESHOLD(rq,
1059 ring_idx, adapter))) {
1060 vmxnet3_rq_alloc_rx_buf(rq, ring_idx, num_to_alloc,
1061 adapter);
1062
1063 /* if needed, update the register */
1064 if (unlikely(rq->shared->updateRxProd)) {
1065 VMXNET3_WRITE_BAR0_REG(adapter,
1066 rxprod_reg[ring_idx] + rq->qid * 8,
1067 rq->rx_ring[ring_idx].next2fill);
1068 rq->uncommitted[ring_idx] = 0;
1069 }
1070 }
1071
1072 vmxnet3_comp_ring_adv_next2proc(&rq->comp_ring);
1073 rcd = &rq->comp_ring.base[rq->comp_ring.next2proc].rcd;
1074 }
1075
1076 return num_rxd;
1077}
1078
1079
1080static void
1081vmxnet3_rq_cleanup(struct vmxnet3_rx_queue *rq,
1082 struct vmxnet3_adapter *adapter)
1083{
1084 u32 i, ring_idx;
1085 struct Vmxnet3_RxDesc *rxd;
1086
1087 for (ring_idx = 0; ring_idx < 2; ring_idx++) {
1088 for (i = 0; i < rq->rx_ring[ring_idx].size; i++) {
1089 rxd = &rq->rx_ring[ring_idx].base[i].rxd;
1090
1091 if (rxd->btype == VMXNET3_RXD_BTYPE_HEAD &&
1092 rq->buf_info[ring_idx][i].skb) {
1093 pci_unmap_single(adapter->pdev, rxd->addr,
1094 rxd->len, PCI_DMA_FROMDEVICE);
1095 dev_kfree_skb(rq->buf_info[ring_idx][i].skb);
1096 rq->buf_info[ring_idx][i].skb = NULL;
1097 } else if (rxd->btype == VMXNET3_RXD_BTYPE_BODY &&
1098 rq->buf_info[ring_idx][i].page) {
1099 pci_unmap_page(adapter->pdev, rxd->addr,
1100 rxd->len, PCI_DMA_FROMDEVICE);
1101 put_page(rq->buf_info[ring_idx][i].page);
1102 rq->buf_info[ring_idx][i].page = NULL;
1103 }
1104 }
1105
1106 rq->rx_ring[ring_idx].gen = VMXNET3_INIT_GEN;
1107 rq->rx_ring[ring_idx].next2fill =
1108 rq->rx_ring[ring_idx].next2comp = 0;
1109 rq->uncommitted[ring_idx] = 0;
1110 }
1111
1112 rq->comp_ring.gen = VMXNET3_INIT_GEN;
1113 rq->comp_ring.next2proc = 0;
1114}
1115
1116
1117void vmxnet3_rq_destroy(struct vmxnet3_rx_queue *rq,
1118 struct vmxnet3_adapter *adapter)
1119{
1120 int i;
1121 int j;
1122
1123 /* all rx buffers must have already been freed */
1124 for (i = 0; i < 2; i++) {
1125 if (rq->buf_info[i]) {
1126 for (j = 0; j < rq->rx_ring[i].size; j++)
1127 BUG_ON(rq->buf_info[i][j].page != NULL);
1128 }
1129 }
1130
1131
1132 kfree(rq->buf_info[0]);
1133
1134 for (i = 0; i < 2; i++) {
1135 if (rq->rx_ring[i].base) {
1136 pci_free_consistent(adapter->pdev, rq->rx_ring[i].size
1137 * sizeof(struct Vmxnet3_RxDesc),
1138 rq->rx_ring[i].base,
1139 rq->rx_ring[i].basePA);
1140 rq->rx_ring[i].base = NULL;
1141 }
1142 rq->buf_info[i] = NULL;
1143 }
1144
1145 if (rq->comp_ring.base) {
1146 pci_free_consistent(adapter->pdev, rq->comp_ring.size *
1147 sizeof(struct Vmxnet3_RxCompDesc),
1148 rq->comp_ring.base, rq->comp_ring.basePA);
1149 rq->comp_ring.base = NULL;
1150 }
1151}
1152
1153
1154static int
1155vmxnet3_rq_init(struct vmxnet3_rx_queue *rq,
1156 struct vmxnet3_adapter *adapter)
1157{
1158 int i;
1159
1160 /* initialize buf_info */
1161 for (i = 0; i < rq->rx_ring[0].size; i++) {
1162
1163 /* 1st buf for a pkt is skbuff */
1164 if (i % adapter->rx_buf_per_pkt == 0) {
1165 rq->buf_info[0][i].buf_type = VMXNET3_RX_BUF_SKB;
1166 rq->buf_info[0][i].len = adapter->skb_buf_size;
1167 } else { /* subsequent bufs for a pkt is frag */
1168 rq->buf_info[0][i].buf_type = VMXNET3_RX_BUF_PAGE;
1169 rq->buf_info[0][i].len = PAGE_SIZE;
1170 }
1171 }
1172 for (i = 0; i < rq->rx_ring[1].size; i++) {
1173 rq->buf_info[1][i].buf_type = VMXNET3_RX_BUF_PAGE;
1174 rq->buf_info[1][i].len = PAGE_SIZE;
1175 }
1176
1177 /* reset internal state and allocate buffers for both rings */
1178 for (i = 0; i < 2; i++) {
1179 rq->rx_ring[i].next2fill = rq->rx_ring[i].next2comp = 0;
1180 rq->uncommitted[i] = 0;
1181
1182 memset(rq->rx_ring[i].base, 0, rq->rx_ring[i].size *
1183 sizeof(struct Vmxnet3_RxDesc));
1184 rq->rx_ring[i].gen = VMXNET3_INIT_GEN;
1185 }
1186 if (vmxnet3_rq_alloc_rx_buf(rq, 0, rq->rx_ring[0].size - 1,
1187 adapter) == 0) {
1188 /* at least has 1 rx buffer for the 1st ring */
1189 return -ENOMEM;
1190 }
1191 vmxnet3_rq_alloc_rx_buf(rq, 1, rq->rx_ring[1].size - 1, adapter);
1192
1193 /* reset the comp ring */
1194 rq->comp_ring.next2proc = 0;
1195 memset(rq->comp_ring.base, 0, rq->comp_ring.size *
1196 sizeof(struct Vmxnet3_RxCompDesc));
1197 rq->comp_ring.gen = VMXNET3_INIT_GEN;
1198
1199 /* reset rxctx */
1200 rq->rx_ctx.skb = NULL;
1201
1202 /* stats are not reset */
1203 return 0;
1204}
1205
1206
1207static int
1208vmxnet3_rq_create(struct vmxnet3_rx_queue *rq, struct vmxnet3_adapter *adapter)
1209{
1210 int i;
1211 size_t sz;
1212 struct vmxnet3_rx_buf_info *bi;
1213
1214 for (i = 0; i < 2; i++) {
1215
1216 sz = rq->rx_ring[i].size * sizeof(struct Vmxnet3_RxDesc);
1217 rq->rx_ring[i].base = pci_alloc_consistent(adapter->pdev, sz,
1218 &rq->rx_ring[i].basePA);
1219 if (!rq->rx_ring[i].base) {
1220 printk(KERN_ERR "%s: failed to allocate rx ring %d\n",
1221 adapter->netdev->name, i);
1222 goto err;
1223 }
1224 }
1225
1226 sz = rq->comp_ring.size * sizeof(struct Vmxnet3_RxCompDesc);
1227 rq->comp_ring.base = pci_alloc_consistent(adapter->pdev, sz,
1228 &rq->comp_ring.basePA);
1229 if (!rq->comp_ring.base) {
1230 printk(KERN_ERR "%s: failed to allocate rx comp ring\n",
1231 adapter->netdev->name);
1232 goto err;
1233 }
1234
1235 sz = sizeof(struct vmxnet3_rx_buf_info) * (rq->rx_ring[0].size +
1236 rq->rx_ring[1].size);
1237 bi = kmalloc(sz, GFP_KERNEL);
1238 if (!bi) {
1239 printk(KERN_ERR "%s: failed to allocate rx bufinfo\n",
1240 adapter->netdev->name);
1241 goto err;
1242 }
1243 memset(bi, 0, sz);
1244 rq->buf_info[0] = bi;
1245 rq->buf_info[1] = bi + rq->rx_ring[0].size;
1246
1247 return 0;
1248
1249err:
1250 vmxnet3_rq_destroy(rq, adapter);
1251 return -ENOMEM;
1252}
1253
1254
1255static int
1256vmxnet3_do_poll(struct vmxnet3_adapter *adapter, int budget)
1257{
1258 if (unlikely(adapter->shared->ecr))
1259 vmxnet3_process_events(adapter);
1260
1261 vmxnet3_tq_tx_complete(&adapter->tx_queue, adapter);
1262 return vmxnet3_rq_rx_complete(&adapter->rx_queue, adapter, budget);
1263}
1264
1265
1266static int
1267vmxnet3_poll(struct napi_struct *napi, int budget)
1268{
1269 struct vmxnet3_adapter *adapter = container_of(napi,
1270 struct vmxnet3_adapter, napi);
1271 int rxd_done;
1272
1273 rxd_done = vmxnet3_do_poll(adapter, budget);
1274
1275 if (rxd_done < budget) {
1276 napi_complete(napi);
1277 vmxnet3_enable_intr(adapter, 0);
1278 }
1279 return rxd_done;
1280}
1281
1282
1283/* Interrupt handler for vmxnet3 */
1284static irqreturn_t
1285vmxnet3_intr(int irq, void *dev_id)
1286{
1287 struct net_device *dev = dev_id;
1288 struct vmxnet3_adapter *adapter = netdev_priv(dev);
1289
1290 if (unlikely(adapter->intr.type == VMXNET3_IT_INTX)) {
1291 u32 icr = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_ICR);
1292 if (unlikely(icr == 0))
1293 /* not ours */
1294 return IRQ_NONE;
1295 }
1296
1297
1298 /* disable intr if needed */
1299 if (adapter->intr.mask_mode == VMXNET3_IMM_ACTIVE)
1300 vmxnet3_disable_intr(adapter, 0);
1301
1302 napi_schedule(&adapter->napi);
1303
1304 return IRQ_HANDLED;
1305}
1306
1307#ifdef CONFIG_NET_POLL_CONTROLLER
1308
1309
1310/* netpoll callback. */
1311static void
1312vmxnet3_netpoll(struct net_device *netdev)
1313{
1314 struct vmxnet3_adapter *adapter = netdev_priv(netdev);
1315 int irq;
1316
1317#ifdef CONFIG_PCI_MSI
1318 if (adapter->intr.type == VMXNET3_IT_MSIX)
1319 irq = adapter->intr.msix_entries[0].vector;
1320 else
1321#endif
1322 irq = adapter->pdev->irq;
1323
1324 disable_irq(irq);
1325 vmxnet3_intr(irq, netdev);
1326 enable_irq(irq);
1327}
1328#endif
1329
1330static int
1331vmxnet3_request_irqs(struct vmxnet3_adapter *adapter)
1332{
1333 int err;
1334
1335#ifdef CONFIG_PCI_MSI
1336 if (adapter->intr.type == VMXNET3_IT_MSIX) {
1337 /* we only use 1 MSI-X vector */
1338 err = request_irq(adapter->intr.msix_entries[0].vector,
1339 vmxnet3_intr, 0, adapter->netdev->name,
1340 adapter->netdev);
1341 } else
1342#endif
1343 if (adapter->intr.type == VMXNET3_IT_MSI) {
1344 err = request_irq(adapter->pdev->irq, vmxnet3_intr, 0,
1345 adapter->netdev->name, adapter->netdev);
1346 } else {
1347 err = request_irq(adapter->pdev->irq, vmxnet3_intr,
1348 IRQF_SHARED, adapter->netdev->name,
1349 adapter->netdev);
1350 }
1351
1352 if (err)
1353 printk(KERN_ERR "Failed to request irq %s (intr type:%d), error"
1354 ":%d\n", adapter->netdev->name, adapter->intr.type, err);
1355
1356
1357 if (!err) {
1358 int i;
1359 /* init our intr settings */
1360 for (i = 0; i < adapter->intr.num_intrs; i++)
1361 adapter->intr.mod_levels[i] = UPT1_IML_ADAPTIVE;
1362
1363 /* next setup intr index for all intr sources */
1364 adapter->tx_queue.comp_ring.intr_idx = 0;
1365 adapter->rx_queue.comp_ring.intr_idx = 0;
1366 adapter->intr.event_intr_idx = 0;
1367
1368 printk(KERN_INFO "%s: intr type %u, mode %u, %u vectors "
1369 "allocated\n", adapter->netdev->name, adapter->intr.type,
1370 adapter->intr.mask_mode, adapter->intr.num_intrs);
1371 }
1372
1373 return err;
1374}
1375
1376
1377static void
1378vmxnet3_free_irqs(struct vmxnet3_adapter *adapter)
1379{
1380 BUG_ON(adapter->intr.type == VMXNET3_IT_AUTO ||
1381 adapter->intr.num_intrs <= 0);
1382
1383 switch (adapter->intr.type) {
1384#ifdef CONFIG_PCI_MSI
1385 case VMXNET3_IT_MSIX:
1386 {
1387 int i;
1388
1389 for (i = 0; i < adapter->intr.num_intrs; i++)
1390 free_irq(adapter->intr.msix_entries[i].vector,
1391 adapter->netdev);
1392 break;
1393 }
1394#endif
1395 case VMXNET3_IT_MSI:
1396 free_irq(adapter->pdev->irq, adapter->netdev);
1397 break;
1398 case VMXNET3_IT_INTX:
1399 free_irq(adapter->pdev->irq, adapter->netdev);
1400 break;
1401 default:
1402 BUG_ON(true);
1403 }
1404}
1405
1406
1407static void
1408vmxnet3_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp)
1409{
1410 struct vmxnet3_adapter *adapter = netdev_priv(netdev);
1411 struct Vmxnet3_DriverShared *shared = adapter->shared;
1412 u32 *vfTable = adapter->shared->devRead.rxFilterConf.vfTable;
1413
1414 if (grp) {
1415 /* add vlan rx stripping. */
1416 if (adapter->netdev->features & NETIF_F_HW_VLAN_RX) {
1417 int i;
1418 struct Vmxnet3_DSDevRead *devRead = &shared->devRead;
1419 adapter->vlan_grp = grp;
1420
1421 /* update FEATURES to device */
1422 devRead->misc.uptFeatures |= UPT1_F_RXVLAN;
1423 VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
1424 VMXNET3_CMD_UPDATE_FEATURE);
1425 /*
1426 * Clear entire vfTable; then enable untagged pkts.
1427 * Note: setting one entry in vfTable to non-zero turns
1428 * on VLAN rx filtering.
1429 */
1430 for (i = 0; i < VMXNET3_VFT_SIZE; i++)
1431 vfTable[i] = 0;
1432
1433 VMXNET3_SET_VFTABLE_ENTRY(vfTable, 0);
1434 VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
1435 VMXNET3_CMD_UPDATE_VLAN_FILTERS);
1436 } else {
1437 printk(KERN_ERR "%s: vlan_rx_register when device has "
1438 "no NETIF_F_HW_VLAN_RX\n", netdev->name);
1439 }
1440 } else {
1441 /* remove vlan rx stripping. */
1442 struct Vmxnet3_DSDevRead *devRead = &shared->devRead;
1443 adapter->vlan_grp = NULL;
1444
1445 if (devRead->misc.uptFeatures & UPT1_F_RXVLAN) {
1446 int i;
1447
1448 for (i = 0; i < VMXNET3_VFT_SIZE; i++) {
1449 /* clear entire vfTable; this also disables
1450 * VLAN rx filtering
1451 */
1452 vfTable[i] = 0;
1453 }
1454 VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
1455 VMXNET3_CMD_UPDATE_VLAN_FILTERS);
1456
1457 /* update FEATURES to device */
1458 devRead->misc.uptFeatures &= ~UPT1_F_RXVLAN;
1459 VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
1460 VMXNET3_CMD_UPDATE_FEATURE);
1461 }
1462 }
1463}
1464
1465
1466static void
1467vmxnet3_restore_vlan(struct vmxnet3_adapter *adapter)
1468{
1469 if (adapter->vlan_grp) {
1470 u16 vid;
1471 u32 *vfTable = adapter->shared->devRead.rxFilterConf.vfTable;
1472 bool activeVlan = false;
1473
1474 for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
1475 if (vlan_group_get_device(adapter->vlan_grp, vid)) {
1476 VMXNET3_SET_VFTABLE_ENTRY(vfTable, vid);
1477 activeVlan = true;
1478 }
1479 }
1480 if (activeVlan) {
1481 /* continue to allow untagged pkts */
1482 VMXNET3_SET_VFTABLE_ENTRY(vfTable, 0);
1483 }
1484 }
1485}
1486
1487
1488static void
1489vmxnet3_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
1490{
1491 struct vmxnet3_adapter *adapter = netdev_priv(netdev);
1492 u32 *vfTable = adapter->shared->devRead.rxFilterConf.vfTable;
1493
1494 VMXNET3_SET_VFTABLE_ENTRY(vfTable, vid);
1495 VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
1496 VMXNET3_CMD_UPDATE_VLAN_FILTERS);
1497}
1498
1499
1500static void
1501vmxnet3_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
1502{
1503 struct vmxnet3_adapter *adapter = netdev_priv(netdev);
1504 u32 *vfTable = adapter->shared->devRead.rxFilterConf.vfTable;
1505
1506 VMXNET3_CLEAR_VFTABLE_ENTRY(vfTable, vid);
1507 VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
1508 VMXNET3_CMD_UPDATE_VLAN_FILTERS);
1509}
1510
1511
1512static u8 *
1513vmxnet3_copy_mc(struct net_device *netdev)
1514{
1515 u8 *buf = NULL;
1516 u32 sz = netdev->mc_count * ETH_ALEN;
1517
1518 /* struct Vmxnet3_RxFilterConf.mfTableLen is u16. */
1519 if (sz <= 0xffff) {
1520 /* We may be called with BH disabled */
1521 buf = kmalloc(sz, GFP_ATOMIC);
1522 if (buf) {
1523 int i;
1524 struct dev_mc_list *mc = netdev->mc_list;
1525
1526 for (i = 0; i < netdev->mc_count; i++) {
1527 BUG_ON(!mc);
1528 memcpy(buf + i * ETH_ALEN, mc->dmi_addr,
1529 ETH_ALEN);
1530 mc = mc->next;
1531 }
1532 }
1533 }
1534 return buf;
1535}
1536
1537
1538static void
1539vmxnet3_set_mc(struct net_device *netdev)
1540{
1541 struct vmxnet3_adapter *adapter = netdev_priv(netdev);
1542 struct Vmxnet3_RxFilterConf *rxConf =
1543 &adapter->shared->devRead.rxFilterConf;
1544 u8 *new_table = NULL;
1545 u32 new_mode = VMXNET3_RXM_UCAST;
1546
1547 if (netdev->flags & IFF_PROMISC)
1548 new_mode |= VMXNET3_RXM_PROMISC;
1549
1550 if (netdev->flags & IFF_BROADCAST)
1551 new_mode |= VMXNET3_RXM_BCAST;
1552
1553 if (netdev->flags & IFF_ALLMULTI)
1554 new_mode |= VMXNET3_RXM_ALL_MULTI;
1555 else
1556 if (netdev->mc_count > 0) {
1557 new_table = vmxnet3_copy_mc(netdev);
1558 if (new_table) {
1559 new_mode |= VMXNET3_RXM_MCAST;
1560 rxConf->mfTableLen = netdev->mc_count *
1561 ETH_ALEN;
1562 rxConf->mfTablePA = virt_to_phys(new_table);
1563 } else {
1564 printk(KERN_INFO "%s: failed to copy mcast list"
1565 ", setting ALL_MULTI\n", netdev->name);
1566 new_mode |= VMXNET3_RXM_ALL_MULTI;
1567 }
1568 }
1569
1570
1571 if (!(new_mode & VMXNET3_RXM_MCAST)) {
1572 rxConf->mfTableLen = 0;
1573 rxConf->mfTablePA = 0;
1574 }
1575
1576 if (new_mode != rxConf->rxMode) {
1577 rxConf->rxMode = new_mode;
1578 VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
1579 VMXNET3_CMD_UPDATE_RX_MODE);
1580 }
1581
1582 VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
1583 VMXNET3_CMD_UPDATE_MAC_FILTERS);
1584
1585 kfree(new_table);
1586}
1587
1588
1589/*
1590 * Set up driver_shared based on settings in adapter.
1591 */
1592
1593static void
1594vmxnet3_setup_driver_shared(struct vmxnet3_adapter *adapter)
1595{
1596 struct Vmxnet3_DriverShared *shared = adapter->shared;
1597 struct Vmxnet3_DSDevRead *devRead = &shared->devRead;
1598 struct Vmxnet3_TxQueueConf *tqc;
1599 struct Vmxnet3_RxQueueConf *rqc;
1600 int i;
1601
1602 memset(shared, 0, sizeof(*shared));
1603
1604 /* driver settings */
1605 shared->magic = VMXNET3_REV1_MAGIC;
1606 devRead->misc.driverInfo.version = VMXNET3_DRIVER_VERSION_NUM;
1607 devRead->misc.driverInfo.gos.gosBits = (sizeof(void *) == 4 ?
1608 VMXNET3_GOS_BITS_32 : VMXNET3_GOS_BITS_64);
1609 devRead->misc.driverInfo.gos.gosType = VMXNET3_GOS_TYPE_LINUX;
1610 devRead->misc.driverInfo.vmxnet3RevSpt = 1;
1611 devRead->misc.driverInfo.uptVerSpt = 1;
1612
1613 devRead->misc.ddPA = virt_to_phys(adapter);
1614 devRead->misc.ddLen = sizeof(struct vmxnet3_adapter);
1615
1616 /* set up feature flags */
1617 if (adapter->rxcsum)
1618 devRead->misc.uptFeatures |= UPT1_F_RXCSUM;
1619
1620 if (adapter->lro) {
1621 devRead->misc.uptFeatures |= UPT1_F_LRO;
1622 devRead->misc.maxNumRxSG = 1 + MAX_SKB_FRAGS;
1623 }
1624 if ((adapter->netdev->features & NETIF_F_HW_VLAN_RX)
1625 && adapter->vlan_grp) {
1626 devRead->misc.uptFeatures |= UPT1_F_RXVLAN;
1627 }
1628
1629 devRead->misc.mtu = adapter->netdev->mtu;
1630 devRead->misc.queueDescPA = adapter->queue_desc_pa;
1631 devRead->misc.queueDescLen = sizeof(struct Vmxnet3_TxQueueDesc) +
1632 sizeof(struct Vmxnet3_RxQueueDesc);
1633
1634 /* tx queue settings */
1635 BUG_ON(adapter->tx_queue.tx_ring.base == NULL);
1636
1637 devRead->misc.numTxQueues = 1;
1638 tqc = &adapter->tqd_start->conf;
1639 tqc->txRingBasePA = adapter->tx_queue.tx_ring.basePA;
1640 tqc->dataRingBasePA = adapter->tx_queue.data_ring.basePA;
1641 tqc->compRingBasePA = adapter->tx_queue.comp_ring.basePA;
1642 tqc->ddPA = virt_to_phys(adapter->tx_queue.buf_info);
1643 tqc->txRingSize = adapter->tx_queue.tx_ring.size;
1644 tqc->dataRingSize = adapter->tx_queue.data_ring.size;
1645 tqc->compRingSize = adapter->tx_queue.comp_ring.size;
1646 tqc->ddLen = sizeof(struct vmxnet3_tx_buf_info) *
1647 tqc->txRingSize;
1648 tqc->intrIdx = adapter->tx_queue.comp_ring.intr_idx;
1649
1650 /* rx queue settings */
1651 devRead->misc.numRxQueues = 1;
1652 rqc = &adapter->rqd_start->conf;
1653 rqc->rxRingBasePA[0] = adapter->rx_queue.rx_ring[0].basePA;
1654 rqc->rxRingBasePA[1] = adapter->rx_queue.rx_ring[1].basePA;
1655 rqc->compRingBasePA = adapter->rx_queue.comp_ring.basePA;
1656 rqc->ddPA = virt_to_phys(adapter->rx_queue.buf_info);
1657 rqc->rxRingSize[0] = adapter->rx_queue.rx_ring[0].size;
1658 rqc->rxRingSize[1] = adapter->rx_queue.rx_ring[1].size;
1659 rqc->compRingSize = adapter->rx_queue.comp_ring.size;
1660 rqc->ddLen = sizeof(struct vmxnet3_rx_buf_info) *
1661 (rqc->rxRingSize[0] + rqc->rxRingSize[1]);
1662 rqc->intrIdx = adapter->rx_queue.comp_ring.intr_idx;
1663
1664 /* intr settings */
1665 devRead->intrConf.autoMask = adapter->intr.mask_mode ==
1666 VMXNET3_IMM_AUTO;
1667 devRead->intrConf.numIntrs = adapter->intr.num_intrs;
1668 for (i = 0; i < adapter->intr.num_intrs; i++)
1669 devRead->intrConf.modLevels[i] = adapter->intr.mod_levels[i];
1670
1671 devRead->intrConf.eventIntrIdx = adapter->intr.event_intr_idx;
1672
1673 /* rx filter settings */
1674 devRead->rxFilterConf.rxMode = 0;
1675 vmxnet3_restore_vlan(adapter);
1676 /* the rest are already zeroed */
1677}
1678
1679
1680int
1681vmxnet3_activate_dev(struct vmxnet3_adapter *adapter)
1682{
1683 int err;
1684 u32 ret;
1685
1686 dprintk(KERN_ERR "%s: skb_buf_size %d, rx_buf_per_pkt %d, ring sizes"
1687 " %u %u %u\n", adapter->netdev->name, adapter->skb_buf_size,
1688 adapter->rx_buf_per_pkt, adapter->tx_queue.tx_ring.size,
1689 adapter->rx_queue.rx_ring[0].size,
1690 adapter->rx_queue.rx_ring[1].size);
1691
1692 vmxnet3_tq_init(&adapter->tx_queue, adapter);
1693 err = vmxnet3_rq_init(&adapter->rx_queue, adapter);
1694 if (err) {
1695 printk(KERN_ERR "Failed to init rx queue for %s: error %d\n",
1696 adapter->netdev->name, err);
1697 goto rq_err;
1698 }
1699
1700 err = vmxnet3_request_irqs(adapter);
1701 if (err) {
1702 printk(KERN_ERR "Failed to setup irq for %s: error %d\n",
1703 adapter->netdev->name, err);
1704 goto irq_err;
1705 }
1706
1707 vmxnet3_setup_driver_shared(adapter);
1708
1709 VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_DSAL,
1710 VMXNET3_GET_ADDR_LO(adapter->shared_pa));
1711 VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_DSAH,
1712 VMXNET3_GET_ADDR_HI(adapter->shared_pa));
1713
1714 VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
1715 VMXNET3_CMD_ACTIVATE_DEV);
1716 ret = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_CMD);
1717
1718 if (ret != 0) {
1719 printk(KERN_ERR "Failed to activate dev %s: error %u\n",
1720 adapter->netdev->name, ret);
1721 err = -EINVAL;
1722 goto activate_err;
1723 }
1724 VMXNET3_WRITE_BAR0_REG(adapter, VMXNET3_REG_RXPROD,
1725 adapter->rx_queue.rx_ring[0].next2fill);
1726 VMXNET3_WRITE_BAR0_REG(adapter, VMXNET3_REG_RXPROD2,
1727 adapter->rx_queue.rx_ring[1].next2fill);
1728
1729 /* Apply the rx filter settins last. */
1730 vmxnet3_set_mc(adapter->netdev);
1731
1732 /*
1733 * Check link state when first activating device. It will start the
1734 * tx queue if the link is up.
1735 */
1736 vmxnet3_check_link(adapter);
1737
1738 napi_enable(&adapter->napi);
1739 vmxnet3_enable_all_intrs(adapter);
1740 clear_bit(VMXNET3_STATE_BIT_QUIESCED, &adapter->state);
1741 return 0;
1742
1743activate_err:
1744 VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_DSAL, 0);
1745 VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_DSAH, 0);
1746 vmxnet3_free_irqs(adapter);
1747irq_err:
1748rq_err:
1749 /* free up buffers we allocated */
1750 vmxnet3_rq_cleanup(&adapter->rx_queue, adapter);
1751 return err;
1752}
1753
1754
1755void
1756vmxnet3_reset_dev(struct vmxnet3_adapter *adapter)
1757{
1758 VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, VMXNET3_CMD_RESET_DEV);
1759}
1760
1761
1762int
1763vmxnet3_quiesce_dev(struct vmxnet3_adapter *adapter)
1764{
1765 if (test_and_set_bit(VMXNET3_STATE_BIT_QUIESCED, &adapter->state))
1766 return 0;
1767
1768
1769 VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
1770 VMXNET3_CMD_QUIESCE_DEV);
1771 vmxnet3_disable_all_intrs(adapter);
1772
1773 napi_disable(&adapter->napi);
1774 netif_tx_disable(adapter->netdev);
1775 adapter->link_speed = 0;
1776 netif_carrier_off(adapter->netdev);
1777
1778 vmxnet3_tq_cleanup(&adapter->tx_queue, adapter);
1779 vmxnet3_rq_cleanup(&adapter->rx_queue, adapter);
1780 vmxnet3_free_irqs(adapter);
1781 return 0;
1782}
1783
1784
1785static void
1786vmxnet3_write_mac_addr(struct vmxnet3_adapter *adapter, u8 *mac)
1787{
1788 u32 tmp;
1789
1790 tmp = *(u32 *)mac;
1791 VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_MACL, tmp);
1792
1793 tmp = (mac[5] << 8) | mac[4];
1794 VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_MACH, tmp);
1795}
1796
1797
1798static int
1799vmxnet3_set_mac_addr(struct net_device *netdev, void *p)
1800{
1801 struct sockaddr *addr = p;
1802 struct vmxnet3_adapter *adapter = netdev_priv(netdev);
1803
1804 memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
1805 vmxnet3_write_mac_addr(adapter, addr->sa_data);
1806
1807 return 0;
1808}
1809
1810
1811/* ==================== initialization and cleanup routines ============ */
1812
1813static int
1814vmxnet3_alloc_pci_resources(struct vmxnet3_adapter *adapter, bool *dma64)
1815{
1816 int err;
1817 unsigned long mmio_start, mmio_len;
1818 struct pci_dev *pdev = adapter->pdev;
1819
1820 err = pci_enable_device(pdev);
1821 if (err) {
1822 printk(KERN_ERR "Failed to enable adapter %s: error %d\n",
1823 pci_name(pdev), err);
1824 return err;
1825 }
1826
1827 if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) == 0) {
1828 if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)) != 0) {
1829 printk(KERN_ERR "pci_set_consistent_dma_mask failed "
1830 "for adapter %s\n", pci_name(pdev));
1831 err = -EIO;
1832 goto err_set_mask;
1833 }
1834 *dma64 = true;
1835 } else {
1836 if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) {
1837 printk(KERN_ERR "pci_set_dma_mask failed for adapter "
1838 "%s\n", pci_name(pdev));
1839 err = -EIO;
1840 goto err_set_mask;
1841 }
1842 *dma64 = false;
1843 }
1844
1845 err = pci_request_selected_regions(pdev, (1 << 2) - 1,
1846 vmxnet3_driver_name);
1847 if (err) {
1848 printk(KERN_ERR "Failed to request region for adapter %s: "
1849 "error %d\n", pci_name(pdev), err);
1850 goto err_set_mask;
1851 }
1852
1853 pci_set_master(pdev);
1854
1855 mmio_start = pci_resource_start(pdev, 0);
1856 mmio_len = pci_resource_len(pdev, 0);
1857 adapter->hw_addr0 = ioremap(mmio_start, mmio_len);
1858 if (!adapter->hw_addr0) {
1859 printk(KERN_ERR "Failed to map bar0 for adapter %s\n",
1860 pci_name(pdev));
1861 err = -EIO;
1862 goto err_ioremap;
1863 }
1864
1865 mmio_start = pci_resource_start(pdev, 1);
1866 mmio_len = pci_resource_len(pdev, 1);
1867 adapter->hw_addr1 = ioremap(mmio_start, mmio_len);
1868 if (!adapter->hw_addr1) {
1869 printk(KERN_ERR "Failed to map bar1 for adapter %s\n",
1870 pci_name(pdev));
1871 err = -EIO;
1872 goto err_bar1;
1873 }
1874 return 0;
1875
1876err_bar1:
1877 iounmap(adapter->hw_addr0);
1878err_ioremap:
1879 pci_release_selected_regions(pdev, (1 << 2) - 1);
1880err_set_mask:
1881 pci_disable_device(pdev);
1882 return err;
1883}
1884
1885
1886static void
1887vmxnet3_free_pci_resources(struct vmxnet3_adapter *adapter)
1888{
1889 BUG_ON(!adapter->pdev);
1890
1891 iounmap(adapter->hw_addr0);
1892 iounmap(adapter->hw_addr1);
1893 pci_release_selected_regions(adapter->pdev, (1 << 2) - 1);
1894 pci_disable_device(adapter->pdev);
1895}
1896
1897
1898static void
1899vmxnet3_adjust_rx_ring_size(struct vmxnet3_adapter *adapter)
1900{
1901 size_t sz;
1902
1903 if (adapter->netdev->mtu <= VMXNET3_MAX_SKB_BUF_SIZE -
1904 VMXNET3_MAX_ETH_HDR_SIZE) {
1905 adapter->skb_buf_size = adapter->netdev->mtu +
1906 VMXNET3_MAX_ETH_HDR_SIZE;
1907 if (adapter->skb_buf_size < VMXNET3_MIN_T0_BUF_SIZE)
1908 adapter->skb_buf_size = VMXNET3_MIN_T0_BUF_SIZE;
1909
1910 adapter->rx_buf_per_pkt = 1;
1911 } else {
1912 adapter->skb_buf_size = VMXNET3_MAX_SKB_BUF_SIZE;
1913 sz = adapter->netdev->mtu - VMXNET3_MAX_SKB_BUF_SIZE +
1914 VMXNET3_MAX_ETH_HDR_SIZE;
1915 adapter->rx_buf_per_pkt = 1 + (sz + PAGE_SIZE - 1) / PAGE_SIZE;
1916 }
1917
1918 /*
1919 * for simplicity, force the ring0 size to be a multiple of
1920 * rx_buf_per_pkt * VMXNET3_RING_SIZE_ALIGN
1921 */
1922 sz = adapter->rx_buf_per_pkt * VMXNET3_RING_SIZE_ALIGN;
1923 adapter->rx_queue.rx_ring[0].size = (adapter->rx_queue.rx_ring[0].size +
1924 sz - 1) / sz * sz;
1925 adapter->rx_queue.rx_ring[0].size = min_t(u32,
1926 adapter->rx_queue.rx_ring[0].size,
1927 VMXNET3_RX_RING_MAX_SIZE / sz * sz);
1928}
1929
1930
1931int
1932vmxnet3_create_queues(struct vmxnet3_adapter *adapter, u32 tx_ring_size,
1933 u32 rx_ring_size, u32 rx_ring2_size)
1934{
1935 int err;
1936
1937 adapter->tx_queue.tx_ring.size = tx_ring_size;
1938 adapter->tx_queue.data_ring.size = tx_ring_size;
1939 adapter->tx_queue.comp_ring.size = tx_ring_size;
1940 adapter->tx_queue.shared = &adapter->tqd_start->ctrl;
1941 adapter->tx_queue.stopped = true;
1942 err = vmxnet3_tq_create(&adapter->tx_queue, adapter);
1943 if (err)
1944 return err;
1945
1946 adapter->rx_queue.rx_ring[0].size = rx_ring_size;
1947 adapter->rx_queue.rx_ring[1].size = rx_ring2_size;
1948 vmxnet3_adjust_rx_ring_size(adapter);
1949 adapter->rx_queue.comp_ring.size = adapter->rx_queue.rx_ring[0].size +
1950 adapter->rx_queue.rx_ring[1].size;
1951 adapter->rx_queue.qid = 0;
1952 adapter->rx_queue.qid2 = 1;
1953 adapter->rx_queue.shared = &adapter->rqd_start->ctrl;
1954 err = vmxnet3_rq_create(&adapter->rx_queue, adapter);
1955 if (err)
1956 vmxnet3_tq_destroy(&adapter->tx_queue, adapter);
1957
1958 return err;
1959}
1960
1961static int
1962vmxnet3_open(struct net_device *netdev)
1963{
1964 struct vmxnet3_adapter *adapter;
1965 int err;
1966
1967 adapter = netdev_priv(netdev);
1968
1969 spin_lock_init(&adapter->tx_queue.tx_lock);
1970
1971 err = vmxnet3_create_queues(adapter, VMXNET3_DEF_TX_RING_SIZE,
1972 VMXNET3_DEF_RX_RING_SIZE,
1973 VMXNET3_DEF_RX_RING_SIZE);
1974 if (err)
1975 goto queue_err;
1976
1977 err = vmxnet3_activate_dev(adapter);
1978 if (err)
1979 goto activate_err;
1980
1981 return 0;
1982
1983activate_err:
1984 vmxnet3_rq_destroy(&adapter->rx_queue, adapter);
1985 vmxnet3_tq_destroy(&adapter->tx_queue, adapter);
1986queue_err:
1987 return err;
1988}
1989
1990
1991static int
1992vmxnet3_close(struct net_device *netdev)
1993{
1994 struct vmxnet3_adapter *adapter = netdev_priv(netdev);
1995
1996 /*
1997 * Reset_work may be in the middle of resetting the device, wait for its
1998 * completion.
1999 */
2000 while (test_and_set_bit(VMXNET3_STATE_BIT_RESETTING, &adapter->state))
2001 msleep(1);
2002
2003 vmxnet3_quiesce_dev(adapter);
2004
2005 vmxnet3_rq_destroy(&adapter->rx_queue, adapter);
2006 vmxnet3_tq_destroy(&adapter->tx_queue, adapter);
2007
2008 clear_bit(VMXNET3_STATE_BIT_RESETTING, &adapter->state);
2009
2010
2011 return 0;
2012}
2013
2014
2015void
2016vmxnet3_force_close(struct vmxnet3_adapter *adapter)
2017{
2018 /*
2019 * we must clear VMXNET3_STATE_BIT_RESETTING, otherwise
2020 * vmxnet3_close() will deadlock.
2021 */
2022 BUG_ON(test_bit(VMXNET3_STATE_BIT_RESETTING, &adapter->state));
2023
2024 /* we need to enable NAPI, otherwise dev_close will deadlock */
2025 napi_enable(&adapter->napi);
2026 dev_close(adapter->netdev);
2027}
2028
2029
2030static int
2031vmxnet3_change_mtu(struct net_device *netdev, int new_mtu)
2032{
2033 struct vmxnet3_adapter *adapter = netdev_priv(netdev);
2034 int err = 0;
2035
2036 if (new_mtu < VMXNET3_MIN_MTU || new_mtu > VMXNET3_MAX_MTU)
2037 return -EINVAL;
2038
2039 if (new_mtu > 1500 && !adapter->jumbo_frame)
2040 return -EINVAL;
2041
2042 netdev->mtu = new_mtu;
2043
2044 /*
2045 * Reset_work may be in the middle of resetting the device, wait for its
2046 * completion.
2047 */
2048 while (test_and_set_bit(VMXNET3_STATE_BIT_RESETTING, &adapter->state))
2049 msleep(1);
2050
2051 if (netif_running(netdev)) {
2052 vmxnet3_quiesce_dev(adapter);
2053 vmxnet3_reset_dev(adapter);
2054
2055 /* we need to re-create the rx queue based on the new mtu */
2056 vmxnet3_rq_destroy(&adapter->rx_queue, adapter);
2057 vmxnet3_adjust_rx_ring_size(adapter);
2058 adapter->rx_queue.comp_ring.size =
2059 adapter->rx_queue.rx_ring[0].size +
2060 adapter->rx_queue.rx_ring[1].size;
2061 err = vmxnet3_rq_create(&adapter->rx_queue, adapter);
2062 if (err) {
2063 printk(KERN_ERR "%s: failed to re-create rx queue,"
2064 " error %d. Closing it.\n", netdev->name, err);
2065 goto out;
2066 }
2067
2068 err = vmxnet3_activate_dev(adapter);
2069 if (err) {
2070 printk(KERN_ERR "%s: failed to re-activate, error %d. "
2071 "Closing it\n", netdev->name, err);
2072 goto out;
2073 }
2074 }
2075
2076out:
2077 clear_bit(VMXNET3_STATE_BIT_RESETTING, &adapter->state);
2078 if (err)
2079 vmxnet3_force_close(adapter);
2080
2081 return err;
2082}
2083
2084
2085static void
2086vmxnet3_declare_features(struct vmxnet3_adapter *adapter, bool dma64)
2087{
2088 struct net_device *netdev = adapter->netdev;
2089
2090 netdev->features = NETIF_F_SG |
2091 NETIF_F_HW_CSUM |
2092 NETIF_F_HW_VLAN_TX |
2093 NETIF_F_HW_VLAN_RX |
2094 NETIF_F_HW_VLAN_FILTER |
2095 NETIF_F_TSO |
2096 NETIF_F_TSO6 |
2097 NETIF_F_LRO;
2098
2099 printk(KERN_INFO "features: sg csum vlan jf tso tsoIPv6 lro");
2100
2101 adapter->rxcsum = true;
2102 adapter->jumbo_frame = true;
2103 adapter->lro = true;
2104
2105 if (dma64) {
2106 netdev->features |= NETIF_F_HIGHDMA;
2107 printk(" highDMA");
2108 }
2109
2110 netdev->vlan_features = netdev->features;
2111 printk("\n");
2112}
2113
2114
2115static void
2116vmxnet3_read_mac_addr(struct vmxnet3_adapter *adapter, u8 *mac)
2117{
2118 u32 tmp;
2119
2120 tmp = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_MACL);
2121 *(u32 *)mac = tmp;
2122
2123 tmp = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_MACH);
2124 mac[4] = tmp & 0xff;
2125 mac[5] = (tmp >> 8) & 0xff;
2126}
2127
2128
2129static void
2130vmxnet3_alloc_intr_resources(struct vmxnet3_adapter *adapter)
2131{
2132 u32 cfg;
2133
2134 /* intr settings */
2135 VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
2136 VMXNET3_CMD_GET_CONF_INTR);
2137 cfg = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_CMD);
2138 adapter->intr.type = cfg & 0x3;
2139 adapter->intr.mask_mode = (cfg >> 2) & 0x3;
2140
2141 if (adapter->intr.type == VMXNET3_IT_AUTO) {
2142 int err;
2143
2144#ifdef CONFIG_PCI_MSI
2145 adapter->intr.msix_entries[0].entry = 0;
2146 err = pci_enable_msix(adapter->pdev, adapter->intr.msix_entries,
2147 VMXNET3_LINUX_MAX_MSIX_VECT);
2148 if (!err) {
2149 adapter->intr.num_intrs = 1;
2150 adapter->intr.type = VMXNET3_IT_MSIX;
2151 return;
2152 }
2153#endif
2154
2155 err = pci_enable_msi(adapter->pdev);
2156 if (!err) {
2157 adapter->intr.num_intrs = 1;
2158 adapter->intr.type = VMXNET3_IT_MSI;
2159 return;
2160 }
2161 }
2162
2163 adapter->intr.type = VMXNET3_IT_INTX;
2164
2165 /* INT-X related setting */
2166 adapter->intr.num_intrs = 1;
2167}
2168
2169
2170static void
2171vmxnet3_free_intr_resources(struct vmxnet3_adapter *adapter)
2172{
2173 if (adapter->intr.type == VMXNET3_IT_MSIX)
2174 pci_disable_msix(adapter->pdev);
2175 else if (adapter->intr.type == VMXNET3_IT_MSI)
2176 pci_disable_msi(adapter->pdev);
2177 else
2178 BUG_ON(adapter->intr.type != VMXNET3_IT_INTX);
2179}
2180
2181
2182static void
2183vmxnet3_tx_timeout(struct net_device *netdev)
2184{
2185 struct vmxnet3_adapter *adapter = netdev_priv(netdev);
2186 adapter->tx_timeout_count++;
2187
2188 printk(KERN_ERR "%s: tx hang\n", adapter->netdev->name);
2189 schedule_work(&adapter->work);
2190}
2191
2192
2193static void
2194vmxnet3_reset_work(struct work_struct *data)
2195{
2196 struct vmxnet3_adapter *adapter;
2197
2198 adapter = container_of(data, struct vmxnet3_adapter, work);
2199
2200 /* if another thread is resetting the device, no need to proceed */
2201 if (test_and_set_bit(VMXNET3_STATE_BIT_RESETTING, &adapter->state))
2202 return;
2203
2204 /* if the device is closed, we must leave it alone */
2205 if (netif_running(adapter->netdev)) {
2206 printk(KERN_INFO "%s: resetting\n", adapter->netdev->name);
2207 vmxnet3_quiesce_dev(adapter);
2208 vmxnet3_reset_dev(adapter);
2209 vmxnet3_activate_dev(adapter);
2210 } else {
2211 printk(KERN_INFO "%s: already closed\n", adapter->netdev->name);
2212 }
2213
2214 clear_bit(VMXNET3_STATE_BIT_RESETTING, &adapter->state);
2215}
2216
2217
2218static int __devinit
2219vmxnet3_probe_device(struct pci_dev *pdev,
2220 const struct pci_device_id *id)
2221{
2222 static const struct net_device_ops vmxnet3_netdev_ops = {
2223 .ndo_open = vmxnet3_open,
2224 .ndo_stop = vmxnet3_close,
2225 .ndo_start_xmit = vmxnet3_xmit_frame,
2226 .ndo_set_mac_address = vmxnet3_set_mac_addr,
2227 .ndo_change_mtu = vmxnet3_change_mtu,
2228 .ndo_get_stats = vmxnet3_get_stats,
2229 .ndo_tx_timeout = vmxnet3_tx_timeout,
2230 .ndo_set_multicast_list = vmxnet3_set_mc,
2231 .ndo_vlan_rx_register = vmxnet3_vlan_rx_register,
2232 .ndo_vlan_rx_add_vid = vmxnet3_vlan_rx_add_vid,
2233 .ndo_vlan_rx_kill_vid = vmxnet3_vlan_rx_kill_vid,
2234#ifdef CONFIG_NET_POLL_CONTROLLER
2235 .ndo_poll_controller = vmxnet3_netpoll,
2236#endif
2237 };
2238 int err;
2239 bool dma64 = false; /* stupid gcc */
2240 u32 ver;
2241 struct net_device *netdev;
2242 struct vmxnet3_adapter *adapter;
2243 u8 mac[ETH_ALEN];
2244
2245 netdev = alloc_etherdev(sizeof(struct vmxnet3_adapter));
2246 if (!netdev) {
2247 printk(KERN_ERR "Failed to alloc ethernet device for adapter "
2248 "%s\n", pci_name(pdev));
2249 return -ENOMEM;
2250 }
2251
2252 pci_set_drvdata(pdev, netdev);
2253 adapter = netdev_priv(netdev);
2254 adapter->netdev = netdev;
2255 adapter->pdev = pdev;
2256
2257 adapter->shared = pci_alloc_consistent(adapter->pdev,
2258 sizeof(struct Vmxnet3_DriverShared),
2259 &adapter->shared_pa);
2260 if (!adapter->shared) {
2261 printk(KERN_ERR "Failed to allocate memory for %s\n",
2262 pci_name(pdev));
2263 err = -ENOMEM;
2264 goto err_alloc_shared;
2265 }
2266
2267 adapter->tqd_start = pci_alloc_consistent(adapter->pdev,
2268 sizeof(struct Vmxnet3_TxQueueDesc) +
2269 sizeof(struct Vmxnet3_RxQueueDesc),
2270 &adapter->queue_desc_pa);
2271
2272 if (!adapter->tqd_start) {
2273 printk(KERN_ERR "Failed to allocate memory for %s\n",
2274 pci_name(pdev));
2275 err = -ENOMEM;
2276 goto err_alloc_queue_desc;
2277 }
2278 adapter->rqd_start = (struct Vmxnet3_RxQueueDesc *)(adapter->tqd_start
2279 + 1);
2280
2281 adapter->pm_conf = kmalloc(sizeof(struct Vmxnet3_PMConf), GFP_KERNEL);
2282 if (adapter->pm_conf == NULL) {
2283 printk(KERN_ERR "Failed to allocate memory for %s\n",
2284 pci_name(pdev));
2285 err = -ENOMEM;
2286 goto err_alloc_pm;
2287 }
2288
2289 err = vmxnet3_alloc_pci_resources(adapter, &dma64);
2290 if (err < 0)
2291 goto err_alloc_pci;
2292
2293 ver = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_VRRS);
2294 if (ver & 1) {
2295 VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_VRRS, 1);
2296 } else {
2297 printk(KERN_ERR "Incompatible h/w version (0x%x) for adapter"
2298 " %s\n", ver, pci_name(pdev));
2299 err = -EBUSY;
2300 goto err_ver;
2301 }
2302
2303 ver = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_UVRS);
2304 if (ver & 1) {
2305 VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_UVRS, 1);
2306 } else {
2307 printk(KERN_ERR "Incompatible upt version (0x%x) for "
2308 "adapter %s\n", ver, pci_name(pdev));
2309 err = -EBUSY;
2310 goto err_ver;
2311 }
2312
2313 vmxnet3_declare_features(adapter, dma64);
2314
2315 adapter->dev_number = atomic_read(&devices_found);
2316 vmxnet3_alloc_intr_resources(adapter);
2317
2318 vmxnet3_read_mac_addr(adapter, mac);
2319 memcpy(netdev->dev_addr, mac, netdev->addr_len);
2320
2321 netdev->netdev_ops = &vmxnet3_netdev_ops;
2322 netdev->watchdog_timeo = 5 * HZ;
2323 vmxnet3_set_ethtool_ops(netdev);
2324
2325 INIT_WORK(&adapter->work, vmxnet3_reset_work);
2326
2327 netif_napi_add(netdev, &adapter->napi, vmxnet3_poll, 64);
2328 SET_NETDEV_DEV(netdev, &pdev->dev);
2329 err = register_netdev(netdev);
2330
2331 if (err) {
2332 printk(KERN_ERR "Failed to register adapter %s\n",
2333 pci_name(pdev));
2334 goto err_register;
2335 }
2336
2337 set_bit(VMXNET3_STATE_BIT_QUIESCED, &adapter->state);
2338 atomic_inc(&devices_found);
2339 return 0;
2340
2341err_register:
2342 vmxnet3_free_intr_resources(adapter);
2343err_ver:
2344 vmxnet3_free_pci_resources(adapter);
2345err_alloc_pci:
2346 kfree(adapter->pm_conf);
2347err_alloc_pm:
2348 pci_free_consistent(adapter->pdev, sizeof(struct Vmxnet3_TxQueueDesc) +
2349 sizeof(struct Vmxnet3_RxQueueDesc),
2350 adapter->tqd_start, adapter->queue_desc_pa);
2351err_alloc_queue_desc:
2352 pci_free_consistent(adapter->pdev, sizeof(struct Vmxnet3_DriverShared),
2353 adapter->shared, adapter->shared_pa);
2354err_alloc_shared:
2355 pci_set_drvdata(pdev, NULL);
2356 free_netdev(netdev);
2357 return err;
2358}
2359
2360
2361static void __devexit
2362vmxnet3_remove_device(struct pci_dev *pdev)
2363{
2364 struct net_device *netdev = pci_get_drvdata(pdev);
2365 struct vmxnet3_adapter *adapter = netdev_priv(netdev);
2366
2367 flush_scheduled_work();
2368
2369 unregister_netdev(netdev);
2370
2371 vmxnet3_free_intr_resources(adapter);
2372 vmxnet3_free_pci_resources(adapter);
2373 kfree(adapter->pm_conf);
2374 pci_free_consistent(adapter->pdev, sizeof(struct Vmxnet3_TxQueueDesc) +
2375 sizeof(struct Vmxnet3_RxQueueDesc),
2376 adapter->tqd_start, adapter->queue_desc_pa);
2377 pci_free_consistent(adapter->pdev, sizeof(struct Vmxnet3_DriverShared),
2378 adapter->shared, adapter->shared_pa);
2379 free_netdev(netdev);
2380}
2381
2382
2383#ifdef CONFIG_PM
2384
2385static int
2386vmxnet3_suspend(struct device *device)
2387{
2388 struct pci_dev *pdev = to_pci_dev(device);
2389 struct net_device *netdev = pci_get_drvdata(pdev);
2390 struct vmxnet3_adapter *adapter = netdev_priv(netdev);
2391 struct Vmxnet3_PMConf *pmConf;
2392 struct ethhdr *ehdr;
2393 struct arphdr *ahdr;
2394 u8 *arpreq;
2395 struct in_device *in_dev;
2396 struct in_ifaddr *ifa;
2397 int i = 0;
2398
2399 if (!netif_running(netdev))
2400 return 0;
2401
2402 vmxnet3_disable_all_intrs(adapter);
2403 vmxnet3_free_irqs(adapter);
2404 vmxnet3_free_intr_resources(adapter);
2405
2406 netif_device_detach(netdev);
2407 netif_stop_queue(netdev);
2408
2409 /* Create wake-up filters. */
2410 pmConf = adapter->pm_conf;
2411 memset(pmConf, 0, sizeof(*pmConf));
2412
2413 if (adapter->wol & WAKE_UCAST) {
2414 pmConf->filters[i].patternSize = ETH_ALEN;
2415 pmConf->filters[i].maskSize = 1;
2416 memcpy(pmConf->filters[i].pattern, netdev->dev_addr, ETH_ALEN);
2417 pmConf->filters[i].mask[0] = 0x3F; /* LSB ETH_ALEN bits */
2418
2419 pmConf->wakeUpEvents |= VMXNET3_PM_WAKEUP_FILTER;
2420 i++;
2421 }
2422
2423 if (adapter->wol & WAKE_ARP) {
2424 in_dev = in_dev_get(netdev);
2425 if (!in_dev)
2426 goto skip_arp;
2427
2428 ifa = (struct in_ifaddr *)in_dev->ifa_list;
2429 if (!ifa)
2430 goto skip_arp;
2431
2432 pmConf->filters[i].patternSize = ETH_HLEN + /* Ethernet header*/
2433 sizeof(struct arphdr) + /* ARP header */
2434 2 * ETH_ALEN + /* 2 Ethernet addresses*/
2435 2 * sizeof(u32); /*2 IPv4 addresses */
2436 pmConf->filters[i].maskSize =
2437 (pmConf->filters[i].patternSize - 1) / 8 + 1;
2438
2439 /* ETH_P_ARP in Ethernet header. */
2440 ehdr = (struct ethhdr *)pmConf->filters[i].pattern;
2441 ehdr->h_proto = htons(ETH_P_ARP);
2442
2443 /* ARPOP_REQUEST in ARP header. */
2444 ahdr = (struct arphdr *)&pmConf->filters[i].pattern[ETH_HLEN];
2445 ahdr->ar_op = htons(ARPOP_REQUEST);
2446 arpreq = (u8 *)(ahdr + 1);
2447
2448 /* The Unicast IPv4 address in 'tip' field. */
2449 arpreq += 2 * ETH_ALEN + sizeof(u32);
2450 *(u32 *)arpreq = ifa->ifa_address;
2451
2452 /* The mask for the relevant bits. */
2453 pmConf->filters[i].mask[0] = 0x00;
2454 pmConf->filters[i].mask[1] = 0x30; /* ETH_P_ARP */
2455 pmConf->filters[i].mask[2] = 0x30; /* ARPOP_REQUEST */
2456 pmConf->filters[i].mask[3] = 0x00;
2457 pmConf->filters[i].mask[4] = 0xC0; /* IPv4 TIP */
2458 pmConf->filters[i].mask[5] = 0x03; /* IPv4 TIP */
2459 in_dev_put(in_dev);
2460
2461 pmConf->wakeUpEvents |= VMXNET3_PM_WAKEUP_FILTER;
2462 i++;
2463 }
2464
2465skip_arp:
2466 if (adapter->wol & WAKE_MAGIC)
2467 pmConf->wakeUpEvents |= VMXNET3_PM_WAKEUP_MAGIC;
2468
2469 pmConf->numFilters = i;
2470
2471 adapter->shared->devRead.pmConfDesc.confVer = 1;
2472 adapter->shared->devRead.pmConfDesc.confLen = sizeof(*pmConf);
2473 adapter->shared->devRead.pmConfDesc.confPA = virt_to_phys(pmConf);
2474
2475 VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
2476 VMXNET3_CMD_UPDATE_PMCFG);
2477
2478 pci_save_state(pdev);
2479 pci_enable_wake(pdev, pci_choose_state(pdev, PMSG_SUSPEND),
2480 adapter->wol);
2481 pci_disable_device(pdev);
2482 pci_set_power_state(pdev, pci_choose_state(pdev, PMSG_SUSPEND));
2483
2484 return 0;
2485}
2486
2487
2488static int
2489vmxnet3_resume(struct device *device)
2490{
2491 int err;
2492 struct pci_dev *pdev = to_pci_dev(device);
2493 struct net_device *netdev = pci_get_drvdata(pdev);
2494 struct vmxnet3_adapter *adapter = netdev_priv(netdev);
2495 struct Vmxnet3_PMConf *pmConf;
2496
2497 if (!netif_running(netdev))
2498 return 0;
2499
2500 /* Destroy wake-up filters. */
2501 pmConf = adapter->pm_conf;
2502 memset(pmConf, 0, sizeof(*pmConf));
2503
2504 adapter->shared->devRead.pmConfDesc.confVer = 1;
2505 adapter->shared->devRead.pmConfDesc.confLen = sizeof(*pmConf);
2506 adapter->shared->devRead.pmConfDesc.confPA = virt_to_phys(pmConf);
2507
2508 netif_device_attach(netdev);
2509 pci_set_power_state(pdev, PCI_D0);
2510 pci_restore_state(pdev);
2511 err = pci_enable_device_mem(pdev);
2512 if (err != 0)
2513 return err;
2514
2515 pci_enable_wake(pdev, PCI_D0, 0);
2516
2517 VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
2518 VMXNET3_CMD_UPDATE_PMCFG);
2519 vmxnet3_alloc_intr_resources(adapter);
2520 vmxnet3_request_irqs(adapter);
2521 vmxnet3_enable_all_intrs(adapter);
2522
2523 return 0;
2524}
2525
2526static struct dev_pm_ops vmxnet3_pm_ops = {
2527 .suspend = vmxnet3_suspend,
2528 .resume = vmxnet3_resume,
2529};
2530#endif
2531
2532static struct pci_driver vmxnet3_driver = {
2533 .name = vmxnet3_driver_name,
2534 .id_table = vmxnet3_pciid_table,
2535 .probe = vmxnet3_probe_device,
2536 .remove = __devexit_p(vmxnet3_remove_device),
2537#ifdef CONFIG_PM
2538 .driver.pm = &vmxnet3_pm_ops,
2539#endif
2540};
2541
2542
2543static int __init
2544vmxnet3_init_module(void)
2545{
2546 printk(KERN_INFO "%s - version %s\n", VMXNET3_DRIVER_DESC,
2547 VMXNET3_DRIVER_VERSION_REPORT);
2548 return pci_register_driver(&vmxnet3_driver);
2549}
2550
2551module_init(vmxnet3_init_module);
2552
2553
2554static void
2555vmxnet3_exit_module(void)
2556{
2557 pci_unregister_driver(&vmxnet3_driver);
2558}
2559
2560module_exit(vmxnet3_exit_module);
2561
2562MODULE_AUTHOR("VMware, Inc.");
2563MODULE_DESCRIPTION(VMXNET3_DRIVER_DESC);
2564MODULE_LICENSE("GPL v2");
2565MODULE_VERSION(VMXNET3_DRIVER_VERSION_STRING);
diff --git a/drivers/net/vmxnet3/vmxnet3_ethtool.c b/drivers/net/vmxnet3/vmxnet3_ethtool.c
new file mode 100644
index 000000000000..c2c15e4cafc7
--- /dev/null
+++ b/drivers/net/vmxnet3/vmxnet3_ethtool.c
@@ -0,0 +1,566 @@
1/*
2 * Linux driver for VMware's vmxnet3 ethernet NIC.
3 *
4 * Copyright (C) 2008-2009, VMware, Inc. All Rights Reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; version 2 of the License and no later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
13 * NON INFRINGEMENT. See the GNU General Public License for more
14 * details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * The full GNU General Public License is included in this distribution in
21 * the file called "COPYING".
22 *
23 * Maintained by: Shreyas Bhatewara <pv-drivers@vmware.com>
24 *
25 */
26
27
28#include "vmxnet3_int.h"
29
30struct vmxnet3_stat_desc {
31 char desc[ETH_GSTRING_LEN];
32 int offset;
33};
34
35
36static u32
37vmxnet3_get_rx_csum(struct net_device *netdev)
38{
39 struct vmxnet3_adapter *adapter = netdev_priv(netdev);
40 return adapter->rxcsum;
41}
42
43
44static int
45vmxnet3_set_rx_csum(struct net_device *netdev, u32 val)
46{
47 struct vmxnet3_adapter *adapter = netdev_priv(netdev);
48
49 if (adapter->rxcsum != val) {
50 adapter->rxcsum = val;
51 if (netif_running(netdev)) {
52 if (val)
53 adapter->shared->devRead.misc.uptFeatures |=
54 UPT1_F_RXCSUM;
55 else
56 adapter->shared->devRead.misc.uptFeatures &=
57 ~UPT1_F_RXCSUM;
58
59 VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
60 VMXNET3_CMD_UPDATE_FEATURE);
61 }
62 }
63 return 0;
64}
65
66
67/* per tq stats maintained by the device */
68static const struct vmxnet3_stat_desc
69vmxnet3_tq_dev_stats[] = {
70 /* description, offset */
71 { "TSO pkts tx", offsetof(struct UPT1_TxStats, TSOPktsTxOK) },
72 { "TSO bytes tx", offsetof(struct UPT1_TxStats, TSOBytesTxOK) },
73 { "ucast pkts tx", offsetof(struct UPT1_TxStats, ucastPktsTxOK) },
74 { "ucast bytes tx", offsetof(struct UPT1_TxStats, ucastBytesTxOK) },
75 { "mcast pkts tx", offsetof(struct UPT1_TxStats, mcastPktsTxOK) },
76 { "mcast bytes tx", offsetof(struct UPT1_TxStats, mcastBytesTxOK) },
77 { "bcast pkts tx", offsetof(struct UPT1_TxStats, bcastPktsTxOK) },
78 { "bcast bytes tx", offsetof(struct UPT1_TxStats, bcastBytesTxOK) },
79 { "pkts tx err", offsetof(struct UPT1_TxStats, pktsTxError) },
80 { "pkts tx discard", offsetof(struct UPT1_TxStats, pktsTxDiscard) },
81};
82
83/* per tq stats maintained by the driver */
84static const struct vmxnet3_stat_desc
85vmxnet3_tq_driver_stats[] = {
86 /* description, offset */
87 {"drv dropped tx total", offsetof(struct vmxnet3_tq_driver_stats,
88 drop_total) },
89 { " too many frags", offsetof(struct vmxnet3_tq_driver_stats,
90 drop_too_many_frags) },
91 { " giant hdr", offsetof(struct vmxnet3_tq_driver_stats,
92 drop_oversized_hdr) },
93 { " hdr err", offsetof(struct vmxnet3_tq_driver_stats,
94 drop_hdr_inspect_err) },
95 { " tso", offsetof(struct vmxnet3_tq_driver_stats,
96 drop_tso) },
97 { "ring full", offsetof(struct vmxnet3_tq_driver_stats,
98 tx_ring_full) },
99 { "pkts linearized", offsetof(struct vmxnet3_tq_driver_stats,
100 linearized) },
101 { "hdr cloned", offsetof(struct vmxnet3_tq_driver_stats,
102 copy_skb_header) },
103 { "giant hdr", offsetof(struct vmxnet3_tq_driver_stats,
104 oversized_hdr) },
105};
106
107/* per rq stats maintained by the device */
108static const struct vmxnet3_stat_desc
109vmxnet3_rq_dev_stats[] = {
110 { "LRO pkts rx", offsetof(struct UPT1_RxStats, LROPktsRxOK) },
111 { "LRO byte rx", offsetof(struct UPT1_RxStats, LROBytesRxOK) },
112 { "ucast pkts rx", offsetof(struct UPT1_RxStats, ucastPktsRxOK) },
113 { "ucast bytes rx", offsetof(struct UPT1_RxStats, ucastBytesRxOK) },
114 { "mcast pkts rx", offsetof(struct UPT1_RxStats, mcastPktsRxOK) },
115 { "mcast bytes rx", offsetof(struct UPT1_RxStats, mcastBytesRxOK) },
116 { "bcast pkts rx", offsetof(struct UPT1_RxStats, bcastPktsRxOK) },
117 { "bcast bytes rx", offsetof(struct UPT1_RxStats, bcastBytesRxOK) },
118 { "pkts rx out of buf", offsetof(struct UPT1_RxStats, pktsRxOutOfBuf) },
119 { "pkts rx err", offsetof(struct UPT1_RxStats, pktsRxError) },
120};
121
122/* per rq stats maintained by the driver */
123static const struct vmxnet3_stat_desc
124vmxnet3_rq_driver_stats[] = {
125 /* description, offset */
126 { "drv dropped rx total", offsetof(struct vmxnet3_rq_driver_stats,
127 drop_total) },
128 { " err", offsetof(struct vmxnet3_rq_driver_stats,
129 drop_err) },
130 { " fcs", offsetof(struct vmxnet3_rq_driver_stats,
131 drop_fcs) },
132 { "rx buf alloc fail", offsetof(struct vmxnet3_rq_driver_stats,
133 rx_buf_alloc_failure) },
134};
135
136/* gloabl stats maintained by the driver */
137static const struct vmxnet3_stat_desc
138vmxnet3_global_stats[] = {
139 /* description, offset */
140 { "tx timeout count", offsetof(struct vmxnet3_adapter,
141 tx_timeout_count) }
142};
143
144
145struct net_device_stats *
146vmxnet3_get_stats(struct net_device *netdev)
147{
148 struct vmxnet3_adapter *adapter;
149 struct vmxnet3_tq_driver_stats *drvTxStats;
150 struct vmxnet3_rq_driver_stats *drvRxStats;
151 struct UPT1_TxStats *devTxStats;
152 struct UPT1_RxStats *devRxStats;
153 struct net_device_stats *net_stats = &netdev->stats;
154
155 adapter = netdev_priv(netdev);
156
157 /* Collect the dev stats into the shared area */
158 VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, VMXNET3_CMD_GET_STATS);
159
160 /* Assuming that we have a single queue device */
161 devTxStats = &adapter->tqd_start->stats;
162 devRxStats = &adapter->rqd_start->stats;
163
164 /* Get access to the driver stats per queue */
165 drvTxStats = &adapter->tx_queue.stats;
166 drvRxStats = &adapter->rx_queue.stats;
167
168 memset(net_stats, 0, sizeof(*net_stats));
169
170 net_stats->rx_packets = devRxStats->ucastPktsRxOK +
171 devRxStats->mcastPktsRxOK +
172 devRxStats->bcastPktsRxOK;
173
174 net_stats->tx_packets = devTxStats->ucastPktsTxOK +
175 devTxStats->mcastPktsTxOK +
176 devTxStats->bcastPktsTxOK;
177
178 net_stats->rx_bytes = devRxStats->ucastBytesRxOK +
179 devRxStats->mcastBytesRxOK +
180 devRxStats->bcastBytesRxOK;
181
182 net_stats->tx_bytes = devTxStats->ucastBytesTxOK +
183 devTxStats->mcastBytesTxOK +
184 devTxStats->bcastBytesTxOK;
185
186 net_stats->rx_errors = devRxStats->pktsRxError;
187 net_stats->tx_errors = devTxStats->pktsTxError;
188 net_stats->rx_dropped = drvRxStats->drop_total;
189 net_stats->tx_dropped = drvTxStats->drop_total;
190 net_stats->multicast = devRxStats->mcastPktsRxOK;
191
192 return net_stats;
193}
194
195static int
196vmxnet3_get_sset_count(struct net_device *netdev, int sset)
197{
198 switch (sset) {
199 case ETH_SS_STATS:
200 return ARRAY_SIZE(vmxnet3_tq_dev_stats) +
201 ARRAY_SIZE(vmxnet3_tq_driver_stats) +
202 ARRAY_SIZE(vmxnet3_rq_dev_stats) +
203 ARRAY_SIZE(vmxnet3_rq_driver_stats) +
204 ARRAY_SIZE(vmxnet3_global_stats);
205 default:
206 return -EOPNOTSUPP;
207 }
208}
209
210
211static int
212vmxnet3_get_regs_len(struct net_device *netdev)
213{
214 return 20 * sizeof(u32);
215}
216
217
218static void
219vmxnet3_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
220{
221 struct vmxnet3_adapter *adapter = netdev_priv(netdev);
222
223 strlcpy(drvinfo->driver, vmxnet3_driver_name, sizeof(drvinfo->driver));
224 drvinfo->driver[sizeof(drvinfo->driver) - 1] = '\0';
225
226 strlcpy(drvinfo->version, VMXNET3_DRIVER_VERSION_REPORT,
227 sizeof(drvinfo->version));
228 drvinfo->driver[sizeof(drvinfo->version) - 1] = '\0';
229
230 strlcpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version));
231 drvinfo->fw_version[sizeof(drvinfo->fw_version) - 1] = '\0';
232
233 strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
234 ETHTOOL_BUSINFO_LEN);
235 drvinfo->n_stats = vmxnet3_get_sset_count(netdev, ETH_SS_STATS);
236 drvinfo->testinfo_len = 0;
237 drvinfo->eedump_len = 0;
238 drvinfo->regdump_len = vmxnet3_get_regs_len(netdev);
239}
240
241
242static void
243vmxnet3_get_strings(struct net_device *netdev, u32 stringset, u8 *buf)
244{
245 if (stringset == ETH_SS_STATS) {
246 int i;
247
248 for (i = 0; i < ARRAY_SIZE(vmxnet3_tq_dev_stats); i++) {
249 memcpy(buf, vmxnet3_tq_dev_stats[i].desc,
250 ETH_GSTRING_LEN);
251 buf += ETH_GSTRING_LEN;
252 }
253 for (i = 0; i < ARRAY_SIZE(vmxnet3_tq_driver_stats); i++) {
254 memcpy(buf, vmxnet3_tq_driver_stats[i].desc,
255 ETH_GSTRING_LEN);
256 buf += ETH_GSTRING_LEN;
257 }
258 for (i = 0; i < ARRAY_SIZE(vmxnet3_rq_dev_stats); i++) {
259 memcpy(buf, vmxnet3_rq_dev_stats[i].desc,
260 ETH_GSTRING_LEN);
261 buf += ETH_GSTRING_LEN;
262 }
263 for (i = 0; i < ARRAY_SIZE(vmxnet3_rq_driver_stats); i++) {
264 memcpy(buf, vmxnet3_rq_driver_stats[i].desc,
265 ETH_GSTRING_LEN);
266 buf += ETH_GSTRING_LEN;
267 }
268 for (i = 0; i < ARRAY_SIZE(vmxnet3_global_stats); i++) {
269 memcpy(buf, vmxnet3_global_stats[i].desc,
270 ETH_GSTRING_LEN);
271 buf += ETH_GSTRING_LEN;
272 }
273 }
274}
275
276static u32
277vmxnet3_get_flags(struct net_device *netdev) {
278 return netdev->features;
279}
280
281static int
282vmxnet3_set_flags(struct net_device *netdev, u32 data) {
283 struct vmxnet3_adapter *adapter = netdev_priv(netdev);
284 u8 lro_requested = (data & ETH_FLAG_LRO) == 0 ? 0 : 1;
285 u8 lro_present = (netdev->features & NETIF_F_LRO) == 0 ? 0 : 1;
286
287 if (lro_requested ^ lro_present) {
288 /* toggle the LRO feature*/
289 netdev->features ^= NETIF_F_LRO;
290
291 /* update harware LRO capability accordingly */
292 if (lro_requested)
293 adapter->shared->devRead.misc.uptFeatures &= UPT1_F_LRO;
294 else
295 adapter->shared->devRead.misc.uptFeatures &=
296 ~UPT1_F_LRO;
297 VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
298 VMXNET3_CMD_UPDATE_FEATURE);
299 }
300 return 0;
301}
302
303static void
304vmxnet3_get_ethtool_stats(struct net_device *netdev,
305 struct ethtool_stats *stats, u64 *buf)
306{
307 struct vmxnet3_adapter *adapter = netdev_priv(netdev);
308 u8 *base;
309 int i;
310
311 VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, VMXNET3_CMD_GET_STATS);
312
313 /* this does assume each counter is 64-bit wide */
314
315 base = (u8 *)&adapter->tqd_start->stats;
316 for (i = 0; i < ARRAY_SIZE(vmxnet3_tq_dev_stats); i++)
317 *buf++ = *(u64 *)(base + vmxnet3_tq_dev_stats[i].offset);
318
319 base = (u8 *)&adapter->tx_queue.stats;
320 for (i = 0; i < ARRAY_SIZE(vmxnet3_tq_driver_stats); i++)
321 *buf++ = *(u64 *)(base + vmxnet3_tq_driver_stats[i].offset);
322
323 base = (u8 *)&adapter->rqd_start->stats;
324 for (i = 0; i < ARRAY_SIZE(vmxnet3_rq_dev_stats); i++)
325 *buf++ = *(u64 *)(base + vmxnet3_rq_dev_stats[i].offset);
326
327 base = (u8 *)&adapter->rx_queue.stats;
328 for (i = 0; i < ARRAY_SIZE(vmxnet3_rq_driver_stats); i++)
329 *buf++ = *(u64 *)(base + vmxnet3_rq_driver_stats[i].offset);
330
331 base = (u8 *)adapter;
332 for (i = 0; i < ARRAY_SIZE(vmxnet3_global_stats); i++)
333 *buf++ = *(u64 *)(base + vmxnet3_global_stats[i].offset);
334}
335
336
337static void
338vmxnet3_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *p)
339{
340 struct vmxnet3_adapter *adapter = netdev_priv(netdev);
341 u32 *buf = p;
342
343 memset(p, 0, vmxnet3_get_regs_len(netdev));
344
345 regs->version = 1;
346
347 /* Update vmxnet3_get_regs_len if we want to dump more registers */
348
349 /* make each ring use multiple of 16 bytes */
350 buf[0] = adapter->tx_queue.tx_ring.next2fill;
351 buf[1] = adapter->tx_queue.tx_ring.next2comp;
352 buf[2] = adapter->tx_queue.tx_ring.gen;
353 buf[3] = 0;
354
355 buf[4] = adapter->tx_queue.comp_ring.next2proc;
356 buf[5] = adapter->tx_queue.comp_ring.gen;
357 buf[6] = adapter->tx_queue.stopped;
358 buf[7] = 0;
359
360 buf[8] = adapter->rx_queue.rx_ring[0].next2fill;
361 buf[9] = adapter->rx_queue.rx_ring[0].next2comp;
362 buf[10] = adapter->rx_queue.rx_ring[0].gen;
363 buf[11] = 0;
364
365 buf[12] = adapter->rx_queue.rx_ring[1].next2fill;
366 buf[13] = adapter->rx_queue.rx_ring[1].next2comp;
367 buf[14] = adapter->rx_queue.rx_ring[1].gen;
368 buf[15] = 0;
369
370 buf[16] = adapter->rx_queue.comp_ring.next2proc;
371 buf[17] = adapter->rx_queue.comp_ring.gen;
372 buf[18] = 0;
373 buf[19] = 0;
374}
375
376
377static void
378vmxnet3_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
379{
380 struct vmxnet3_adapter *adapter = netdev_priv(netdev);
381
382 wol->supported = WAKE_UCAST | WAKE_ARP | WAKE_MAGIC;
383 wol->wolopts = adapter->wol;
384}
385
386
387static int
388vmxnet3_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
389{
390 struct vmxnet3_adapter *adapter = netdev_priv(netdev);
391
392 if (wol->wolopts & (WAKE_PHY | WAKE_MCAST | WAKE_BCAST |
393 WAKE_MAGICSECURE)) {
394 return -EOPNOTSUPP;
395 }
396
397 adapter->wol = wol->wolopts;
398
399 device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
400
401 return 0;
402}
403
404
405static int
406vmxnet3_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
407{
408 struct vmxnet3_adapter *adapter = netdev_priv(netdev);
409
410 ecmd->supported = SUPPORTED_10000baseT_Full | SUPPORTED_1000baseT_Full |
411 SUPPORTED_TP;
412 ecmd->advertising = ADVERTISED_TP;
413 ecmd->port = PORT_TP;
414 ecmd->transceiver = XCVR_INTERNAL;
415
416 if (adapter->link_speed) {
417 ecmd->speed = adapter->link_speed;
418 ecmd->duplex = DUPLEX_FULL;
419 } else {
420 ecmd->speed = -1;
421 ecmd->duplex = -1;
422 }
423 return 0;
424}
425
426
427static void
428vmxnet3_get_ringparam(struct net_device *netdev,
429 struct ethtool_ringparam *param)
430{
431 struct vmxnet3_adapter *adapter = netdev_priv(netdev);
432
433 param->rx_max_pending = VMXNET3_RX_RING_MAX_SIZE;
434 param->tx_max_pending = VMXNET3_TX_RING_MAX_SIZE;
435 param->rx_mini_max_pending = 0;
436 param->rx_jumbo_max_pending = 0;
437
438 param->rx_pending = adapter->rx_queue.rx_ring[0].size;
439 param->tx_pending = adapter->tx_queue.tx_ring.size;
440 param->rx_mini_pending = 0;
441 param->rx_jumbo_pending = 0;
442}
443
444
445static int
446vmxnet3_set_ringparam(struct net_device *netdev,
447 struct ethtool_ringparam *param)
448{
449 struct vmxnet3_adapter *adapter = netdev_priv(netdev);
450 u32 new_tx_ring_size, new_rx_ring_size;
451 u32 sz;
452 int err = 0;
453
454 if (param->tx_pending == 0 || param->tx_pending >
455 VMXNET3_TX_RING_MAX_SIZE)
456 return -EINVAL;
457
458 if (param->rx_pending == 0 || param->rx_pending >
459 VMXNET3_RX_RING_MAX_SIZE)
460 return -EINVAL;
461
462
463 /* round it up to a multiple of VMXNET3_RING_SIZE_ALIGN */
464 new_tx_ring_size = (param->tx_pending + VMXNET3_RING_SIZE_MASK) &
465 ~VMXNET3_RING_SIZE_MASK;
466 new_tx_ring_size = min_t(u32, new_tx_ring_size,
467 VMXNET3_TX_RING_MAX_SIZE);
468 if (new_tx_ring_size > VMXNET3_TX_RING_MAX_SIZE || (new_tx_ring_size %
469 VMXNET3_RING_SIZE_ALIGN) != 0)
470 return -EINVAL;
471
472 /* ring0 has to be a multiple of
473 * rx_buf_per_pkt * VMXNET3_RING_SIZE_ALIGN
474 */
475 sz = adapter->rx_buf_per_pkt * VMXNET3_RING_SIZE_ALIGN;
476 new_rx_ring_size = (param->rx_pending + sz - 1) / sz * sz;
477 new_rx_ring_size = min_t(u32, new_rx_ring_size,
478 VMXNET3_RX_RING_MAX_SIZE / sz * sz);
479 if (new_rx_ring_size > VMXNET3_RX_RING_MAX_SIZE || (new_rx_ring_size %
480 sz) != 0)
481 return -EINVAL;
482
483 if (new_tx_ring_size == adapter->tx_queue.tx_ring.size &&
484 new_rx_ring_size == adapter->rx_queue.rx_ring[0].size) {
485 return 0;
486 }
487
488 /*
489 * Reset_work may be in the middle of resetting the device, wait for its
490 * completion.
491 */
492 while (test_and_set_bit(VMXNET3_STATE_BIT_RESETTING, &adapter->state))
493 msleep(1);
494
495 if (netif_running(netdev)) {
496 vmxnet3_quiesce_dev(adapter);
497 vmxnet3_reset_dev(adapter);
498
499 /* recreate the rx queue and the tx queue based on the
500 * new sizes */
501 vmxnet3_tq_destroy(&adapter->tx_queue, adapter);
502 vmxnet3_rq_destroy(&adapter->rx_queue, adapter);
503
504 err = vmxnet3_create_queues(adapter, new_tx_ring_size,
505 new_rx_ring_size, VMXNET3_DEF_RX_RING_SIZE);
506 if (err) {
507 /* failed, most likely because of OOM, try default
508 * size */
509 printk(KERN_ERR "%s: failed to apply new sizes, try the"
510 " default ones\n", netdev->name);
511 err = vmxnet3_create_queues(adapter,
512 VMXNET3_DEF_TX_RING_SIZE,
513 VMXNET3_DEF_RX_RING_SIZE,
514 VMXNET3_DEF_RX_RING_SIZE);
515 if (err) {
516 printk(KERN_ERR "%s: failed to create queues "
517 "with default sizes. Closing it\n",
518 netdev->name);
519 goto out;
520 }
521 }
522
523 err = vmxnet3_activate_dev(adapter);
524 if (err)
525 printk(KERN_ERR "%s: failed to re-activate, error %d."
526 " Closing it\n", netdev->name, err);
527 }
528
529out:
530 clear_bit(VMXNET3_STATE_BIT_RESETTING, &adapter->state);
531 if (err)
532 vmxnet3_force_close(adapter);
533
534 return err;
535}
536
537
538static struct ethtool_ops vmxnet3_ethtool_ops = {
539 .get_settings = vmxnet3_get_settings,
540 .get_drvinfo = vmxnet3_get_drvinfo,
541 .get_regs_len = vmxnet3_get_regs_len,
542 .get_regs = vmxnet3_get_regs,
543 .get_wol = vmxnet3_get_wol,
544 .set_wol = vmxnet3_set_wol,
545 .get_link = ethtool_op_get_link,
546 .get_rx_csum = vmxnet3_get_rx_csum,
547 .set_rx_csum = vmxnet3_set_rx_csum,
548 .get_tx_csum = ethtool_op_get_tx_csum,
549 .set_tx_csum = ethtool_op_set_tx_hw_csum,
550 .get_sg = ethtool_op_get_sg,
551 .set_sg = ethtool_op_set_sg,
552 .get_tso = ethtool_op_get_tso,
553 .set_tso = ethtool_op_set_tso,
554 .get_strings = vmxnet3_get_strings,
555 .get_flags = vmxnet3_get_flags,
556 .set_flags = vmxnet3_set_flags,
557 .get_sset_count = vmxnet3_get_sset_count,
558 .get_ethtool_stats = vmxnet3_get_ethtool_stats,
559 .get_ringparam = vmxnet3_get_ringparam,
560 .set_ringparam = vmxnet3_set_ringparam,
561};
562
563void vmxnet3_set_ethtool_ops(struct net_device *netdev)
564{
565 SET_ETHTOOL_OPS(netdev, &vmxnet3_ethtool_ops);
566}
diff --git a/drivers/net/vmxnet3/vmxnet3_int.h b/drivers/net/vmxnet3/vmxnet3_int.h
new file mode 100644
index 000000000000..6bb91576e999
--- /dev/null
+++ b/drivers/net/vmxnet3/vmxnet3_int.h
@@ -0,0 +1,389 @@
1/*
2 * Linux driver for VMware's vmxnet3 ethernet NIC.
3 *
4 * Copyright (C) 2008-2009, VMware, Inc. All Rights Reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; version 2 of the License and no later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
13 * NON INFRINGEMENT. See the GNU General Public License for more
14 * details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * The full GNU General Public License is included in this distribution in
21 * the file called "COPYING".
22 *
23 * Maintained by: Shreyas Bhatewara <pv-drivers@vmware.com>
24 *
25 */
26
27#ifndef _VMXNET3_INT_H
28#define _VMXNET3_INT_H
29
30#include <linux/types.h>
31#include <linux/ethtool.h>
32#include <linux/delay.h>
33#include <linux/netdevice.h>
34#include <linux/pci.h>
35#include <linux/ethtool.h>
36#include <linux/compiler.h>
37#include <linux/module.h>
38#include <linux/moduleparam.h>
39#include <linux/slab.h>
40#include <linux/spinlock.h>
41#include <linux/ioport.h>
42#include <linux/highmem.h>
43#include <linux/init.h>
44#include <linux/timer.h>
45#include <linux/skbuff.h>
46#include <linux/interrupt.h>
47#include <linux/workqueue.h>
48#include <linux/uaccess.h>
49#include <asm/dma.h>
50#include <asm/page.h>
51
52#include <linux/tcp.h>
53#include <linux/udp.h>
54#include <linux/ip.h>
55#include <linux/ipv6.h>
56#include <linux/in.h>
57#include <linux/etherdevice.h>
58#include <asm/checksum.h>
59#include <linux/if_vlan.h>
60#include <linux/if_arp.h>
61#include <linux/inetdevice.h>
62#include <linux/dst.h>
63
64#include "vmxnet3_defs.h"
65
66#ifdef DEBUG
67# define VMXNET3_DRIVER_VERSION_REPORT VMXNET3_DRIVER_VERSION_STRING"-NAPI(debug)"
68#else
69# define VMXNET3_DRIVER_VERSION_REPORT VMXNET3_DRIVER_VERSION_STRING"-NAPI"
70#endif
71
72
73/*
74 * Version numbers
75 */
76#define VMXNET3_DRIVER_VERSION_STRING "1.0.5.0-k"
77
78/* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */
79#define VMXNET3_DRIVER_VERSION_NUM 0x01000500
80
81
82/*
83 * Capabilities
84 */
85
86enum {
87 VMNET_CAP_SG = 0x0001, /* Can do scatter-gather transmits. */
88 VMNET_CAP_IP4_CSUM = 0x0002, /* Can checksum only TCP/UDP over
89 * IPv4 */
90 VMNET_CAP_HW_CSUM = 0x0004, /* Can checksum all packets. */
91 VMNET_CAP_HIGH_DMA = 0x0008, /* Can DMA to high memory. */
92 VMNET_CAP_TOE = 0x0010, /* Supports TCP/IP offload. */
93 VMNET_CAP_TSO = 0x0020, /* Supports TCP Segmentation
94 * offload */
95 VMNET_CAP_SW_TSO = 0x0040, /* Supports SW TCP Segmentation */
96 VMNET_CAP_VMXNET_APROM = 0x0080, /* Vmxnet APROM support */
97 VMNET_CAP_HW_TX_VLAN = 0x0100, /* Can we do VLAN tagging in HW */
98 VMNET_CAP_HW_RX_VLAN = 0x0200, /* Can we do VLAN untagging in HW */
99 VMNET_CAP_SW_VLAN = 0x0400, /* VLAN tagging/untagging in SW */
100 VMNET_CAP_WAKE_PCKT_RCV = 0x0800, /* Can wake on network packet recv? */
101 VMNET_CAP_ENABLE_INT_INLINE = 0x1000, /* Enable Interrupt Inline */
102 VMNET_CAP_ENABLE_HEADER_COPY = 0x2000, /* copy header for vmkernel */
103 VMNET_CAP_TX_CHAIN = 0x4000, /* Guest can use multiple tx entries
104 * for a pkt */
105 VMNET_CAP_RX_CHAIN = 0x8000, /* pkt can span multiple rx entries */
106 VMNET_CAP_LPD = 0x10000, /* large pkt delivery */
107 VMNET_CAP_BPF = 0x20000, /* BPF Support in VMXNET Virtual HW*/
108 VMNET_CAP_SG_SPAN_PAGES = 0x40000, /* Scatter-gather can span multiple*/
109 /* pages transmits */
110 VMNET_CAP_IP6_CSUM = 0x80000, /* Can do IPv6 csum offload. */
111 VMNET_CAP_TSO6 = 0x100000, /* TSO seg. offload for IPv6 pkts. */
112 VMNET_CAP_TSO256k = 0x200000, /* Can do TSO seg offload for */
113 /* pkts up to 256kB. */
114 VMNET_CAP_UPT = 0x400000 /* Support UPT */
115};
116
117/*
118 * PCI vendor and device IDs.
119 */
120#define PCI_VENDOR_ID_VMWARE 0x15AD
121#define PCI_DEVICE_ID_VMWARE_VMXNET3 0x07B0
122#define MAX_ETHERNET_CARDS 10
123#define MAX_PCI_PASSTHRU_DEVICE 6
124
125struct vmxnet3_cmd_ring {
126 union Vmxnet3_GenericDesc *base;
127 u32 size;
128 u32 next2fill;
129 u32 next2comp;
130 u8 gen;
131 dma_addr_t basePA;
132};
133
134static inline void
135vmxnet3_cmd_ring_adv_next2fill(struct vmxnet3_cmd_ring *ring)
136{
137 ring->next2fill++;
138 if (unlikely(ring->next2fill == ring->size)) {
139 ring->next2fill = 0;
140 VMXNET3_FLIP_RING_GEN(ring->gen);
141 }
142}
143
144static inline void
145vmxnet3_cmd_ring_adv_next2comp(struct vmxnet3_cmd_ring *ring)
146{
147 VMXNET3_INC_RING_IDX_ONLY(ring->next2comp, ring->size);
148}
149
150static inline int
151vmxnet3_cmd_ring_desc_avail(struct vmxnet3_cmd_ring *ring)
152{
153 return (ring->next2comp > ring->next2fill ? 0 : ring->size) +
154 ring->next2comp - ring->next2fill - 1;
155}
156
157struct vmxnet3_comp_ring {
158 union Vmxnet3_GenericDesc *base;
159 u32 size;
160 u32 next2proc;
161 u8 gen;
162 u8 intr_idx;
163 dma_addr_t basePA;
164};
165
166static inline void
167vmxnet3_comp_ring_adv_next2proc(struct vmxnet3_comp_ring *ring)
168{
169 ring->next2proc++;
170 if (unlikely(ring->next2proc == ring->size)) {
171 ring->next2proc = 0;
172 VMXNET3_FLIP_RING_GEN(ring->gen);
173 }
174}
175
176struct vmxnet3_tx_data_ring {
177 struct Vmxnet3_TxDataDesc *base;
178 u32 size;
179 dma_addr_t basePA;
180};
181
182enum vmxnet3_buf_map_type {
183 VMXNET3_MAP_INVALID = 0,
184 VMXNET3_MAP_NONE,
185 VMXNET3_MAP_SINGLE,
186 VMXNET3_MAP_PAGE,
187};
188
189struct vmxnet3_tx_buf_info {
190 u32 map_type;
191 u16 len;
192 u16 sop_idx;
193 dma_addr_t dma_addr;
194 struct sk_buff *skb;
195};
196
197struct vmxnet3_tq_driver_stats {
198 u64 drop_total; /* # of pkts dropped by the driver, the
199 * counters below track droppings due to
200 * different reasons
201 */
202 u64 drop_too_many_frags;
203 u64 drop_oversized_hdr;
204 u64 drop_hdr_inspect_err;
205 u64 drop_tso;
206
207 u64 tx_ring_full;
208 u64 linearized; /* # of pkts linearized */
209 u64 copy_skb_header; /* # of times we have to copy skb header */
210 u64 oversized_hdr;
211};
212
213struct vmxnet3_tx_ctx {
214 bool ipv4;
215 u16 mss;
216 u32 eth_ip_hdr_size; /* only valid for pkts requesting tso or csum
217 * offloading
218 */
219 u32 l4_hdr_size; /* only valid if mss != 0 */
220 u32 copy_size; /* # of bytes copied into the data ring */
221 union Vmxnet3_GenericDesc *sop_txd;
222 union Vmxnet3_GenericDesc *eop_txd;
223};
224
225struct vmxnet3_tx_queue {
226 spinlock_t tx_lock;
227 struct vmxnet3_cmd_ring tx_ring;
228 struct vmxnet3_tx_buf_info *buf_info;
229 struct vmxnet3_tx_data_ring data_ring;
230 struct vmxnet3_comp_ring comp_ring;
231 struct Vmxnet3_TxQueueCtrl *shared;
232 struct vmxnet3_tq_driver_stats stats;
233 bool stopped;
234 int num_stop; /* # of times the queue is
235 * stopped */
236} __attribute__((__aligned__(SMP_CACHE_BYTES)));
237
238enum vmxnet3_rx_buf_type {
239 VMXNET3_RX_BUF_NONE = 0,
240 VMXNET3_RX_BUF_SKB = 1,
241 VMXNET3_RX_BUF_PAGE = 2
242};
243
244struct vmxnet3_rx_buf_info {
245 enum vmxnet3_rx_buf_type buf_type;
246 u16 len;
247 union {
248 struct sk_buff *skb;
249 struct page *page;
250 };
251 dma_addr_t dma_addr;
252};
253
254struct vmxnet3_rx_ctx {
255 struct sk_buff *skb;
256 u32 sop_idx;
257};
258
259struct vmxnet3_rq_driver_stats {
260 u64 drop_total;
261 u64 drop_err;
262 u64 drop_fcs;
263 u64 rx_buf_alloc_failure;
264};
265
266struct vmxnet3_rx_queue {
267 struct vmxnet3_cmd_ring rx_ring[2];
268 struct vmxnet3_comp_ring comp_ring;
269 struct vmxnet3_rx_ctx rx_ctx;
270 u32 qid; /* rqID in RCD for buffer from 1st ring */
271 u32 qid2; /* rqID in RCD for buffer from 2nd ring */
272 u32 uncommitted[2]; /* # of buffers allocated since last RXPROD
273 * update */
274 struct vmxnet3_rx_buf_info *buf_info[2];
275 struct Vmxnet3_RxQueueCtrl *shared;
276 struct vmxnet3_rq_driver_stats stats;
277} __attribute__((__aligned__(SMP_CACHE_BYTES)));
278
279#define VMXNET3_LINUX_MAX_MSIX_VECT 1
280
281struct vmxnet3_intr {
282 enum vmxnet3_intr_mask_mode mask_mode;
283 enum vmxnet3_intr_type type; /* MSI-X, MSI, or INTx? */
284 u8 num_intrs; /* # of intr vectors */
285 u8 event_intr_idx; /* idx of the intr vector for event */
286 u8 mod_levels[VMXNET3_LINUX_MAX_MSIX_VECT]; /* moderation level */
287#ifdef CONFIG_PCI_MSI
288 struct msix_entry msix_entries[VMXNET3_LINUX_MAX_MSIX_VECT];
289#endif
290};
291
292#define VMXNET3_STATE_BIT_RESETTING 0
293#define VMXNET3_STATE_BIT_QUIESCED 1
294struct vmxnet3_adapter {
295 struct vmxnet3_tx_queue tx_queue;
296 struct vmxnet3_rx_queue rx_queue;
297 struct napi_struct napi;
298 struct vlan_group *vlan_grp;
299
300 struct vmxnet3_intr intr;
301
302 struct Vmxnet3_DriverShared *shared;
303 struct Vmxnet3_PMConf *pm_conf;
304 struct Vmxnet3_TxQueueDesc *tqd_start; /* first tx queue desc */
305 struct Vmxnet3_RxQueueDesc *rqd_start; /* first rx queue desc */
306 struct net_device *netdev;
307 struct pci_dev *pdev;
308
309 u8 *hw_addr0; /* for BAR 0 */
310 u8 *hw_addr1; /* for BAR 1 */
311
312 /* feature control */
313 bool rxcsum;
314 bool lro;
315 bool jumbo_frame;
316
317 /* rx buffer related */
318 unsigned skb_buf_size;
319 int rx_buf_per_pkt; /* only apply to the 1st ring */
320 dma_addr_t shared_pa;
321 dma_addr_t queue_desc_pa;
322
323 /* Wake-on-LAN */
324 u32 wol;
325
326 /* Link speed */
327 u32 link_speed; /* in mbps */
328
329 u64 tx_timeout_count;
330 struct work_struct work;
331
332 unsigned long state; /* VMXNET3_STATE_BIT_xxx */
333
334 int dev_number;
335};
336
337#define VMXNET3_WRITE_BAR0_REG(adapter, reg, val) \
338 writel((val), (adapter)->hw_addr0 + (reg))
339#define VMXNET3_READ_BAR0_REG(adapter, reg) \
340 readl((adapter)->hw_addr0 + (reg))
341
342#define VMXNET3_WRITE_BAR1_REG(adapter, reg, val) \
343 writel((val), (adapter)->hw_addr1 + (reg))
344#define VMXNET3_READ_BAR1_REG(adapter, reg) \
345 readl((adapter)->hw_addr1 + (reg))
346
347#define VMXNET3_WAKE_QUEUE_THRESHOLD(tq) (5)
348#define VMXNET3_RX_ALLOC_THRESHOLD(rq, ring_idx, adapter) \
349 ((rq)->rx_ring[ring_idx].size >> 3)
350
351#define VMXNET3_GET_ADDR_LO(dma) ((u32)(dma))
352#define VMXNET3_GET_ADDR_HI(dma) ((u32)(((u64)(dma)) >> 32))
353
354/* must be a multiple of VMXNET3_RING_SIZE_ALIGN */
355#define VMXNET3_DEF_TX_RING_SIZE 512
356#define VMXNET3_DEF_RX_RING_SIZE 256
357
358#define VMXNET3_MAX_ETH_HDR_SIZE 22
359#define VMXNET3_MAX_SKB_BUF_SIZE (3*1024)
360
361int
362vmxnet3_quiesce_dev(struct vmxnet3_adapter *adapter);
363
364int
365vmxnet3_activate_dev(struct vmxnet3_adapter *adapter);
366
367void
368vmxnet3_force_close(struct vmxnet3_adapter *adapter);
369
370void
371vmxnet3_reset_dev(struct vmxnet3_adapter *adapter);
372
373void
374vmxnet3_tq_destroy(struct vmxnet3_tx_queue *tq,
375 struct vmxnet3_adapter *adapter);
376
377void
378vmxnet3_rq_destroy(struct vmxnet3_rx_queue *rq,
379 struct vmxnet3_adapter *adapter);
380
381int
382vmxnet3_create_queues(struct vmxnet3_adapter *adapter,
383 u32 tx_ring_size, u32 rx_ring_size, u32 rx_ring2_size);
384
385extern void vmxnet3_set_ethtool_ops(struct net_device *netdev);
386extern struct net_device_stats *vmxnet3_get_stats(struct net_device *netdev);
387
388extern char vmxnet3_driver_name[];
389#endif
diff --git a/drivers/net/wan/c101.c b/drivers/net/wan/c101.c
index 9693b0fd323d..0bd898c94759 100644
--- a/drivers/net/wan/c101.c
+++ b/drivers/net/wan/c101.c
@@ -16,6 +16,7 @@
16 16
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/kernel.h> 18#include <linux/kernel.h>
19#include <linux/capability.h>
19#include <linux/slab.h> 20#include <linux/slab.h>
20#include <linux/types.h> 21#include <linux/types.h>
21#include <linux/string.h> 22#include <linux/string.h>
diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c
index 66360a2a14c2..e2c33c06190b 100644
--- a/drivers/net/wan/cosa.c
+++ b/drivers/net/wan/cosa.c
@@ -76,6 +76,7 @@
76 76
77#include <linux/module.h> 77#include <linux/module.h>
78#include <linux/kernel.h> 78#include <linux/kernel.h>
79#include <linux/sched.h>
79#include <linux/slab.h> 80#include <linux/slab.h>
80#include <linux/poll.h> 81#include <linux/poll.h>
81#include <linux/fs.h> 82#include <linux/fs.h>
diff --git a/drivers/net/wan/cycx_x25.c b/drivers/net/wan/cycx_x25.c
index 2573c18b6aa5..cd8cb95c5bd7 100644
--- a/drivers/net/wan/cycx_x25.c
+++ b/drivers/net/wan/cycx_x25.c
@@ -84,6 +84,7 @@
84#include <linux/kernel.h> /* printk(), and other useful stuff */ 84#include <linux/kernel.h> /* printk(), and other useful stuff */
85#include <linux/module.h> 85#include <linux/module.h>
86#include <linux/string.h> /* inline memset(), etc. */ 86#include <linux/string.h> /* inline memset(), etc. */
87#include <linux/sched.h>
87#include <linux/slab.h> /* kmalloc(), kfree() */ 88#include <linux/slab.h> /* kmalloc(), kfree() */
88#include <linux/stddef.h> /* offsetof(), etc. */ 89#include <linux/stddef.h> /* offsetof(), etc. */
89#include <linux/wanrouter.h> /* WAN router definitions */ 90#include <linux/wanrouter.h> /* WAN router definitions */
diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c
index 81c8aec9df92..07d00b4cf48a 100644
--- a/drivers/net/wan/dscc4.c
+++ b/drivers/net/wan/dscc4.c
@@ -81,6 +81,7 @@
81 */ 81 */
82 82
83#include <linux/module.h> 83#include <linux/module.h>
84#include <linux/sched.h>
84#include <linux/types.h> 85#include <linux/types.h>
85#include <linux/errno.h> 86#include <linux/errno.h>
86#include <linux/list.h> 87#include <linux/list.h>
diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c
index 3e90eb816181..beda387f2fc7 100644
--- a/drivers/net/wan/farsync.c
+++ b/drivers/net/wan/farsync.c
@@ -19,6 +19,7 @@
19#include <linux/kernel.h> 19#include <linux/kernel.h>
20#include <linux/version.h> 20#include <linux/version.h>
21#include <linux/pci.h> 21#include <linux/pci.h>
22#include <linux/sched.h>
22#include <linux/ioport.h> 23#include <linux/ioport.h>
23#include <linux/init.h> 24#include <linux/init.h>
24#include <linux/if.h> 25#include <linux/if.h>
diff --git a/drivers/net/wan/hdlc_cisco.c b/drivers/net/wan/hdlc_cisco.c
index cf5fd17ad707..f1bff98acd1f 100644
--- a/drivers/net/wan/hdlc_cisco.c
+++ b/drivers/net/wan/hdlc_cisco.c
@@ -58,8 +58,7 @@ struct cisco_state {
58 spinlock_t lock; 58 spinlock_t lock;
59 unsigned long last_poll; 59 unsigned long last_poll;
60 int up; 60 int up;
61 int request_sent; 61 u32 txseq; /* TX sequence number, 0 = none */
62 u32 txseq; /* TX sequence number */
63 u32 rxseq; /* RX sequence number */ 62 u32 rxseq; /* RX sequence number */
64}; 63};
65 64
@@ -163,6 +162,7 @@ static int cisco_rx(struct sk_buff *skb)
163 struct cisco_packet *cisco_data; 162 struct cisco_packet *cisco_data;
164 struct in_device *in_dev; 163 struct in_device *in_dev;
165 __be32 addr, mask; 164 __be32 addr, mask;
165 u32 ack;
166 166
167 if (skb->len < sizeof(struct hdlc_header)) 167 if (skb->len < sizeof(struct hdlc_header))
168 goto rx_error; 168 goto rx_error;
@@ -223,8 +223,10 @@ static int cisco_rx(struct sk_buff *skb)
223 case CISCO_KEEPALIVE_REQ: 223 case CISCO_KEEPALIVE_REQ:
224 spin_lock(&st->lock); 224 spin_lock(&st->lock);
225 st->rxseq = ntohl(cisco_data->par1); 225 st->rxseq = ntohl(cisco_data->par1);
226 if (st->request_sent && 226 ack = ntohl(cisco_data->par2);
227 ntohl(cisco_data->par2) == st->txseq) { 227 if (ack && (ack == st->txseq ||
228 /* our current REQ may be in transit */
229 ack == st->txseq - 1)) {
228 st->last_poll = jiffies; 230 st->last_poll = jiffies;
229 if (!st->up) { 231 if (!st->up) {
230 u32 sec, min, hrs, days; 232 u32 sec, min, hrs, days;
@@ -275,7 +277,6 @@ static void cisco_timer(unsigned long arg)
275 277
276 cisco_keepalive_send(dev, CISCO_KEEPALIVE_REQ, htonl(++st->txseq), 278 cisco_keepalive_send(dev, CISCO_KEEPALIVE_REQ, htonl(++st->txseq),
277 htonl(st->rxseq)); 279 htonl(st->rxseq));
278 st->request_sent = 1;
279 spin_unlock(&st->lock); 280 spin_unlock(&st->lock);
280 281
281 st->timer.expires = jiffies + st->settings.interval * HZ; 282 st->timer.expires = jiffies + st->settings.interval * HZ;
@@ -293,9 +294,7 @@ static void cisco_start(struct net_device *dev)
293 unsigned long flags; 294 unsigned long flags;
294 295
295 spin_lock_irqsave(&st->lock, flags); 296 spin_lock_irqsave(&st->lock, flags);
296 st->up = 0; 297 st->up = st->txseq = st->rxseq = 0;
297 st->request_sent = 0;
298 st->txseq = st->rxseq = 0;
299 spin_unlock_irqrestore(&st->lock, flags); 298 spin_unlock_irqrestore(&st->lock, flags);
300 299
301 init_timer(&st->timer); 300 init_timer(&st->timer);
@@ -317,8 +316,7 @@ static void cisco_stop(struct net_device *dev)
317 316
318 spin_lock_irqsave(&st->lock, flags); 317 spin_lock_irqsave(&st->lock, flags);
319 netif_dormant_on(dev); 318 netif_dormant_on(dev);
320 st->up = 0; 319 st->up = st->txseq = 0;
321 st->request_sent = 0;
322 spin_unlock_irqrestore(&st->lock, flags); 320 spin_unlock_irqrestore(&st->lock, flags);
323} 321}
324 322
diff --git a/drivers/net/wan/n2.c b/drivers/net/wan/n2.c
index 83da596e2052..58c66819f39b 100644
--- a/drivers/net/wan/n2.c
+++ b/drivers/net/wan/n2.c
@@ -18,6 +18,7 @@
18 18
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/kernel.h> 20#include <linux/kernel.h>
21#include <linux/capability.h>
21#include <linux/slab.h> 22#include <linux/slab.h>
22#include <linux/types.h> 23#include <linux/types.h>
23#include <linux/fcntl.h> 24#include <linux/fcntl.h>
diff --git a/drivers/net/wan/pci200syn.c b/drivers/net/wan/pci200syn.c
index a52f29c72c33..f1340faaf022 100644
--- a/drivers/net/wan/pci200syn.c
+++ b/drivers/net/wan/pci200syn.c
@@ -16,6 +16,7 @@
16 16
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/kernel.h> 18#include <linux/kernel.h>
19#include <linux/capability.h>
19#include <linux/slab.h> 20#include <linux/slab.h>
20#include <linux/types.h> 21#include <linux/types.h>
21#include <linux/fcntl.h> 22#include <linux/fcntl.h>
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 49ea9c92b7e6..d7a764a2fc1a 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -31,13 +31,12 @@ config STRIP
31 ---help--- 31 ---help---
32 Say Y if you have a Metricom radio and intend to use Starmode Radio 32 Say Y if you have a Metricom radio and intend to use Starmode Radio
33 IP. STRIP is a radio protocol developed for the MosquitoNet project 33 IP. STRIP is a radio protocol developed for the MosquitoNet project
34 (on the WWW at <http://mosquitonet.stanford.edu/>) to send Internet 34 to send Internet traffic using Metricom radios. Metricom radios are
35 traffic using Metricom radios. Metricom radios are small, battery 35 small, battery powered, 100kbit/sec packet radio transceivers, about
36 powered, 100kbit/sec packet radio transceivers, about the size and 36 the size and weight of a cellular telephone. (You may also have heard
37 weight of a cellular telephone. (You may also have heard them called 37 them called "Metricom modems" but we avoid the term "modem" because
38 "Metricom modems" but we avoid the term "modem" because it misleads 38 it misleads many people into thinking that you can plug a Metricom
39 many people into thinking that you can plug a Metricom modem into a 39 modem into a phone line and use it as a modem.)
40 phone line and use it as a modem.)
41 40
42 You can use STRIP on any Linux machine with a serial port, although 41 You can use STRIP on any Linux machine with a serial port, although
43 it is obviously most useful for people with laptop computers. If you 42 it is obviously most useful for people with laptop computers. If you
diff --git a/drivers/net/wireless/adm8211.h b/drivers/net/wireless/adm8211.h
index 4f6ab1322189..b07e4d3a6b4d 100644
--- a/drivers/net/wireless/adm8211.h
+++ b/drivers/net/wireless/adm8211.h
@@ -266,7 +266,7 @@ do { \
266#define ADM8211_SYNCTL_CS1 (1 << 28) 266#define ADM8211_SYNCTL_CS1 (1 << 28)
267#define ADM8211_SYNCTL_CAL (1 << 27) 267#define ADM8211_SYNCTL_CAL (1 << 27)
268#define ADM8211_SYNCTL_SELCAL (1 << 26) 268#define ADM8211_SYNCTL_SELCAL (1 << 26)
269#define ADM8211_SYNCTL_RFtype ((1 << 24) || (1 << 23) || (1 << 22)) 269#define ADM8211_SYNCTL_RFtype ((1 << 24) | (1 << 23) | (1 << 22))
270#define ADM8211_SYNCTL_RFMD (1 << 22) 270#define ADM8211_SYNCTL_RFMD (1 << 22)
271#define ADM8211_SYNCTL_GENERAL (0x7 << 22) 271#define ADM8211_SYNCTL_GENERAL (0x7 << 22)
272/* SYNCTL 21:0 Data (Si4126: 18-bit data, 4-bit address) */ 272/* SYNCTL 21:0 Data (Si4126: 18-bit data, 4-bit address) */
diff --git a/drivers/net/wireless/ath/ar9170/phy.c b/drivers/net/wireless/ath/ar9170/phy.c
index b3e5cf3735b0..dbd488da18b1 100644
--- a/drivers/net/wireless/ath/ar9170/phy.c
+++ b/drivers/net/wireless/ath/ar9170/phy.c
@@ -1141,7 +1141,8 @@ static int ar9170_set_freq_cal_data(struct ar9170 *ar,
1141 u8 vpds[2][AR5416_PD_GAIN_ICEPTS]; 1141 u8 vpds[2][AR5416_PD_GAIN_ICEPTS];
1142 u8 pwrs[2][AR5416_PD_GAIN_ICEPTS]; 1142 u8 pwrs[2][AR5416_PD_GAIN_ICEPTS];
1143 int chain, idx, i; 1143 int chain, idx, i;
1144 u8 f; 1144 u32 phy_data = 0;
1145 u8 f, tmp;
1145 1146
1146 switch (channel->band) { 1147 switch (channel->band) {
1147 case IEEE80211_BAND_2GHZ: 1148 case IEEE80211_BAND_2GHZ:
@@ -1208,9 +1209,6 @@ static int ar9170_set_freq_cal_data(struct ar9170 *ar,
1208 } 1209 }
1209 1210
1210 for (i = 0; i < 76; i++) { 1211 for (i = 0; i < 76; i++) {
1211 u32 phy_data;
1212 u8 tmp;
1213
1214 if (i < 25) { 1212 if (i < 25) {
1215 tmp = ar9170_interpolate_val(i, &pwrs[0][0], 1213 tmp = ar9170_interpolate_val(i, &pwrs[0][0],
1216 &vpds[0][0]); 1214 &vpds[0][0]);
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index fa1549a03c71..660716214d49 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -607,82 +607,7 @@ struct b43_qos_params {
607 struct ieee80211_tx_queue_params p; 607 struct ieee80211_tx_queue_params p;
608}; 608};
609 609
610struct b43_wldev; 610struct b43_wl;
611
612/* Data structure for the WLAN parts (802.11 cores) of the b43 chip. */
613struct b43_wl {
614 /* Pointer to the active wireless device on this chip */
615 struct b43_wldev *current_dev;
616 /* Pointer to the ieee80211 hardware data structure */
617 struct ieee80211_hw *hw;
618
619 /* Global driver mutex. Every operation must run with this mutex locked. */
620 struct mutex mutex;
621 /* Hard-IRQ spinlock. This lock protects things used in the hard-IRQ
622 * handler, only. This basically is just the IRQ mask register. */
623 spinlock_t hardirq_lock;
624
625 /* The number of queues that were registered with the mac80211 subsystem
626 * initially. This is a backup copy of hw->queues in case hw->queues has
627 * to be dynamically lowered at runtime (Firmware does not support QoS).
628 * hw->queues has to be restored to the original value before unregistering
629 * from the mac80211 subsystem. */
630 u16 mac80211_initially_registered_queues;
631
632 /* We can only have one operating interface (802.11 core)
633 * at a time. General information about this interface follows.
634 */
635
636 struct ieee80211_vif *vif;
637 /* The MAC address of the operating interface. */
638 u8 mac_addr[ETH_ALEN];
639 /* Current BSSID */
640 u8 bssid[ETH_ALEN];
641 /* Interface type. (NL80211_IFTYPE_XXX) */
642 int if_type;
643 /* Is the card operating in AP, STA or IBSS mode? */
644 bool operating;
645 /* filter flags */
646 unsigned int filter_flags;
647 /* Stats about the wireless interface */
648 struct ieee80211_low_level_stats ieee_stats;
649
650#ifdef CONFIG_B43_HWRNG
651 struct hwrng rng;
652 bool rng_initialized;
653 char rng_name[30 + 1];
654#endif /* CONFIG_B43_HWRNG */
655
656 /* List of all wireless devices on this chip */
657 struct list_head devlist;
658 u8 nr_devs;
659
660 bool radiotap_enabled;
661 bool radio_enabled;
662
663 /* The beacon we are currently using (AP or IBSS mode). */
664 struct sk_buff *current_beacon;
665 bool beacon0_uploaded;
666 bool beacon1_uploaded;
667 bool beacon_templates_virgin; /* Never wrote the templates? */
668 struct work_struct beacon_update_trigger;
669
670 /* The current QOS parameters for the 4 queues. */
671 struct b43_qos_params qos_params[4];
672
673 /* Work for adjustment of the transmission power.
674 * This is scheduled when we determine that the actual TX output
675 * power doesn't match what we want. */
676 struct work_struct txpower_adjust_work;
677
678 /* Packet transmit work */
679 struct work_struct tx_work;
680 /* Queue of packets to be transmitted. */
681 struct sk_buff_head tx_queue;
682
683 /* The device LEDs. */
684 struct b43_leds leds;
685};
686 611
687/* The type of the firmware file. */ 612/* The type of the firmware file. */
688enum b43_firmware_file_type { 613enum b43_firmware_file_type {
@@ -824,6 +749,97 @@ struct b43_wldev {
824#endif 749#endif
825}; 750};
826 751
752/*
753 * Include goes here to avoid a dependency problem.
754 * A better fix would be to integrate xmit.h into b43.h.
755 */
756#include "xmit.h"
757
758/* Data structure for the WLAN parts (802.11 cores) of the b43 chip. */
759struct b43_wl {
760 /* Pointer to the active wireless device on this chip */
761 struct b43_wldev *current_dev;
762 /* Pointer to the ieee80211 hardware data structure */
763 struct ieee80211_hw *hw;
764
765 /* Global driver mutex. Every operation must run with this mutex locked. */
766 struct mutex mutex;
767 /* Hard-IRQ spinlock. This lock protects things used in the hard-IRQ
768 * handler, only. This basically is just the IRQ mask register. */
769 spinlock_t hardirq_lock;
770
771 /* The number of queues that were registered with the mac80211 subsystem
772 * initially. This is a backup copy of hw->queues in case hw->queues has
773 * to be dynamically lowered at runtime (Firmware does not support QoS).
774 * hw->queues has to be restored to the original value before unregistering
775 * from the mac80211 subsystem. */
776 u16 mac80211_initially_registered_queues;
777
778 /* We can only have one operating interface (802.11 core)
779 * at a time. General information about this interface follows.
780 */
781
782 struct ieee80211_vif *vif;
783 /* The MAC address of the operating interface. */
784 u8 mac_addr[ETH_ALEN];
785 /* Current BSSID */
786 u8 bssid[ETH_ALEN];
787 /* Interface type. (NL80211_IFTYPE_XXX) */
788 int if_type;
789 /* Is the card operating in AP, STA or IBSS mode? */
790 bool operating;
791 /* filter flags */
792 unsigned int filter_flags;
793 /* Stats about the wireless interface */
794 struct ieee80211_low_level_stats ieee_stats;
795
796#ifdef CONFIG_B43_HWRNG
797 struct hwrng rng;
798 bool rng_initialized;
799 char rng_name[30 + 1];
800#endif /* CONFIG_B43_HWRNG */
801
802 /* List of all wireless devices on this chip */
803 struct list_head devlist;
804 u8 nr_devs;
805
806 bool radiotap_enabled;
807 bool radio_enabled;
808
809 /* The beacon we are currently using (AP or IBSS mode). */
810 struct sk_buff *current_beacon;
811 bool beacon0_uploaded;
812 bool beacon1_uploaded;
813 bool beacon_templates_virgin; /* Never wrote the templates? */
814 struct work_struct beacon_update_trigger;
815
816 /* The current QOS parameters for the 4 queues. */
817 struct b43_qos_params qos_params[4];
818
819 /* Work for adjustment of the transmission power.
820 * This is scheduled when we determine that the actual TX output
821 * power doesn't match what we want. */
822 struct work_struct txpower_adjust_work;
823
824 /* Packet transmit work */
825 struct work_struct tx_work;
826 /* Queue of packets to be transmitted. */
827 struct sk_buff_head tx_queue;
828
829 /* The device LEDs. */
830 struct b43_leds leds;
831
832#ifdef CONFIG_B43_PIO
833 /*
834 * RX/TX header/tail buffers used by the frame transmit functions.
835 */
836 struct b43_rxhdr_fw4 rxhdr;
837 struct b43_txhdr txhdr;
838 u8 rx_tail[4];
839 u8 tx_tail[4];
840#endif /* CONFIG_B43_PIO */
841};
842
827static inline struct b43_wl *hw_to_b43_wl(struct ieee80211_hw *hw) 843static inline struct b43_wl *hw_to_b43_wl(struct ieee80211_hw *hw)
828{ 844{
829 return hw->priv; 845 return hw->priv;
diff --git a/drivers/net/wireless/b43/leds.c b/drivers/net/wireless/b43/leds.c
index fbe3d4f62ce2..1e8dba488004 100644
--- a/drivers/net/wireless/b43/leds.c
+++ b/drivers/net/wireless/b43/leds.c
@@ -348,9 +348,9 @@ void b43_leds_register(struct b43_wldev *dev)
348 } 348 }
349} 349}
350 350
351void b43_leds_unregister(struct b43_wldev *dev) 351void b43_leds_unregister(struct b43_wl *wl)
352{ 352{
353 struct b43_leds *leds = &dev->wl->leds; 353 struct b43_leds *leds = &wl->leds;
354 354
355 b43_unregister_led(&leds->led_tx); 355 b43_unregister_led(&leds->led_tx);
356 b43_unregister_led(&leds->led_rx); 356 b43_unregister_led(&leds->led_rx);
diff --git a/drivers/net/wireless/b43/leds.h b/drivers/net/wireless/b43/leds.h
index 9592e4c5a5f5..4c56187810fc 100644
--- a/drivers/net/wireless/b43/leds.h
+++ b/drivers/net/wireless/b43/leds.h
@@ -60,7 +60,7 @@ enum b43_led_behaviour {
60}; 60};
61 61
62void b43_leds_register(struct b43_wldev *dev); 62void b43_leds_register(struct b43_wldev *dev);
63void b43_leds_unregister(struct b43_wldev *dev); 63void b43_leds_unregister(struct b43_wl *wl);
64void b43_leds_init(struct b43_wldev *dev); 64void b43_leds_init(struct b43_wldev *dev);
65void b43_leds_exit(struct b43_wldev *dev); 65void b43_leds_exit(struct b43_wldev *dev);
66void b43_leds_stop(struct b43_wldev *dev); 66void b43_leds_stop(struct b43_wldev *dev);
@@ -76,7 +76,7 @@ struct b43_leds {
76static inline void b43_leds_register(struct b43_wldev *dev) 76static inline void b43_leds_register(struct b43_wldev *dev)
77{ 77{
78} 78}
79static inline void b43_leds_unregister(struct b43_wldev *dev) 79static inline void b43_leds_unregister(struct b43_wl *wl)
80{ 80{
81} 81}
82static inline void b43_leds_init(struct b43_wldev *dev) 82static inline void b43_leds_init(struct b43_wldev *dev)
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 9b907a36bb8c..df6b26a0c05e 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -3874,6 +3874,7 @@ static struct b43_wldev * b43_wireless_core_stop(struct b43_wldev *dev)
3874{ 3874{
3875 struct b43_wl *wl = dev->wl; 3875 struct b43_wl *wl = dev->wl;
3876 struct b43_wldev *orig_dev; 3876 struct b43_wldev *orig_dev;
3877 u32 mask;
3877 3878
3878redo: 3879redo:
3879 if (!dev || b43_status(dev) < B43_STAT_STARTED) 3880 if (!dev || b43_status(dev) < B43_STAT_STARTED)
@@ -3920,7 +3921,8 @@ redo:
3920 goto redo; 3921 goto redo;
3921 return dev; 3922 return dev;
3922 } 3923 }
3923 B43_WARN_ON(b43_read32(dev, B43_MMIO_GEN_IRQ_MASK)); 3924 mask = b43_read32(dev, B43_MMIO_GEN_IRQ_MASK);
3925 B43_WARN_ON(mask != 0xFFFFFFFF && mask);
3924 3926
3925 /* Drain the TX queue */ 3927 /* Drain the TX queue */
3926 while (skb_queue_len(&wl->tx_queue)) 3928 while (skb_queue_len(&wl->tx_queue))
@@ -4499,6 +4501,7 @@ static void b43_op_stop(struct ieee80211_hw *hw)
4499 4501
4500 cancel_work_sync(&(wl->beacon_update_trigger)); 4502 cancel_work_sync(&(wl->beacon_update_trigger));
4501 4503
4504 wiphy_rfkill_stop_polling(hw->wiphy);
4502 mutex_lock(&wl->mutex); 4505 mutex_lock(&wl->mutex);
4503 if (b43_status(dev) >= B43_STAT_STARTED) { 4506 if (b43_status(dev) >= B43_STAT_STARTED) {
4504 dev = b43_wireless_core_stop(dev); 4507 dev = b43_wireless_core_stop(dev);
@@ -4997,7 +5000,7 @@ static void b43_remove(struct ssb_device *dev)
4997 5000
4998 if (list_empty(&wl->devlist)) { 5001 if (list_empty(&wl->devlist)) {
4999 b43_rng_exit(wl); 5002 b43_rng_exit(wl);
5000 b43_leds_unregister(wldev); 5003 b43_leds_unregister(wl);
5001 /* Last core on the chip unregistered. 5004 /* Last core on the chip unregistered.
5002 * We can destroy common struct b43_wl. 5005 * We can destroy common struct b43_wl.
5003 */ 5006 */
diff --git a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c
index e96091b31499..9b9044400218 100644
--- a/drivers/net/wireless/b43/pio.c
+++ b/drivers/net/wireless/b43/pio.c
@@ -30,6 +30,7 @@
30#include "xmit.h" 30#include "xmit.h"
31 31
32#include <linux/delay.h> 32#include <linux/delay.h>
33#include <linux/sched.h>
33 34
34 35
35static u16 generate_cookie(struct b43_pio_txqueue *q, 36static u16 generate_cookie(struct b43_pio_txqueue *q,
@@ -331,6 +332,7 @@ static u16 tx_write_2byte_queue(struct b43_pio_txqueue *q,
331 unsigned int data_len) 332 unsigned int data_len)
332{ 333{
333 struct b43_wldev *dev = q->dev; 334 struct b43_wldev *dev = q->dev;
335 struct b43_wl *wl = dev->wl;
334 const u8 *data = _data; 336 const u8 *data = _data;
335 337
336 ctl |= B43_PIO_TXCTL_WRITELO | B43_PIO_TXCTL_WRITEHI; 338 ctl |= B43_PIO_TXCTL_WRITELO | B43_PIO_TXCTL_WRITEHI;
@@ -343,7 +345,11 @@ static u16 tx_write_2byte_queue(struct b43_pio_txqueue *q,
343 /* Write the last byte. */ 345 /* Write the last byte. */
344 ctl &= ~B43_PIO_TXCTL_WRITEHI; 346 ctl &= ~B43_PIO_TXCTL_WRITEHI;
345 b43_piotx_write16(q, B43_PIO_TXCTL, ctl); 347 b43_piotx_write16(q, B43_PIO_TXCTL, ctl);
346 b43_piotx_write16(q, B43_PIO_TXDATA, data[data_len - 1]); 348 wl->tx_tail[0] = data[data_len - 1];
349 wl->tx_tail[1] = 0;
350 ssb_block_write(dev->dev, wl->tx_tail, 2,
351 q->mmio_base + B43_PIO_TXDATA,
352 sizeof(u16));
347 } 353 }
348 354
349 return ctl; 355 return ctl;
@@ -376,6 +382,7 @@ static u32 tx_write_4byte_queue(struct b43_pio_txqueue *q,
376 unsigned int data_len) 382 unsigned int data_len)
377{ 383{
378 struct b43_wldev *dev = q->dev; 384 struct b43_wldev *dev = q->dev;
385 struct b43_wl *wl = dev->wl;
379 const u8 *data = _data; 386 const u8 *data = _data;
380 387
381 ctl |= B43_PIO8_TXCTL_0_7 | B43_PIO8_TXCTL_8_15 | 388 ctl |= B43_PIO8_TXCTL_0_7 | B43_PIO8_TXCTL_8_15 |
@@ -386,26 +393,33 @@ static u32 tx_write_4byte_queue(struct b43_pio_txqueue *q,
386 q->mmio_base + B43_PIO8_TXDATA, 393 q->mmio_base + B43_PIO8_TXDATA,
387 sizeof(u32)); 394 sizeof(u32));
388 if (data_len & 3) { 395 if (data_len & 3) {
389 u32 value = 0; 396 wl->tx_tail[3] = 0;
390
391 /* Write the last few bytes. */ 397 /* Write the last few bytes. */
392 ctl &= ~(B43_PIO8_TXCTL_8_15 | B43_PIO8_TXCTL_16_23 | 398 ctl &= ~(B43_PIO8_TXCTL_8_15 | B43_PIO8_TXCTL_16_23 |
393 B43_PIO8_TXCTL_24_31); 399 B43_PIO8_TXCTL_24_31);
394 data = &(data[data_len - 1]);
395 switch (data_len & 3) { 400 switch (data_len & 3) {
396 case 3: 401 case 3:
397 ctl |= B43_PIO8_TXCTL_16_23; 402 ctl |= B43_PIO8_TXCTL_16_23 | B43_PIO8_TXCTL_8_15;
398 value |= (u32)(*data) << 16; 403 wl->tx_tail[0] = data[data_len - 3];
399 data--; 404 wl->tx_tail[1] = data[data_len - 2];
405 wl->tx_tail[2] = data[data_len - 1];
406 break;
400 case 2: 407 case 2:
401 ctl |= B43_PIO8_TXCTL_8_15; 408 ctl |= B43_PIO8_TXCTL_8_15;
402 value |= (u32)(*data) << 8; 409 wl->tx_tail[0] = data[data_len - 2];
403 data--; 410 wl->tx_tail[1] = data[data_len - 1];
411 wl->tx_tail[2] = 0;
412 break;
404 case 1: 413 case 1:
405 value |= (u32)(*data); 414 wl->tx_tail[0] = data[data_len - 1];
415 wl->tx_tail[1] = 0;
416 wl->tx_tail[2] = 0;
417 break;
406 } 418 }
407 b43_piotx_write32(q, B43_PIO8_TXCTL, ctl); 419 b43_piotx_write32(q, B43_PIO8_TXCTL, ctl);
408 b43_piotx_write32(q, B43_PIO8_TXDATA, value); 420 ssb_block_write(dev->dev, wl->tx_tail, 4,
421 q->mmio_base + B43_PIO8_TXDATA,
422 sizeof(u32));
409 } 423 }
410 424
411 return ctl; 425 return ctl;
@@ -435,8 +449,9 @@ static void pio_tx_frame_4byte_queue(struct b43_pio_txpacket *pack,
435static int pio_tx_frame(struct b43_pio_txqueue *q, 449static int pio_tx_frame(struct b43_pio_txqueue *q,
436 struct sk_buff *skb) 450 struct sk_buff *skb)
437{ 451{
452 struct b43_wldev *dev = q->dev;
453 struct b43_wl *wl = dev->wl;
438 struct b43_pio_txpacket *pack; 454 struct b43_pio_txpacket *pack;
439 struct b43_txhdr txhdr;
440 u16 cookie; 455 u16 cookie;
441 int err; 456 int err;
442 unsigned int hdrlen; 457 unsigned int hdrlen;
@@ -447,8 +462,8 @@ static int pio_tx_frame(struct b43_pio_txqueue *q,
447 struct b43_pio_txpacket, list); 462 struct b43_pio_txpacket, list);
448 463
449 cookie = generate_cookie(q, pack); 464 cookie = generate_cookie(q, pack);
450 hdrlen = b43_txhdr_size(q->dev); 465 hdrlen = b43_txhdr_size(dev);
451 err = b43_generate_txhdr(q->dev, (u8 *)&txhdr, skb, 466 err = b43_generate_txhdr(dev, (u8 *)&wl->txhdr, skb,
452 info, cookie); 467 info, cookie);
453 if (err) 468 if (err)
454 return err; 469 return err;
@@ -456,15 +471,15 @@ static int pio_tx_frame(struct b43_pio_txqueue *q,
456 if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) { 471 if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) {
457 /* Tell the firmware about the cookie of the last 472 /* Tell the firmware about the cookie of the last
458 * mcast frame, so it can clear the more-data bit in it. */ 473 * mcast frame, so it can clear the more-data bit in it. */
459 b43_shm_write16(q->dev, B43_SHM_SHARED, 474 b43_shm_write16(dev, B43_SHM_SHARED,
460 B43_SHM_SH_MCASTCOOKIE, cookie); 475 B43_SHM_SH_MCASTCOOKIE, cookie);
461 } 476 }
462 477
463 pack->skb = skb; 478 pack->skb = skb;
464 if (q->rev >= 8) 479 if (q->rev >= 8)
465 pio_tx_frame_4byte_queue(pack, (const u8 *)&txhdr, hdrlen); 480 pio_tx_frame_4byte_queue(pack, (const u8 *)&wl->txhdr, hdrlen);
466 else 481 else
467 pio_tx_frame_2byte_queue(pack, (const u8 *)&txhdr, hdrlen); 482 pio_tx_frame_2byte_queue(pack, (const u8 *)&wl->txhdr, hdrlen);
468 483
469 /* Remove it from the list of available packet slots. 484 /* Remove it from the list of available packet slots.
470 * It will be put back when we receive the status report. */ 485 * It will be put back when we receive the status report. */
@@ -604,14 +619,14 @@ void b43_pio_get_tx_stats(struct b43_wldev *dev,
604static bool pio_rx_frame(struct b43_pio_rxqueue *q) 619static bool pio_rx_frame(struct b43_pio_rxqueue *q)
605{ 620{
606 struct b43_wldev *dev = q->dev; 621 struct b43_wldev *dev = q->dev;
607 struct b43_rxhdr_fw4 rxhdr; 622 struct b43_wl *wl = dev->wl;
608 u16 len; 623 u16 len;
609 u32 macstat; 624 u32 macstat;
610 unsigned int i, padding; 625 unsigned int i, padding;
611 struct sk_buff *skb; 626 struct sk_buff *skb;
612 const char *err_msg = NULL; 627 const char *err_msg = NULL;
613 628
614 memset(&rxhdr, 0, sizeof(rxhdr)); 629 memset(&wl->rxhdr, 0, sizeof(wl->rxhdr));
615 630
616 /* Check if we have data and wait for it to get ready. */ 631 /* Check if we have data and wait for it to get ready. */
617 if (q->rev >= 8) { 632 if (q->rev >= 8) {
@@ -649,16 +664,16 @@ data_ready:
649 664
650 /* Get the preamble (RX header) */ 665 /* Get the preamble (RX header) */
651 if (q->rev >= 8) { 666 if (q->rev >= 8) {
652 ssb_block_read(dev->dev, &rxhdr, sizeof(rxhdr), 667 ssb_block_read(dev->dev, &wl->rxhdr, sizeof(wl->rxhdr),
653 q->mmio_base + B43_PIO8_RXDATA, 668 q->mmio_base + B43_PIO8_RXDATA,
654 sizeof(u32)); 669 sizeof(u32));
655 } else { 670 } else {
656 ssb_block_read(dev->dev, &rxhdr, sizeof(rxhdr), 671 ssb_block_read(dev->dev, &wl->rxhdr, sizeof(wl->rxhdr),
657 q->mmio_base + B43_PIO_RXDATA, 672 q->mmio_base + B43_PIO_RXDATA,
658 sizeof(u16)); 673 sizeof(u16));
659 } 674 }
660 /* Sanity checks. */ 675 /* Sanity checks. */
661 len = le16_to_cpu(rxhdr.frame_len); 676 len = le16_to_cpu(wl->rxhdr.frame_len);
662 if (unlikely(len > 0x700)) { 677 if (unlikely(len > 0x700)) {
663 err_msg = "len > 0x700"; 678 err_msg = "len > 0x700";
664 goto rx_error; 679 goto rx_error;
@@ -668,7 +683,7 @@ data_ready:
668 goto rx_error; 683 goto rx_error;
669 } 684 }
670 685
671 macstat = le32_to_cpu(rxhdr.mac_status); 686 macstat = le32_to_cpu(wl->rxhdr.mac_status);
672 if (macstat & B43_RX_MAC_FCSERR) { 687 if (macstat & B43_RX_MAC_FCSERR) {
673 if (!(q->dev->wl->filter_flags & FIF_FCSFAIL)) { 688 if (!(q->dev->wl->filter_flags & FIF_FCSFAIL)) {
674 /* Drop frames with failed FCS. */ 689 /* Drop frames with failed FCS. */
@@ -693,21 +708,23 @@ data_ready:
693 q->mmio_base + B43_PIO8_RXDATA, 708 q->mmio_base + B43_PIO8_RXDATA,
694 sizeof(u32)); 709 sizeof(u32));
695 if (len & 3) { 710 if (len & 3) {
696 u32 value;
697 char *data;
698
699 /* Read the last few bytes. */ 711 /* Read the last few bytes. */
700 value = b43_piorx_read32(q, B43_PIO8_RXDATA); 712 ssb_block_read(dev->dev, wl->rx_tail, 4,
701 data = &(skb->data[len + padding - 1]); 713 q->mmio_base + B43_PIO8_RXDATA,
714 sizeof(u32));
702 switch (len & 3) { 715 switch (len & 3) {
703 case 3: 716 case 3:
704 *data = (value >> 16); 717 skb->data[len + padding - 3] = wl->rx_tail[0];
705 data--; 718 skb->data[len + padding - 2] = wl->rx_tail[1];
719 skb->data[len + padding - 1] = wl->rx_tail[2];
720 break;
706 case 2: 721 case 2:
707 *data = (value >> 8); 722 skb->data[len + padding - 2] = wl->rx_tail[0];
708 data--; 723 skb->data[len + padding - 1] = wl->rx_tail[1];
724 break;
709 case 1: 725 case 1:
710 *data = value; 726 skb->data[len + padding - 1] = wl->rx_tail[0];
727 break;
711 } 728 }
712 } 729 }
713 } else { 730 } else {
@@ -715,15 +732,15 @@ data_ready:
715 q->mmio_base + B43_PIO_RXDATA, 732 q->mmio_base + B43_PIO_RXDATA,
716 sizeof(u16)); 733 sizeof(u16));
717 if (len & 1) { 734 if (len & 1) {
718 u16 value;
719
720 /* Read the last byte. */ 735 /* Read the last byte. */
721 value = b43_piorx_read16(q, B43_PIO_RXDATA); 736 ssb_block_read(dev->dev, wl->rx_tail, 2,
722 skb->data[len + padding - 1] = value; 737 q->mmio_base + B43_PIO_RXDATA,
738 sizeof(u16));
739 skb->data[len + padding - 1] = wl->rx_tail[0];
723 } 740 }
724 } 741 }
725 742
726 b43_rx(q->dev, skb, &rxhdr); 743 b43_rx(q->dev, skb, &wl->rxhdr);
727 744
728 return 1; 745 return 1;
729 746
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index ac9f600995e4..f4e9695ec186 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -27,7 +27,7 @@
27 27
28*/ 28*/
29 29
30#include "xmit.h" 30#include "b43.h"
31#include "phy_common.h" 31#include "phy_common.h"
32#include "dma.h" 32#include "dma.h"
33#include "pio.h" 33#include "pio.h"
@@ -690,7 +690,10 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
690 } 690 }
691 691
692 memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status)); 692 memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
693
694 local_bh_disable();
693 ieee80211_rx(dev->wl->hw, skb); 695 ieee80211_rx(dev->wl->hw, skb);
696 local_bh_enable();
694 697
695#if B43_DEBUG 698#if B43_DEBUG
696 dev->rx_count++; 699 dev->rx_count++;
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index 1d9223b3d4c4..4b60148a5e61 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -37,6 +37,7 @@
37#include <linux/firmware.h> 37#include <linux/firmware.h>
38#include <linux/wireless.h> 38#include <linux/wireless.h>
39#include <linux/workqueue.h> 39#include <linux/workqueue.h>
40#include <linux/sched.h>
40#include <linux/skbuff.h> 41#include <linux/skbuff.h>
41#include <linux/dma-mapping.h> 42#include <linux/dma-mapping.h>
42#include <net/dst.h> 43#include <net/dst.h>
diff --git a/drivers/net/wireless/b43legacy/phy.c b/drivers/net/wireless/b43legacy/phy.c
index 11319ec2d64a..aaf227203a98 100644
--- a/drivers/net/wireless/b43legacy/phy.c
+++ b/drivers/net/wireless/b43legacy/phy.c
@@ -31,6 +31,7 @@
31 31
32#include <linux/delay.h> 32#include <linux/delay.h>
33#include <linux/pci.h> 33#include <linux/pci.h>
34#include <linux/sched.h>
34#include <linux/types.h> 35#include <linux/types.h>
35 36
36#include "b43legacy.h" 37#include "b43legacy.h"
diff --git a/drivers/net/wireless/hostap/hostap_info.c b/drivers/net/wireless/hostap/hostap_info.c
index 6fa14a4e4b53..4dfb40a84c96 100644
--- a/drivers/net/wireless/hostap/hostap_info.c
+++ b/drivers/net/wireless/hostap/hostap_info.c
@@ -1,6 +1,7 @@
1/* Host AP driver Info Frame processing (part of hostap.o module) */ 1/* Host AP driver Info Frame processing (part of hostap.o module) */
2 2
3#include <linux/if_arp.h> 3#include <linux/if_arp.h>
4#include <linux/sched.h>
4#include "hostap_wlan.h" 5#include "hostap_wlan.h"
5#include "hostap.h" 6#include "hostap.h"
6#include "hostap_ap.h" 7#include "hostap_ap.h"
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c
index 3f2bda881a4f..9419cebca8a5 100644
--- a/drivers/net/wireless/hostap/hostap_ioctl.c
+++ b/drivers/net/wireless/hostap/hostap_ioctl.c
@@ -1,6 +1,7 @@
1/* ioctl() (mostly Linux Wireless Extensions) routines for Host AP driver */ 1/* ioctl() (mostly Linux Wireless Extensions) routines for Host AP driver */
2 2
3#include <linux/types.h> 3#include <linux/types.h>
4#include <linux/sched.h>
4#include <linux/ethtool.h> 5#include <linux/ethtool.h>
5#include <linux/if_arp.h> 6#include <linux/if_arp.h>
6#include <net/lib80211.h> 7#include <net/lib80211.h>
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index 8d58e6ed4e7d..827824d45de9 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -30,6 +30,7 @@
30 30
31******************************************************************************/ 31******************************************************************************/
32 32
33#include <linux/sched.h>
33#include "ipw2200.h" 34#include "ipw2200.h"
34 35
35 36
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
index a16bd4147eac..cbb0585083a9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
@@ -702,7 +702,7 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
702 u8 sta_id = iwl_find_station(priv, hdr->addr1); 702 u8 sta_id = iwl_find_station(priv, hdr->addr1);
703 703
704 if (sta_id == IWL_INVALID_STATION) { 704 if (sta_id == IWL_INVALID_STATION) {
705 IWL_DEBUG_RATE(priv, "LQ: ADD station %pm\n", 705 IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n",
706 hdr->addr1); 706 hdr->addr1);
707 sta_id = iwl_add_station(priv, hdr->addr1, false, 707 sta_id = iwl_add_station(priv, hdr->addr1, false,
708 CMD_ASYNC, NULL); 708 CMD_ASYNC, NULL);
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index e70c5b0af364..f059b49dc691 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -30,6 +30,7 @@
30#include <linux/pci.h> 30#include <linux/pci.h>
31#include <linux/dma-mapping.h> 31#include <linux/dma-mapping.h>
32#include <linux/delay.h> 32#include <linux/delay.h>
33#include <linux/sched.h>
33#include <linux/skbuff.h> 34#include <linux/skbuff.h>
34#include <linux/netdevice.h> 35#include <linux/netdevice.h>
35#include <linux/wireless.h> 36#include <linux/wireless.h>
@@ -610,7 +611,7 @@ static void iwl3945_rx_reply_rx(struct iwl_priv *priv,
610 if (rx_status.band == IEEE80211_BAND_5GHZ) 611 if (rx_status.band == IEEE80211_BAND_5GHZ)
611 rx_status.rate_idx -= IWL_FIRST_OFDM_RATE; 612 rx_status.rate_idx -= IWL_FIRST_OFDM_RATE;
612 613
613 rx_status.antenna = le16_to_cpu(rx_hdr->phy_flags & 614 rx_status.antenna = (le16_to_cpu(rx_hdr->phy_flags) &
614 RX_RES_PHY_FLAGS_ANTENNA_MSK) >> 4; 615 RX_RES_PHY_FLAGS_ANTENNA_MSK) >> 4;
615 616
616 /* set the preamble flag if appropriate */ 617 /* set the preamble flag if appropriate */
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index a22a0501c190..6f703a041847 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -30,6 +30,7 @@
30#include <linux/pci.h> 30#include <linux/pci.h>
31#include <linux/dma-mapping.h> 31#include <linux/dma-mapping.h>
32#include <linux/delay.h> 32#include <linux/delay.h>
33#include <linux/sched.h>
33#include <linux/skbuff.h> 34#include <linux/skbuff.h>
34#include <linux/netdevice.h> 35#include <linux/netdevice.h>
35#include <linux/wireless.h> 36#include <linux/wireless.h>
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index eb08f4411000..6e6f516ba404 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -29,6 +29,7 @@
29#include <linux/pci.h> 29#include <linux/pci.h>
30#include <linux/dma-mapping.h> 30#include <linux/dma-mapping.h>
31#include <linux/delay.h> 31#include <linux/delay.h>
32#include <linux/sched.h>
32#include <linux/skbuff.h> 33#include <linux/skbuff.h>
33#include <linux/netdevice.h> 34#include <linux/netdevice.h>
34#include <linux/wireless.h> 35#include <linux/wireless.h>
@@ -317,7 +318,7 @@ static void iwl5000_gain_computation(struct iwl_priv *priv,
317 (s32)average_noise[i])) / 1500; 318 (s32)average_noise[i])) / 1500;
318 /* bound gain by 2 bits value max, 3rd bit is sign */ 319 /* bound gain by 2 bits value max, 3rd bit is sign */
319 data->delta_gain_code[i] = 320 data->delta_gain_code[i] =
320 min(abs(delta_g), CHAIN_NOISE_MAX_DELTA_GAIN_CODE); 321 min(abs(delta_g), (long) CHAIN_NOISE_MAX_DELTA_GAIN_CODE);
321 322
322 if (delta_g < 0) 323 if (delta_g < 0)
323 /* set negative sign */ 324 /* set negative sign */
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index cdc07c477457..eaafae091f5b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -33,6 +33,7 @@
33#include <linux/pci.h> 33#include <linux/pci.h>
34#include <linux/dma-mapping.h> 34#include <linux/dma-mapping.h>
35#include <linux/delay.h> 35#include <linux/delay.h>
36#include <linux/sched.h>
36#include <linux/skbuff.h> 37#include <linux/skbuff.h>
37#include <linux/netdevice.h> 38#include <linux/netdevice.h>
38#include <linux/wireless.h> 39#include <linux/wireless.h>
@@ -3105,8 +3106,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
3105 out_pci_disable_device: 3106 out_pci_disable_device:
3106 pci_disable_device(pdev); 3107 pci_disable_device(pdev);
3107 out_ieee80211_free_hw: 3108 out_ieee80211_free_hw:
3108 ieee80211_free_hw(priv->hw);
3109 iwl_free_traffic_mem(priv); 3109 iwl_free_traffic_mem(priv);
3110 ieee80211_free_hw(priv->hw);
3110 out: 3111 out:
3111 return err; 3112 return err;
3112} 3113}
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 2c5c88fc38f5..4afaf773aeac 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -1154,7 +1154,7 @@ struct iwl_wep_cmd {
1154#define RX_RES_PHY_FLAGS_MOD_CCK_MSK cpu_to_le16(1 << 1) 1154#define RX_RES_PHY_FLAGS_MOD_CCK_MSK cpu_to_le16(1 << 1)
1155#define RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK cpu_to_le16(1 << 2) 1155#define RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK cpu_to_le16(1 << 2)
1156#define RX_RES_PHY_FLAGS_NARROW_BAND_MSK cpu_to_le16(1 << 3) 1156#define RX_RES_PHY_FLAGS_NARROW_BAND_MSK cpu_to_le16(1 << 3)
1157#define RX_RES_PHY_FLAGS_ANTENNA_MSK cpu_to_le16(0xf0) 1157#define RX_RES_PHY_FLAGS_ANTENNA_MSK 0xf0
1158#define RX_RES_PHY_FLAGS_ANTENNA_POS 4 1158#define RX_RES_PHY_FLAGS_ANTENNA_POS 4
1159 1159
1160#define RX_RES_STATUS_SEC_TYPE_MSK (0x7 << 8) 1160#define RX_RES_STATUS_SEC_TYPE_MSK (0x7 << 8)
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 484d5c1a7312..2dc928755454 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -29,6 +29,7 @@
29#include <linux/kernel.h> 29#include <linux/kernel.h>
30#include <linux/module.h> 30#include <linux/module.h>
31#include <linux/etherdevice.h> 31#include <linux/etherdevice.h>
32#include <linux/sched.h>
32#include <net/mac80211.h> 33#include <net/mac80211.h>
33 34
34#include "iwl-eeprom.h" 35#include "iwl-eeprom.h"
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index 3d2b93a61e62..e14c9952a935 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -410,7 +410,6 @@ static int iwl_find_otp_image(struct iwl_priv *priv,
410 u16 *validblockaddr) 410 u16 *validblockaddr)
411{ 411{
412 u16 next_link_addr = 0, link_value = 0, valid_addr; 412 u16 next_link_addr = 0, link_value = 0, valid_addr;
413 int ret = 0;
414 int usedblocks = 0; 413 int usedblocks = 0;
415 414
416 /* set addressing mode to absolute to traverse the link list */ 415 /* set addressing mode to absolute to traverse the link list */
@@ -430,29 +429,29 @@ static int iwl_find_otp_image(struct iwl_priv *priv,
430 * check for more block on the link list 429 * check for more block on the link list
431 */ 430 */
432 valid_addr = next_link_addr; 431 valid_addr = next_link_addr;
433 next_link_addr = link_value; 432 next_link_addr = link_value * sizeof(u16);
434 IWL_DEBUG_INFO(priv, "OTP blocks %d addr 0x%x\n", 433 IWL_DEBUG_INFO(priv, "OTP blocks %d addr 0x%x\n",
435 usedblocks, next_link_addr); 434 usedblocks, next_link_addr);
436 if (iwl_read_otp_word(priv, next_link_addr, &link_value)) 435 if (iwl_read_otp_word(priv, next_link_addr, &link_value))
437 return -EINVAL; 436 return -EINVAL;
438 if (!link_value) { 437 if (!link_value) {
439 /* 438 /*
440 * reach the end of link list, 439 * reach the end of link list, return success and
441 * set address point to the starting address 440 * set address point to the starting address
442 * of the image 441 * of the image
443 */ 442 */
444 goto done; 443 *validblockaddr = valid_addr;
444 /* skip first 2 bytes (link list pointer) */
445 *validblockaddr += 2;
446 return 0;
445 } 447 }
446 /* more in the link list, continue */ 448 /* more in the link list, continue */
447 usedblocks++; 449 usedblocks++;
448 } while (usedblocks < priv->cfg->max_ll_items); 450 } while (usedblocks <= priv->cfg->max_ll_items);
449 /* OTP full, use last block */ 451
450 IWL_DEBUG_INFO(priv, "OTP is full, use last block\n"); 452 /* OTP has no valid blocks */
451done: 453 IWL_DEBUG_INFO(priv, "OTP has no valid blocks\n");
452 *validblockaddr = valid_addr; 454 return -EINVAL;
453 /* skip first 2 bytes (link list pointer) */
454 *validblockaddr += 2;
455 return ret;
456} 455}
457 456
458/** 457/**
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
index 6b68db7b1b81..80b9e45d9b9c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
@@ -220,35 +220,35 @@ struct iwl_eeprom_enhanced_txpwr {
220 * Section 10: 2.4 GHz 40MHz channels: 132, 44 (_above_) 220 * Section 10: 2.4 GHz 40MHz channels: 132, 44 (_above_)
221 */ 221 */
222/* 2.4 GHz band: CCK */ 222/* 2.4 GHz band: CCK */
223#define EEPROM_LB_CCK_20_COMMON ((0xAA)\ 223#define EEPROM_LB_CCK_20_COMMON ((0xA8)\
224 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 8 bytes */ 224 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 8 bytes */
225/* 2.4 GHz band: 20MHz-Legacy, 20MHz-HT, 40MHz-HT */ 225/* 2.4 GHz band: 20MHz-Legacy, 20MHz-HT, 40MHz-HT */
226#define EEPROM_LB_OFDM_COMMON ((0xB2)\ 226#define EEPROM_LB_OFDM_COMMON ((0xB0)\
227 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 24 bytes */ 227 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 24 bytes */
228/* 5.2 GHz band: 20MHz-Legacy, 20MHz-HT, 40MHz-HT */ 228/* 5.2 GHz band: 20MHz-Legacy, 20MHz-HT, 40MHz-HT */
229#define EEPROM_HB_OFDM_COMMON ((0xCA)\ 229#define EEPROM_HB_OFDM_COMMON ((0xC8)\
230 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 24 bytes */ 230 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 24 bytes */
231/* 2.4GHz band channels: 231/* 2.4GHz band channels:
232 * 1Legacy, 1HT, 2Legacy, 2HT, 10Legacy, 10HT, 11Legacy, 11HT */ 232 * 1Legacy, 1HT, 2Legacy, 2HT, 10Legacy, 10HT, 11Legacy, 11HT */
233#define EEPROM_LB_OFDM_20_BAND ((0xE2)\ 233#define EEPROM_LB_OFDM_20_BAND ((0xE0)\
234 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 64 bytes */ 234 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 64 bytes */
235/* 2.4 GHz band HT40 channels: (1,+1) (2,+1) (6,+1) (7,+1) (9,+1) */ 235/* 2.4 GHz band HT40 channels: (1,+1) (2,+1) (6,+1) (7,+1) (9,+1) */
236#define EEPROM_LB_OFDM_HT40_BAND ((0x122)\ 236#define EEPROM_LB_OFDM_HT40_BAND ((0x120)\
237 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 40 bytes */ 237 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 40 bytes */
238/* 5.2GHz band channels: 36Legacy, 36HT, 64Legacy, 64HT, 100Legacy, 100HT */ 238/* 5.2GHz band channels: 36Legacy, 36HT, 64Legacy, 64HT, 100Legacy, 100HT */
239#define EEPROM_HB_OFDM_20_BAND ((0x14A)\ 239#define EEPROM_HB_OFDM_20_BAND ((0x148)\
240 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 48 bytes */ 240 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 48 bytes */
241/* 5.2 GHz band HT40 channels: (36,+1) (60,+1) (100,+1) */ 241/* 5.2 GHz band HT40 channels: (36,+1) (60,+1) (100,+1) */
242#define EEPROM_HB_OFDM_HT40_BAND ((0x17A)\ 242#define EEPROM_HB_OFDM_HT40_BAND ((0x178)\
243 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 24 bytes */ 243 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 24 bytes */
244/* 2.4 GHz band, channnel 13: Legacy, HT */ 244/* 2.4 GHz band, channnel 13: Legacy, HT */
245#define EEPROM_LB_OFDM_20_CHANNEL_13 ((0x192)\ 245#define EEPROM_LB_OFDM_20_CHANNEL_13 ((0x190)\
246 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 16 bytes */ 246 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 16 bytes */
247/* 5.2 GHz band, channnel 140: Legacy, HT */ 247/* 5.2 GHz band, channnel 140: Legacy, HT */
248#define EEPROM_HB_OFDM_20_CHANNEL_140 ((0x1A2)\ 248#define EEPROM_HB_OFDM_20_CHANNEL_140 ((0x1A0)\
249 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 16 bytes */ 249 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 16 bytes */
250/* 5.2 GHz band, HT40 channnels (132,+1) (44,+1) */ 250/* 5.2 GHz band, HT40 channnels (132,+1) (44,+1) */
251#define EEPROM_HB_OFDM_HT40_BAND_1 ((0x1B2)\ 251#define EEPROM_HB_OFDM_HT40_BAND_1 ((0x1B0)\
252 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 16 bytes */ 252 | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 16 bytes */
253 253
254 254
diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
index 532c8d6cd8da..a6856daf14cb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
@@ -28,6 +28,7 @@
28 28
29#include <linux/kernel.h> 29#include <linux/kernel.h>
30#include <linux/module.h> 30#include <linux/module.h>
31#include <linux/sched.h>
31#include <net/mac80211.h> 32#include <net/mac80211.h>
32 33
33#include "iwl-dev.h" /* FIXME: remove */ 34#include "iwl-dev.h" /* FIXME: remove */
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index 8e1bb53c0aa3..493626bcd3ec 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -1044,7 +1044,7 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
1044 * as a bitmask. 1044 * as a bitmask.
1045 */ 1045 */
1046 rx_status.antenna = 1046 rx_status.antenna =
1047 le16_to_cpu(phy_res->phy_flags & RX_RES_PHY_FLAGS_ANTENNA_MSK) 1047 (le16_to_cpu(phy_res->phy_flags) & RX_RES_PHY_FLAGS_ANTENNA_MSK)
1048 >> RX_RES_PHY_FLAGS_ANTENNA_POS; 1048 >> RX_RES_PHY_FLAGS_ANTENNA_POS;
1049 1049
1050 /* set the preamble flag if appropriate */ 1050 /* set the preamble flag if appropriate */
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index c18907544701..fb9bcfa6d947 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -28,6 +28,7 @@
28 *****************************************************************************/ 28 *****************************************************************************/
29 29
30#include <linux/etherdevice.h> 30#include <linux/etherdevice.h>
31#include <linux/sched.h>
31#include <net/mac80211.h> 32#include <net/mac80211.h>
32#include "iwl-eeprom.h" 33#include "iwl-eeprom.h"
33#include "iwl-dev.h" 34#include "iwl-dev.h"
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index c390dbd877e4..d00a80334095 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -33,6 +33,7 @@
33#include <linux/pci.h> 33#include <linux/pci.h>
34#include <linux/dma-mapping.h> 34#include <linux/dma-mapping.h>
35#include <linux/delay.h> 35#include <linux/delay.h>
36#include <linux/sched.h>
36#include <linux/skbuff.h> 37#include <linux/skbuff.h>
37#include <linux/netdevice.h> 38#include <linux/netdevice.h>
38#include <linux/wireless.h> 39#include <linux/wireless.h>
@@ -4096,8 +4097,8 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
4096 pci_set_drvdata(pdev, NULL); 4097 pci_set_drvdata(pdev, NULL);
4097 pci_disable_device(pdev); 4098 pci_disable_device(pdev);
4098 out_ieee80211_free_hw: 4099 out_ieee80211_free_hw:
4099 ieee80211_free_hw(priv->hw);
4100 iwl_free_traffic_mem(priv); 4100 iwl_free_traffic_mem(priv);
4101 ieee80211_free_hw(priv->hw);
4101 out: 4102 out:
4102 return err; 4103 return err;
4103} 4104}
diff --git a/drivers/net/wireless/iwmc3200wifi/cfg80211.c b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
index a56a2b0ac99a..f3c55658225b 100644
--- a/drivers/net/wireless/iwmc3200wifi/cfg80211.c
+++ b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
@@ -23,6 +23,7 @@
23 23
24#include <linux/kernel.h> 24#include <linux/kernel.h>
25#include <linux/netdevice.h> 25#include <linux/netdevice.h>
26#include <linux/sched.h>
26#include <linux/etherdevice.h> 27#include <linux/etherdevice.h>
27#include <linux/wireless.h> 28#include <linux/wireless.h>
28#include <linux/ieee80211.h> 29#include <linux/ieee80211.h>
diff --git a/drivers/net/wireless/iwmc3200wifi/commands.c b/drivers/net/wireless/iwmc3200wifi/commands.c
index 23b52fa2605f..84158b6d35d8 100644
--- a/drivers/net/wireless/iwmc3200wifi/commands.c
+++ b/drivers/net/wireless/iwmc3200wifi/commands.c
@@ -40,6 +40,7 @@
40#include <linux/wireless.h> 40#include <linux/wireless.h>
41#include <linux/etherdevice.h> 41#include <linux/etherdevice.h>
42#include <linux/ieee80211.h> 42#include <linux/ieee80211.h>
43#include <linux/sched.h>
43 44
44#include "iwm.h" 45#include "iwm.h"
45#include "bus.h" 46#include "bus.h"
diff --git a/drivers/net/wireless/iwmc3200wifi/main.c b/drivers/net/wireless/iwmc3200wifi/main.c
index d668e4756324..222eb2cf1b30 100644
--- a/drivers/net/wireless/iwmc3200wifi/main.c
+++ b/drivers/net/wireless/iwmc3200wifi/main.c
@@ -38,6 +38,7 @@
38 38
39#include <linux/kernel.h> 39#include <linux/kernel.h>
40#include <linux/netdevice.h> 40#include <linux/netdevice.h>
41#include <linux/sched.h>
41#include <linux/ieee80211.h> 42#include <linux/ieee80211.h>
42#include <linux/wireless.h> 43#include <linux/wireless.h>
43 44
diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c
index 40dbcbc16593..771a301003c9 100644
--- a/drivers/net/wireless/iwmc3200wifi/rx.c
+++ b/drivers/net/wireless/iwmc3200wifi/rx.c
@@ -38,6 +38,7 @@
38 38
39#include <linux/kernel.h> 39#include <linux/kernel.h>
40#include <linux/netdevice.h> 40#include <linux/netdevice.h>
41#include <linux/sched.h>
41#include <linux/etherdevice.h> 42#include <linux/etherdevice.h>
42#include <linux/wireless.h> 43#include <linux/wireless.h>
43#include <linux/ieee80211.h> 44#include <linux/ieee80211.h>
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index 685098148e10..0a324dcd264c 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -6,6 +6,7 @@
6#include <net/iw_handler.h> 6#include <net/iw_handler.h>
7#include <net/lib80211.h> 7#include <net/lib80211.h>
8#include <linux/kfifo.h> 8#include <linux/kfifo.h>
9#include <linux/sched.h>
9#include "host.h" 10#include "host.h"
10#include "hostcmd.h" 11#include "hostcmd.h"
11#include "decl.h" 12#include "decl.h"
diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c
index c42d3faa2660..23f684337fdd 100644
--- a/drivers/net/wireless/libertas/cmdresp.c
+++ b/drivers/net/wireless/libertas/cmdresp.c
@@ -3,6 +3,7 @@
3 * responses as well as events generated by firmware. 3 * responses as well as events generated by firmware.
4 */ 4 */
5#include <linux/delay.h> 5#include <linux/delay.h>
6#include <linux/sched.h>
6#include <linux/if_arp.h> 7#include <linux/if_arp.h>
7#include <linux/netdevice.h> 8#include <linux/netdevice.h>
8#include <asm/unaligned.h> 9#include <asm/unaligned.h>
diff --git a/drivers/net/wireless/libertas/tx.c b/drivers/net/wireless/libertas/tx.c
index 4c018f7a0a8d..8c3766a6e8e7 100644
--- a/drivers/net/wireless/libertas/tx.c
+++ b/drivers/net/wireless/libertas/tx.c
@@ -3,6 +3,7 @@
3 */ 3 */
4#include <linux/netdevice.h> 4#include <linux/netdevice.h>
5#include <linux/etherdevice.h> 5#include <linux/etherdevice.h>
6#include <linux/sched.h>
6 7
7#include "hostcmd.h" 8#include "hostcmd.h"
8#include "radiotap.h" 9#include "radiotap.h"
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 896f532182f0..38cfd79e0590 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -631,6 +631,9 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw,
631 data->beacon_int = 1024 * info->beacon_int / 1000 * HZ / 1000; 631 data->beacon_int = 1024 * info->beacon_int / 1000 * HZ / 1000;
632 if (WARN_ON(!data->beacon_int)) 632 if (WARN_ON(!data->beacon_int))
633 data->beacon_int = 1; 633 data->beacon_int = 1;
634 if (data->started)
635 mod_timer(&data->beacon_timer,
636 jiffies + data->beacon_int);
634 } 637 }
635 638
636 if (changed & BSS_CHANGED_ERP_CTS_PROT) { 639 if (changed & BSS_CHANGED_ERP_CTS_PROT) {
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c
index 4c97c6ad6f5d..bc08464d8323 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.c
+++ b/drivers/net/wireless/prism54/isl_ioctl.c
@@ -19,6 +19,7 @@
19 * 19 *
20 */ 20 */
21 21
22#include <linux/capability.h>
22#include <linux/module.h> 23#include <linux/module.h>
23#include <linux/kernel.h> 24#include <linux/kernel.h>
24#include <linux/if_arp.h> 25#include <linux/if_arp.h>
diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c
index e26d7b3ceab5..2505be56ae39 100644
--- a/drivers/net/wireless/prism54/islpci_dev.c
+++ b/drivers/net/wireless/prism54/islpci_dev.c
@@ -23,6 +23,7 @@
23#include <linux/netdevice.h> 23#include <linux/netdevice.h>
24#include <linux/ethtool.h> 24#include <linux/ethtool.h>
25#include <linux/pci.h> 25#include <linux/pci.h>
26#include <linux/sched.h>
26#include <linux/etherdevice.h> 27#include <linux/etherdevice.h>
27#include <linux/delay.h> 28#include <linux/delay.h>
28#include <linux/if_arp.h> 29#include <linux/if_arp.h>
diff --git a/drivers/net/wireless/prism54/islpci_mgt.c b/drivers/net/wireless/prism54/islpci_mgt.c
index f7c677e2094d..69d2f882fd06 100644
--- a/drivers/net/wireless/prism54/islpci_mgt.c
+++ b/drivers/net/wireless/prism54/islpci_mgt.c
@@ -20,6 +20,7 @@
20#include <linux/netdevice.h> 20#include <linux/netdevice.h>
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/pci.h> 22#include <linux/pci.h>
23#include <linux/sched.h>
23 24
24#include <asm/io.h> 25#include <asm/io.h>
25#include <asm/system.h> 26#include <asm/system.h>
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c
index 7b3ee8c2eaef..68bc9bb1dbf9 100644
--- a/drivers/net/wireless/rt2x00/rt2x00debug.c
+++ b/drivers/net/wireless/rt2x00/rt2x00debug.c
@@ -27,6 +27,7 @@
27#include <linux/kernel.h> 27#include <linux/kernel.h>
28#include <linux/module.h> 28#include <linux/module.h>
29#include <linux/poll.h> 29#include <linux/poll.h>
30#include <linux/sched.h>
30#include <linux/uaccess.h> 31#include <linux/uaccess.h>
31 32
32#include "rt2x00.h" 33#include "rt2x00.h"
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 1cbd9b4a3efc..b8f5ee33445e 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -2381,6 +2381,7 @@ static struct usb_device_id rt73usb_device_table[] = {
2381 /* Huawei-3Com */ 2381 /* Huawei-3Com */
2382 { USB_DEVICE(0x1472, 0x0009), USB_DEVICE_DATA(&rt73usb_ops) }, 2382 { USB_DEVICE(0x1472, 0x0009), USB_DEVICE_DATA(&rt73usb_ops) },
2383 /* Hercules */ 2383 /* Hercules */
2384 { USB_DEVICE(0x06f8, 0xe002), USB_DEVICE_DATA(&rt73usb_ops) },
2384 { USB_DEVICE(0x06f8, 0xe010), USB_DEVICE_DATA(&rt73usb_ops) }, 2385 { USB_DEVICE(0x06f8, 0xe010), USB_DEVICE_DATA(&rt73usb_ops) },
2385 { USB_DEVICE(0x06f8, 0xe020), USB_DEVICE_DATA(&rt73usb_ops) }, 2386 { USB_DEVICE(0x06f8, 0xe020), USB_DEVICE_DATA(&rt73usb_ops) },
2386 /* Linksys */ 2387 /* Linksys */
diff --git a/drivers/net/znet.c b/drivers/net/znet.c
index a0384b6f09b6..b42347333750 100644
--- a/drivers/net/znet.c
+++ b/drivers/net/znet.c
@@ -169,7 +169,6 @@ static void znet_tx_timeout (struct net_device *dev);
169static int znet_request_resources (struct net_device *dev) 169static int znet_request_resources (struct net_device *dev)
170{ 170{
171 struct znet_private *znet = netdev_priv(dev); 171 struct znet_private *znet = netdev_priv(dev);
172 unsigned long flags;
173 172
174 if (request_irq (dev->irq, &znet_interrupt, 0, "ZNet", dev)) 173 if (request_irq (dev->irq, &znet_interrupt, 0, "ZNet", dev))
175 goto failed; 174 goto failed;
@@ -187,13 +186,9 @@ static int znet_request_resources (struct net_device *dev)
187 free_sia: 186 free_sia:
188 release_region (znet->sia_base, znet->sia_size); 187 release_region (znet->sia_base, znet->sia_size);
189 free_tx_dma: 188 free_tx_dma:
190 flags = claim_dma_lock();
191 free_dma (znet->tx_dma); 189 free_dma (znet->tx_dma);
192 release_dma_lock (flags);
193 free_rx_dma: 190 free_rx_dma:
194 flags = claim_dma_lock();
195 free_dma (znet->rx_dma); 191 free_dma (znet->rx_dma);
196 release_dma_lock (flags);
197 free_irq: 192 free_irq:
198 free_irq (dev->irq, dev); 193 free_irq (dev->irq, dev);
199 failed: 194 failed:
@@ -203,14 +198,11 @@ static int znet_request_resources (struct net_device *dev)
203static void znet_release_resources (struct net_device *dev) 198static void znet_release_resources (struct net_device *dev)
204{ 199{
205 struct znet_private *znet = netdev_priv(dev); 200 struct znet_private *znet = netdev_priv(dev);
206 unsigned long flags;
207 201
208 release_region (znet->sia_base, znet->sia_size); 202 release_region (znet->sia_base, znet->sia_size);
209 release_region (dev->base_addr, znet->io_size); 203 release_region (dev->base_addr, znet->io_size);
210 flags = claim_dma_lock();
211 free_dma (znet->tx_dma); 204 free_dma (znet->tx_dma);
212 free_dma (znet->rx_dma); 205 free_dma (znet->rx_dma);
213 release_dma_lock (flags);
214 free_irq (dev->irq, dev); 206 free_irq (dev->irq, dev);
215} 207}
216 208
diff --git a/drivers/oprofile/event_buffer.c b/drivers/oprofile/event_buffer.c
index 2b7ae366ceb1..5df60a6b6776 100644
--- a/drivers/oprofile/event_buffer.c
+++ b/drivers/oprofile/event_buffer.c
@@ -35,12 +35,23 @@ static size_t buffer_pos;
35/* atomic_t because wait_event checks it outside of buffer_mutex */ 35/* atomic_t because wait_event checks it outside of buffer_mutex */
36static atomic_t buffer_ready = ATOMIC_INIT(0); 36static atomic_t buffer_ready = ATOMIC_INIT(0);
37 37
38/* Add an entry to the event buffer. When we 38/*
39 * get near to the end we wake up the process 39 * Add an entry to the event buffer. When we get near to the end we
40 * sleeping on the read() of the file. 40 * wake up the process sleeping on the read() of the file. To protect
41 * the event_buffer this function may only be called when buffer_mutex
42 * is set.
41 */ 43 */
42void add_event_entry(unsigned long value) 44void add_event_entry(unsigned long value)
43{ 45{
46 /*
47 * This shouldn't happen since all workqueues or handlers are
48 * canceled or flushed before the event buffer is freed.
49 */
50 if (!event_buffer) {
51 WARN_ON_ONCE(1);
52 return;
53 }
54
44 if (buffer_pos == buffer_size) { 55 if (buffer_pos == buffer_size) {
45 atomic_inc(&oprofile_stats.event_lost_overflow); 56 atomic_inc(&oprofile_stats.event_lost_overflow);
46 return; 57 return;
@@ -69,7 +80,6 @@ void wake_up_buffer_waiter(void)
69 80
70int alloc_event_buffer(void) 81int alloc_event_buffer(void)
71{ 82{
72 int err = -ENOMEM;
73 unsigned long flags; 83 unsigned long flags;
74 84
75 spin_lock_irqsave(&oprofilefs_lock, flags); 85 spin_lock_irqsave(&oprofilefs_lock, flags);
@@ -80,21 +90,22 @@ int alloc_event_buffer(void)
80 if (buffer_watershed >= buffer_size) 90 if (buffer_watershed >= buffer_size)
81 return -EINVAL; 91 return -EINVAL;
82 92
93 buffer_pos = 0;
83 event_buffer = vmalloc(sizeof(unsigned long) * buffer_size); 94 event_buffer = vmalloc(sizeof(unsigned long) * buffer_size);
84 if (!event_buffer) 95 if (!event_buffer)
85 goto out; 96 return -ENOMEM;
86 97
87 err = 0; 98 return 0;
88out:
89 return err;
90} 99}
91 100
92 101
93void free_event_buffer(void) 102void free_event_buffer(void)
94{ 103{
104 mutex_lock(&buffer_mutex);
95 vfree(event_buffer); 105 vfree(event_buffer);
96 106 buffer_pos = 0;
97 event_buffer = NULL; 107 event_buffer = NULL;
108 mutex_unlock(&buffer_mutex);
98} 109}
99 110
100 111
@@ -167,6 +178,12 @@ static ssize_t event_buffer_read(struct file *file, char __user *buf,
167 178
168 mutex_lock(&buffer_mutex); 179 mutex_lock(&buffer_mutex);
169 180
181 /* May happen if the buffer is freed during pending reads. */
182 if (!event_buffer) {
183 retval = -EINTR;
184 goto out;
185 }
186
170 atomic_set(&buffer_ready, 0); 187 atomic_set(&buffer_ready, 0);
171 188
172 retval = -EFAULT; 189 retval = -EFAULT;
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c
index 14bbaa17e2ca..22b02c6df854 100644
--- a/drivers/pci/dmar.c
+++ b/drivers/pci/dmar.c
@@ -354,6 +354,7 @@ dmar_table_print_dmar_entry(struct acpi_dmar_header *header)
354 struct acpi_dmar_hardware_unit *drhd; 354 struct acpi_dmar_hardware_unit *drhd;
355 struct acpi_dmar_reserved_memory *rmrr; 355 struct acpi_dmar_reserved_memory *rmrr;
356 struct acpi_dmar_atsr *atsr; 356 struct acpi_dmar_atsr *atsr;
357 struct acpi_dmar_rhsa *rhsa;
357 358
358 switch (header->type) { 359 switch (header->type) {
359 case ACPI_DMAR_TYPE_HARDWARE_UNIT: 360 case ACPI_DMAR_TYPE_HARDWARE_UNIT:
@@ -375,6 +376,12 @@ dmar_table_print_dmar_entry(struct acpi_dmar_header *header)
375 atsr = container_of(header, struct acpi_dmar_atsr, header); 376 atsr = container_of(header, struct acpi_dmar_atsr, header);
376 printk(KERN_INFO PREFIX "ATSR flags: %#x\n", atsr->flags); 377 printk(KERN_INFO PREFIX "ATSR flags: %#x\n", atsr->flags);
377 break; 378 break;
379 case ACPI_DMAR_HARDWARE_AFFINITY:
380 rhsa = container_of(header, struct acpi_dmar_rhsa, header);
381 printk(KERN_INFO PREFIX "RHSA base: %#016Lx proximity domain: %#x\n",
382 (unsigned long long)rhsa->base_address,
383 rhsa->proximity_domain);
384 break;
378 } 385 }
379} 386}
380 387
@@ -459,9 +466,13 @@ parse_dmar_table(void)
459 ret = dmar_parse_one_atsr(entry_header); 466 ret = dmar_parse_one_atsr(entry_header);
460#endif 467#endif
461 break; 468 break;
469 case ACPI_DMAR_HARDWARE_AFFINITY:
470 /* We don't do anything with RHSA (yet?) */
471 break;
462 default: 472 default:
463 printk(KERN_WARNING PREFIX 473 printk(KERN_WARNING PREFIX
464 "Unknown DMAR structure type\n"); 474 "Unknown DMAR structure type %d\n",
475 entry_header->type);
465 ret = 0; /* for forward compatibility */ 476 ret = 0; /* for forward compatibility */
466 break; 477 break;
467 } 478 }
diff --git a/drivers/pci/hotplug/cpqphp.h b/drivers/pci/hotplug/cpqphp.h
index 53836001d511..9c6a9fd26812 100644
--- a/drivers/pci/hotplug/cpqphp.h
+++ b/drivers/pci/hotplug/cpqphp.h
@@ -32,6 +32,7 @@
32#include <asm/io.h> /* for read? and write? functions */ 32#include <asm/io.h> /* for read? and write? functions */
33#include <linux/delay.h> /* for delays */ 33#include <linux/delay.h> /* for delays */
34#include <linux/mutex.h> 34#include <linux/mutex.h>
35#include <linux/sched.h> /* for signal_pending() */
35 36
36#define MY_NAME "cpqphp" 37#define MY_NAME "cpqphp"
37 38
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c
index 855dd7ca47f3..b1e97e682500 100644
--- a/drivers/pci/intel-iommu.c
+++ b/drivers/pci/intel-iommu.c
@@ -48,6 +48,7 @@
48 48
49#define IS_GFX_DEVICE(pdev) ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY) 49#define IS_GFX_DEVICE(pdev) ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY)
50#define IS_ISA_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_BRIDGE_ISA) 50#define IS_ISA_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_BRIDGE_ISA)
51#define IS_AZALIA(pdev) ((pdev)->vendor == 0x8086 && (pdev)->device == 0x3a3e)
51 52
52#define IOAPIC_RANGE_START (0xfee00000) 53#define IOAPIC_RANGE_START (0xfee00000)
53#define IOAPIC_RANGE_END (0xfeefffff) 54#define IOAPIC_RANGE_END (0xfeefffff)
@@ -94,6 +95,7 @@ static inline unsigned long virt_to_dma_pfn(void *p)
94/* global iommu list, set NULL for ignored DMAR units */ 95/* global iommu list, set NULL for ignored DMAR units */
95static struct intel_iommu **g_iommus; 96static struct intel_iommu **g_iommus;
96 97
98static void __init check_tylersburg_isoch(void);
97static int rwbf_quirk; 99static int rwbf_quirk;
98 100
99/* 101/*
@@ -1934,6 +1936,9 @@ error:
1934} 1936}
1935 1937
1936static int iommu_identity_mapping; 1938static int iommu_identity_mapping;
1939#define IDENTMAP_ALL 1
1940#define IDENTMAP_GFX 2
1941#define IDENTMAP_AZALIA 4
1937 1942
1938static int iommu_domain_identity_map(struct dmar_domain *domain, 1943static int iommu_domain_identity_map(struct dmar_domain *domain,
1939 unsigned long long start, 1944 unsigned long long start,
@@ -2151,8 +2156,14 @@ static int domain_add_dev_info(struct dmar_domain *domain,
2151 2156
2152static int iommu_should_identity_map(struct pci_dev *pdev, int startup) 2157static int iommu_should_identity_map(struct pci_dev *pdev, int startup)
2153{ 2158{
2154 if (iommu_identity_mapping == 2) 2159 if ((iommu_identity_mapping & IDENTMAP_AZALIA) && IS_AZALIA(pdev))
2155 return IS_GFX_DEVICE(pdev); 2160 return 1;
2161
2162 if ((iommu_identity_mapping & IDENTMAP_GFX) && IS_GFX_DEVICE(pdev))
2163 return 1;
2164
2165 if (!(iommu_identity_mapping & IDENTMAP_ALL))
2166 return 0;
2156 2167
2157 /* 2168 /*
2158 * We want to start off with all devices in the 1:1 domain, and 2169 * We want to start off with all devices in the 1:1 domain, and
@@ -2332,11 +2343,14 @@ int __init init_dmars(void)
2332 } 2343 }
2333 2344
2334 if (iommu_pass_through) 2345 if (iommu_pass_through)
2335 iommu_identity_mapping = 1; 2346 iommu_identity_mapping |= IDENTMAP_ALL;
2347
2336#ifdef CONFIG_DMAR_BROKEN_GFX_WA 2348#ifdef CONFIG_DMAR_BROKEN_GFX_WA
2337 else 2349 iommu_identity_mapping |= IDENTMAP_GFX;
2338 iommu_identity_mapping = 2;
2339#endif 2350#endif
2351
2352 check_tylersburg_isoch();
2353
2340 /* 2354 /*
2341 * If pass through is not set or not enabled, setup context entries for 2355 * If pass through is not set or not enabled, setup context entries for
2342 * identity mappings for rmrr, gfx, and isa and may fall back to static 2356 * identity mappings for rmrr, gfx, and isa and may fall back to static
@@ -3670,3 +3684,61 @@ static void __devinit quirk_iommu_rwbf(struct pci_dev *dev)
3670} 3684}
3671 3685
3672DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_rwbf); 3686DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_rwbf);
3687
3688/* On Tylersburg chipsets, some BIOSes have been known to enable the
3689 ISOCH DMAR unit for the Azalia sound device, but not give it any
3690 TLB entries, which causes it to deadlock. Check for that. We do
3691 this in a function called from init_dmars(), instead of in a PCI
3692 quirk, because we don't want to print the obnoxious "BIOS broken"
3693 message if VT-d is actually disabled.
3694*/
3695static void __init check_tylersburg_isoch(void)
3696{
3697 struct pci_dev *pdev;
3698 uint32_t vtisochctrl;
3699
3700 /* If there's no Azalia in the system anyway, forget it. */
3701 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x3a3e, NULL);
3702 if (!pdev)
3703 return;
3704 pci_dev_put(pdev);
3705
3706 /* System Management Registers. Might be hidden, in which case
3707 we can't do the sanity check. But that's OK, because the
3708 known-broken BIOSes _don't_ actually hide it, so far. */
3709 pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x342e, NULL);
3710 if (!pdev)
3711 return;
3712
3713 if (pci_read_config_dword(pdev, 0x188, &vtisochctrl)) {
3714 pci_dev_put(pdev);
3715 return;
3716 }
3717
3718 pci_dev_put(pdev);
3719
3720 /* If Azalia DMA is routed to the non-isoch DMAR unit, fine. */
3721 if (vtisochctrl & 1)
3722 return;
3723
3724 /* Drop all bits other than the number of TLB entries */
3725 vtisochctrl &= 0x1c;
3726
3727 /* If we have the recommended number of TLB entries (16), fine. */
3728 if (vtisochctrl == 0x10)
3729 return;
3730
3731 /* Zero TLB entries? You get to ride the short bus to school. */
3732 if (!vtisochctrl) {
3733 WARN(1, "Your BIOS is broken; DMA routed to ISOCH DMAR unit but no TLB space.\n"
3734 "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
3735 dmi_get_system_info(DMI_BIOS_VENDOR),
3736 dmi_get_system_info(DMI_BIOS_VERSION),
3737 dmi_get_system_info(DMI_PRODUCT_VERSION));
3738 iommu_identity_mapping |= IDENTMAP_AZALIA;
3739 return;
3740 }
3741
3742 printk(KERN_WARNING "DMAR: Recommended TLB entries for ISOCH unit is 16; your BIOS set %d\n",
3743 vtisochctrl);
3744}
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 6edecff0b419..4e4c295a049f 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -513,7 +513,11 @@ static int pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state)
513 else if (state == PCI_D2 || dev->current_state == PCI_D2) 513 else if (state == PCI_D2 || dev->current_state == PCI_D2)
514 udelay(PCI_PM_D2_DELAY); 514 udelay(PCI_PM_D2_DELAY);
515 515
516 dev->current_state = state; 516 pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr);
517 dev->current_state = (pmcsr & PCI_PM_CTRL_STATE_MASK);
518 if (dev->current_state != state && printk_ratelimit())
519 dev_info(&dev->dev, "Refused to change power state, "
520 "currently in D%d\n", dev->current_state);
517 521
518 /* According to section 5.4.1 of the "PCI BUS POWER MANAGEMENT 522 /* According to section 5.4.1 of the "PCI BUS POWER MANAGEMENT
519 * INTERFACE SPECIFICATION, REV. 1.2", a device transitioning 523 * INTERFACE SPECIFICATION, REV. 1.2", a device transitioning
@@ -2542,10 +2546,10 @@ int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type)
2542 2546
2543/** 2547/**
2544 * pci_set_vga_state - set VGA decode state on device and parents if requested 2548 * pci_set_vga_state - set VGA decode state on device and parents if requested
2545 * @dev the PCI device 2549 * @dev: the PCI device
2546 * @decode - true = enable decoding, false = disable decoding 2550 * @decode: true = enable decoding, false = disable decoding
2547 * @command_bits PCI_COMMAND_IO and/or PCI_COMMAND_MEMORY 2551 * @command_bits: PCI_COMMAND_IO and/or PCI_COMMAND_MEMORY
2548 * @change_bridge - traverse ancestors and change bridges 2552 * @change_bridge: traverse ancestors and change bridges
2549 */ 2553 */
2550int pci_set_vga_state(struct pci_dev *dev, bool decode, 2554int pci_set_vga_state(struct pci_dev *dev, bool decode,
2551 unsigned int command_bits, bool change_bridge) 2555 unsigned int command_bits, bool change_bridge)
@@ -2719,17 +2723,6 @@ int __attribute__ ((weak)) pci_ext_cfg_avail(struct pci_dev *dev)
2719 return 1; 2723 return 1;
2720} 2724}
2721 2725
2722static int __devinit pci_init(void)
2723{
2724 struct pci_dev *dev = NULL;
2725
2726 while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
2727 pci_fixup_device(pci_fixup_final, dev);
2728 }
2729
2730 return 0;
2731}
2732
2733static int __init pci_setup(char *str) 2726static int __init pci_setup(char *str)
2734{ 2727{
2735 while (str) { 2728 while (str) {
@@ -2767,8 +2760,6 @@ static int __init pci_setup(char *str)
2767} 2760}
2768early_param("pci", pci_setup); 2761early_param("pci", pci_setup);
2769 2762
2770device_initcall(pci_init);
2771
2772EXPORT_SYMBOL(pci_reenable_device); 2763EXPORT_SYMBOL(pci_reenable_device);
2773EXPORT_SYMBOL(pci_enable_device_io); 2764EXPORT_SYMBOL(pci_enable_device_io);
2774EXPORT_SYMBOL(pci_enable_device_mem); 2765EXPORT_SYMBOL(pci_enable_device_mem);
diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c
index 2ce8f9ccc66e..40c3cc5d1caf 100644
--- a/drivers/pci/pcie/aer/aerdrv.c
+++ b/drivers/pci/pcie/aer/aerdrv.c
@@ -17,6 +17,7 @@
17 17
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/pci.h> 19#include <linux/pci.h>
20#include <linux/sched.h>
20#include <linux/kernel.h> 21#include <linux/kernel.h>
21#include <linux/errno.h> 22#include <linux/errno.h>
22#include <linux/pm.h> 23#include <linux/pm.h>
@@ -52,7 +53,7 @@ static struct pci_error_handlers aer_error_handlers = {
52 53
53static struct pcie_port_service_driver aerdriver = { 54static struct pcie_port_service_driver aerdriver = {
54 .name = "aer", 55 .name = "aer",
55 .port_type = PCIE_ANY_PORT, 56 .port_type = PCIE_RC_PORT,
56 .service = PCIE_PORT_SERVICE_AER, 57 .service = PCIE_PORT_SERVICE_AER,
57 58
58 .probe = aer_probe, 59 .probe = aer_probe,
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
index 6df5c984a791..f635e476d632 100644
--- a/drivers/pci/pcie/portdrv_pci.c
+++ b/drivers/pci/pcie/portdrv_pci.c
@@ -30,7 +30,6 @@ MODULE_DESCRIPTION(DRIVER_DESC);
30MODULE_LICENSE("GPL"); 30MODULE_LICENSE("GPL");
31 31
32/* global data */ 32/* global data */
33static const char device_name[] = "pcieport-driver";
34 33
35static int pcie_portdrv_restore_config(struct pci_dev *dev) 34static int pcie_portdrv_restore_config(struct pci_dev *dev)
36{ 35{
@@ -262,7 +261,7 @@ static struct pci_error_handlers pcie_portdrv_err_handler = {
262}; 261};
263 262
264static struct pci_driver pcie_portdriver = { 263static struct pci_driver pcie_portdriver = {
265 .name = (char *)device_name, 264 .name = "pcieport",
266 .id_table = &port_pci_ids[0], 265 .id_table = &port_pci_ids[0],
267 266
268 .probe = pcie_portdrv_probe, 267 .probe = pcie_portdrv_probe,
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 6099facecd79..a790b1771f9f 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -670,6 +670,25 @@ static void __devinit quirk_vt8235_acpi(struct pci_dev *dev)
670} 670}
671DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, quirk_vt8235_acpi); 671DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, quirk_vt8235_acpi);
672 672
673/*
674 * TI XIO2000a PCIe-PCI Bridge erroneously reports it supports fast back-to-back:
675 * Disable fast back-to-back on the secondary bus segment
676 */
677static void __devinit quirk_xio2000a(struct pci_dev *dev)
678{
679 struct pci_dev *pdev;
680 u16 command;
681
682 dev_warn(&dev->dev, "TI XIO2000a quirk detected; "
683 "secondary bus fast back-to-back transfers disabled\n");
684 list_for_each_entry(pdev, &dev->subordinate->devices, bus_list) {
685 pci_read_config_word(pdev, PCI_COMMAND, &command);
686 if (command & PCI_COMMAND_FAST_BACK)
687 pci_write_config_word(pdev, PCI_COMMAND, command & ~PCI_COMMAND_FAST_BACK);
688 }
689}
690DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_XIO2000A,
691 quirk_xio2000a);
673 692
674#ifdef CONFIG_X86_IO_APIC 693#ifdef CONFIG_X86_IO_APIC
675 694
@@ -2572,6 +2591,19 @@ void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev)
2572 } 2591 }
2573 pci_do_fixups(dev, start, end); 2592 pci_do_fixups(dev, start, end);
2574} 2593}
2594
2595static int __init pci_apply_final_quirks(void)
2596{
2597 struct pci_dev *dev = NULL;
2598
2599 while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
2600 pci_fixup_device(pci_fixup_final, dev);
2601 }
2602
2603 return 0;
2604}
2605
2606fs_initcall_sync(pci_apply_final_quirks);
2575#else 2607#else
2576void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) {} 2608void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) {}
2577#endif 2609#endif
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index cb1a027eb552..0959430534b2 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -299,8 +299,17 @@ static struct resource *find_free_bus_resource(struct pci_bus *bus, unsigned lon
299 r = bus->resource[i]; 299 r = bus->resource[i];
300 if (r == &ioport_resource || r == &iomem_resource) 300 if (r == &ioport_resource || r == &iomem_resource)
301 continue; 301 continue;
302 if (r && (r->flags & type_mask) == type && !r->parent) 302 if (r && (r->flags & type_mask) == type) {
303 return r; 303 if (!r->parent)
304 return r;
305 /*
306 * if there is no child under that, we should release
307 * and use it. don't need to reset it, pbus_size_* will
308 * set it again
309 */
310 if (!r->child && !release_resource(r))
311 return r;
312 }
304 } 313 }
305 return NULL; 314 return NULL;
306} 315}
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
index 706f82d8111f..c54526b206b5 100644
--- a/drivers/pci/setup-res.c
+++ b/drivers/pci/setup-res.c
@@ -205,43 +205,6 @@ int pci_assign_resource(struct pci_dev *dev, int resno)
205 return ret; 205 return ret;
206} 206}
207 207
208#if 0
209int pci_assign_resource_fixed(struct pci_dev *dev, int resno)
210{
211 struct pci_bus *bus = dev->bus;
212 struct resource *res = dev->resource + resno;
213 unsigned int type_mask;
214 int i, ret = -EBUSY;
215
216 type_mask = IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_PREFETCH;
217
218 for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
219 struct resource *r = bus->resource[i];
220 if (!r)
221 continue;
222
223 /* type_mask must match */
224 if ((res->flags ^ r->flags) & type_mask)
225 continue;
226
227 ret = request_resource(r, res);
228
229 if (ret == 0)
230 break;
231 }
232
233 if (ret) {
234 dev_err(&dev->dev, "BAR %d: can't allocate %s resource %pR\n",
235 resno, res->flags & IORESOURCE_IO ? "I/O" : "mem", res);
236 } else if (resno < PCI_BRIDGE_RESOURCES) {
237 pci_update_resource(dev, resno);
238 }
239
240 return ret;
241}
242EXPORT_SYMBOL_GPL(pci_assign_resource_fixed);
243#endif
244
245/* Sort resources by alignment */ 208/* Sort resources by alignment */
246void pdev_sort_resources(struct pci_dev *dev, struct resource_list *head) 209void pdev_sort_resources(struct pci_dev *dev, struct resource_list *head)
247{ 210{
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index fbf965b31c14..17f38a781d47 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -192,6 +192,10 @@ config PCMCIA_AU1X00
192 tristate "Au1x00 pcmcia support" 192 tristate "Au1x00 pcmcia support"
193 depends on SOC_AU1X00 && PCMCIA 193 depends on SOC_AU1X00 && PCMCIA
194 194
195config PCMCIA_BCM63XX
196 tristate "bcm63xx pcmcia support"
197 depends on BCM63XX && PCMCIA
198
195config PCMCIA_SA1100 199config PCMCIA_SA1100
196 tristate "SA1100 support" 200 tristate "SA1100 support"
197 depends on ARM && ARCH_SA1100 && PCMCIA 201 depends on ARM && ARCH_SA1100 && PCMCIA
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
index 3247828aa203..a03a38acd77d 100644
--- a/drivers/pcmcia/Makefile
+++ b/drivers/pcmcia/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_PCMCIA_SA1111) += sa11xx_core.o sa1111_cs.o
27obj-$(CONFIG_M32R_PCC) += m32r_pcc.o 27obj-$(CONFIG_M32R_PCC) += m32r_pcc.o
28obj-$(CONFIG_M32R_CFC) += m32r_cfc.o 28obj-$(CONFIG_M32R_CFC) += m32r_cfc.o
29obj-$(CONFIG_PCMCIA_AU1X00) += au1x00_ss.o 29obj-$(CONFIG_PCMCIA_AU1X00) += au1x00_ss.o
30obj-$(CONFIG_PCMCIA_BCM63XX) += bcm63xx_pcmcia.o
30obj-$(CONFIG_PCMCIA_VRC4171) += vrc4171_card.o 31obj-$(CONFIG_PCMCIA_VRC4171) += vrc4171_card.o
31obj-$(CONFIG_PCMCIA_VRC4173) += vrc4173_cardu.o 32obj-$(CONFIG_PCMCIA_VRC4173) += vrc4173_cardu.o
32obj-$(CONFIG_OMAP_CF) += omap_cf.o 33obj-$(CONFIG_OMAP_CF) += omap_cf.o
diff --git a/drivers/pcmcia/bcm63xx_pcmcia.c b/drivers/pcmcia/bcm63xx_pcmcia.c
new file mode 100644
index 000000000000..bc88a3b19bb3
--- /dev/null
+++ b/drivers/pcmcia/bcm63xx_pcmcia.c
@@ -0,0 +1,536 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
7 */
8
9#include <linux/kernel.h>
10#include <linux/module.h>
11#include <linux/ioport.h>
12#include <linux/timer.h>
13#include <linux/platform_device.h>
14#include <linux/delay.h>
15#include <linux/pci.h>
16#include <linux/gpio.h>
17
18#include <bcm63xx_regs.h>
19#include <bcm63xx_io.h>
20#include "bcm63xx_pcmcia.h"
21
22#define PFX "bcm63xx_pcmcia: "
23
24#ifdef CONFIG_CARDBUS
25/* if cardbus is used, platform device needs reference to actual pci
26 * device */
27static struct pci_dev *bcm63xx_cb_dev;
28#endif
29
30/*
31 * read/write helper for pcmcia regs
32 */
33static inline u32 pcmcia_readl(struct bcm63xx_pcmcia_socket *skt, u32 off)
34{
35 return bcm_readl(skt->base + off);
36}
37
38static inline void pcmcia_writel(struct bcm63xx_pcmcia_socket *skt,
39 u32 val, u32 off)
40{
41 bcm_writel(val, skt->base + off);
42}
43
44/*
45 * This callback should (re-)initialise the socket, turn on status
46 * interrupts and PCMCIA bus, and wait for power to stabilise so that
47 * the card status signals report correctly.
48 *
49 * Hardware cannot do that.
50 */
51static int bcm63xx_pcmcia_sock_init(struct pcmcia_socket *sock)
52{
53 return 0;
54}
55
56/*
57 * This callback should remove power on the socket, disable IRQs from
58 * the card, turn off status interrupts, and disable the PCMCIA bus.
59 *
60 * Hardware cannot do that.
61 */
62static int bcm63xx_pcmcia_suspend(struct pcmcia_socket *sock)
63{
64 return 0;
65}
66
67/*
68 * Implements the set_socket() operation for the in-kernel PCMCIA
69 * service (formerly SS_SetSocket in Card Services). We more or
70 * less punt all of this work and let the kernel handle the details
71 * of power configuration, reset, &c. We also record the value of
72 * `state' in order to regurgitate it to the PCMCIA core later.
73 */
74static int bcm63xx_pcmcia_set_socket(struct pcmcia_socket *sock,
75 socket_state_t *state)
76{
77 struct bcm63xx_pcmcia_socket *skt;
78 unsigned long flags;
79 u32 val;
80
81 skt = sock->driver_data;
82
83 spin_lock_irqsave(&skt->lock, flags);
84
85 /* note: hardware cannot control socket power, so we will
86 * always report SS_POWERON */
87
88 /* apply socket reset */
89 val = pcmcia_readl(skt, PCMCIA_C1_REG);
90 if (state->flags & SS_RESET)
91 val |= PCMCIA_C1_RESET_MASK;
92 else
93 val &= ~PCMCIA_C1_RESET_MASK;
94
95 /* reverse reset logic for cardbus card */
96 if (skt->card_detected && (skt->card_type & CARD_CARDBUS))
97 val ^= PCMCIA_C1_RESET_MASK;
98
99 pcmcia_writel(skt, val, PCMCIA_C1_REG);
100
101 /* keep requested state for event reporting */
102 skt->requested_state = *state;
103
104 spin_unlock_irqrestore(&skt->lock, flags);
105
106 return 0;
107}
108
109/*
110 * identity cardtype from VS[12] input, CD[12] input while only VS2 is
111 * floating, and CD[12] input while only VS1 is floating
112 */
113enum {
114 IN_VS1 = (1 << 0),
115 IN_VS2 = (1 << 1),
116 IN_CD1_VS2H = (1 << 2),
117 IN_CD2_VS2H = (1 << 3),
118 IN_CD1_VS1H = (1 << 4),
119 IN_CD2_VS1H = (1 << 5),
120};
121
122static const u8 vscd_to_cardtype[] = {
123
124 /* VS1 float, VS2 float */
125 [IN_VS1 | IN_VS2] = (CARD_PCCARD | CARD_5V),
126
127 /* VS1 grounded, VS2 float */
128 [IN_VS2] = (CARD_PCCARD | CARD_5V | CARD_3V),
129
130 /* VS1 grounded, VS2 grounded */
131 [0] = (CARD_PCCARD | CARD_5V | CARD_3V | CARD_XV),
132
133 /* VS1 tied to CD1, VS2 float */
134 [IN_VS1 | IN_VS2 | IN_CD1_VS1H] = (CARD_CARDBUS | CARD_3V),
135
136 /* VS1 grounded, VS2 tied to CD2 */
137 [IN_VS2 | IN_CD2_VS2H] = (CARD_CARDBUS | CARD_3V | CARD_XV),
138
139 /* VS1 tied to CD2, VS2 grounded */
140 [IN_VS1 | IN_CD2_VS1H] = (CARD_CARDBUS | CARD_3V | CARD_XV | CARD_YV),
141
142 /* VS1 float, VS2 grounded */
143 [IN_VS1] = (CARD_PCCARD | CARD_XV),
144
145 /* VS1 float, VS2 tied to CD2 */
146 [IN_VS1 | IN_VS2 | IN_CD2_VS2H] = (CARD_CARDBUS | CARD_3V),
147
148 /* VS1 float, VS2 tied to CD1 */
149 [IN_VS1 | IN_VS2 | IN_CD1_VS2H] = (CARD_CARDBUS | CARD_XV | CARD_YV),
150
151 /* VS1 tied to CD2, VS2 float */
152 [IN_VS1 | IN_VS2 | IN_CD2_VS1H] = (CARD_CARDBUS | CARD_YV),
153
154 /* VS2 grounded, VS1 is tied to CD1, CD2 is grounded */
155 [IN_VS1 | IN_CD1_VS1H] = 0, /* ignore cardbay */
156};
157
158/*
159 * poll hardware to check card insertion status
160 */
161static unsigned int __get_socket_status(struct bcm63xx_pcmcia_socket *skt)
162{
163 unsigned int stat;
164 u32 val;
165
166 stat = 0;
167
168 /* check CD for card presence */
169 val = pcmcia_readl(skt, PCMCIA_C1_REG);
170
171 if (!(val & PCMCIA_C1_CD1_MASK) && !(val & PCMCIA_C1_CD2_MASK))
172 stat |= SS_DETECT;
173
174 /* if new insertion, detect cardtype */
175 if ((stat & SS_DETECT) && !skt->card_detected) {
176 unsigned int stat = 0;
177
178 /* float VS1, float VS2 */
179 val |= PCMCIA_C1_VS1OE_MASK;
180 val |= PCMCIA_C1_VS2OE_MASK;
181 pcmcia_writel(skt, val, PCMCIA_C1_REG);
182
183 /* wait for output to stabilize and read VS[12] */
184 udelay(10);
185 val = pcmcia_readl(skt, PCMCIA_C1_REG);
186 stat |= (val & PCMCIA_C1_VS1_MASK) ? IN_VS1 : 0;
187 stat |= (val & PCMCIA_C1_VS2_MASK) ? IN_VS2 : 0;
188
189 /* drive VS1 low, float VS2 */
190 val &= ~PCMCIA_C1_VS1OE_MASK;
191 val |= PCMCIA_C1_VS2OE_MASK;
192 pcmcia_writel(skt, val, PCMCIA_C1_REG);
193
194 /* wait for output to stabilize and read CD[12] */
195 udelay(10);
196 val = pcmcia_readl(skt, PCMCIA_C1_REG);
197 stat |= (val & PCMCIA_C1_CD1_MASK) ? IN_CD1_VS2H : 0;
198 stat |= (val & PCMCIA_C1_CD2_MASK) ? IN_CD2_VS2H : 0;
199
200 /* float VS1, drive VS2 low */
201 val |= PCMCIA_C1_VS1OE_MASK;
202 val &= ~PCMCIA_C1_VS2OE_MASK;
203 pcmcia_writel(skt, val, PCMCIA_C1_REG);
204
205 /* wait for output to stabilize and read CD[12] */
206 udelay(10);
207 val = pcmcia_readl(skt, PCMCIA_C1_REG);
208 stat |= (val & PCMCIA_C1_CD1_MASK) ? IN_CD1_VS1H : 0;
209 stat |= (val & PCMCIA_C1_CD2_MASK) ? IN_CD2_VS1H : 0;
210
211 /* guess cardtype from all this */
212 skt->card_type = vscd_to_cardtype[stat];
213 if (!skt->card_type)
214 dev_err(&skt->socket.dev, "unsupported card type\n");
215
216 /* drive both VS pin to 0 again */
217 val &= ~(PCMCIA_C1_VS1OE_MASK | PCMCIA_C1_VS2OE_MASK);
218
219 /* enable correct logic */
220 val &= ~(PCMCIA_C1_EN_PCMCIA_MASK | PCMCIA_C1_EN_CARDBUS_MASK);
221 if (skt->card_type & CARD_PCCARD)
222 val |= PCMCIA_C1_EN_PCMCIA_MASK;
223 else
224 val |= PCMCIA_C1_EN_CARDBUS_MASK;
225
226 pcmcia_writel(skt, val, PCMCIA_C1_REG);
227 }
228 skt->card_detected = (stat & SS_DETECT) ? 1 : 0;
229
230 /* report card type/voltage */
231 if (skt->card_type & CARD_CARDBUS)
232 stat |= SS_CARDBUS;
233 if (skt->card_type & CARD_3V)
234 stat |= SS_3VCARD;
235 if (skt->card_type & CARD_XV)
236 stat |= SS_XVCARD;
237 stat |= SS_POWERON;
238
239 if (gpio_get_value(skt->pd->ready_gpio))
240 stat |= SS_READY;
241
242 return stat;
243}
244
245/*
246 * core request to get current socket status
247 */
248static int bcm63xx_pcmcia_get_status(struct pcmcia_socket *sock,
249 unsigned int *status)
250{
251 struct bcm63xx_pcmcia_socket *skt;
252
253 skt = sock->driver_data;
254
255 spin_lock_bh(&skt->lock);
256 *status = __get_socket_status(skt);
257 spin_unlock_bh(&skt->lock);
258
259 return 0;
260}
261
262/*
263 * socket polling timer callback
264 */
265static void bcm63xx_pcmcia_poll(unsigned long data)
266{
267 struct bcm63xx_pcmcia_socket *skt;
268 unsigned int stat, events;
269
270 skt = (struct bcm63xx_pcmcia_socket *)data;
271
272 spin_lock_bh(&skt->lock);
273
274 stat = __get_socket_status(skt);
275
276 /* keep only changed bits, and mask with required one from the
277 * core */
278 events = (stat ^ skt->old_status) & skt->requested_state.csc_mask;
279 skt->old_status = stat;
280 spin_unlock_bh(&skt->lock);
281
282 if (events)
283 pcmcia_parse_events(&skt->socket, events);
284
285 mod_timer(&skt->timer,
286 jiffies + msecs_to_jiffies(BCM63XX_PCMCIA_POLL_RATE));
287}
288
289static int bcm63xx_pcmcia_set_io_map(struct pcmcia_socket *sock,
290 struct pccard_io_map *map)
291{
292 /* this doesn't seem to be called by pcmcia layer if static
293 * mapping is used */
294 return 0;
295}
296
297static int bcm63xx_pcmcia_set_mem_map(struct pcmcia_socket *sock,
298 struct pccard_mem_map *map)
299{
300 struct bcm63xx_pcmcia_socket *skt;
301 struct resource *res;
302
303 skt = sock->driver_data;
304 if (map->flags & MAP_ATTRIB)
305 res = skt->attr_res;
306 else
307 res = skt->common_res;
308
309 map->static_start = res->start + map->card_start;
310 return 0;
311}
312
313static struct pccard_operations bcm63xx_pcmcia_operations = {
314 .init = bcm63xx_pcmcia_sock_init,
315 .suspend = bcm63xx_pcmcia_suspend,
316 .get_status = bcm63xx_pcmcia_get_status,
317 .set_socket = bcm63xx_pcmcia_set_socket,
318 .set_io_map = bcm63xx_pcmcia_set_io_map,
319 .set_mem_map = bcm63xx_pcmcia_set_mem_map,
320};
321
322/*
323 * register pcmcia socket to core
324 */
325static int __devinit bcm63xx_drv_pcmcia_probe(struct platform_device *pdev)
326{
327 struct bcm63xx_pcmcia_socket *skt;
328 struct pcmcia_socket *sock;
329 struct resource *res, *irq_res;
330 unsigned int regmem_size = 0, iomem_size = 0;
331 u32 val;
332 int ret;
333
334 skt = kzalloc(sizeof(*skt), GFP_KERNEL);
335 if (!skt)
336 return -ENOMEM;
337 spin_lock_init(&skt->lock);
338 sock = &skt->socket;
339 sock->driver_data = skt;
340
341 /* make sure we have all resources we need */
342 skt->common_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
343 skt->attr_res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
344 irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
345 skt->pd = pdev->dev.platform_data;
346 if (!skt->common_res || !skt->attr_res || !irq_res || !skt->pd) {
347 ret = -EINVAL;
348 goto err;
349 }
350
351 /* remap pcmcia registers */
352 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
353 regmem_size = resource_size(res);
354 if (!request_mem_region(res->start, regmem_size, "bcm63xx_pcmcia")) {
355 ret = -EINVAL;
356 goto err;
357 }
358 skt->reg_res = res;
359
360 skt->base = ioremap(res->start, regmem_size);
361 if (!skt->base) {
362 ret = -ENOMEM;
363 goto err;
364 }
365
366 /* remap io registers */
367 res = platform_get_resource(pdev, IORESOURCE_MEM, 3);
368 iomem_size = resource_size(res);
369 skt->io_base = ioremap(res->start, iomem_size);
370 if (!skt->io_base) {
371 ret = -ENOMEM;
372 goto err;
373 }
374
375 /* resources are static */
376 sock->resource_ops = &pccard_static_ops;
377 sock->ops = &bcm63xx_pcmcia_operations;
378 sock->owner = THIS_MODULE;
379 sock->dev.parent = &pdev->dev;
380 sock->features = SS_CAP_STATIC_MAP | SS_CAP_PCCARD;
381 sock->io_offset = (unsigned long)skt->io_base;
382 sock->pci_irq = irq_res->start;
383
384#ifdef CONFIG_CARDBUS
385 sock->cb_dev = bcm63xx_cb_dev;
386 if (bcm63xx_cb_dev)
387 sock->features |= SS_CAP_CARDBUS;
388#endif
389
390 /* assume common & attribute memory have the same size */
391 sock->map_size = resource_size(skt->common_res);
392
393 /* initialize polling timer */
394 setup_timer(&skt->timer, bcm63xx_pcmcia_poll, (unsigned long)skt);
395
396 /* initialize pcmcia control register, drive VS[12] to 0,
397 * leave CB IDSEL to the old value since it is set by the PCI
398 * layer */
399 val = pcmcia_readl(skt, PCMCIA_C1_REG);
400 val &= PCMCIA_C1_CBIDSEL_MASK;
401 val |= PCMCIA_C1_EN_PCMCIA_GPIO_MASK;
402 pcmcia_writel(skt, val, PCMCIA_C1_REG);
403
404 /*
405 * Hardware has only one set of timings registers, not one for
406 * each memory access type, so we configure them for the
407 * slowest one: attribute memory.
408 */
409 val = PCMCIA_C2_DATA16_MASK;
410 val |= 10 << PCMCIA_C2_RWCOUNT_SHIFT;
411 val |= 6 << PCMCIA_C2_INACTIVE_SHIFT;
412 val |= 3 << PCMCIA_C2_SETUP_SHIFT;
413 val |= 3 << PCMCIA_C2_HOLD_SHIFT;
414 pcmcia_writel(skt, val, PCMCIA_C2_REG);
415
416 ret = pcmcia_register_socket(sock);
417 if (ret)
418 goto err;
419
420 /* start polling socket */
421 mod_timer(&skt->timer,
422 jiffies + msecs_to_jiffies(BCM63XX_PCMCIA_POLL_RATE));
423
424 platform_set_drvdata(pdev, skt);
425 return 0;
426
427err:
428 if (skt->io_base)
429 iounmap(skt->io_base);
430 if (skt->base)
431 iounmap(skt->base);
432 if (skt->reg_res)
433 release_mem_region(skt->reg_res->start, regmem_size);
434 kfree(skt);
435 return ret;
436}
437
438static int __devexit bcm63xx_drv_pcmcia_remove(struct platform_device *pdev)
439{
440 struct bcm63xx_pcmcia_socket *skt;
441 struct resource *res;
442
443 skt = platform_get_drvdata(pdev);
444 del_timer_sync(&skt->timer);
445 iounmap(skt->base);
446 iounmap(skt->io_base);
447 res = skt->reg_res;
448 release_mem_region(res->start, resource_size(res));
449 kfree(skt);
450 return 0;
451}
452
453struct platform_driver bcm63xx_pcmcia_driver = {
454 .probe = bcm63xx_drv_pcmcia_probe,
455 .remove = __devexit_p(bcm63xx_drv_pcmcia_remove),
456 .driver = {
457 .name = "bcm63xx_pcmcia",
458 .owner = THIS_MODULE,
459 },
460};
461
462#ifdef CONFIG_CARDBUS
463static int __devinit bcm63xx_cb_probe(struct pci_dev *dev,
464 const struct pci_device_id *id)
465{
466 /* keep pci device */
467 bcm63xx_cb_dev = dev;
468 return platform_driver_register(&bcm63xx_pcmcia_driver);
469}
470
471static void __devexit bcm63xx_cb_exit(struct pci_dev *dev)
472{
473 platform_driver_unregister(&bcm63xx_pcmcia_driver);
474 bcm63xx_cb_dev = NULL;
475}
476
477static struct pci_device_id bcm63xx_cb_table[] = {
478 {
479 .vendor = PCI_VENDOR_ID_BROADCOM,
480 .device = BCM6348_CPU_ID,
481 .subvendor = PCI_VENDOR_ID_BROADCOM,
482 .subdevice = PCI_ANY_ID,
483 .class = PCI_CLASS_BRIDGE_CARDBUS << 8,
484 .class_mask = ~0,
485 },
486
487 {
488 .vendor = PCI_VENDOR_ID_BROADCOM,
489 .device = BCM6358_CPU_ID,
490 .subvendor = PCI_VENDOR_ID_BROADCOM,
491 .subdevice = PCI_ANY_ID,
492 .class = PCI_CLASS_BRIDGE_CARDBUS << 8,
493 .class_mask = ~0,
494 },
495
496 { },
497};
498
499MODULE_DEVICE_TABLE(pci, bcm63xx_cb_table);
500
501static struct pci_driver bcm63xx_cardbus_driver = {
502 .name = "bcm63xx_cardbus",
503 .id_table = bcm63xx_cb_table,
504 .probe = bcm63xx_cb_probe,
505 .remove = __devexit_p(bcm63xx_cb_exit),
506};
507#endif
508
509/*
510 * if cardbus support is enabled, register our platform device after
511 * our fake cardbus bridge has been registered
512 */
513static int __init bcm63xx_pcmcia_init(void)
514{
515#ifdef CONFIG_CARDBUS
516 return pci_register_driver(&bcm63xx_cardbus_driver);
517#else
518 return platform_driver_register(&bcm63xx_pcmcia_driver);
519#endif
520}
521
522static void __exit bcm63xx_pcmcia_exit(void)
523{
524#ifdef CONFIG_CARDBUS
525 return pci_unregister_driver(&bcm63xx_cardbus_driver);
526#else
527 platform_driver_unregister(&bcm63xx_pcmcia_driver);
528#endif
529}
530
531module_init(bcm63xx_pcmcia_init);
532module_exit(bcm63xx_pcmcia_exit);
533
534MODULE_LICENSE("GPL");
535MODULE_AUTHOR("Maxime Bizon <mbizon@freebox.fr>");
536MODULE_DESCRIPTION("Linux PCMCIA Card Services: bcm63xx Socket Controller");
diff --git a/drivers/pcmcia/bcm63xx_pcmcia.h b/drivers/pcmcia/bcm63xx_pcmcia.h
new file mode 100644
index 000000000000..ed957399d863
--- /dev/null
+++ b/drivers/pcmcia/bcm63xx_pcmcia.h
@@ -0,0 +1,60 @@
1#ifndef BCM63XX_PCMCIA_H_
2#define BCM63XX_PCMCIA_H_
3
4#include <linux/types.h>
5#include <linux/timer.h>
6#include <pcmcia/ss.h>
7#include <bcm63xx_dev_pcmcia.h>
8
9/* socket polling rate in ms */
10#define BCM63XX_PCMCIA_POLL_RATE 500
11
12enum {
13 CARD_CARDBUS = (1 << 0),
14 CARD_PCCARD = (1 << 1),
15 CARD_5V = (1 << 2),
16 CARD_3V = (1 << 3),
17 CARD_XV = (1 << 4),
18 CARD_YV = (1 << 5),
19};
20
21struct bcm63xx_pcmcia_socket {
22 struct pcmcia_socket socket;
23
24 /* platform specific data */
25 struct bcm63xx_pcmcia_platform_data *pd;
26
27 /* all regs access are protected by this spinlock */
28 spinlock_t lock;
29
30 /* pcmcia registers resource */
31 struct resource *reg_res;
32
33 /* base remapped address of registers */
34 void __iomem *base;
35
36 /* whether a card is detected at the moment */
37 int card_detected;
38
39 /* type of detected card (mask of above enum) */
40 u8 card_type;
41
42 /* keep last socket status to implement event reporting */
43 unsigned int old_status;
44
45 /* backup of requested socket state */
46 socket_state_t requested_state;
47
48 /* timer used for socket status polling */
49 struct timer_list timer;
50
51 /* attribute/common memory resources */
52 struct resource *attr_res;
53 struct resource *common_res;
54 struct resource *io_res;
55
56 /* base address of io memory */
57 void __iomem *io_base;
58};
59
60#endif /* BCM63XX_PCMCIA_H_ */
diff --git a/drivers/pcmcia/sa1100_assabet.c b/drivers/pcmcia/sa1100_assabet.c
index f424146a2bc9..ac8aa09ba0da 100644
--- a/drivers/pcmcia/sa1100_assabet.c
+++ b/drivers/pcmcia/sa1100_assabet.c
@@ -130,7 +130,7 @@ static struct pcmcia_low_level assabet_pcmcia_ops = {
130 .socket_suspend = assabet_pcmcia_socket_suspend, 130 .socket_suspend = assabet_pcmcia_socket_suspend,
131}; 131};
132 132
133int __init pcmcia_assabet_init(struct device *dev) 133int pcmcia_assabet_init(struct device *dev)
134{ 134{
135 int ret = -ENODEV; 135 int ret = -ENODEV;
136 136
diff --git a/drivers/pcmcia/sa1100_neponset.c b/drivers/pcmcia/sa1100_neponset.c
index 4c41e86ccff9..0c76d337815b 100644
--- a/drivers/pcmcia/sa1100_neponset.c
+++ b/drivers/pcmcia/sa1100_neponset.c
@@ -123,7 +123,7 @@ static struct pcmcia_low_level neponset_pcmcia_ops = {
123 .socket_suspend = sa1111_pcmcia_socket_suspend, 123 .socket_suspend = sa1111_pcmcia_socket_suspend,
124}; 124};
125 125
126int __init pcmcia_neponset_init(struct sa1111_dev *sadev) 126int pcmcia_neponset_init(struct sa1111_dev *sadev)
127{ 127{
128 int ret = -ENODEV; 128 int ret = -ENODEV;
129 129
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c
index 749e2102b2be..d379e74a05d0 100644
--- a/drivers/platform/x86/eeepc-laptop.c
+++ b/drivers/platform/x86/eeepc-laptop.c
@@ -150,6 +150,8 @@ struct eeepc_hotk {
150/* The actual device the driver binds to */ 150/* The actual device the driver binds to */
151static struct eeepc_hotk *ehotk; 151static struct eeepc_hotk *ehotk;
152 152
153static void eeepc_rfkill_hotplug(bool real);
154
153/* Platform device/driver */ 155/* Platform device/driver */
154static int eeepc_hotk_thaw(struct device *device); 156static int eeepc_hotk_thaw(struct device *device);
155static int eeepc_hotk_restore(struct device *device); 157static int eeepc_hotk_restore(struct device *device);
@@ -343,14 +345,23 @@ static bool eeepc_wlan_rfkill_blocked(void)
343static int eeepc_rfkill_set(void *data, bool blocked) 345static int eeepc_rfkill_set(void *data, bool blocked)
344{ 346{
345 unsigned long asl = (unsigned long)data; 347 unsigned long asl = (unsigned long)data;
346 return set_acpi(asl, !blocked); 348 int ret;
349
350 if (asl != CM_ASL_WLAN)
351 return set_acpi(asl, !blocked);
352
353 /* hack to avoid panic with rt2860sta */
354 if (blocked)
355 eeepc_rfkill_hotplug(false);
356 ret = set_acpi(asl, !blocked);
357 return ret;
347} 358}
348 359
349static const struct rfkill_ops eeepc_rfkill_ops = { 360static const struct rfkill_ops eeepc_rfkill_ops = {
350 .set_block = eeepc_rfkill_set, 361 .set_block = eeepc_rfkill_set,
351}; 362};
352 363
353static void __init eeepc_enable_camera(void) 364static void __devinit eeepc_enable_camera(void)
354{ 365{
355 /* 366 /*
356 * If the following call to set_acpi() fails, it's because there's no 367 * If the following call to set_acpi() fails, it's because there's no
@@ -643,13 +654,13 @@ static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot,
643 return 0; 654 return 0;
644} 655}
645 656
646static void eeepc_rfkill_hotplug(void) 657static void eeepc_rfkill_hotplug(bool real)
647{ 658{
648 struct pci_dev *dev; 659 struct pci_dev *dev;
649 struct pci_bus *bus; 660 struct pci_bus *bus;
650 bool blocked = eeepc_wlan_rfkill_blocked(); 661 bool blocked = real ? eeepc_wlan_rfkill_blocked() : true;
651 662
652 if (ehotk->wlan_rfkill) 663 if (real && ehotk->wlan_rfkill)
653 rfkill_set_sw_state(ehotk->wlan_rfkill, blocked); 664 rfkill_set_sw_state(ehotk->wlan_rfkill, blocked);
654 665
655 mutex_lock(&ehotk->hotplug_lock); 666 mutex_lock(&ehotk->hotplug_lock);
@@ -692,7 +703,7 @@ static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
692 if (event != ACPI_NOTIFY_BUS_CHECK) 703 if (event != ACPI_NOTIFY_BUS_CHECK)
693 return; 704 return;
694 705
695 eeepc_rfkill_hotplug(); 706 eeepc_rfkill_hotplug(true);
696} 707}
697 708
698static void eeepc_hotk_notify(struct acpi_device *device, u32 event) 709static void eeepc_hotk_notify(struct acpi_device *device, u32 event)
@@ -850,7 +861,7 @@ static int eeepc_hotk_restore(struct device *device)
850{ 861{
851 /* Refresh both wlan rfkill state and pci hotplug */ 862 /* Refresh both wlan rfkill state and pci hotplug */
852 if (ehotk->wlan_rfkill) 863 if (ehotk->wlan_rfkill)
853 eeepc_rfkill_hotplug(); 864 eeepc_rfkill_hotplug(true);
854 865
855 if (ehotk->bluetooth_rfkill) 866 if (ehotk->bluetooth_rfkill)
856 rfkill_set_sw_state(ehotk->bluetooth_rfkill, 867 rfkill_set_sw_state(ehotk->bluetooth_rfkill,
@@ -993,7 +1004,7 @@ static void eeepc_rfkill_exit(void)
993 * Refresh pci hotplug in case the rfkill state was changed after 1004 * Refresh pci hotplug in case the rfkill state was changed after
994 * eeepc_unregister_rfkill_notifier() 1005 * eeepc_unregister_rfkill_notifier()
995 */ 1006 */
996 eeepc_rfkill_hotplug(); 1007 eeepc_rfkill_hotplug(true);
997 if (ehotk->hotplug_slot) 1008 if (ehotk->hotplug_slot)
998 pci_hp_deregister(ehotk->hotplug_slot); 1009 pci_hp_deregister(ehotk->hotplug_slot);
999 1010
@@ -1109,7 +1120,7 @@ static int eeepc_rfkill_init(struct device *dev)
1109 * Refresh pci hotplug in case the rfkill state was changed during 1120 * Refresh pci hotplug in case the rfkill state was changed during
1110 * setup. 1121 * setup.
1111 */ 1122 */
1112 eeepc_rfkill_hotplug(); 1123 eeepc_rfkill_hotplug(true);
1113 1124
1114exit: 1125exit:
1115 if (result && result != -ENODEV) 1126 if (result && result != -ENODEV)
@@ -1189,7 +1200,7 @@ static int eeepc_input_init(struct device *dev)
1189 return 0; 1200 return 0;
1190} 1201}
1191 1202
1192static int eeepc_hotk_add(struct acpi_device *device) 1203static int __devinit eeepc_hotk_add(struct acpi_device *device)
1193{ 1204{
1194 struct device *dev; 1205 struct device *dev;
1195 int result; 1206 int result;
diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c
index f35aee5c2149..bcd4ba8be7db 100644
--- a/drivers/platform/x86/fujitsu-laptop.c
+++ b/drivers/platform/x86/fujitsu-laptop.c
@@ -944,7 +944,7 @@ static int acpi_fujitsu_hotkey_remove(struct acpi_device *device, int type)
944 struct fujitsu_hotkey_t *fujitsu_hotkey = acpi_driver_data(device); 944 struct fujitsu_hotkey_t *fujitsu_hotkey = acpi_driver_data(device);
945 struct input_dev *input = fujitsu_hotkey->input; 945 struct input_dev *input = fujitsu_hotkey->input;
946 946
947#ifdef CONFIG_LEDS_CLASS 947#if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE)
948 if (fujitsu_hotkey->logolamp_registered) 948 if (fujitsu_hotkey->logolamp_registered)
949 led_classdev_unregister(&logolamp_led); 949 led_classdev_unregister(&logolamp_led);
950 950
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c
index afdbdaaf80cb..a2a742c8ff7e 100644
--- a/drivers/platform/x86/sony-laptop.c
+++ b/drivers/platform/x86/sony-laptop.c
@@ -1211,15 +1211,6 @@ static int sony_nc_add(struct acpi_device *device)
1211 } 1211 }
1212 } 1212 }
1213 1213
1214 /* try to _INI the device if such method exists (ACPI spec 3.0-6.5.1
1215 * should be respected as we already checked for the device presence above */
1216 if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, METHOD_NAME__INI, &handle))) {
1217 dprintk("Invoking _INI\n");
1218 if (ACPI_FAILURE(acpi_evaluate_object(sony_nc_acpi_handle, METHOD_NAME__INI,
1219 NULL, NULL)))
1220 dprintk("_INI Method failed\n");
1221 }
1222
1223 if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "ECON", 1214 if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "ECON",
1224 &handle))) { 1215 &handle))) {
1225 if (acpi_callsetfunc(sony_nc_acpi_handle, "ECON", 1, NULL)) 1216 if (acpi_callsetfunc(sony_nc_acpi_handle, "ECON", 1, NULL))
@@ -1399,27 +1390,20 @@ struct sonypi_eventtypes {
1399 struct sonypi_event *events; 1390 struct sonypi_event *events;
1400}; 1391};
1401 1392
1402struct device_ctrl { 1393struct sony_pic_dev {
1394 struct acpi_device *acpi_dev;
1395 struct sony_pic_irq *cur_irq;
1396 struct sony_pic_ioport *cur_ioport;
1397 struct list_head interrupts;
1398 struct list_head ioports;
1399 struct mutex lock;
1400 struct sonypi_eventtypes *event_types;
1401 int (*handle_irq)(const u8, const u8);
1403 int model; 1402 int model;
1404 int (*handle_irq)(const u8, const u8);
1405 u16 evport_offset; 1403 u16 evport_offset;
1406 u8 has_camera; 1404 u8 camera_power;
1407 u8 has_bluetooth; 1405 u8 bluetooth_power;
1408 u8 has_wwan; 1406 u8 wwan_power;
1409 struct sonypi_eventtypes *event_types;
1410};
1411
1412struct sony_pic_dev {
1413 struct device_ctrl *control;
1414 struct acpi_device *acpi_dev;
1415 struct sony_pic_irq *cur_irq;
1416 struct sony_pic_ioport *cur_ioport;
1417 struct list_head interrupts;
1418 struct list_head ioports;
1419 struct mutex lock;
1420 u8 camera_power;
1421 u8 bluetooth_power;
1422 u8 wwan_power;
1423}; 1407};
1424 1408
1425static struct sony_pic_dev spic_dev = { 1409static struct sony_pic_dev spic_dev = {
@@ -1427,6 +1411,8 @@ static struct sony_pic_dev spic_dev = {
1427 .ioports = LIST_HEAD_INIT(spic_dev.ioports), 1411 .ioports = LIST_HEAD_INIT(spic_dev.ioports),
1428}; 1412};
1429 1413
1414static int spic_drv_registered;
1415
1430/* Event masks */ 1416/* Event masks */
1431#define SONYPI_JOGGER_MASK 0x00000001 1417#define SONYPI_JOGGER_MASK 0x00000001
1432#define SONYPI_CAPTURE_MASK 0x00000002 1418#define SONYPI_CAPTURE_MASK 0x00000002
@@ -1724,27 +1710,6 @@ static int type3_handle_irq(const u8 data_mask, const u8 ev)
1724 return 1; 1710 return 1;
1725} 1711}
1726 1712
1727static struct device_ctrl spic_types[] = {
1728 {
1729 .model = SONYPI_DEVICE_TYPE1,
1730 .handle_irq = NULL,
1731 .evport_offset = SONYPI_TYPE1_OFFSET,
1732 .event_types = type1_events,
1733 },
1734 {
1735 .model = SONYPI_DEVICE_TYPE2,
1736 .handle_irq = NULL,
1737 .evport_offset = SONYPI_TYPE2_OFFSET,
1738 .event_types = type2_events,
1739 },
1740 {
1741 .model = SONYPI_DEVICE_TYPE3,
1742 .handle_irq = type3_handle_irq,
1743 .evport_offset = SONYPI_TYPE3_OFFSET,
1744 .event_types = type3_events,
1745 },
1746};
1747
1748static void sony_pic_detect_device_type(struct sony_pic_dev *dev) 1713static void sony_pic_detect_device_type(struct sony_pic_dev *dev)
1749{ 1714{
1750 struct pci_dev *pcidev; 1715 struct pci_dev *pcidev;
@@ -1752,48 +1717,63 @@ static void sony_pic_detect_device_type(struct sony_pic_dev *dev)
1752 pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, 1717 pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
1753 PCI_DEVICE_ID_INTEL_82371AB_3, NULL); 1718 PCI_DEVICE_ID_INTEL_82371AB_3, NULL);
1754 if (pcidev) { 1719 if (pcidev) {
1755 dev->control = &spic_types[0]; 1720 dev->model = SONYPI_DEVICE_TYPE1;
1721 dev->evport_offset = SONYPI_TYPE1_OFFSET;
1722 dev->event_types = type1_events;
1756 goto out; 1723 goto out;
1757 } 1724 }
1758 1725
1759 pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, 1726 pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
1760 PCI_DEVICE_ID_INTEL_ICH6_1, NULL); 1727 PCI_DEVICE_ID_INTEL_ICH6_1, NULL);
1761 if (pcidev) { 1728 if (pcidev) {
1762 dev->control = &spic_types[2]; 1729 dev->model = SONYPI_DEVICE_TYPE2;
1730 dev->evport_offset = SONYPI_TYPE2_OFFSET;
1731 dev->event_types = type2_events;
1763 goto out; 1732 goto out;
1764 } 1733 }
1765 1734
1766 pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, 1735 pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
1767 PCI_DEVICE_ID_INTEL_ICH7_1, NULL); 1736 PCI_DEVICE_ID_INTEL_ICH7_1, NULL);
1768 if (pcidev) { 1737 if (pcidev) {
1769 dev->control = &spic_types[2]; 1738 dev->model = SONYPI_DEVICE_TYPE3;
1739 dev->handle_irq = type3_handle_irq;
1740 dev->evport_offset = SONYPI_TYPE3_OFFSET;
1741 dev->event_types = type3_events;
1770 goto out; 1742 goto out;
1771 } 1743 }
1772 1744
1773 pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, 1745 pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
1774 PCI_DEVICE_ID_INTEL_ICH8_4, NULL); 1746 PCI_DEVICE_ID_INTEL_ICH8_4, NULL);
1775 if (pcidev) { 1747 if (pcidev) {
1776 dev->control = &spic_types[2]; 1748 dev->model = SONYPI_DEVICE_TYPE3;
1749 dev->handle_irq = type3_handle_irq;
1750 dev->evport_offset = SONYPI_TYPE3_OFFSET;
1751 dev->event_types = type3_events;
1777 goto out; 1752 goto out;
1778 } 1753 }
1779 1754
1780 pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, 1755 pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
1781 PCI_DEVICE_ID_INTEL_ICH9_1, NULL); 1756 PCI_DEVICE_ID_INTEL_ICH9_1, NULL);
1782 if (pcidev) { 1757 if (pcidev) {
1783 dev->control = &spic_types[2]; 1758 dev->model = SONYPI_DEVICE_TYPE3;
1759 dev->handle_irq = type3_handle_irq;
1760 dev->evport_offset = SONYPI_TYPE3_OFFSET;
1761 dev->event_types = type3_events;
1784 goto out; 1762 goto out;
1785 } 1763 }
1786 1764
1787 /* default */ 1765 /* default */
1788 dev->control = &spic_types[1]; 1766 dev->model = SONYPI_DEVICE_TYPE2;
1767 dev->evport_offset = SONYPI_TYPE2_OFFSET;
1768 dev->event_types = type2_events;
1789 1769
1790out: 1770out:
1791 if (pcidev) 1771 if (pcidev)
1792 pci_dev_put(pcidev); 1772 pci_dev_put(pcidev);
1793 1773
1794 printk(KERN_INFO DRV_PFX "detected Type%d model\n", 1774 printk(KERN_INFO DRV_PFX "detected Type%d model\n",
1795 dev->control->model == SONYPI_DEVICE_TYPE1 ? 1 : 1775 dev->model == SONYPI_DEVICE_TYPE1 ? 1 :
1796 dev->control->model == SONYPI_DEVICE_TYPE2 ? 2 : 3); 1776 dev->model == SONYPI_DEVICE_TYPE2 ? 2 : 3);
1797} 1777}
1798 1778
1799/* camera tests and poweron/poweroff */ 1779/* camera tests and poweron/poweroff */
@@ -2566,7 +2546,7 @@ static int sony_pic_enable(struct acpi_device *device,
2566 buffer.pointer = resource; 2546 buffer.pointer = resource;
2567 2547
2568 /* setup Type 1 resources */ 2548 /* setup Type 1 resources */
2569 if (spic_dev.control->model == SONYPI_DEVICE_TYPE1) { 2549 if (spic_dev.model == SONYPI_DEVICE_TYPE1) {
2570 2550
2571 /* setup io resources */ 2551 /* setup io resources */
2572 resource->res1.type = ACPI_RESOURCE_TYPE_IO; 2552 resource->res1.type = ACPI_RESOURCE_TYPE_IO;
@@ -2649,29 +2629,28 @@ static irqreturn_t sony_pic_irq(int irq, void *dev_id)
2649 data_mask = inb_p(dev->cur_ioport->io2.minimum); 2629 data_mask = inb_p(dev->cur_ioport->io2.minimum);
2650 else 2630 else
2651 data_mask = inb_p(dev->cur_ioport->io1.minimum + 2631 data_mask = inb_p(dev->cur_ioport->io1.minimum +
2652 dev->control->evport_offset); 2632 dev->evport_offset);
2653 2633
2654 dprintk("event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n", 2634 dprintk("event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n",
2655 ev, data_mask, dev->cur_ioport->io1.minimum, 2635 ev, data_mask, dev->cur_ioport->io1.minimum,
2656 dev->control->evport_offset); 2636 dev->evport_offset);
2657 2637
2658 if (ev == 0x00 || ev == 0xff) 2638 if (ev == 0x00 || ev == 0xff)
2659 return IRQ_HANDLED; 2639 return IRQ_HANDLED;
2660 2640
2661 for (i = 0; dev->control->event_types[i].mask; i++) { 2641 for (i = 0; dev->event_types[i].mask; i++) {
2662 2642
2663 if ((data_mask & dev->control->event_types[i].data) != 2643 if ((data_mask & dev->event_types[i].data) !=
2664 dev->control->event_types[i].data) 2644 dev->event_types[i].data)
2665 continue; 2645 continue;
2666 2646
2667 if (!(mask & dev->control->event_types[i].mask)) 2647 if (!(mask & dev->event_types[i].mask))
2668 continue; 2648 continue;
2669 2649
2670 for (j = 0; dev->control->event_types[i].events[j].event; j++) { 2650 for (j = 0; dev->event_types[i].events[j].event; j++) {
2671 if (ev == dev->control->event_types[i].events[j].data) { 2651 if (ev == dev->event_types[i].events[j].data) {
2672 device_event = 2652 device_event =
2673 dev->control-> 2653 dev->event_types[i].events[j].event;
2674 event_types[i].events[j].event;
2675 goto found; 2654 goto found;
2676 } 2655 }
2677 } 2656 }
@@ -2679,13 +2658,12 @@ static irqreturn_t sony_pic_irq(int irq, void *dev_id)
2679 /* Still not able to decode the event try to pass 2658 /* Still not able to decode the event try to pass
2680 * it over to the minidriver 2659 * it over to the minidriver
2681 */ 2660 */
2682 if (dev->control->handle_irq && 2661 if (dev->handle_irq && dev->handle_irq(data_mask, ev) == 0)
2683 dev->control->handle_irq(data_mask, ev) == 0)
2684 return IRQ_HANDLED; 2662 return IRQ_HANDLED;
2685 2663
2686 dprintk("unknown event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n", 2664 dprintk("unknown event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n",
2687 ev, data_mask, dev->cur_ioport->io1.minimum, 2665 ev, data_mask, dev->cur_ioport->io1.minimum,
2688 dev->control->evport_offset); 2666 dev->evport_offset);
2689 return IRQ_HANDLED; 2667 return IRQ_HANDLED;
2690 2668
2691found: 2669found:
@@ -2816,7 +2794,7 @@ static int sony_pic_add(struct acpi_device *device)
2816 /* request IRQ */ 2794 /* request IRQ */
2817 list_for_each_entry_reverse(irq, &spic_dev.interrupts, list) { 2795 list_for_each_entry_reverse(irq, &spic_dev.interrupts, list) {
2818 if (!request_irq(irq->irq.interrupts[0], sony_pic_irq, 2796 if (!request_irq(irq->irq.interrupts[0], sony_pic_irq,
2819 IRQF_SHARED, "sony-laptop", &spic_dev)) { 2797 IRQF_DISABLED, "sony-laptop", &spic_dev)) {
2820 dprintk("IRQ: %d - triggering: %d - " 2798 dprintk("IRQ: %d - triggering: %d - "
2821 "polarity: %d - shr: %d\n", 2799 "polarity: %d - shr: %d\n",
2822 irq->irq.interrupts[0], 2800 irq->irq.interrupts[0],
@@ -2949,6 +2927,7 @@ static int __init sony_laptop_init(void)
2949 "Unable to register SPIC driver."); 2927 "Unable to register SPIC driver.");
2950 goto out; 2928 goto out;
2951 } 2929 }
2930 spic_drv_registered = 1;
2952 } 2931 }
2953 2932
2954 result = acpi_bus_register_driver(&sony_nc_driver); 2933 result = acpi_bus_register_driver(&sony_nc_driver);
@@ -2960,7 +2939,7 @@ static int __init sony_laptop_init(void)
2960 return 0; 2939 return 0;
2961 2940
2962out_unregister_pic: 2941out_unregister_pic:
2963 if (!no_spic) 2942 if (spic_drv_registered)
2964 acpi_bus_unregister_driver(&sony_pic_driver); 2943 acpi_bus_unregister_driver(&sony_pic_driver);
2965out: 2944out:
2966 return result; 2945 return result;
@@ -2969,7 +2948,7 @@ out:
2969static void __exit sony_laptop_exit(void) 2948static void __exit sony_laptop_exit(void)
2970{ 2949{
2971 acpi_bus_unregister_driver(&sony_nc_driver); 2950 acpi_bus_unregister_driver(&sony_nc_driver);
2972 if (!no_spic) 2951 if (spic_drv_registered)
2973 acpi_bus_unregister_driver(&sony_pic_driver); 2952 acpi_bus_unregister_driver(&sony_pic_driver);
2974} 2953}
2975 2954
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
index 4cdb31a362ca..a0c816238aa9 100644
--- a/drivers/rtc/interface.c
+++ b/drivers/rtc/interface.c
@@ -12,6 +12,7 @@
12*/ 12*/
13 13
14#include <linux/rtc.h> 14#include <linux/rtc.h>
15#include <linux/sched.h>
15#include <linux/log2.h> 16#include <linux/log2.h>
16 17
17int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm) 18int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm)
diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c
index 8a11de9552cd..62227cd52410 100644
--- a/drivers/rtc/rtc-dev.c
+++ b/drivers/rtc/rtc-dev.c
@@ -13,6 +13,7 @@
13 13
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/rtc.h> 15#include <linux/rtc.h>
16#include <linux/sched.h>
16#include "rtc-core.h" 17#include "rtc-core.h"
17 18
18static dev_t rtc_devt; 19static dev_t rtc_devt;
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index dad0449475b6..aaccc8ecfa8f 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -2508,8 +2508,6 @@ int dasd_generic_restore_device(struct ccw_device *cdev)
2508 device->stopped &= ~DASD_UNRESUMED_PM; 2508 device->stopped &= ~DASD_UNRESUMED_PM;
2509 2509
2510 dasd_schedule_device_bh(device); 2510 dasd_schedule_device_bh(device);
2511 if (device->block)
2512 dasd_schedule_block_bh(device->block);
2513 2511
2514 if (device->discipline->restore) 2512 if (device->discipline->restore)
2515 rc = device->discipline->restore(device); 2513 rc = device->discipline->restore(device);
@@ -2520,6 +2518,9 @@ int dasd_generic_restore_device(struct ccw_device *cdev)
2520 */ 2518 */
2521 device->stopped |= DASD_UNRESUMED_PM; 2519 device->stopped |= DASD_UNRESUMED_PM;
2522 2520
2521 if (device->block)
2522 dasd_schedule_block_bh(device->block);
2523
2523 dasd_put_device(device); 2524 dasd_put_device(device);
2524 return 0; 2525 return 0;
2525} 2526}
@@ -2532,6 +2533,7 @@ static struct dasd_ccw_req *dasd_generic_build_rdc(struct dasd_device *device,
2532{ 2533{
2533 struct dasd_ccw_req *cqr; 2534 struct dasd_ccw_req *cqr;
2534 struct ccw1 *ccw; 2535 struct ccw1 *ccw;
2536 unsigned long *idaw;
2535 2537
2536 cqr = dasd_smalloc_request(magic, 1 /* RDC */, rdc_buffer_size, device); 2538 cqr = dasd_smalloc_request(magic, 1 /* RDC */, rdc_buffer_size, device);
2537 2539
@@ -2545,9 +2547,17 @@ static struct dasd_ccw_req *dasd_generic_build_rdc(struct dasd_device *device,
2545 2547
2546 ccw = cqr->cpaddr; 2548 ccw = cqr->cpaddr;
2547 ccw->cmd_code = CCW_CMD_RDC; 2549 ccw->cmd_code = CCW_CMD_RDC;
2548 ccw->cda = (__u32)(addr_t)rdc_buffer; 2550 if (idal_is_needed(rdc_buffer, rdc_buffer_size)) {
2549 ccw->count = rdc_buffer_size; 2551 idaw = (unsigned long *) (cqr->data);
2552 ccw->cda = (__u32)(addr_t) idaw;
2553 ccw->flags = CCW_FLAG_IDA;
2554 idaw = idal_create_words(idaw, rdc_buffer, rdc_buffer_size);
2555 } else {
2556 ccw->cda = (__u32)(addr_t) rdc_buffer;
2557 ccw->flags = 0;
2558 }
2550 2559
2560 ccw->count = rdc_buffer_size;
2551 cqr->startdev = device; 2561 cqr->startdev = device;
2552 cqr->memdev = device; 2562 cqr->memdev = device;
2553 cqr->expires = 10*HZ; 2563 cqr->expires = 10*HZ;
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index ab3521755588..417b97cd3f94 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -2338,6 +2338,8 @@ static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
2338 /* Calculate number of blocks/records per track. */ 2338 /* Calculate number of blocks/records per track. */
2339 blksize = block->bp_block; 2339 blksize = block->bp_block;
2340 blk_per_trk = recs_per_track(&private->rdc_data, 0, blksize); 2340 blk_per_trk = recs_per_track(&private->rdc_data, 0, blksize);
2341 if (blk_per_trk == 0)
2342 return ERR_PTR(-EINVAL);
2341 /* Calculate record id of first and last block. */ 2343 /* Calculate record id of first and last block. */
2342 first_rec = first_trk = blk_rq_pos(req) >> block->s2b_shift; 2344 first_rec = first_trk = blk_rq_pos(req) >> block->s2b_shift;
2343 first_offs = sector_div(first_trk, blk_per_trk); 2345 first_offs = sector_div(first_trk, blk_per_trk);
@@ -3211,8 +3213,10 @@ int dasd_eckd_pm_freeze(struct dasd_device *device)
3211int dasd_eckd_restore_device(struct dasd_device *device) 3213int dasd_eckd_restore_device(struct dasd_device *device)
3212{ 3214{
3213 struct dasd_eckd_private *private; 3215 struct dasd_eckd_private *private;
3216 struct dasd_eckd_characteristics temp_rdc_data;
3214 int is_known, rc; 3217 int is_known, rc;
3215 struct dasd_uid temp_uid; 3218 struct dasd_uid temp_uid;
3219 unsigned long flags;
3216 3220
3217 private = (struct dasd_eckd_private *) device->private; 3221 private = (struct dasd_eckd_private *) device->private;
3218 3222
@@ -3225,7 +3229,8 @@ int dasd_eckd_restore_device(struct dasd_device *device)
3225 rc = dasd_eckd_generate_uid(device, &private->uid); 3229 rc = dasd_eckd_generate_uid(device, &private->uid);
3226 dasd_get_uid(device->cdev, &temp_uid); 3230 dasd_get_uid(device->cdev, &temp_uid);
3227 if (memcmp(&private->uid, &temp_uid, sizeof(struct dasd_uid)) != 0) 3231 if (memcmp(&private->uid, &temp_uid, sizeof(struct dasd_uid)) != 0)
3228 dev_err(&device->cdev->dev, "The UID of the DASD has changed\n"); 3232 dev_err(&device->cdev->dev, "The UID of the DASD has "
3233 "changed\n");
3229 if (rc) 3234 if (rc)
3230 goto out_err; 3235 goto out_err;
3231 dasd_set_uid(device->cdev, &private->uid); 3236 dasd_set_uid(device->cdev, &private->uid);
@@ -3245,15 +3250,17 @@ int dasd_eckd_restore_device(struct dasd_device *device)
3245 dasd_eckd_read_features(device); 3250 dasd_eckd_read_features(device);
3246 3251
3247 /* Read Device Characteristics */ 3252 /* Read Device Characteristics */
3248 memset(&private->rdc_data, 0, sizeof(private->rdc_data));
3249 rc = dasd_generic_read_dev_chars(device, DASD_ECKD_MAGIC, 3253 rc = dasd_generic_read_dev_chars(device, DASD_ECKD_MAGIC,
3250 &private->rdc_data, 64); 3254 &temp_rdc_data, 64);
3251 if (rc) { 3255 if (rc) {
3252 DBF_EVENT(DBF_WARNING, 3256 DBF_EVENT(DBF_WARNING,
3253 "Read device characteristics failed, rc=%d for " 3257 "Read device characteristics failed, rc=%d for "
3254 "device: %s", rc, dev_name(&device->cdev->dev)); 3258 "device: %s", rc, dev_name(&device->cdev->dev));
3255 goto out_err; 3259 goto out_err;
3256 } 3260 }
3261 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
3262 memcpy(&private->rdc_data, &temp_rdc_data, sizeof(temp_rdc_data));
3263 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
3257 3264
3258 /* add device to alias management */ 3265 /* add device to alias management */
3259 dasd_alias_add_device(device); 3266 dasd_alias_add_device(device);
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c
index d6a022f55e92..62ddf5202b79 100644
--- a/drivers/s390/char/raw3270.c
+++ b/drivers/s390/char/raw3270.c
@@ -1361,11 +1361,13 @@ static int raw3270_pm_start(struct ccw_device *cdev)
1361 1361
1362void raw3270_pm_unfreeze(struct raw3270_view *view) 1362void raw3270_pm_unfreeze(struct raw3270_view *view)
1363{ 1363{
1364#ifdef CONFIG_TN3270_CONSOLE
1364 struct raw3270 *rp; 1365 struct raw3270 *rp;
1365 1366
1366 rp = view->dev; 1367 rp = view->dev;
1367 if (rp && test_bit(RAW3270_FLAGS_FROZEN, &rp->flags)) 1368 if (rp && test_bit(RAW3270_FLAGS_FROZEN, &rp->flags))
1368 ccw_device_force_console(); 1369 ccw_device_force_console();
1370#endif
1369} 1371}
1370 1372
1371static struct ccw_device_id raw3270_id[] = { 1373static struct ccw_device_id raw3270_id[] = {
diff --git a/drivers/s390/char/sclp_async.c b/drivers/s390/char/sclp_async.c
index daaec185ed36..a4f68e5b9c96 100644
--- a/drivers/s390/char/sclp_async.c
+++ b/drivers/s390/char/sclp_async.c
@@ -62,7 +62,7 @@ static struct notifier_block call_home_panic_nb = {
62 .priority = INT_MAX, 62 .priority = INT_MAX,
63}; 63};
64 64
65static int proc_handler_callhome(ctl_table *ctl, int write, struct file *filp, 65static int proc_handler_callhome(struct ctl_table *ctl, int write,
66 void __user *buffer, size_t *count, 66 void __user *buffer, size_t *count,
67 loff_t *ppos) 67 loff_t *ppos)
68{ 68{
@@ -100,7 +100,7 @@ static struct ctl_table callhome_table[] = {
100 { 100 {
101 .procname = "callhome", 101 .procname = "callhome",
102 .mode = 0644, 102 .mode = 0644,
103 .proc_handler = &proc_handler_callhome, 103 .proc_handler = proc_handler_callhome,
104 }, 104 },
105 { .ctl_name = 0 } 105 { .ctl_name = 0 }
106}; 106};
diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c
index 178724f2a4c3..b9d2a007e93b 100644
--- a/drivers/s390/char/sclp_vt220.c
+++ b/drivers/s390/char/sclp_vt220.c
@@ -705,21 +705,6 @@ out_driver:
705} 705}
706__initcall(sclp_vt220_tty_init); 706__initcall(sclp_vt220_tty_init);
707 707
708#ifdef CONFIG_SCLP_VT220_CONSOLE
709
710static void
711sclp_vt220_con_write(struct console *con, const char *buf, unsigned int count)
712{
713 __sclp_vt220_write((const unsigned char *) buf, count, 1, 1, 0);
714}
715
716static struct tty_driver *
717sclp_vt220_con_device(struct console *c, int *index)
718{
719 *index = 0;
720 return sclp_vt220_driver;
721}
722
723static void __sclp_vt220_flush_buffer(void) 708static void __sclp_vt220_flush_buffer(void)
724{ 709{
725 unsigned long flags; 710 unsigned long flags;
@@ -776,6 +761,21 @@ static void sclp_vt220_pm_event_fn(struct sclp_register *reg,
776 } 761 }
777} 762}
778 763
764#ifdef CONFIG_SCLP_VT220_CONSOLE
765
766static void
767sclp_vt220_con_write(struct console *con, const char *buf, unsigned int count)
768{
769 __sclp_vt220_write((const unsigned char *) buf, count, 1, 1, 0);
770}
771
772static struct tty_driver *
773sclp_vt220_con_device(struct console *c, int *index)
774{
775 *index = 0;
776 return sclp_vt220_driver;
777}
778
779static int 779static int
780sclp_vt220_notify(struct notifier_block *self, 780sclp_vt220_notify(struct notifier_block *self,
781 unsigned long event, void *data) 781 unsigned long event, void *data)
diff --git a/drivers/s390/char/tape_block.c b/drivers/s390/char/tape_block.c
index 64f57ef2763c..0c0705b91c28 100644
--- a/drivers/s390/char/tape_block.c
+++ b/drivers/s390/char/tape_block.c
@@ -162,9 +162,10 @@ tapeblock_requeue(struct work_struct *work) {
162 spin_lock_irq(&device->blk_data.request_queue_lock); 162 spin_lock_irq(&device->blk_data.request_queue_lock);
163 while ( 163 while (
164 !blk_queue_plugged(queue) && 164 !blk_queue_plugged(queue) &&
165 (req = blk_fetch_request(queue)) && 165 blk_peek_request(queue) &&
166 nr_queued < TAPEBLOCK_MIN_REQUEUE 166 nr_queued < TAPEBLOCK_MIN_REQUEUE
167 ) { 167 ) {
168 req = blk_fetch_request(queue);
168 if (rq_data_dir(req) == WRITE) { 169 if (rq_data_dir(req) == WRITE) {
169 DBF_EVENT(1, "TBLOCK: Rejecting write request\n"); 170 DBF_EVENT(1, "TBLOCK: Rejecting write request\n");
170 spin_unlock_irq(&device->blk_data.request_queue_lock); 171 spin_unlock_irq(&device->blk_data.request_queue_lock);
diff --git a/drivers/s390/cio/blacklist.c b/drivers/s390/cio/blacklist.c
index 6565f027791e..7eab9ab9f406 100644
--- a/drivers/s390/cio/blacklist.c
+++ b/drivers/s390/cio/blacklist.c
@@ -265,13 +265,11 @@ struct ccwdev_iter {
265static void * 265static void *
266cio_ignore_proc_seq_start(struct seq_file *s, loff_t *offset) 266cio_ignore_proc_seq_start(struct seq_file *s, loff_t *offset)
267{ 267{
268 struct ccwdev_iter *iter; 268 struct ccwdev_iter *iter = s->private;
269 269
270 if (*offset >= (__MAX_SUBCHANNEL + 1) * (__MAX_SSID + 1)) 270 if (*offset >= (__MAX_SUBCHANNEL + 1) * (__MAX_SSID + 1))
271 return NULL; 271 return NULL;
272 iter = kzalloc(sizeof(struct ccwdev_iter), GFP_KERNEL); 272 memset(iter, 0, sizeof(*iter));
273 if (!iter)
274 return ERR_PTR(-ENOMEM);
275 iter->ssid = *offset / (__MAX_SUBCHANNEL + 1); 273 iter->ssid = *offset / (__MAX_SUBCHANNEL + 1);
276 iter->devno = *offset % (__MAX_SUBCHANNEL + 1); 274 iter->devno = *offset % (__MAX_SUBCHANNEL + 1);
277 return iter; 275 return iter;
@@ -280,8 +278,6 @@ cio_ignore_proc_seq_start(struct seq_file *s, loff_t *offset)
280static void 278static void
281cio_ignore_proc_seq_stop(struct seq_file *s, void *it) 279cio_ignore_proc_seq_stop(struct seq_file *s, void *it)
282{ 280{
283 if (!IS_ERR(it))
284 kfree(it);
285} 281}
286 282
287static void * 283static void *
@@ -378,14 +374,15 @@ static const struct seq_operations cio_ignore_proc_seq_ops = {
378static int 374static int
379cio_ignore_proc_open(struct inode *inode, struct file *file) 375cio_ignore_proc_open(struct inode *inode, struct file *file)
380{ 376{
381 return seq_open(file, &cio_ignore_proc_seq_ops); 377 return seq_open_private(file, &cio_ignore_proc_seq_ops,
378 sizeof(struct ccwdev_iter));
382} 379}
383 380
384static const struct file_operations cio_ignore_proc_fops = { 381static const struct file_operations cio_ignore_proc_fops = {
385 .open = cio_ignore_proc_open, 382 .open = cio_ignore_proc_open,
386 .read = seq_read, 383 .read = seq_read,
387 .llseek = seq_lseek, 384 .llseek = seq_lseek,
388 .release = seq_release, 385 .release = seq_release_private,
389 .write = cio_ignore_write, 386 .write = cio_ignore_write,
390}; 387};
391 388
diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c
index 40002830d48a..8ab51608da55 100644
--- a/drivers/s390/cio/chp.c
+++ b/drivers/s390/cio/chp.c
@@ -393,7 +393,6 @@ int chp_new(struct chp_id chpid)
393 chp->state = 1; 393 chp->state = 1;
394 chp->dev.parent = &channel_subsystems[chpid.cssid]->device; 394 chp->dev.parent = &channel_subsystems[chpid.cssid]->device;
395 chp->dev.release = chp_release; 395 chp->dev.release = chp_release;
396 dev_set_name(&chp->dev, "chp%x.%02x", chpid.cssid, chpid.id);
397 396
398 /* Obtain channel path description and fill it in. */ 397 /* Obtain channel path description and fill it in. */
399 ret = chsc_determine_base_channel_path_desc(chpid, &chp->desc); 398 ret = chsc_determine_base_channel_path_desc(chpid, &chp->desc);
@@ -411,6 +410,7 @@ int chp_new(struct chp_id chpid)
411 } else { 410 } else {
412 chp->cmg = -1; 411 chp->cmg = -1;
413 } 412 }
413 dev_set_name(&chp->dev, "chp%x.%02x", chpid.cssid, chpid.id);
414 414
415 /* make it known to the system */ 415 /* make it known to the system */
416 ret = device_register(&chp->dev); 416 ret = device_register(&chp->dev);
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index f780bdd3a04e..2490b741e16a 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -1250,8 +1250,7 @@ static int io_subchannel_probe(struct subchannel *sch)
1250 unsigned long flags; 1250 unsigned long flags;
1251 struct ccw_dev_id dev_id; 1251 struct ccw_dev_id dev_id;
1252 1252
1253 cdev = sch_get_cdev(sch); 1253 if (cio_is_console(sch->schid)) {
1254 if (cdev) {
1255 rc = sysfs_create_group(&sch->dev.kobj, 1254 rc = sysfs_create_group(&sch->dev.kobj,
1256 &io_subchannel_attr_group); 1255 &io_subchannel_attr_group);
1257 if (rc) 1256 if (rc)
@@ -1260,13 +1259,13 @@ static int io_subchannel_probe(struct subchannel *sch)
1260 "0.%x.%04x (rc=%d)\n", 1259 "0.%x.%04x (rc=%d)\n",
1261 sch->schid.ssid, sch->schid.sch_no, rc); 1260 sch->schid.ssid, sch->schid.sch_no, rc);
1262 /* 1261 /*
1263 * This subchannel already has an associated ccw_device. 1262 * The console subchannel already has an associated ccw_device.
1264 * Throw the delayed uevent for the subchannel, register 1263 * Throw the delayed uevent for the subchannel, register
1265 * the ccw_device and exit. This happens for all early 1264 * the ccw_device and exit.
1266 * devices, e.g. the console.
1267 */ 1265 */
1268 dev_set_uevent_suppress(&sch->dev, 0); 1266 dev_set_uevent_suppress(&sch->dev, 0);
1269 kobject_uevent(&sch->dev.kobj, KOBJ_ADD); 1267 kobject_uevent(&sch->dev.kobj, KOBJ_ADD);
1268 cdev = sch_get_cdev(sch);
1270 cdev->dev.groups = ccwdev_attr_groups; 1269 cdev->dev.groups = ccwdev_attr_groups;
1271 device_initialize(&cdev->dev); 1270 device_initialize(&cdev->dev);
1272 ccw_device_register(cdev); 1271 ccw_device_register(cdev);
@@ -1609,7 +1608,7 @@ int ccw_purge_blacklisted(void)
1609 return 0; 1608 return 0;
1610} 1609}
1611 1610
1612static void device_set_disconnected(struct ccw_device *cdev) 1611void ccw_device_set_disconnected(struct ccw_device *cdev)
1613{ 1612{
1614 if (!cdev) 1613 if (!cdev)
1615 return; 1614 return;
@@ -1705,7 +1704,7 @@ static int io_subchannel_sch_event(struct subchannel *sch, int slow)
1705 ccw_device_trigger_reprobe(cdev); 1704 ccw_device_trigger_reprobe(cdev);
1706 break; 1705 break;
1707 case DISC: 1706 case DISC:
1708 device_set_disconnected(cdev); 1707 ccw_device_set_disconnected(cdev);
1709 break; 1708 break;
1710 default: 1709 default:
1711 break; 1710 break;
diff --git a/drivers/s390/cio/device.h b/drivers/s390/cio/device.h
index ed39a2caaf47..246c6482842c 100644
--- a/drivers/s390/cio/device.h
+++ b/drivers/s390/cio/device.h
@@ -125,6 +125,7 @@ int ccw_device_stlck(struct ccw_device *);
125void ccw_device_trigger_reprobe(struct ccw_device *); 125void ccw_device_trigger_reprobe(struct ccw_device *);
126void ccw_device_kill_io(struct ccw_device *); 126void ccw_device_kill_io(struct ccw_device *);
127int ccw_device_notify(struct ccw_device *, int); 127int ccw_device_notify(struct ccw_device *, int);
128void ccw_device_set_disconnected(struct ccw_device *cdev);
128void ccw_device_set_notoper(struct ccw_device *cdev); 129void ccw_device_set_notoper(struct ccw_device *cdev);
129 130
130/* qdio needs this. */ 131/* qdio needs this. */
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
index e728ce447f6e..b9613d7df9ef 100644
--- a/drivers/s390/cio/device_fsm.c
+++ b/drivers/s390/cio/device_fsm.c
@@ -387,19 +387,35 @@ ccw_device_done(struct ccw_device *cdev, int state)
387 387
388 cdev->private->state = state; 388 cdev->private->state = state;
389 389
390 if (state == DEV_STATE_BOXED) { 390 switch (state) {
391 case DEV_STATE_BOXED:
391 CIO_MSG_EVENT(0, "Boxed device %04x on subchannel %04x\n", 392 CIO_MSG_EVENT(0, "Boxed device %04x on subchannel %04x\n",
392 cdev->private->dev_id.devno, sch->schid.sch_no); 393 cdev->private->dev_id.devno, sch->schid.sch_no);
393 if (cdev->online && !ccw_device_notify(cdev, CIO_BOXED)) 394 if (cdev->online && !ccw_device_notify(cdev, CIO_BOXED))
394 ccw_device_schedule_sch_unregister(cdev); 395 ccw_device_schedule_sch_unregister(cdev);
395 cdev->private->flags.donotify = 0; 396 cdev->private->flags.donotify = 0;
396 } 397 break;
397 if (state == DEV_STATE_NOT_OPER) { 398 case DEV_STATE_NOT_OPER:
398 CIO_MSG_EVENT(0, "Device %04x gone on subchannel %04x\n", 399 CIO_MSG_EVENT(0, "Device %04x gone on subchannel %04x\n",
399 cdev->private->dev_id.devno, sch->schid.sch_no); 400 cdev->private->dev_id.devno, sch->schid.sch_no);
400 if (!ccw_device_notify(cdev, CIO_GONE)) 401 if (!ccw_device_notify(cdev, CIO_GONE))
401 ccw_device_schedule_sch_unregister(cdev); 402 ccw_device_schedule_sch_unregister(cdev);
403 else
404 ccw_device_set_disconnected(cdev);
402 cdev->private->flags.donotify = 0; 405 cdev->private->flags.donotify = 0;
406 break;
407 case DEV_STATE_DISCONNECTED:
408 CIO_MSG_EVENT(0, "Disconnected device %04x on subchannel "
409 "%04x\n", cdev->private->dev_id.devno,
410 sch->schid.sch_no);
411 if (!ccw_device_notify(cdev, CIO_NO_PATH))
412 ccw_device_schedule_sch_unregister(cdev);
413 else
414 ccw_device_set_disconnected(cdev);
415 cdev->private->flags.donotify = 0;
416 break;
417 default:
418 break;
403 } 419 }
404 420
405 if (cdev->private->flags.donotify) { 421 if (cdev->private->flags.donotify) {
@@ -671,6 +687,10 @@ ccw_device_offline(struct ccw_device *cdev)
671 ccw_device_done(cdev, DEV_STATE_NOT_OPER); 687 ccw_device_done(cdev, DEV_STATE_NOT_OPER);
672 return 0; 688 return 0;
673 } 689 }
690 if (cdev->private->state == DEV_STATE_BOXED) {
691 ccw_device_done(cdev, DEV_STATE_BOXED);
692 return 0;
693 }
674 if (ccw_device_is_orphan(cdev)) { 694 if (ccw_device_is_orphan(cdev)) {
675 ccw_device_done(cdev, DEV_STATE_OFFLINE); 695 ccw_device_done(cdev, DEV_STATE_OFFLINE);
676 return 0; 696 return 0;
@@ -730,11 +750,10 @@ ccw_device_recog_notoper(struct ccw_device *cdev, enum dev_event dev_event)
730static void ccw_device_generic_notoper(struct ccw_device *cdev, 750static void ccw_device_generic_notoper(struct ccw_device *cdev,
731 enum dev_event dev_event) 751 enum dev_event dev_event)
732{ 752{
733 struct subchannel *sch; 753 if (!ccw_device_notify(cdev, CIO_GONE))
734 754 ccw_device_schedule_sch_unregister(cdev);
735 ccw_device_set_notoper(cdev); 755 else
736 sch = to_subchannel(cdev->dev.parent); 756 ccw_device_set_disconnected(cdev);
737 css_schedule_eval(sch->schid);
738} 757}
739 758
740/* 759/*
diff --git a/drivers/s390/cio/qdio_debug.c b/drivers/s390/cio/qdio_debug.c
index 1b78f639ead3..76769978285f 100644
--- a/drivers/s390/cio/qdio_debug.c
+++ b/drivers/s390/cio/qdio_debug.c
@@ -125,7 +125,7 @@ static int qstat_seq_open(struct inode *inode, struct file *filp)
125 filp->f_path.dentry->d_inode->i_private); 125 filp->f_path.dentry->d_inode->i_private);
126} 126}
127 127
128static struct file_operations debugfs_fops = { 128static const struct file_operations debugfs_fops = {
129 .owner = THIS_MODULE, 129 .owner = THIS_MODULE,
130 .open = qstat_seq_open, 130 .open = qstat_seq_open,
131 .read = seq_read, 131 .read = seq_read,
diff --git a/drivers/s390/cio/qdio_perf.c b/drivers/s390/cio/qdio_perf.c
index eff943923c6f..968e3c7c2632 100644
--- a/drivers/s390/cio/qdio_perf.c
+++ b/drivers/s390/cio/qdio_perf.c
@@ -84,7 +84,7 @@ static int qdio_perf_seq_open(struct inode *inode, struct file *filp)
84 return single_open(filp, qdio_perf_proc_show, NULL); 84 return single_open(filp, qdio_perf_proc_show, NULL);
85} 85}
86 86
87static struct file_operations qdio_perf_proc_fops = { 87static const struct file_operations qdio_perf_proc_fops = {
88 .owner = THIS_MODULE, 88 .owner = THIS_MODULE,
89 .open = qdio_perf_seq_open, 89 .open = qdio_perf_seq_open,
90 .read = seq_read, 90 .read = seq_read,
diff --git a/drivers/s390/crypto/zcrypt_pcixcc.c b/drivers/s390/crypto/zcrypt_pcixcc.c
index c20d4790258e..5677b40e4ac0 100644
--- a/drivers/s390/crypto/zcrypt_pcixcc.c
+++ b/drivers/s390/crypto/zcrypt_pcixcc.c
@@ -361,7 +361,7 @@ static void rng_type6CPRB_msgX(struct ap_device *ap_dev,
361 .ToCardLen1 = sizeof *msg - sizeof(msg->hdr), 361 .ToCardLen1 = sizeof *msg - sizeof(msg->hdr),
362 .FromCardLen1 = sizeof *msg - sizeof(msg->hdr), 362 .FromCardLen1 = sizeof *msg - sizeof(msg->hdr),
363 }; 363 };
364 static struct CPRBX static_cprbx = { 364 static struct CPRBX local_cprbx = {
365 .cprb_len = 0x00dc, 365 .cprb_len = 0x00dc,
366 .cprb_ver_id = 0x02, 366 .cprb_ver_id = 0x02,
367 .func_id = {0x54, 0x32}, 367 .func_id = {0x54, 0x32},
@@ -372,7 +372,7 @@ static void rng_type6CPRB_msgX(struct ap_device *ap_dev,
372 372
373 msg->hdr = static_type6_hdrX; 373 msg->hdr = static_type6_hdrX;
374 msg->hdr.FromCardLen2 = random_number_length, 374 msg->hdr.FromCardLen2 = random_number_length,
375 msg->cprbx = static_cprbx; 375 msg->cprbx = local_cprbx;
376 msg->cprbx.rpl_datal = random_number_length, 376 msg->cprbx.rpl_datal = random_number_length,
377 msg->cprbx.domain = AP_QID_QUEUE(ap_dev->qid); 377 msg->cprbx.domain = AP_QID_QUEUE(ap_dev->qid);
378 memcpy(msg->function_code, msg->hdr.function_code, 0x02); 378 memcpy(msg->function_code, msg->hdr.function_code, 0x02);
@@ -561,7 +561,8 @@ static int convert_response_ica(struct zcrypt_device *zdev,
561 if (msg->cprbx.cprb_ver_id == 0x02) 561 if (msg->cprbx.cprb_ver_id == 0x02)
562 return convert_type86_ica(zdev, reply, 562 return convert_type86_ica(zdev, reply,
563 outputdata, outputdatalength); 563 outputdata, outputdatalength);
564 /* no break, incorrect cprb version is an unknown response */ 564 /* Fall through, no break, incorrect cprb version is an unknown
565 * response */
565 default: /* Unknown response type, this should NEVER EVER happen */ 566 default: /* Unknown response type, this should NEVER EVER happen */
566 zdev->online = 0; 567 zdev->online = 0;
567 return -EAGAIN; /* repeat the request on a different device. */ 568 return -EAGAIN; /* repeat the request on a different device. */
@@ -587,7 +588,8 @@ static int convert_response_xcrb(struct zcrypt_device *zdev,
587 } 588 }
588 if (msg->cprbx.cprb_ver_id == 0x02) 589 if (msg->cprbx.cprb_ver_id == 0x02)
589 return convert_type86_xcrb(zdev, reply, xcRB); 590 return convert_type86_xcrb(zdev, reply, xcRB);
590 /* no break, incorrect cprb version is an unknown response */ 591 /* Fall through, no break, incorrect cprb version is an unknown
592 * response */
591 default: /* Unknown response type, this should NEVER EVER happen */ 593 default: /* Unknown response type, this should NEVER EVER happen */
592 xcRB->status = 0x0008044DL; /* HDD_InvalidParm */ 594 xcRB->status = 0x0008044DL; /* HDD_InvalidParm */
593 zdev->online = 0; 595 zdev->online = 0;
@@ -610,7 +612,8 @@ static int convert_response_rng(struct zcrypt_device *zdev,
610 return -EINVAL; 612 return -EINVAL;
611 if (msg->cprbx.cprb_ver_id == 0x02) 613 if (msg->cprbx.cprb_ver_id == 0x02)
612 return convert_type86_rng(zdev, reply, data); 614 return convert_type86_rng(zdev, reply, data);
613 /* no break, incorrect cprb version is an unknown response */ 615 /* Fall through, no break, incorrect cprb version is an unknown
616 * response */
614 default: /* Unknown response type, this should NEVER EVER happen */ 617 default: /* Unknown response type, this should NEVER EVER happen */
615 zdev->online = 0; 618 zdev->online = 0;
616 return -EAGAIN; /* repeat the request on a different device. */ 619 return -EAGAIN; /* repeat the request on a different device. */
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index 1be6bf7e8ce6..0f79f3af4f54 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -80,28 +80,35 @@ int zfcp_reqlist_isempty(struct zfcp_adapter *adapter)
80 80
81static void __init zfcp_init_device_configure(char *busid, u64 wwpn, u64 lun) 81static void __init zfcp_init_device_configure(char *busid, u64 wwpn, u64 lun)
82{ 82{
83 struct ccw_device *ccwdev;
83 struct zfcp_adapter *adapter; 84 struct zfcp_adapter *adapter;
84 struct zfcp_port *port; 85 struct zfcp_port *port;
85 struct zfcp_unit *unit; 86 struct zfcp_unit *unit;
86 87
87 mutex_lock(&zfcp_data.config_mutex); 88 ccwdev = get_ccwdev_by_busid(&zfcp_ccw_driver, busid);
88 read_lock_irq(&zfcp_data.config_lock); 89 if (!ccwdev)
89 adapter = zfcp_get_adapter_by_busid(busid); 90 return;
90 if (adapter) 91
91 zfcp_adapter_get(adapter); 92 if (ccw_device_set_online(ccwdev))
92 read_unlock_irq(&zfcp_data.config_lock); 93 goto out_ccwdev;
93 94
95 mutex_lock(&zfcp_data.config_mutex);
96 adapter = dev_get_drvdata(&ccwdev->dev);
94 if (!adapter) 97 if (!adapter)
95 goto out_adapter; 98 goto out_unlock;
96 port = zfcp_port_enqueue(adapter, wwpn, 0, 0); 99 zfcp_adapter_get(adapter);
97 if (IS_ERR(port)) 100
101 port = zfcp_get_port_by_wwpn(adapter, wwpn);
102 if (!port)
98 goto out_port; 103 goto out_port;
104
105 zfcp_port_get(port);
99 unit = zfcp_unit_enqueue(port, lun); 106 unit = zfcp_unit_enqueue(port, lun);
100 if (IS_ERR(unit)) 107 if (IS_ERR(unit))
101 goto out_unit; 108 goto out_unit;
102 mutex_unlock(&zfcp_data.config_mutex); 109 mutex_unlock(&zfcp_data.config_mutex);
103 ccw_device_set_online(adapter->ccw_device);
104 110
111 zfcp_erp_unit_reopen(unit, 0, "auidc_1", NULL);
105 zfcp_erp_wait(adapter); 112 zfcp_erp_wait(adapter);
106 flush_work(&unit->scsi_work); 113 flush_work(&unit->scsi_work);
107 114
@@ -111,8 +118,10 @@ out_unit:
111 zfcp_port_put(port); 118 zfcp_port_put(port);
112out_port: 119out_port:
113 zfcp_adapter_put(adapter); 120 zfcp_adapter_put(adapter);
114out_adapter: 121out_unlock:
115 mutex_unlock(&zfcp_data.config_mutex); 122 mutex_unlock(&zfcp_data.config_mutex);
123out_ccwdev:
124 put_device(&ccwdev->dev);
116 return; 125 return;
117} 126}
118 127
@@ -593,10 +602,8 @@ void zfcp_adapter_dequeue(struct zfcp_adapter *adapter)
593 int retval = 0; 602 int retval = 0;
594 unsigned long flags; 603 unsigned long flags;
595 604
596 cancel_work_sync(&adapter->scan_work);
597 cancel_work_sync(&adapter->stat_work); 605 cancel_work_sync(&adapter->stat_work);
598 zfcp_fc_wka_ports_force_offline(adapter->gs); 606 zfcp_fc_wka_ports_force_offline(adapter->gs);
599 zfcp_adapter_scsi_unregister(adapter);
600 sysfs_remove_group(&adapter->ccw_device->dev.kobj, 607 sysfs_remove_group(&adapter->ccw_device->dev.kobj,
601 &zfcp_sysfs_adapter_attrs); 608 &zfcp_sysfs_adapter_attrs);
602 dev_set_drvdata(&adapter->ccw_device->dev, NULL); 609 dev_set_drvdata(&adapter->ccw_device->dev, NULL);
diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c
index 0c90f8e71605..e08339428ecf 100644
--- a/drivers/s390/scsi/zfcp_ccw.c
+++ b/drivers/s390/scsi/zfcp_ccw.c
@@ -102,6 +102,14 @@ static void zfcp_ccw_remove(struct ccw_device *ccw_device)
102 adapter = dev_get_drvdata(&ccw_device->dev); 102 adapter = dev_get_drvdata(&ccw_device->dev);
103 if (!adapter) 103 if (!adapter)
104 goto out; 104 goto out;
105 mutex_unlock(&zfcp_data.config_mutex);
106
107 cancel_work_sync(&adapter->scan_work);
108
109 mutex_lock(&zfcp_data.config_mutex);
110
111 /* this also removes the scsi devices, so call it first */
112 zfcp_adapter_scsi_unregister(adapter);
105 113
106 write_lock_irq(&zfcp_data.config_lock); 114 write_lock_irq(&zfcp_data.config_lock);
107 list_for_each_entry_safe(port, p, &adapter->port_list_head, list) { 115 list_for_each_entry_safe(port, p, &adapter->port_list_head, list) {
@@ -117,11 +125,8 @@ static void zfcp_ccw_remove(struct ccw_device *ccw_device)
117 write_unlock_irq(&zfcp_data.config_lock); 125 write_unlock_irq(&zfcp_data.config_lock);
118 126
119 list_for_each_entry_safe(port, p, &port_remove_lh, list) { 127 list_for_each_entry_safe(port, p, &port_remove_lh, list) {
120 list_for_each_entry_safe(unit, u, &unit_remove_lh, list) { 128 list_for_each_entry_safe(unit, u, &unit_remove_lh, list)
121 if (unit->device)
122 scsi_remove_device(unit->device);
123 zfcp_unit_dequeue(unit); 129 zfcp_unit_dequeue(unit);
124 }
125 zfcp_port_dequeue(port); 130 zfcp_port_dequeue(port);
126 } 131 }
127 wait_event(adapter->remove_wq, atomic_read(&adapter->refcount) == 0); 132 wait_event(adapter->remove_wq, atomic_read(&adapter->refcount) == 0);
@@ -192,13 +197,9 @@ static int zfcp_ccw_set_offline(struct ccw_device *ccw_device)
192 197
193 mutex_lock(&zfcp_data.config_mutex); 198 mutex_lock(&zfcp_data.config_mutex);
194 adapter = dev_get_drvdata(&ccw_device->dev); 199 adapter = dev_get_drvdata(&ccw_device->dev);
195 if (!adapter)
196 goto out;
197
198 zfcp_erp_adapter_shutdown(adapter, 0, "ccsoff1", NULL); 200 zfcp_erp_adapter_shutdown(adapter, 0, "ccsoff1", NULL);
199 zfcp_erp_wait(adapter); 201 zfcp_erp_wait(adapter);
200 mutex_unlock(&zfcp_data.config_mutex); 202 mutex_unlock(&zfcp_data.config_mutex);
201out:
202 return 0; 203 return 0;
203} 204}
204 205
@@ -253,13 +254,17 @@ static void zfcp_ccw_shutdown(struct ccw_device *cdev)
253 254
254 mutex_lock(&zfcp_data.config_mutex); 255 mutex_lock(&zfcp_data.config_mutex);
255 adapter = dev_get_drvdata(&cdev->dev); 256 adapter = dev_get_drvdata(&cdev->dev);
257 if (!adapter)
258 goto out;
259
256 zfcp_erp_adapter_shutdown(adapter, 0, "ccshut1", NULL); 260 zfcp_erp_adapter_shutdown(adapter, 0, "ccshut1", NULL);
257 zfcp_erp_wait(adapter); 261 zfcp_erp_wait(adapter);
258 zfcp_erp_thread_kill(adapter); 262 zfcp_erp_thread_kill(adapter);
263out:
259 mutex_unlock(&zfcp_data.config_mutex); 264 mutex_unlock(&zfcp_data.config_mutex);
260} 265}
261 266
262static struct ccw_driver zfcp_ccw_driver = { 267struct ccw_driver zfcp_ccw_driver = {
263 .owner = THIS_MODULE, 268 .owner = THIS_MODULE,
264 .name = "zfcp", 269 .name = "zfcp",
265 .ids = zfcp_ccw_device_id, 270 .ids = zfcp_ccw_device_id,
@@ -284,20 +289,3 @@ int __init zfcp_ccw_register(void)
284{ 289{
285 return ccw_driver_register(&zfcp_ccw_driver); 290 return ccw_driver_register(&zfcp_ccw_driver);
286} 291}
287
288/**
289 * zfcp_get_adapter_by_busid - find zfcp_adapter struct
290 * @busid: bus id string of zfcp adapter to find
291 */
292struct zfcp_adapter *zfcp_get_adapter_by_busid(char *busid)
293{
294 struct ccw_device *ccw_device;
295 struct zfcp_adapter *adapter = NULL;
296
297 ccw_device = get_ccwdev_by_busid(&zfcp_ccw_driver, busid);
298 if (ccw_device) {
299 adapter = dev_get_drvdata(&ccw_device->dev);
300 put_device(&ccw_device->dev);
301 }
302 return adapter;
303}
diff --git a/drivers/s390/scsi/zfcp_cfdc.c b/drivers/s390/scsi/zfcp_cfdc.c
index 8305c874e86f..ef681dfed0cc 100644
--- a/drivers/s390/scsi/zfcp_cfdc.c
+++ b/drivers/s390/scsi/zfcp_cfdc.c
@@ -86,8 +86,23 @@ static int zfcp_cfdc_copy_to_user(void __user *user_buffer,
86static struct zfcp_adapter *zfcp_cfdc_get_adapter(u32 devno) 86static struct zfcp_adapter *zfcp_cfdc_get_adapter(u32 devno)
87{ 87{
88 char busid[9]; 88 char busid[9];
89 struct ccw_device *ccwdev;
90 struct zfcp_adapter *adapter = NULL;
91
89 snprintf(busid, sizeof(busid), "0.0.%04x", devno); 92 snprintf(busid, sizeof(busid), "0.0.%04x", devno);
90 return zfcp_get_adapter_by_busid(busid); 93 ccwdev = get_ccwdev_by_busid(&zfcp_ccw_driver, busid);
94 if (!ccwdev)
95 goto out;
96
97 adapter = dev_get_drvdata(&ccwdev->dev);
98 if (!adapter)
99 goto out_put;
100
101 zfcp_adapter_get(adapter);
102out_put:
103 put_device(&ccwdev->dev);
104out:
105 return adapter;
91} 106}
92 107
93static int zfcp_cfdc_set_fsf(struct zfcp_fsf_cfdc *fsf_cfdc, int command) 108static int zfcp_cfdc_set_fsf(struct zfcp_fsf_cfdc *fsf_cfdc, int command)
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
index 36935bc0818f..629edec70405 100644
--- a/drivers/s390/scsi/zfcp_ext.h
+++ b/drivers/s390/scsi/zfcp_ext.h
@@ -28,7 +28,7 @@ extern int zfcp_sg_setup_table(struct scatterlist *, int);
28/* zfcp_ccw.c */ 28/* zfcp_ccw.c */
29extern int zfcp_ccw_register(void); 29extern int zfcp_ccw_register(void);
30extern int zfcp_ccw_priv_sch(struct zfcp_adapter *); 30extern int zfcp_ccw_priv_sch(struct zfcp_adapter *);
31extern struct zfcp_adapter *zfcp_get_adapter_by_busid(char *); 31extern struct ccw_driver zfcp_ccw_driver;
32 32
33/* zfcp_cfdc.c */ 33/* zfcp_cfdc.c */
34extern struct miscdevice zfcp_cfdc_misc; 34extern struct miscdevice zfcp_cfdc_misc;
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index f09c863dc6bd..38a7e4a6b639 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -1058,11 +1058,25 @@ static int zfcp_fsf_setup_ct_els_sbals(struct zfcp_fsf_req *req,
1058 bytes = zfcp_qdio_sbals_from_sg(adapter->qdio, &req->queue_req, 1058 bytes = zfcp_qdio_sbals_from_sg(adapter->qdio, &req->queue_req,
1059 SBAL_FLAGS0_TYPE_WRITE_READ, 1059 SBAL_FLAGS0_TYPE_WRITE_READ,
1060 sg_resp, max_sbals); 1060 sg_resp, max_sbals);
1061 req->qtcb->bottom.support.resp_buf_length = bytes;
1061 if (bytes <= 0) 1062 if (bytes <= 0)
1062 return -EIO; 1063 return -EIO;
1063 1064
1065 return 0;
1066}
1067
1068static int zfcp_fsf_setup_ct_els(struct zfcp_fsf_req *req,
1069 struct scatterlist *sg_req,
1070 struct scatterlist *sg_resp,
1071 int max_sbals)
1072{
1073 int ret;
1074
1075 ret = zfcp_fsf_setup_ct_els_sbals(req, sg_req, sg_resp, max_sbals);
1076 if (ret)
1077 return ret;
1078
1064 /* common settings for ct/gs and els requests */ 1079 /* common settings for ct/gs and els requests */
1065 req->qtcb->bottom.support.resp_buf_length = bytes;
1066 req->qtcb->bottom.support.service_class = FSF_CLASS_3; 1080 req->qtcb->bottom.support.service_class = FSF_CLASS_3;
1067 req->qtcb->bottom.support.timeout = 2 * R_A_TOV; 1081 req->qtcb->bottom.support.timeout = 2 * R_A_TOV;
1068 zfcp_fsf_start_timer(req, 2 * R_A_TOV + 10); 1082 zfcp_fsf_start_timer(req, 2 * R_A_TOV + 10);
@@ -1094,8 +1108,8 @@ int zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool)
1094 } 1108 }
1095 1109
1096 req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; 1110 req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
1097 ret = zfcp_fsf_setup_ct_els_sbals(req, ct->req, ct->resp, 1111 ret = zfcp_fsf_setup_ct_els(req, ct->req, ct->resp,
1098 FSF_MAX_SBALS_PER_REQ); 1112 FSF_MAX_SBALS_PER_REQ);
1099 if (ret) 1113 if (ret)
1100 goto failed_send; 1114 goto failed_send;
1101 1115
@@ -1192,7 +1206,7 @@ int zfcp_fsf_send_els(struct zfcp_send_els *els)
1192 } 1206 }
1193 1207
1194 req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; 1208 req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
1195 ret = zfcp_fsf_setup_ct_els_sbals(req, els->req, els->resp, 2); 1209 ret = zfcp_fsf_setup_ct_els(req, els->req, els->resp, 2);
1196 1210
1197 if (ret) 1211 if (ret)
1198 goto failed_send; 1212 goto failed_send;
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 82bb3b2d207a..e11cca4c784c 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -366,6 +366,7 @@ config ISCSI_TCP
366 366
367source "drivers/scsi/cxgb3i/Kconfig" 367source "drivers/scsi/cxgb3i/Kconfig"
368source "drivers/scsi/bnx2i/Kconfig" 368source "drivers/scsi/bnx2i/Kconfig"
369source "drivers/scsi/be2iscsi/Kconfig"
369 370
370config SGIWD93_SCSI 371config SGIWD93_SCSI
371 tristate "SGI WD93C93 SCSI Driver" 372 tristate "SGI WD93C93 SCSI Driver"
@@ -1827,6 +1828,16 @@ config SCSI_SRP
1827 To compile this driver as a module, choose M here: the 1828 To compile this driver as a module, choose M here: the
1828 module will be called libsrp. 1829 module will be called libsrp.
1829 1830
1831config SCSI_BFA_FC
1832 tristate "Brocade BFA Fibre Channel Support"
1833 depends on PCI && SCSI
1834 select SCSI_FC_ATTRS
1835 help
1836 This bfa driver supports all Brocade PCIe FC/FCOE host adapters.
1837
1838 To compile this driver as a module, choose M here. The module will
1839 be called bfa.
1840
1830endif # SCSI_LOWLEVEL 1841endif # SCSI_LOWLEVEL
1831 1842
1832source "drivers/scsi/pcmcia/Kconfig" 1843source "drivers/scsi/pcmcia/Kconfig"
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index 61a94af3cee7..3ad61db5e3fa 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -86,6 +86,7 @@ obj-$(CONFIG_SCSI_QLOGIC_1280) += qla1280.o
86obj-$(CONFIG_SCSI_QLA_FC) += qla2xxx/ 86obj-$(CONFIG_SCSI_QLA_FC) += qla2xxx/
87obj-$(CONFIG_SCSI_QLA_ISCSI) += qla4xxx/ 87obj-$(CONFIG_SCSI_QLA_ISCSI) += qla4xxx/
88obj-$(CONFIG_SCSI_LPFC) += lpfc/ 88obj-$(CONFIG_SCSI_LPFC) += lpfc/
89obj-$(CONFIG_SCSI_BFA_FC) += bfa/
89obj-$(CONFIG_SCSI_PAS16) += pas16.o 90obj-$(CONFIG_SCSI_PAS16) += pas16.o
90obj-$(CONFIG_SCSI_T128) += t128.o 91obj-$(CONFIG_SCSI_T128) += t128.o
91obj-$(CONFIG_SCSI_DMX3191D) += dmx3191d.o 92obj-$(CONFIG_SCSI_DMX3191D) += dmx3191d.o
@@ -130,6 +131,7 @@ obj-$(CONFIG_SCSI_MVSAS) += mvsas/
130obj-$(CONFIG_PS3_ROM) += ps3rom.o 131obj-$(CONFIG_PS3_ROM) += ps3rom.o
131obj-$(CONFIG_SCSI_CXGB3_ISCSI) += libiscsi.o libiscsi_tcp.o cxgb3i/ 132obj-$(CONFIG_SCSI_CXGB3_ISCSI) += libiscsi.o libiscsi_tcp.o cxgb3i/
132obj-$(CONFIG_SCSI_BNX2_ISCSI) += libiscsi.o bnx2i/ 133obj-$(CONFIG_SCSI_BNX2_ISCSI) += libiscsi.o bnx2i/
134obj-$(CONFIG_BE2ISCSI) += libiscsi.o be2iscsi/
133obj-$(CONFIG_SCSI_PMCRAID) += pmcraid.o 135obj-$(CONFIG_SCSI_PMCRAID) += pmcraid.o
134 136
135obj-$(CONFIG_ARM) += arm/ 137obj-$(CONFIG_ARM) += arm/
diff --git a/drivers/scsi/be2iscsi/Kconfig b/drivers/scsi/be2iscsi/Kconfig
new file mode 100644
index 000000000000..2952fcd008ea
--- /dev/null
+++ b/drivers/scsi/be2iscsi/Kconfig
@@ -0,0 +1,8 @@
1config BE2ISCSI
2 tristate "ServerEngines' 10Gbps iSCSI - BladeEngine 2"
3 depends on PCI && SCSI
4 select SCSI_ISCSI_ATTRS
5
6 help
7 This driver implements the iSCSI functionality for ServerEngines'
8 10Gbps Storage adapter - BladeEngine 2.
diff --git a/drivers/scsi/be2iscsi/Makefile b/drivers/scsi/be2iscsi/Makefile
new file mode 100644
index 000000000000..c11f443e3f83
--- /dev/null
+++ b/drivers/scsi/be2iscsi/Makefile
@@ -0,0 +1,8 @@
1#
2# Makefile to build the iSCSI driver for ServerEngine's BladeEngine.
3#
4#
5
6obj-$(CONFIG_BE2ISCSI) += be2iscsi.o
7
8be2iscsi-y := be_iscsi.o be_main.o be_mgmt.o be_cmds.o
diff --git a/drivers/scsi/be2iscsi/be.h b/drivers/scsi/be2iscsi/be.h
new file mode 100644
index 000000000000..b36020dcf012
--- /dev/null
+++ b/drivers/scsi/be2iscsi/be.h
@@ -0,0 +1,183 @@
1/**
2 * Copyright (C) 2005 - 2009 ServerEngines
3 * All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License version 2
7 * as published by the Free Software Foundation. The full GNU General
8 * Public License is included in this distribution in the file called COPYING.
9 *
10 * Contact Information:
11 * linux-drivers@serverengines.com
12 *
13 * ServerEngines
14 * 209 N. Fair Oaks Ave
15 * Sunnyvale, CA 94085
16 */
17
18#ifndef BEISCSI_H
19#define BEISCSI_H
20
21#include <linux/pci.h>
22#include <linux/if_vlan.h>
23
24#define FW_VER_LEN 32
25
26struct be_dma_mem {
27 void *va;
28 dma_addr_t dma;
29 u32 size;
30};
31
32struct be_queue_info {
33 struct be_dma_mem dma_mem;
34 u16 len;
35 u16 entry_size; /* Size of an element in the queue */
36 u16 id;
37 u16 tail, head;
38 bool created;
39 atomic_t used; /* Number of valid elements in the queue */
40};
41
42static inline u32 MODULO(u16 val, u16 limit)
43{
44 WARN_ON(limit & (limit - 1));
45 return val & (limit - 1);
46}
47
48static inline void index_inc(u16 *index, u16 limit)
49{
50 *index = MODULO((*index + 1), limit);
51}
52
53static inline void *queue_head_node(struct be_queue_info *q)
54{
55 return q->dma_mem.va + q->head * q->entry_size;
56}
57
58static inline void *queue_tail_node(struct be_queue_info *q)
59{
60 return q->dma_mem.va + q->tail * q->entry_size;
61}
62
63static inline void queue_head_inc(struct be_queue_info *q)
64{
65 index_inc(&q->head, q->len);
66}
67
68static inline void queue_tail_inc(struct be_queue_info *q)
69{
70 index_inc(&q->tail, q->len);
71}
72
73/*ISCSI */
74
75struct be_eq_obj {
76 struct be_queue_info q;
77 char desc[32];
78
79 /* Adaptive interrupt coalescing (AIC) info */
80 bool enable_aic;
81 u16 min_eqd; /* in usecs */
82 u16 max_eqd; /* in usecs */
83 u16 cur_eqd; /* in usecs */
84};
85
86struct be_mcc_obj {
87 struct be_queue_info *q;
88 struct be_queue_info *cq;
89};
90
91struct be_ctrl_info {
92 u8 __iomem *csr;
93 u8 __iomem *db; /* Door Bell */
94 u8 __iomem *pcicfg; /* PCI config space */
95 struct pci_dev *pdev;
96
97 /* Mbox used for cmd request/response */
98 spinlock_t mbox_lock; /* For serializing mbox cmds to BE card */
99 struct be_dma_mem mbox_mem;
100 /* Mbox mem is adjusted to align to 16 bytes. The allocated addr
101 * is stored for freeing purpose */
102 struct be_dma_mem mbox_mem_alloced;
103
104 /* MCC Rings */
105 struct be_mcc_obj mcc_obj;
106 spinlock_t mcc_lock; /* For serializing mcc cmds to BE card */
107 spinlock_t mcc_cq_lock;
108
109 /* MCC Async callback */
110 void (*async_cb) (void *adapter, bool link_up);
111 void *adapter_ctxt;
112};
113
114#include "be_cmds.h"
115
116#define PAGE_SHIFT_4K 12
117#define PAGE_SIZE_4K (1 << PAGE_SHIFT_4K)
118
119/* Returns number of pages spanned by the data starting at the given addr */
120#define PAGES_4K_SPANNED(_address, size) \
121 ((u32)((((size_t)(_address) & (PAGE_SIZE_4K - 1)) + \
122 (size) + (PAGE_SIZE_4K - 1)) >> PAGE_SHIFT_4K))
123
124/* Byte offset into the page corresponding to given address */
125#define OFFSET_IN_PAGE(addr) \
126 ((size_t)(addr) & (PAGE_SIZE_4K-1))
127
128/* Returns bit offset within a DWORD of a bitfield */
129#define AMAP_BIT_OFFSET(_struct, field) \
130 (((size_t)&(((_struct *)0)->field))%32)
131
132/* Returns the bit mask of the field that is NOT shifted into location. */
133static inline u32 amap_mask(u32 bitsize)
134{
135 return (bitsize == 32 ? 0xFFFFFFFF : (1 << bitsize) - 1);
136}
137
138static inline void amap_set(void *ptr, u32 dw_offset, u32 mask,
139 u32 offset, u32 value)
140{
141 u32 *dw = (u32 *) ptr + dw_offset;
142 *dw &= ~(mask << offset);
143 *dw |= (mask & value) << offset;
144}
145
146#define AMAP_SET_BITS(_struct, field, ptr, val) \
147 amap_set(ptr, \
148 offsetof(_struct, field)/32, \
149 amap_mask(sizeof(((_struct *)0)->field)), \
150 AMAP_BIT_OFFSET(_struct, field), \
151 val)
152
153static inline u32 amap_get(void *ptr, u32 dw_offset, u32 mask, u32 offset)
154{
155 u32 *dw = ptr;
156 return mask & (*(dw + dw_offset) >> offset);
157}
158
159#define AMAP_GET_BITS(_struct, field, ptr) \
160 amap_get(ptr, \
161 offsetof(_struct, field)/32, \
162 amap_mask(sizeof(((_struct *)0)->field)), \
163 AMAP_BIT_OFFSET(_struct, field))
164
165#define be_dws_cpu_to_le(wrb, len) swap_dws(wrb, len)
166#define be_dws_le_to_cpu(wrb, len) swap_dws(wrb, len)
167static inline void swap_dws(void *wrb, int len)
168{
169#ifdef __BIG_ENDIAN
170 u32 *dw = wrb;
171 WARN_ON(len % 4);
172 do {
173 *dw = cpu_to_le32(*dw);
174 dw++;
175 len -= 4;
176 } while (len);
177#endif /* __BIG_ENDIAN */
178}
179
180extern void beiscsi_cq_notify(struct be_ctrl_info *ctrl, u16 qid, bool arm,
181 u16 num_popped);
182
183#endif /* BEISCSI_H */
diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
new file mode 100644
index 000000000000..08007b6e42df
--- /dev/null
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -0,0 +1,523 @@
1/**
2 * Copyright (C) 2005 - 2009 ServerEngines
3 * All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License version 2
7 * as published by the Free Software Foundation. The full GNU General
8 * Public License is included in this distribution in the file called COPYING.
9 *
10 * Contact Information:
11 * linux-drivers@serverengines.com
12 *
13 * ServerEngines
14 * 209 N. Fair Oaks Ave
15 * Sunnyvale, CA 94085
16 */
17
18#include "be.h"
19#include "be_mgmt.h"
20#include "be_main.h"
21
22static inline bool be_mcc_compl_is_new(struct be_mcc_compl *compl)
23{
24 if (compl->flags != 0) {
25 compl->flags = le32_to_cpu(compl->flags);
26 WARN_ON((compl->flags & CQE_FLAGS_VALID_MASK) == 0);
27 return true;
28 } else
29 return false;
30}
31
32static inline void be_mcc_compl_use(struct be_mcc_compl *compl)
33{
34 compl->flags = 0;
35}
36
37static int be_mcc_compl_process(struct be_ctrl_info *ctrl,
38 struct be_mcc_compl *compl)
39{
40 u16 compl_status, extd_status;
41
42 be_dws_le_to_cpu(compl, 4);
43
44 compl_status = (compl->status >> CQE_STATUS_COMPL_SHIFT) &
45 CQE_STATUS_COMPL_MASK;
46 if (compl_status != MCC_STATUS_SUCCESS) {
47 extd_status = (compl->status >> CQE_STATUS_EXTD_SHIFT) &
48 CQE_STATUS_EXTD_MASK;
49 dev_err(&ctrl->pdev->dev,
50 "error in cmd completion: status(compl/extd)=%d/%d\n",
51 compl_status, extd_status);
52 return -1;
53 }
54 return 0;
55}
56
57static inline bool is_link_state_evt(u32 trailer)
58{
59 return (((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) &
60 ASYNC_TRAILER_EVENT_CODE_MASK) == ASYNC_EVENT_CODE_LINK_STATE);
61}
62
63void beiscsi_cq_notify(struct be_ctrl_info *ctrl, u16 qid, bool arm,
64 u16 num_popped)
65{
66 u32 val = 0;
67 val |= qid & DB_CQ_RING_ID_MASK;
68 if (arm)
69 val |= 1 << DB_CQ_REARM_SHIFT;
70 val |= num_popped << DB_CQ_NUM_POPPED_SHIFT;
71 iowrite32(val, ctrl->db + DB_CQ_OFFSET);
72}
73
74static int be_mbox_db_ready_wait(struct be_ctrl_info *ctrl)
75{
76#define long_delay 2000
77 void __iomem *db = ctrl->db + MPU_MAILBOX_DB_OFFSET;
78 int cnt = 0, wait = 5; /* in usecs */
79 u32 ready;
80
81 do {
82 ready = ioread32(db) & MPU_MAILBOX_DB_RDY_MASK;
83 if (ready)
84 break;
85
86 if (cnt > 6000000) {
87 dev_err(&ctrl->pdev->dev, "mbox_db poll timed out\n");
88 return -1;
89 }
90
91 if (cnt > 50) {
92 wait = long_delay;
93 mdelay(long_delay / 1000);
94 } else
95 udelay(wait);
96 cnt += wait;
97 } while (true);
98 return 0;
99}
100
101int be_mbox_notify(struct be_ctrl_info *ctrl)
102{
103 int status;
104 u32 val = 0;
105 void __iomem *db = ctrl->db + MPU_MAILBOX_DB_OFFSET;
106 struct be_dma_mem *mbox_mem = &ctrl->mbox_mem;
107 struct be_mcc_mailbox *mbox = mbox_mem->va;
108 struct be_mcc_compl *compl = &mbox->compl;
109
110 val &= ~MPU_MAILBOX_DB_RDY_MASK;
111 val |= MPU_MAILBOX_DB_HI_MASK;
112 val |= (upper_32_bits(mbox_mem->dma) >> 2) << 2;
113 iowrite32(val, db);
114
115 status = be_mbox_db_ready_wait(ctrl);
116 if (status != 0) {
117 SE_DEBUG(DBG_LVL_1, " be_mbox_db_ready_wait failed 1\n");
118 return status;
119 }
120 val = 0;
121 val &= ~MPU_MAILBOX_DB_RDY_MASK;
122 val &= ~MPU_MAILBOX_DB_HI_MASK;
123 val |= (u32) (mbox_mem->dma >> 4) << 2;
124 iowrite32(val, db);
125
126 status = be_mbox_db_ready_wait(ctrl);
127 if (status != 0) {
128 SE_DEBUG(DBG_LVL_1, " be_mbox_db_ready_wait failed 2\n");
129 return status;
130 }
131 if (be_mcc_compl_is_new(compl)) {
132 status = be_mcc_compl_process(ctrl, &mbox->compl);
133 be_mcc_compl_use(compl);
134 if (status) {
135 SE_DEBUG(DBG_LVL_1, "After be_mcc_compl_process \n");
136 return status;
137 }
138 } else {
139 dev_err(&ctrl->pdev->dev, "invalid mailbox completion\n");
140 return -1;
141 }
142 return 0;
143}
144
145void be_wrb_hdr_prepare(struct be_mcc_wrb *wrb, int payload_len,
146 bool embedded, u8 sge_cnt)
147{
148 if (embedded)
149 wrb->embedded |= MCC_WRB_EMBEDDED_MASK;
150 else
151 wrb->embedded |= (sge_cnt & MCC_WRB_SGE_CNT_MASK) <<
152 MCC_WRB_SGE_CNT_SHIFT;
153 wrb->payload_length = payload_len;
154 be_dws_cpu_to_le(wrb, 8);
155}
156
157void be_cmd_hdr_prepare(struct be_cmd_req_hdr *req_hdr,
158 u8 subsystem, u8 opcode, int cmd_len)
159{
160 req_hdr->opcode = opcode;
161 req_hdr->subsystem = subsystem;
162 req_hdr->request_length = cpu_to_le32(cmd_len - sizeof(*req_hdr));
163}
164
165static void be_cmd_page_addrs_prepare(struct phys_addr *pages, u32 max_pages,
166 struct be_dma_mem *mem)
167{
168 int i, buf_pages;
169 u64 dma = (u64) mem->dma;
170
171 buf_pages = min(PAGES_4K_SPANNED(mem->va, mem->size), max_pages);
172 for (i = 0; i < buf_pages; i++) {
173 pages[i].lo = cpu_to_le32(dma & 0xFFFFFFFF);
174 pages[i].hi = cpu_to_le32(upper_32_bits(dma));
175 dma += PAGE_SIZE_4K;
176 }
177}
178
179static u32 eq_delay_to_mult(u32 usec_delay)
180{
181#define MAX_INTR_RATE 651042
182 const u32 round = 10;
183 u32 multiplier;
184
185 if (usec_delay == 0)
186 multiplier = 0;
187 else {
188 u32 interrupt_rate = 1000000 / usec_delay;
189 if (interrupt_rate == 0)
190 multiplier = 1023;
191 else {
192 multiplier = (MAX_INTR_RATE - interrupt_rate) * round;
193 multiplier /= interrupt_rate;
194 multiplier = (multiplier + round / 2) / round;
195 multiplier = min(multiplier, (u32) 1023);
196 }
197 }
198 return multiplier;
199}
200
201struct be_mcc_wrb *wrb_from_mbox(struct be_dma_mem *mbox_mem)
202{
203 return &((struct be_mcc_mailbox *)(mbox_mem->va))->wrb;
204}
205
206int beiscsi_cmd_eq_create(struct be_ctrl_info *ctrl,
207 struct be_queue_info *eq, int eq_delay)
208{
209 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
210 struct be_cmd_req_eq_create *req = embedded_payload(wrb);
211 struct be_cmd_resp_eq_create *resp = embedded_payload(wrb);
212 struct be_dma_mem *q_mem = &eq->dma_mem;
213 int status;
214
215 spin_lock(&ctrl->mbox_lock);
216 memset(wrb, 0, sizeof(*wrb));
217
218 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
219
220 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
221 OPCODE_COMMON_EQ_CREATE, sizeof(*req));
222
223 req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
224
225 AMAP_SET_BITS(struct amap_eq_context, func, req->context,
226 PCI_FUNC(ctrl->pdev->devfn));
227 AMAP_SET_BITS(struct amap_eq_context, valid, req->context, 1);
228 AMAP_SET_BITS(struct amap_eq_context, size, req->context, 0);
229 AMAP_SET_BITS(struct amap_eq_context, count, req->context,
230 __ilog2_u32(eq->len / 256));
231 AMAP_SET_BITS(struct amap_eq_context, delaymult, req->context,
232 eq_delay_to_mult(eq_delay));
233 be_dws_cpu_to_le(req->context, sizeof(req->context));
234
235 be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
236
237 status = be_mbox_notify(ctrl);
238 if (!status) {
239 eq->id = le16_to_cpu(resp->eq_id);
240 eq->created = true;
241 }
242 spin_unlock(&ctrl->mbox_lock);
243 return status;
244}
245
246int be_cmd_fw_initialize(struct be_ctrl_info *ctrl)
247{
248 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
249 int status;
250 u8 *endian_check;
251
252 spin_lock(&ctrl->mbox_lock);
253 memset(wrb, 0, sizeof(*wrb));
254
255 endian_check = (u8 *) wrb;
256 *endian_check++ = 0xFF;
257 *endian_check++ = 0x12;
258 *endian_check++ = 0x34;
259 *endian_check++ = 0xFF;
260 *endian_check++ = 0xFF;
261 *endian_check++ = 0x56;
262 *endian_check++ = 0x78;
263 *endian_check++ = 0xFF;
264 be_dws_cpu_to_le(wrb, sizeof(*wrb));
265
266 status = be_mbox_notify(ctrl);
267 if (status)
268 SE_DEBUG(DBG_LVL_1, "be_cmd_fw_initialize Failed \n");
269
270 spin_unlock(&ctrl->mbox_lock);
271 return status;
272}
273
274int beiscsi_cmd_cq_create(struct be_ctrl_info *ctrl,
275 struct be_queue_info *cq, struct be_queue_info *eq,
276 bool sol_evts, bool no_delay, int coalesce_wm)
277{
278 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
279 struct be_cmd_req_cq_create *req = embedded_payload(wrb);
280 struct be_cmd_resp_cq_create *resp = embedded_payload(wrb);
281 struct be_dma_mem *q_mem = &cq->dma_mem;
282 void *ctxt = &req->context;
283 int status;
284
285 spin_lock(&ctrl->mbox_lock);
286 memset(wrb, 0, sizeof(*wrb));
287
288 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
289
290 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
291 OPCODE_COMMON_CQ_CREATE, sizeof(*req));
292
293 if (!q_mem->va)
294 SE_DEBUG(DBG_LVL_1, "uninitialized q_mem->va\n");
295
296 req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
297
298 AMAP_SET_BITS(struct amap_cq_context, coalescwm, ctxt, coalesce_wm);
299 AMAP_SET_BITS(struct amap_cq_context, nodelay, ctxt, no_delay);
300 AMAP_SET_BITS(struct amap_cq_context, count, ctxt,
301 __ilog2_u32(cq->len / 256));
302 AMAP_SET_BITS(struct amap_cq_context, valid, ctxt, 1);
303 AMAP_SET_BITS(struct amap_cq_context, solevent, ctxt, sol_evts);
304 AMAP_SET_BITS(struct amap_cq_context, eventable, ctxt, 1);
305 AMAP_SET_BITS(struct amap_cq_context, eqid, ctxt, eq->id);
306 AMAP_SET_BITS(struct amap_cq_context, armed, ctxt, 1);
307 AMAP_SET_BITS(struct amap_cq_context, func, ctxt,
308 PCI_FUNC(ctrl->pdev->devfn));
309 be_dws_cpu_to_le(ctxt, sizeof(req->context));
310
311 be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
312
313 status = be_mbox_notify(ctrl);
314 if (!status) {
315 cq->id = le16_to_cpu(resp->cq_id);
316 cq->created = true;
317 } else
318 SE_DEBUG(DBG_LVL_1, "In be_cmd_cq_create, status=ox%08x \n",
319 status);
320 spin_unlock(&ctrl->mbox_lock);
321
322 return status;
323}
324
325static u32 be_encoded_q_len(int q_len)
326{
327 u32 len_encoded = fls(q_len); /* log2(len) + 1 */
328 if (len_encoded == 16)
329 len_encoded = 0;
330 return len_encoded;
331}
332int beiscsi_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q,
333 int queue_type)
334{
335 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
336 struct be_cmd_req_q_destroy *req = embedded_payload(wrb);
337 u8 subsys = 0, opcode = 0;
338 int status;
339
340 spin_lock(&ctrl->mbox_lock);
341 memset(wrb, 0, sizeof(*wrb));
342 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
343
344 switch (queue_type) {
345 case QTYPE_EQ:
346 subsys = CMD_SUBSYSTEM_COMMON;
347 opcode = OPCODE_COMMON_EQ_DESTROY;
348 break;
349 case QTYPE_CQ:
350 subsys = CMD_SUBSYSTEM_COMMON;
351 opcode = OPCODE_COMMON_CQ_DESTROY;
352 break;
353 case QTYPE_WRBQ:
354 subsys = CMD_SUBSYSTEM_ISCSI;
355 opcode = OPCODE_COMMON_ISCSI_WRBQ_DESTROY;
356 break;
357 case QTYPE_DPDUQ:
358 subsys = CMD_SUBSYSTEM_ISCSI;
359 opcode = OPCODE_COMMON_ISCSI_DEFQ_DESTROY;
360 break;
361 case QTYPE_SGL:
362 subsys = CMD_SUBSYSTEM_ISCSI;
363 opcode = OPCODE_COMMON_ISCSI_CFG_REMOVE_SGL_PAGES;
364 break;
365 default:
366 spin_unlock(&ctrl->mbox_lock);
367 BUG();
368 return -1;
369 }
370 be_cmd_hdr_prepare(&req->hdr, subsys, opcode, sizeof(*req));
371 if (queue_type != QTYPE_SGL)
372 req->id = cpu_to_le16(q->id);
373
374 status = be_mbox_notify(ctrl);
375
376 spin_unlock(&ctrl->mbox_lock);
377 return status;
378}
379
380int be_cmd_get_mac_addr(struct be_ctrl_info *ctrl, u8 *mac_addr)
381{
382 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
383 struct be_cmd_req_get_mac_addr *req = embedded_payload(wrb);
384 int status;
385
386 spin_lock(&ctrl->mbox_lock);
387 memset(wrb, 0, sizeof(*wrb));
388 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
389 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
390 OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG,
391 sizeof(*req));
392
393 status = be_mbox_notify(ctrl);
394 if (!status) {
395 struct be_cmd_resp_get_mac_addr *resp = embedded_payload(wrb);
396
397 memcpy(mac_addr, resp->mac_address, ETH_ALEN);
398 }
399
400 spin_unlock(&ctrl->mbox_lock);
401 return status;
402}
403
404int be_cmd_create_default_pdu_queue(struct be_ctrl_info *ctrl,
405 struct be_queue_info *cq,
406 struct be_queue_info *dq, int length,
407 int entry_size)
408{
409 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
410 struct be_defq_create_req *req = embedded_payload(wrb);
411 struct be_dma_mem *q_mem = &dq->dma_mem;
412 void *ctxt = &req->context;
413 int status;
414
415 spin_lock(&ctrl->mbox_lock);
416 memset(wrb, 0, sizeof(*wrb));
417
418 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
419
420 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
421 OPCODE_COMMON_ISCSI_DEFQ_CREATE, sizeof(*req));
422
423 req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size);
424 AMAP_SET_BITS(struct amap_be_default_pdu_context, rx_pdid, ctxt, 0);
425 AMAP_SET_BITS(struct amap_be_default_pdu_context, rx_pdid_valid, ctxt,
426 1);
427 AMAP_SET_BITS(struct amap_be_default_pdu_context, pci_func_id, ctxt,
428 PCI_FUNC(ctrl->pdev->devfn));
429 AMAP_SET_BITS(struct amap_be_default_pdu_context, ring_size, ctxt,
430 be_encoded_q_len(length / sizeof(struct phys_addr)));
431 AMAP_SET_BITS(struct amap_be_default_pdu_context, default_buffer_size,
432 ctxt, entry_size);
433 AMAP_SET_BITS(struct amap_be_default_pdu_context, cq_id_recv, ctxt,
434 cq->id);
435
436 be_dws_cpu_to_le(ctxt, sizeof(req->context));
437
438 be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
439
440 status = be_mbox_notify(ctrl);
441 if (!status) {
442 struct be_defq_create_resp *resp = embedded_payload(wrb);
443
444 dq->id = le16_to_cpu(resp->id);
445 dq->created = true;
446 }
447 spin_unlock(&ctrl->mbox_lock);
448
449 return status;
450}
451
452int be_cmd_wrbq_create(struct be_ctrl_info *ctrl, struct be_dma_mem *q_mem,
453 struct be_queue_info *wrbq)
454{
455 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
456 struct be_wrbq_create_req *req = embedded_payload(wrb);
457 struct be_wrbq_create_resp *resp = embedded_payload(wrb);
458 int status;
459
460 spin_lock(&ctrl->mbox_lock);
461 memset(wrb, 0, sizeof(*wrb));
462
463 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
464
465 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
466 OPCODE_COMMON_ISCSI_WRBQ_CREATE, sizeof(*req));
467 req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size);
468 be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
469
470 status = be_mbox_notify(ctrl);
471 if (!status)
472 wrbq->id = le16_to_cpu(resp->cid);
473 spin_unlock(&ctrl->mbox_lock);
474 return status;
475}
476
477int be_cmd_iscsi_post_sgl_pages(struct be_ctrl_info *ctrl,
478 struct be_dma_mem *q_mem,
479 u32 page_offset, u32 num_pages)
480{
481 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
482 struct be_post_sgl_pages_req *req = embedded_payload(wrb);
483 int status;
484 unsigned int curr_pages;
485 u32 internal_page_offset = 0;
486 u32 temp_num_pages = num_pages;
487
488 if (num_pages == 0xff)
489 num_pages = 1;
490
491 spin_lock(&ctrl->mbox_lock);
492 do {
493 memset(wrb, 0, sizeof(*wrb));
494 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
495 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
496 OPCODE_COMMON_ISCSI_CFG_POST_SGL_PAGES,
497 sizeof(*req));
498 curr_pages = BE_NUMBER_OF_FIELD(struct be_post_sgl_pages_req,
499 pages);
500 req->num_pages = min(num_pages, curr_pages);
501 req->page_offset = page_offset;
502 be_cmd_page_addrs_prepare(req->pages, req->num_pages, q_mem);
503 q_mem->dma = q_mem->dma + (req->num_pages * PAGE_SIZE);
504 internal_page_offset += req->num_pages;
505 page_offset += req->num_pages;
506 num_pages -= req->num_pages;
507
508 if (temp_num_pages == 0xff)
509 req->num_pages = temp_num_pages;
510
511 status = be_mbox_notify(ctrl);
512 if (status) {
513 SE_DEBUG(DBG_LVL_1,
514 "FW CMD to map iscsi frags failed.\n");
515 goto error;
516 }
517 } while (num_pages > 0);
518error:
519 spin_unlock(&ctrl->mbox_lock);
520 if (status != 0)
521 beiscsi_cmd_q_destroy(ctrl, NULL, QTYPE_SGL);
522 return status;
523}
diff --git a/drivers/scsi/be2iscsi/be_cmds.h b/drivers/scsi/be2iscsi/be_cmds.h
new file mode 100644
index 000000000000..c20d686cbb43
--- /dev/null
+++ b/drivers/scsi/be2iscsi/be_cmds.h
@@ -0,0 +1,877 @@
1/**
2 * Copyright (C) 2005 - 2009 ServerEngines
3 * All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License version 2
7 * as published by the Free Software Foundation. The full GNU General
8 * Public License is included in this distribution in the file called COPYING.
9 *
10 * Contact Information:
11 * linux-drivers@serverengines.com
12 *
13 * ServerEngines
14 * 209 N. Fair Oaks Ave
15 * Sunnyvale, CA 94085
16 */
17
18#ifndef BEISCSI_CMDS_H
19#define BEISCSI_CMDS_H
20
21/**
22 * The driver sends configuration and managements command requests to the
23 * firmware in the BE. These requests are communicated to the processor
24 * using Work Request Blocks (WRBs) submitted to the MCC-WRB ring or via one
25 * WRB inside a MAILBOX.
26 * The commands are serviced by the ARM processor in the BladeEngine's MPU.
27 */
28struct be_sge {
29 u32 pa_lo;
30 u32 pa_hi;
31 u32 len;
32};
33
34#define MCC_WRB_SGE_CNT_SHIFT 3 /* bits 3 - 7 of dword 0 */
35#define MCC_WRB_SGE_CNT_MASK 0x1F /* bits 3 - 7 of dword 0 */
36struct be_mcc_wrb {
37 u32 embedded; /* dword 0 */
38 u32 payload_length; /* dword 1 */
39 u32 tag0; /* dword 2 */
40 u32 tag1; /* dword 3 */
41 u32 rsvd; /* dword 4 */
42 union {
43 u8 embedded_payload[236]; /* used by embedded cmds */
44 struct be_sge sgl[19]; /* used by non-embedded cmds */
45 } payload;
46};
47
48#define CQE_FLAGS_VALID_MASK (1 << 31)
49#define CQE_FLAGS_ASYNC_MASK (1 << 30)
50
51/* Completion Status */
52#define MCC_STATUS_SUCCESS 0x0
53
54#define CQE_STATUS_COMPL_MASK 0xFFFF
55#define CQE_STATUS_COMPL_SHIFT 0 /* bits 0 - 15 */
56#define CQE_STATUS_EXTD_MASK 0xFFFF
57#define CQE_STATUS_EXTD_SHIFT 0 /* bits 0 - 15 */
58
59struct be_mcc_compl {
60 u32 status; /* dword 0 */
61 u32 tag0; /* dword 1 */
62 u32 tag1; /* dword 2 */
63 u32 flags; /* dword 3 */
64};
65
66/********* Mailbox door bell *************/
67/**
68 * Used for driver communication with the FW.
69 * The software must write this register twice to post any command. First,
70 * it writes the register with hi=1 and the upper bits of the physical address
71 * for the MAILBOX structure. Software must poll the ready bit until this
72 * is acknowledged. Then, sotware writes the register with hi=0 with the lower
73 * bits in the address. It must poll the ready bit until the command is
74 * complete. Upon completion, the MAILBOX will contain a valid completion
75 * queue entry.
76 */
77#define MPU_MAILBOX_DB_OFFSET 0x160
78#define MPU_MAILBOX_DB_RDY_MASK 0x1 /* bit 0 */
79#define MPU_MAILBOX_DB_HI_MASK 0x2 /* bit 1 */
80
81/********** MPU semphore ******************/
82#define MPU_EP_SEMAPHORE_OFFSET 0xac
83#define EP_SEMAPHORE_POST_STAGE_MASK 0x0000FFFF
84#define EP_SEMAPHORE_POST_ERR_MASK 0x1
85#define EP_SEMAPHORE_POST_ERR_SHIFT 31
86
87/********** MCC door bell ************/
88#define DB_MCCQ_OFFSET 0x140
89#define DB_MCCQ_RING_ID_MASK 0x7FF /* bits 0 - 10 */
90/* Number of entries posted */
91#define DB_MCCQ_NUM_POSTED_SHIFT 16 /* bits 16 - 29 */
92
93/* MPU semphore POST stage values */
94#define POST_STAGE_ARMFW_RDY 0xc000 /* FW is done with POST */
95
96/**
97 * When the async bit of mcc_compl is set, the last 4 bytes of
98 * mcc_compl is interpreted as follows:
99 */
100#define ASYNC_TRAILER_EVENT_CODE_SHIFT 8 /* bits 8 - 15 */
101#define ASYNC_TRAILER_EVENT_CODE_MASK 0xFF
102#define ASYNC_EVENT_CODE_LINK_STATE 0x1
103struct be_async_event_trailer {
104 u32 code;
105};
106
107enum {
108 ASYNC_EVENT_LINK_DOWN = 0x0,
109 ASYNC_EVENT_LINK_UP = 0x1
110};
111
112/**
113 * When the event code of an async trailer is link-state, the mcc_compl
114 * must be interpreted as follows
115 */
116struct be_async_event_link_state {
117 u8 physical_port;
118 u8 port_link_status;
119 u8 port_duplex;
120 u8 port_speed;
121 u8 port_fault;
122 u8 rsvd0[7];
123 struct be_async_event_trailer trailer;
124} __packed;
125
126struct be_mcc_mailbox {
127 struct be_mcc_wrb wrb;
128 struct be_mcc_compl compl;
129};
130
131/* Type of subsystems supported by FW */
132#define CMD_SUBSYSTEM_COMMON 0x1
133#define CMD_SUBSYSTEM_ISCSI 0x2
134#define CMD_SUBSYSTEM_ETH 0x3
135#define CMD_SUBSYSTEM_ISCSI_INI 0x6
136#define CMD_COMMON_TCP_UPLOAD 0x1
137
138/**
139 * List of common opcodes subsystem CMD_SUBSYSTEM_COMMON
140 * These opcodes are unique for each subsystem defined above
141 */
142#define OPCODE_COMMON_CQ_CREATE 12
143#define OPCODE_COMMON_EQ_CREATE 13
144#define OPCODE_COMMON_MCC_CREATE 21
145#define OPCODE_COMMON_GET_CNTL_ATTRIBUTES 32
146#define OPCODE_COMMON_GET_FW_VERSION 35
147#define OPCODE_COMMON_MODIFY_EQ_DELAY 41
148#define OPCODE_COMMON_FIRMWARE_CONFIG 42
149#define OPCODE_COMMON_MCC_DESTROY 53
150#define OPCODE_COMMON_CQ_DESTROY 54
151#define OPCODE_COMMON_EQ_DESTROY 55
152#define OPCODE_COMMON_QUERY_FIRMWARE_CONFIG 58
153#define OPCODE_COMMON_FUNCTION_RESET 61
154
155/**
156 * LIST of opcodes that are common between Initiator and Target
157 * used by CMD_SUBSYSTEM_ISCSI
158 * These opcodes are unique for each subsystem defined above
159 */
160#define OPCODE_COMMON_ISCSI_CFG_POST_SGL_PAGES 2
161#define OPCODE_COMMON_ISCSI_CFG_REMOVE_SGL_PAGES 3
162#define OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG 7
163#define OPCODE_COMMON_ISCSI_SET_FRAGNUM_BITS_FOR_SGL_CRA 61
164#define OPCODE_COMMON_ISCSI_DEFQ_CREATE 64
165#define OPCODE_COMMON_ISCSI_DEFQ_DESTROY 65
166#define OPCODE_COMMON_ISCSI_WRBQ_CREATE 66
167#define OPCODE_COMMON_ISCSI_WRBQ_DESTROY 67
168
169struct be_cmd_req_hdr {
170 u8 opcode; /* dword 0 */
171 u8 subsystem; /* dword 0 */
172 u8 port_number; /* dword 0 */
173 u8 domain; /* dword 0 */
174 u32 timeout; /* dword 1 */
175 u32 request_length; /* dword 2 */
176 u32 rsvd; /* dword 3 */
177};
178
179struct be_cmd_resp_hdr {
180 u32 info; /* dword 0 */
181 u32 status; /* dword 1 */
182 u32 response_length; /* dword 2 */
183 u32 actual_resp_len; /* dword 3 */
184};
185
186struct phys_addr {
187 u32 lo;
188 u32 hi;
189};
190
191/**************************
192 * BE Command definitions *
193 **************************/
194
195/**
196 * Pseudo amap definition in which each bit of the actual structure is defined
197 * as a byte - used to calculate offset/shift/mask of each field
198 */
199struct amap_eq_context {
200 u8 cidx[13]; /* dword 0 */
201 u8 rsvd0[3]; /* dword 0 */
202 u8 epidx[13]; /* dword 0 */
203 u8 valid; /* dword 0 */
204 u8 rsvd1; /* dword 0 */
205 u8 size; /* dword 0 */
206 u8 pidx[13]; /* dword 1 */
207 u8 rsvd2[3]; /* dword 1 */
208 u8 pd[10]; /* dword 1 */
209 u8 count[3]; /* dword 1 */
210 u8 solevent; /* dword 1 */
211 u8 stalled; /* dword 1 */
212 u8 armed; /* dword 1 */
213 u8 rsvd3[4]; /* dword 2 */
214 u8 func[8]; /* dword 2 */
215 u8 rsvd4; /* dword 2 */
216 u8 delaymult[10]; /* dword 2 */
217 u8 rsvd5[2]; /* dword 2 */
218 u8 phase[2]; /* dword 2 */
219 u8 nodelay; /* dword 2 */
220 u8 rsvd6[4]; /* dword 2 */
221 u8 rsvd7[32]; /* dword 3 */
222} __packed;
223
224struct be_cmd_req_eq_create {
225 struct be_cmd_req_hdr hdr; /* dw[4] */
226 u16 num_pages; /* sword */
227 u16 rsvd0; /* sword */
228 u8 context[sizeof(struct amap_eq_context) / 8]; /* dw[4] */
229 struct phys_addr pages[8];
230} __packed;
231
232struct be_cmd_resp_eq_create {
233 struct be_cmd_resp_hdr resp_hdr;
234 u16 eq_id; /* sword */
235 u16 rsvd0; /* sword */
236} __packed;
237
238struct mac_addr {
239 u16 size_of_struct;
240 u8 addr[ETH_ALEN];
241} __packed;
242
243struct be_cmd_req_mac_query {
244 struct be_cmd_req_hdr hdr;
245 u8 type;
246 u8 permanent;
247 u16 if_id;
248} __packed;
249
250struct be_cmd_resp_mac_query {
251 struct be_cmd_resp_hdr hdr;
252 struct mac_addr mac;
253};
254
255/******************** Create CQ ***************************/
256/**
257 * Pseudo amap definition in which each bit of the actual structure is defined
258 * as a byte - used to calculate offset/shift/mask of each field
259 */
260struct amap_cq_context {
261 u8 cidx[11]; /* dword 0 */
262 u8 rsvd0; /* dword 0 */
263 u8 coalescwm[2]; /* dword 0 */
264 u8 nodelay; /* dword 0 */
265 u8 epidx[11]; /* dword 0 */
266 u8 rsvd1; /* dword 0 */
267 u8 count[2]; /* dword 0 */
268 u8 valid; /* dword 0 */
269 u8 solevent; /* dword 0 */
270 u8 eventable; /* dword 0 */
271 u8 pidx[11]; /* dword 1 */
272 u8 rsvd2; /* dword 1 */
273 u8 pd[10]; /* dword 1 */
274 u8 eqid[8]; /* dword 1 */
275 u8 stalled; /* dword 1 */
276 u8 armed; /* dword 1 */
277 u8 rsvd3[4]; /* dword 2 */
278 u8 func[8]; /* dword 2 */
279 u8 rsvd4[20]; /* dword 2 */
280 u8 rsvd5[32]; /* dword 3 */
281} __packed;
282
283struct be_cmd_req_cq_create {
284 struct be_cmd_req_hdr hdr;
285 u16 num_pages;
286 u16 rsvd0;
287 u8 context[sizeof(struct amap_cq_context) / 8];
288 struct phys_addr pages[4];
289} __packed;
290
291struct be_cmd_resp_cq_create {
292 struct be_cmd_resp_hdr hdr;
293 u16 cq_id;
294 u16 rsvd0;
295} __packed;
296
297/******************** Create MCCQ ***************************/
298/**
299 * Pseudo amap definition in which each bit of the actual structure is defined
300 * as a byte - used to calculate offset/shift/mask of each field
301 */
302struct amap_mcc_context {
303 u8 con_index[14];
304 u8 rsvd0[2];
305 u8 ring_size[4];
306 u8 fetch_wrb;
307 u8 fetch_r2t;
308 u8 cq_id[10];
309 u8 prod_index[14];
310 u8 fid[8];
311 u8 pdid[9];
312 u8 valid;
313 u8 rsvd1[32];
314 u8 rsvd2[32];
315} __packed;
316
317struct be_cmd_req_mcc_create {
318 struct be_cmd_req_hdr hdr;
319 u16 num_pages;
320 u16 rsvd0;
321 u8 context[sizeof(struct amap_mcc_context) / 8];
322 struct phys_addr pages[8];
323} __packed;
324
325struct be_cmd_resp_mcc_create {
326 struct be_cmd_resp_hdr hdr;
327 u16 id;
328 u16 rsvd0;
329} __packed;
330
331/******************** Q Destroy ***************************/
332/* Type of Queue to be destroyed */
333enum {
334 QTYPE_EQ = 1,
335 QTYPE_CQ,
336 QTYPE_MCCQ,
337 QTYPE_WRBQ,
338 QTYPE_DPDUQ,
339 QTYPE_SGL
340};
341
342struct be_cmd_req_q_destroy {
343 struct be_cmd_req_hdr hdr;
344 u16 id;
345 u16 bypass_flush; /* valid only for rx q destroy */
346} __packed;
347
348struct macaddr {
349 u8 byte[ETH_ALEN];
350};
351
352struct be_cmd_req_mcast_mac_config {
353 struct be_cmd_req_hdr hdr;
354 u16 num_mac;
355 u8 promiscuous;
356 u8 interface_id;
357 struct macaddr mac[32];
358} __packed;
359
360static inline void *embedded_payload(struct be_mcc_wrb *wrb)
361{
362 return wrb->payload.embedded_payload;
363}
364
365static inline struct be_sge *nonembedded_sgl(struct be_mcc_wrb *wrb)
366{
367 return &wrb->payload.sgl[0];
368}
369
370/******************** Modify EQ Delay *******************/
371struct be_cmd_req_modify_eq_delay {
372 struct be_cmd_req_hdr hdr;
373 u32 num_eq;
374 struct {
375 u32 eq_id;
376 u32 phase;
377 u32 delay_multiplier;
378 } delay[8];
379} __packed;
380
381/******************** Get MAC ADDR *******************/
382
383#define ETH_ALEN 6
384
385
386struct be_cmd_req_get_mac_addr {
387 struct be_cmd_req_hdr hdr;
388 u32 nic_port_count;
389 u32 speed;
390 u32 max_speed;
391 u32 link_state;
392 u32 max_frame_size;
393 u16 size_of_structure;
394 u8 mac_address[ETH_ALEN];
395 u32 rsvd[23];
396};
397
398struct be_cmd_resp_get_mac_addr {
399 struct be_cmd_resp_hdr hdr;
400 u32 nic_port_count;
401 u32 speed;
402 u32 max_speed;
403 u32 link_state;
404 u32 max_frame_size;
405 u16 size_of_structure;
406 u8 mac_address[6];
407 u32 rsvd[23];
408};
409
410int beiscsi_cmd_eq_create(struct be_ctrl_info *ctrl,
411 struct be_queue_info *eq, int eq_delay);
412
413int beiscsi_cmd_cq_create(struct be_ctrl_info *ctrl,
414 struct be_queue_info *cq, struct be_queue_info *eq,
415 bool sol_evts, bool no_delay,
416 int num_cqe_dma_coalesce);
417
418int beiscsi_cmd_q_destroy(struct be_ctrl_info *ctrl, struct be_queue_info *q,
419 int type);
420int be_poll_mcc(struct be_ctrl_info *ctrl);
421unsigned char mgmt_check_supported_fw(struct be_ctrl_info *ctrl);
422int be_cmd_get_mac_addr(struct be_ctrl_info *ctrl, u8 *mac_addr);
423
424/*ISCSI Functuions */
425int be_cmd_fw_initialize(struct be_ctrl_info *ctrl);
426
427struct be_mcc_wrb *wrb_from_mbox(struct be_dma_mem *mbox_mem);
428
429int be_mbox_notify(struct be_ctrl_info *ctrl);
430
431int be_cmd_create_default_pdu_queue(struct be_ctrl_info *ctrl,
432 struct be_queue_info *cq,
433 struct be_queue_info *dq, int length,
434 int entry_size);
435
436int be_cmd_iscsi_post_sgl_pages(struct be_ctrl_info *ctrl,
437 struct be_dma_mem *q_mem, u32 page_offset,
438 u32 num_pages);
439
440int be_cmd_wrbq_create(struct be_ctrl_info *ctrl, struct be_dma_mem *q_mem,
441 struct be_queue_info *wrbq);
442
443struct be_default_pdu_context {
444 u32 dw[4];
445} __packed;
446
447struct amap_be_default_pdu_context {
448 u8 dbuf_cindex[13]; /* dword 0 */
449 u8 rsvd0[3]; /* dword 0 */
450 u8 ring_size[4]; /* dword 0 */
451 u8 ring_state[4]; /* dword 0 */
452 u8 rsvd1[8]; /* dword 0 */
453 u8 dbuf_pindex[13]; /* dword 1 */
454 u8 rsvd2; /* dword 1 */
455 u8 pci_func_id[8]; /* dword 1 */
456 u8 rx_pdid[9]; /* dword 1 */
457 u8 rx_pdid_valid; /* dword 1 */
458 u8 default_buffer_size[16]; /* dword 2 */
459 u8 cq_id_recv[10]; /* dword 2 */
460 u8 rx_pdid_not_valid; /* dword 2 */
461 u8 rsvd3[5]; /* dword 2 */
462 u8 rsvd4[32]; /* dword 3 */
463} __packed;
464
465struct be_defq_create_req {
466 struct be_cmd_req_hdr hdr;
467 u16 num_pages;
468 u8 ulp_num;
469 u8 rsvd0;
470 struct be_default_pdu_context context;
471 struct phys_addr pages[8];
472} __packed;
473
474struct be_defq_create_resp {
475 struct be_cmd_req_hdr hdr;
476 u16 id;
477 u16 rsvd0;
478} __packed;
479
480struct be_post_sgl_pages_req {
481 struct be_cmd_req_hdr hdr;
482 u16 num_pages;
483 u16 page_offset;
484 u32 rsvd0;
485 struct phys_addr pages[26];
486 u32 rsvd1;
487} __packed;
488
489struct be_wrbq_create_req {
490 struct be_cmd_req_hdr hdr;
491 u16 num_pages;
492 u8 ulp_num;
493 u8 rsvd0;
494 struct phys_addr pages[8];
495} __packed;
496
497struct be_wrbq_create_resp {
498 struct be_cmd_resp_hdr resp_hdr;
499 u16 cid;
500 u16 rsvd0;
501} __packed;
502
503#define SOL_CID_MASK 0x0000FFC0
504#define SOL_CODE_MASK 0x0000003F
505#define SOL_WRB_INDEX_MASK 0x00FF0000
506#define SOL_CMD_WND_MASK 0xFF000000
507#define SOL_RES_CNT_MASK 0x7FFFFFFF
508#define SOL_EXP_CMD_SN_MASK 0xFFFFFFFF
509#define SOL_HW_STS_MASK 0x000000FF
510#define SOL_STS_MASK 0x0000FF00
511#define SOL_RESP_MASK 0x00FF0000
512#define SOL_FLAGS_MASK 0x7F000000
513#define SOL_S_MASK 0x80000000
514
515struct sol_cqe {
516 u32 dw[4];
517};
518
519struct amap_sol_cqe {
520 u8 hw_sts[8]; /* dword 0 */
521 u8 i_sts[8]; /* dword 0 */
522 u8 i_resp[8]; /* dword 0 */
523 u8 i_flags[7]; /* dword 0 */
524 u8 s; /* dword 0 */
525 u8 i_exp_cmd_sn[32]; /* dword 1 */
526 u8 code[6]; /* dword 2 */
527 u8 cid[10]; /* dword 2 */
528 u8 wrb_index[8]; /* dword 2 */
529 u8 i_cmd_wnd[8]; /* dword 2 */
530 u8 i_res_cnt[31]; /* dword 3 */
531 u8 valid; /* dword 3 */
532} __packed;
533
534
535/**
536 * Post WRB Queue Doorbell Register used by the host Storage
537 * stack to notify the
538 * controller of a posted Work Request Block
539 */
540#define DB_WRB_POST_CID_MASK 0x3FF /* bits 0 - 9 */
541#define DB_DEF_PDU_WRB_INDEX_MASK 0xFF /* bits 0 - 9 */
542
543#define DB_DEF_PDU_WRB_INDEX_SHIFT 16
544#define DB_DEF_PDU_NUM_POSTED_SHIFT 24
545
546struct fragnum_bits_for_sgl_cra_in {
547 struct be_cmd_req_hdr hdr;
548 u32 num_bits;
549} __packed;
550
551struct iscsi_cleanup_req {
552 struct be_cmd_req_hdr hdr;
553 u16 chute;
554 u8 hdr_ring_id;
555 u8 data_ring_id;
556
557} __packed;
558
559struct eq_delay {
560 u32 eq_id;
561 u32 phase;
562 u32 delay_multiplier;
563} __packed;
564
565struct be_eq_delay_params_in {
566 struct be_cmd_req_hdr hdr;
567 u32 num_eq;
568 struct eq_delay delay[8];
569} __packed;
570
571struct ip_address_format {
572 u16 size_of_structure;
573 u8 reserved;
574 u8 ip_type;
575 u8 ip_address[16];
576 u32 rsvd0;
577} __packed;
578
579struct tcp_connect_and_offload_in {
580 struct be_cmd_req_hdr hdr;
581 struct ip_address_format ip_address;
582 u16 tcp_port;
583 u16 cid;
584 u16 cq_id;
585 u16 defq_id;
586 struct phys_addr dataout_template_pa;
587 u16 hdr_ring_id;
588 u16 data_ring_id;
589 u8 do_offload;
590 u8 rsvd0[3];
591} __packed;
592
593struct tcp_connect_and_offload_out {
594 struct be_cmd_resp_hdr hdr;
595 u32 connection_handle;
596 u16 cid;
597 u16 rsvd0;
598
599} __packed;
600
601struct be_mcc_wrb_context {
602 struct MCC_WRB *wrb;
603 int *users_final_status;
604} __packed;
605
606#define DB_DEF_PDU_RING_ID_MASK 0x3FF /* bits 0 - 9 */
607#define DB_DEF_PDU_CQPROC_MASK 0x3FFF /* bits 0 - 9 */
608#define DB_DEF_PDU_REARM_SHIFT 14
609#define DB_DEF_PDU_EVENT_SHIFT 15
610#define DB_DEF_PDU_CQPROC_SHIFT 16
611
612struct dmsg_cqe {
613 u32 dw[4];
614} __packed;
615
616struct tcp_upload_params_in {
617 struct be_cmd_req_hdr hdr;
618 u16 id;
619 u16 upload_type;
620 u32 reset_seq;
621} __packed;
622
623struct tcp_upload_params_out {
624 u32 dw[32];
625} __packed;
626
627union tcp_upload_params {
628 struct tcp_upload_params_in request;
629 struct tcp_upload_params_out response;
630} __packed;
631
632struct be_ulp_fw_cfg {
633 u32 ulp_mode;
634 u32 etx_base;
635 u32 etx_count;
636 u32 sq_base;
637 u32 sq_count;
638 u32 rq_base;
639 u32 rq_count;
640 u32 dq_base;
641 u32 dq_count;
642 u32 lro_base;
643 u32 lro_count;
644 u32 icd_base;
645 u32 icd_count;
646};
647
648struct be_fw_cfg {
649 struct be_cmd_req_hdr hdr;
650 u32 be_config_number;
651 u32 asic_revision;
652 u32 phys_port;
653 u32 function_mode;
654 struct be_ulp_fw_cfg ulp[2];
655 u32 function_caps;
656} __packed;
657
658#define CMD_ISCSI_COMMAND_INVALIDATE 1
659#define ISCSI_OPCODE_SCSI_DATA_OUT 5
660#define OPCODE_COMMON_ISCSI_TCP_CONNECT_AND_OFFLOAD 70
661#define OPCODE_ISCSI_INI_DRIVER_OFFLOAD_SESSION 41
662#define OPCODE_COMMON_MODIFY_EQ_DELAY 41
663#define OPCODE_COMMON_ISCSI_CLEANUP 59
664#define OPCODE_COMMON_TCP_UPLOAD 56
665#define OPCODE_COMMON_ISCSI_ERROR_RECOVERY_INVALIDATE_COMMANDS 1
666/* --- CMD_ISCSI_INVALIDATE_CONNECTION_TYPE --- */
667#define CMD_ISCSI_CONNECTION_INVALIDATE 1
668#define CMD_ISCSI_CONNECTION_ISSUE_TCP_RST 2
669#define OPCODE_ISCSI_INI_DRIVER_INVALIDATE_CONNECTION 42
670
671#define INI_WR_CMD 1 /* Initiator write command */
672#define INI_TMF_CMD 2 /* Initiator TMF command */
673#define INI_NOPOUT_CMD 3 /* Initiator; Send a NOP-OUT */
674#define INI_RD_CMD 5 /* Initiator requesting to send
675 * a read command
676 */
677#define TGT_CTX_UPDT_CMD 7 /* Target context update */
678#define TGT_STS_CMD 8 /* Target R2T and other BHS
679 * where only the status number
680 * need to be updated
681 */
682#define TGT_DATAIN_CMD 9 /* Target Data-Ins in response
683 * to read command
684 */
685#define TGT_SOS_PDU 10 /* Target:standalone status
686 * response
687 */
688#define TGT_DM_CMD 11 /* Indicates that the bhs
689 * preparedby
690 * driver should not be touched
691 */
692/* --- CMD_CHUTE_TYPE --- */
693#define CMD_CONNECTION_CHUTE_0 1
694#define CMD_CONNECTION_CHUTE_1 2
695#define CMD_CONNECTION_CHUTE_2 3
696
697#define EQ_MAJOR_CODE_COMPLETION 0
698
699#define CMD_ISCSI_SESSION_DEL_CFG_FROM_FLASH 0
700#define CMD_ISCSI_SESSION_SAVE_CFG_ON_FLASH 1
701
702/* --- CONNECTION_UPLOAD_PARAMS --- */
703/* These parameters are used to define the type of upload desired. */
704#define CONNECTION_UPLOAD_GRACEFUL 1 /* Graceful upload */
705#define CONNECTION_UPLOAD_ABORT_RESET 2 /* Abortive upload with
706 * reset
707 */
708#define CONNECTION_UPLOAD_ABORT 3 /* Abortive upload without
709 * reset
710 */
711#define CONNECTION_UPLOAD_ABORT_WITH_SEQ 4 /* Abortive upload with reset,
712 * sequence number by driver */
713
714/* Returns byte size of given field with a structure. */
715
716/* Returns the number of items in the field array. */
717#define BE_NUMBER_OF_FIELD(_type_, _field_) \
718 (FIELD_SIZEOF(_type_, _field_)/sizeof((((_type_ *)0)->_field_[0])))\
719
720/**
721 * Different types of iSCSI completions to host driver for both initiator
722 * and taget mode
723 * of operation.
724 */
725#define SOL_CMD_COMPLETE 1 /* Solicited command completed
726 * normally
727 */
728#define SOL_CMD_KILLED_DATA_DIGEST_ERR 2 /* Solicited command got
729 * invalidated internally due
730 * to Data Digest error
731 */
732#define CXN_KILLED_PDU_SIZE_EXCEEDS_DSL 3 /* Connection got invalidated
733 * internally
734 * due to a recieved PDU
735 * size > DSL
736 */
737#define CXN_KILLED_BURST_LEN_MISMATCH 4 /* Connection got invalidated
738 * internally due ti received
739 * PDU sequence size >
740 * FBL/MBL.
741 */
742#define CXN_KILLED_AHS_RCVD 5 /* Connection got invalidated
743 * internally due to a recieved
744 * PDU Hdr that has
745 * AHS */
746#define CXN_KILLED_HDR_DIGEST_ERR 6 /* Connection got invalidated
747 * internally due to Hdr Digest
748 * error
749 */
750#define CXN_KILLED_UNKNOWN_HDR 7 /* Connection got invalidated
751 * internally
752 * due to a bad opcode in the
753 * pdu hdr
754 */
755#define CXN_KILLED_STALE_ITT_TTT_RCVD 8 /* Connection got invalidated
756 * internally due to a recieved
757 * ITT/TTT that does not belong
758 * to this Connection
759 */
760#define CXN_KILLED_INVALID_ITT_TTT_RCVD 9 /* Connection got invalidated
761 * internally due to recieved
762 * ITT/TTT value > Max
763 * Supported ITTs/TTTs
764 */
765#define CXN_KILLED_RST_RCVD 10 /* Connection got invalidated
766 * internally due to an
767 * incoming TCP RST
768 */
769#define CXN_KILLED_TIMED_OUT 11 /* Connection got invalidated
770 * internally due to timeout on
771 * tcp segment 12 retransmit
772 * attempts failed
773 */
774#define CXN_KILLED_RST_SENT 12 /* Connection got invalidated
775 * internally due to TCP RST
776 * sent by the Tx side
777 */
778#define CXN_KILLED_FIN_RCVD 13 /* Connection got invalidated
779 * internally due to an
780 * incoming TCP FIN.
781 */
782#define CXN_KILLED_BAD_UNSOL_PDU_RCVD 14 /* Connection got invalidated
783 * internally due to bad
784 * unsolicited PDU Unsolicited
785 * PDUs are PDUs with
786 * ITT=0xffffffff
787 */
788#define CXN_KILLED_BAD_WRB_INDEX_ERROR 15 /* Connection got invalidated
789 * internally due to bad WRB
790 * index.
791 */
792#define CXN_KILLED_OVER_RUN_RESIDUAL 16 /* Command got invalidated
793 * internally due to recived
794 * command has residual
795 * over run bytes.
796 */
797#define CXN_KILLED_UNDER_RUN_RESIDUAL 17 /* Command got invalidated
798 * internally due to recived
799 * command has residual under
800 * run bytes.
801 */
802#define CMD_KILLED_INVALID_STATSN_RCVD 18 /* Command got invalidated
803 * internally due to a recieved
804 * PDU has an invalid StatusSN
805 */
806#define CMD_KILLED_INVALID_R2T_RCVD 19 /* Command got invalidated
807 * internally due to a recieved
808 * an R2T with some invalid
809 * fields in it
810 */
811#define CMD_CXN_KILLED_LUN_INVALID 20 /* Command got invalidated
812 * internally due to received
813 * PDU has an invalid LUN.
814 */
815#define CMD_CXN_KILLED_ICD_INVALID 21 /* Command got invalidated
816 * internally due to the
817 * corresponding ICD not in a
818 * valid state
819 */
820#define CMD_CXN_KILLED_ITT_INVALID 22 /* Command got invalidated due
821 * to received PDU has an
822 * invalid ITT.
823 */
824#define CMD_CXN_KILLED_SEQ_OUTOFORDER 23 /* Command got invalidated due
825 * to received sequence buffer
826 * offset is out of order.
827 */
828#define CMD_CXN_KILLED_INVALID_DATASN_RCVD 24 /* Command got invalidated
829 * internally due to a
830 * recieved PDU has an invalid
831 * DataSN
832 */
833#define CXN_INVALIDATE_NOTIFY 25 /* Connection invalidation
834 * completion notify.
835 */
836#define CXN_INVALIDATE_INDEX_NOTIFY 26 /* Connection invalidation
837 * completion
838 * with data PDU index.
839 */
840#define CMD_INVALIDATED_NOTIFY 27 /* Command invalidation
841 * completionnotifify.
842 */
843#define UNSOL_HDR_NOTIFY 28 /* Unsolicited header notify.*/
844#define UNSOL_DATA_NOTIFY 29 /* Unsolicited data notify.*/
845#define UNSOL_DATA_DIGEST_ERROR_NOTIFY 30 /* Unsolicited data digest
846 * error notify.
847 */
848#define DRIVERMSG_NOTIFY 31 /* TCP acknowledge based
849 * notification.
850 */
851#define CXN_KILLED_CMND_DATA_NOT_ON_SAME_CONN 32 /* Connection got invalidated
852 * internally due to command
853 * and data are not on same
854 * connection.
855 */
856#define SOL_CMD_KILLED_DIF_ERR 33 /* Solicited command got
857 * invalidated internally due
858 * to DIF error
859 */
860#define CXN_KILLED_SYN_RCVD 34 /* Connection got invalidated
861 * internally due to incoming
862 * TCP SYN
863 */
864#define CXN_KILLED_IMM_DATA_RCVD 35 /* Connection got invalidated
865 * internally due to an
866 * incoming Unsolicited PDU
867 * that has immediate data on
868 * the cxn
869 */
870
871void be_wrb_hdr_prepare(struct be_mcc_wrb *wrb, int payload_len,
872 bool embedded, u8 sge_cnt);
873
874void be_cmd_hdr_prepare(struct be_cmd_req_hdr *req_hdr,
875 u8 subsystem, u8 opcode, int cmd_len);
876
877#endif /* !BEISCSI_CMDS_H */
diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c
new file mode 100644
index 000000000000..2fd25442cfaf
--- /dev/null
+++ b/drivers/scsi/be2iscsi/be_iscsi.c
@@ -0,0 +1,638 @@
1/**
2 * Copyright (C) 2005 - 2009 ServerEngines
3 * All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License version 2
7 * as published by the Free Software Foundation. The full GNU General
8 * Public License is included in this distribution in the file called COPYING.
9 *
10 * Written by: Jayamohan Kallickal (jayamohank@serverengines.com)
11 *
12 * Contact Information:
13 * linux-drivers@serverengines.com
14 *
15 * ServerEngines
16 * 209 N. Fair Oaks Ave
17 * Sunnyvale, CA 94085
18 *
19 */
20
21#include <scsi/libiscsi.h>
22#include <scsi/scsi_transport_iscsi.h>
23#include <scsi/scsi_transport.h>
24#include <scsi/scsi_cmnd.h>
25#include <scsi/scsi_device.h>
26#include <scsi/scsi_host.h>
27#include <scsi/scsi.h>
28
29#include "be_iscsi.h"
30
31extern struct iscsi_transport beiscsi_iscsi_transport;
32
33/**
34 * beiscsi_session_create - creates a new iscsi session
35 * @cmds_max: max commands supported
36 * @qdepth: max queue depth supported
37 * @initial_cmdsn: initial iscsi CMDSN
38 */
39struct iscsi_cls_session *beiscsi_session_create(struct iscsi_endpoint *ep,
40 u16 cmds_max,
41 u16 qdepth,
42 u32 initial_cmdsn)
43{
44 struct Scsi_Host *shost;
45 struct beiscsi_endpoint *beiscsi_ep;
46 struct iscsi_cls_session *cls_session;
47 struct beiscsi_hba *phba;
48 struct iscsi_session *sess;
49 struct beiscsi_session *beiscsi_sess;
50 struct beiscsi_io_task *io_task;
51
52 SE_DEBUG(DBG_LVL_8, "In beiscsi_session_create\n");
53
54 if (!ep) {
55 SE_DEBUG(DBG_LVL_1, "beiscsi_session_create: invalid ep \n");
56 return NULL;
57 }
58 beiscsi_ep = ep->dd_data;
59 phba = beiscsi_ep->phba;
60 shost = phba->shost;
61 if (cmds_max > beiscsi_ep->phba->params.wrbs_per_cxn) {
62 shost_printk(KERN_ERR, shost, "Cannot handle %d cmds."
63 "Max cmds per session supported is %d. Using %d. "
64 "\n", cmds_max,
65 beiscsi_ep->phba->params.wrbs_per_cxn,
66 beiscsi_ep->phba->params.wrbs_per_cxn);
67 cmds_max = beiscsi_ep->phba->params.wrbs_per_cxn;
68 }
69
70 cls_session = iscsi_session_setup(&beiscsi_iscsi_transport,
71 shost, cmds_max,
72 sizeof(*beiscsi_sess),
73 sizeof(*io_task),
74 initial_cmdsn, ISCSI_MAX_TARGET);
75 if (!cls_session)
76 return NULL;
77 sess = cls_session->dd_data;
78 beiscsi_sess = sess->dd_data;
79 beiscsi_sess->bhs_pool = pci_pool_create("beiscsi_bhs_pool",
80 phba->pcidev,
81 sizeof(struct be_cmd_bhs),
82 64, 0);
83 if (!beiscsi_sess->bhs_pool)
84 goto destroy_sess;
85
86 return cls_session;
87destroy_sess:
88 iscsi_session_teardown(cls_session);
89 return NULL;
90}
91
92/**
93 * beiscsi_session_destroy - destroys iscsi session
94 * @cls_session: pointer to iscsi cls session
95 *
96 * Destroys iSCSI session instance and releases
97 * resources allocated for it.
98 */
99void beiscsi_session_destroy(struct iscsi_cls_session *cls_session)
100{
101 struct iscsi_session *sess = cls_session->dd_data;
102 struct beiscsi_session *beiscsi_sess = sess->dd_data;
103
104 pci_pool_destroy(beiscsi_sess->bhs_pool);
105 iscsi_session_teardown(cls_session);
106}
107
108/**
109 * beiscsi_conn_create - create an instance of iscsi connection
110 * @cls_session: ptr to iscsi_cls_session
111 * @cid: iscsi cid
112 */
113struct iscsi_cls_conn *
114beiscsi_conn_create(struct iscsi_cls_session *cls_session, u32 cid)
115{
116 struct beiscsi_hba *phba;
117 struct Scsi_Host *shost;
118 struct iscsi_cls_conn *cls_conn;
119 struct beiscsi_conn *beiscsi_conn;
120 struct iscsi_conn *conn;
121 struct iscsi_session *sess;
122 struct beiscsi_session *beiscsi_sess;
123
124 SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_create ,cid"
125 "from iscsi layer=%d\n", cid);
126 shost = iscsi_session_to_shost(cls_session);
127 phba = iscsi_host_priv(shost);
128
129 cls_conn = iscsi_conn_setup(cls_session, sizeof(*beiscsi_conn), cid);
130 if (!cls_conn)
131 return NULL;
132
133 conn = cls_conn->dd_data;
134 beiscsi_conn = conn->dd_data;
135 beiscsi_conn->ep = NULL;
136 beiscsi_conn->phba = phba;
137 beiscsi_conn->conn = conn;
138 sess = cls_session->dd_data;
139 beiscsi_sess = sess->dd_data;
140 beiscsi_conn->beiscsi_sess = beiscsi_sess;
141 return cls_conn;
142}
143
144/**
145 * beiscsi_bindconn_cid - Bind the beiscsi_conn with phba connection table
146 * @beiscsi_conn: The pointer to beiscsi_conn structure
147 * @phba: The phba instance
148 * @cid: The cid to free
149 */
150static int beiscsi_bindconn_cid(struct beiscsi_hba *phba,
151 struct beiscsi_conn *beiscsi_conn,
152 unsigned int cid)
153{
154 if (phba->conn_table[cid]) {
155 SE_DEBUG(DBG_LVL_1,
156 "Connection table already occupied. Detected clash\n");
157 return -EINVAL;
158 } else {
159 SE_DEBUG(DBG_LVL_8, "phba->conn_table[%d]=%p(beiscsi_conn) \n",
160 cid, beiscsi_conn);
161 phba->conn_table[cid] = beiscsi_conn;
162 }
163 return 0;
164}
165
166/**
167 * beiscsi_conn_bind - Binds iscsi session/connection with TCP connection
168 * @cls_session: pointer to iscsi cls session
169 * @cls_conn: pointer to iscsi cls conn
170 * @transport_fd: EP handle(64 bit)
171 *
172 * This function binds the TCP Conn with iSCSI Connection and Session.
173 */
174int beiscsi_conn_bind(struct iscsi_cls_session *cls_session,
175 struct iscsi_cls_conn *cls_conn,
176 u64 transport_fd, int is_leading)
177{
178 struct iscsi_conn *conn = cls_conn->dd_data;
179 struct beiscsi_conn *beiscsi_conn = conn->dd_data;
180 struct Scsi_Host *shost =
181 (struct Scsi_Host *)iscsi_session_to_shost(cls_session);
182 struct beiscsi_hba *phba = (struct beiscsi_hba *)iscsi_host_priv(shost);
183 struct beiscsi_endpoint *beiscsi_ep;
184 struct iscsi_endpoint *ep;
185
186 SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_bind\n");
187 ep = iscsi_lookup_endpoint(transport_fd);
188 if (!ep)
189 return -EINVAL;
190
191 beiscsi_ep = ep->dd_data;
192
193 if (iscsi_conn_bind(cls_session, cls_conn, is_leading))
194 return -EINVAL;
195
196 if (beiscsi_ep->phba != phba) {
197 SE_DEBUG(DBG_LVL_8,
198 "beiscsi_ep->hba=%p not equal to phba=%p \n",
199 beiscsi_ep->phba, phba);
200 return -EEXIST;
201 }
202
203 beiscsi_conn->beiscsi_conn_cid = beiscsi_ep->ep_cid;
204 beiscsi_conn->ep = beiscsi_ep;
205 beiscsi_ep->conn = beiscsi_conn;
206 SE_DEBUG(DBG_LVL_8, "beiscsi_conn=%p conn=%p ep_cid=%d \n",
207 beiscsi_conn, conn, beiscsi_ep->ep_cid);
208 return beiscsi_bindconn_cid(phba, beiscsi_conn, beiscsi_ep->ep_cid);
209}
210
211/**
212 * beiscsi_conn_get_param - get the iscsi parameter
213 * @cls_conn: pointer to iscsi cls conn
214 * @param: parameter type identifier
215 * @buf: buffer pointer
216 *
217 * returns iscsi parameter
218 */
219int beiscsi_conn_get_param(struct iscsi_cls_conn *cls_conn,
220 enum iscsi_param param, char *buf)
221{
222 struct beiscsi_endpoint *beiscsi_ep;
223 struct iscsi_conn *conn = cls_conn->dd_data;
224 struct beiscsi_conn *beiscsi_conn = conn->dd_data;
225 int len = 0;
226
227 beiscsi_ep = beiscsi_conn->ep;
228 if (!beiscsi_ep) {
229 SE_DEBUG(DBG_LVL_1,
230 "In beiscsi_conn_get_param , no beiscsi_ep\n");
231 return -1;
232 }
233
234 switch (param) {
235 case ISCSI_PARAM_CONN_PORT:
236 len = sprintf(buf, "%hu\n", beiscsi_ep->dst_tcpport);
237 break;
238 case ISCSI_PARAM_CONN_ADDRESS:
239 if (beiscsi_ep->ip_type == BE2_IPV4)
240 len = sprintf(buf, "%pI4\n", &beiscsi_ep->dst_addr);
241 else
242 len = sprintf(buf, "%pI6\n", &beiscsi_ep->dst6_addr);
243 break;
244 default:
245 return iscsi_conn_get_param(cls_conn, param, buf);
246 }
247 return len;
248}
249
250int beiscsi_set_param(struct iscsi_cls_conn *cls_conn,
251 enum iscsi_param param, char *buf, int buflen)
252{
253 struct iscsi_conn *conn = cls_conn->dd_data;
254 struct iscsi_session *session = conn->session;
255 int ret;
256
257 ret = iscsi_set_param(cls_conn, param, buf, buflen);
258 if (ret)
259 return ret;
260 /*
261 * If userspace tried to set the value to higher than we can
262 * support override here.
263 */
264 switch (param) {
265 case ISCSI_PARAM_FIRST_BURST:
266 if (session->first_burst > 8192)
267 session->first_burst = 8192;
268 break;
269 case ISCSI_PARAM_MAX_RECV_DLENGTH:
270 if (conn->max_recv_dlength > 65536)
271 conn->max_recv_dlength = 65536;
272 break;
273 case ISCSI_PARAM_MAX_BURST:
274 if (session->first_burst > 262144)
275 session->first_burst = 262144;
276 break;
277 default:
278 return 0;
279 }
280
281 return 0;
282}
283
284/**
285 * beiscsi_get_host_param - get the iscsi parameter
286 * @shost: pointer to scsi_host structure
287 * @param: parameter type identifier
288 * @buf: buffer pointer
289 *
290 * returns host parameter
291 */
292int beiscsi_get_host_param(struct Scsi_Host *shost,
293 enum iscsi_host_param param, char *buf)
294{
295 struct beiscsi_hba *phba = (struct beiscsi_hba *)iscsi_host_priv(shost);
296 int len = 0;
297
298 switch (param) {
299 case ISCSI_HOST_PARAM_HWADDRESS:
300 be_cmd_get_mac_addr(&phba->ctrl, phba->mac_address);
301 len = sysfs_format_mac(buf, phba->mac_address, ETH_ALEN);
302 break;
303 default:
304 return iscsi_host_get_param(shost, param, buf);
305 }
306 return len;
307}
308
309/**
310 * beiscsi_conn_get_stats - get the iscsi stats
311 * @cls_conn: pointer to iscsi cls conn
312 * @stats: pointer to iscsi_stats structure
313 *
314 * returns iscsi stats
315 */
316void beiscsi_conn_get_stats(struct iscsi_cls_conn *cls_conn,
317 struct iscsi_stats *stats)
318{
319 struct iscsi_conn *conn = cls_conn->dd_data;
320
321 SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_get_stats\n");
322 stats->txdata_octets = conn->txdata_octets;
323 stats->rxdata_octets = conn->rxdata_octets;
324 stats->dataout_pdus = conn->dataout_pdus_cnt;
325 stats->scsirsp_pdus = conn->scsirsp_pdus_cnt;
326 stats->scsicmd_pdus = conn->scsicmd_pdus_cnt;
327 stats->datain_pdus = conn->datain_pdus_cnt;
328 stats->tmfrsp_pdus = conn->tmfrsp_pdus_cnt;
329 stats->tmfcmd_pdus = conn->tmfcmd_pdus_cnt;
330 stats->r2t_pdus = conn->r2t_pdus_cnt;
331 stats->digest_err = 0;
332 stats->timeout_err = 0;
333 stats->custom_length = 0;
334 strcpy(stats->custom[0].desc, "eh_abort_cnt");
335 stats->custom[0].value = conn->eh_abort_cnt;
336}
337
338/**
339 * beiscsi_set_params_for_offld - get the parameters for offload
340 * @beiscsi_conn: pointer to beiscsi_conn
341 * @params: pointer to offload_params structure
342 */
343static void beiscsi_set_params_for_offld(struct beiscsi_conn *beiscsi_conn,
344 struct beiscsi_offload_params *params)
345{
346 struct iscsi_conn *conn = beiscsi_conn->conn;
347 struct iscsi_session *session = conn->session;
348
349 AMAP_SET_BITS(struct amap_beiscsi_offload_params, max_burst_length,
350 params, session->max_burst);
351 AMAP_SET_BITS(struct amap_beiscsi_offload_params,
352 max_send_data_segment_length, params,
353 conn->max_xmit_dlength);
354 AMAP_SET_BITS(struct amap_beiscsi_offload_params, first_burst_length,
355 params, session->first_burst);
356 AMAP_SET_BITS(struct amap_beiscsi_offload_params, erl, params,
357 session->erl);
358 AMAP_SET_BITS(struct amap_beiscsi_offload_params, dde, params,
359 conn->datadgst_en);
360 AMAP_SET_BITS(struct amap_beiscsi_offload_params, hde, params,
361 conn->hdrdgst_en);
362 AMAP_SET_BITS(struct amap_beiscsi_offload_params, ir2t, params,
363 session->initial_r2t_en);
364 AMAP_SET_BITS(struct amap_beiscsi_offload_params, imd, params,
365 session->imm_data_en);
366 AMAP_SET_BITS(struct amap_beiscsi_offload_params, exp_statsn, params,
367 (conn->exp_statsn - 1));
368}
369
370/**
371 * beiscsi_conn_start - offload of session to chip
372 * @cls_conn: pointer to beiscsi_conn
373 */
374int beiscsi_conn_start(struct iscsi_cls_conn *cls_conn)
375{
376 struct iscsi_conn *conn = cls_conn->dd_data;
377 struct beiscsi_conn *beiscsi_conn = conn->dd_data;
378 struct beiscsi_endpoint *beiscsi_ep;
379 struct beiscsi_offload_params params;
380 struct iscsi_session *session = conn->session;
381 struct Scsi_Host *shost = iscsi_session_to_shost(session->cls_session);
382 struct beiscsi_hba *phba = iscsi_host_priv(shost);
383
384 memset(&params, 0, sizeof(struct beiscsi_offload_params));
385 beiscsi_ep = beiscsi_conn->ep;
386 if (!beiscsi_ep)
387 SE_DEBUG(DBG_LVL_1, "In beiscsi_conn_start , no beiscsi_ep\n");
388
389 free_mgmt_sgl_handle(phba, beiscsi_conn->plogin_sgl_handle);
390 beiscsi_conn->login_in_progress = 0;
391 beiscsi_set_params_for_offld(beiscsi_conn, &params);
392 beiscsi_offload_connection(beiscsi_conn, &params);
393 iscsi_conn_start(cls_conn);
394 return 0;
395}
396
397/**
398 * beiscsi_get_cid - Allocate a cid
399 * @phba: The phba instance
400 */
401static int beiscsi_get_cid(struct beiscsi_hba *phba)
402{
403 unsigned short cid = 0xFFFF;
404
405 if (!phba->avlbl_cids)
406 return cid;
407
408 cid = phba->cid_array[phba->cid_alloc++];
409 if (phba->cid_alloc == phba->params.cxns_per_ctrl)
410 phba->cid_alloc = 0;
411 phba->avlbl_cids--;
412 return cid;
413}
414
415/**
416 * beiscsi_open_conn - Ask FW to open a TCP connection
417 * @ep: endpoint to be used
418 * @src_addr: The source IP address
419 * @dst_addr: The Destination IP address
420 *
421 * Asks the FW to open a TCP connection
422 */
423static int beiscsi_open_conn(struct iscsi_endpoint *ep,
424 struct sockaddr *src_addr,
425 struct sockaddr *dst_addr, int non_blocking)
426{
427 struct beiscsi_endpoint *beiscsi_ep = ep->dd_data;
428 struct beiscsi_hba *phba = beiscsi_ep->phba;
429 int ret = -1;
430
431 beiscsi_ep->ep_cid = beiscsi_get_cid(phba);
432 if (beiscsi_ep->ep_cid == 0xFFFF) {
433 SE_DEBUG(DBG_LVL_1, "No free cid available\n");
434 return ret;
435 }
436 SE_DEBUG(DBG_LVL_8, "In beiscsi_open_conn, ep_cid=%d ",
437 beiscsi_ep->ep_cid);
438 phba->ep_array[beiscsi_ep->ep_cid] = ep;
439 if (beiscsi_ep->ep_cid >
440 (phba->fw_config.iscsi_cid_start + phba->params.cxns_per_ctrl)) {
441 SE_DEBUG(DBG_LVL_1, "Failed in allocate iscsi cid\n");
442 return ret;
443 }
444
445 beiscsi_ep->cid_vld = 0;
446 return mgmt_open_connection(phba, dst_addr, beiscsi_ep);
447}
448
449/**
450 * beiscsi_put_cid - Free the cid
451 * @phba: The phba for which the cid is being freed
452 * @cid: The cid to free
453 */
454static void beiscsi_put_cid(struct beiscsi_hba *phba, unsigned short cid)
455{
456 phba->avlbl_cids++;
457 phba->cid_array[phba->cid_free++] = cid;
458 if (phba->cid_free == phba->params.cxns_per_ctrl)
459 phba->cid_free = 0;
460}
461
462/**
463 * beiscsi_free_ep - free endpoint
464 * @ep: pointer to iscsi endpoint structure
465 */
466static void beiscsi_free_ep(struct iscsi_endpoint *ep)
467{
468 struct beiscsi_endpoint *beiscsi_ep = ep->dd_data;
469 struct beiscsi_hba *phba = beiscsi_ep->phba;
470
471 beiscsi_put_cid(phba, beiscsi_ep->ep_cid);
472 beiscsi_ep->phba = NULL;
473 iscsi_destroy_endpoint(ep);
474}
475
476/**
477 * beiscsi_ep_connect - Ask chip to create TCP Conn
478 * @scsi_host: Pointer to scsi_host structure
479 * @dst_addr: The IP address of Target
480 * @non_blocking: blocking or non-blocking call
481 *
482 * This routines first asks chip to create a connection and then allocates an EP
483 */
484struct iscsi_endpoint *
485beiscsi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr,
486 int non_blocking)
487{
488 struct beiscsi_hba *phba;
489 struct beiscsi_endpoint *beiscsi_ep;
490 struct iscsi_endpoint *ep;
491 int ret;
492
493 SE_DEBUG(DBG_LVL_8, "In beiscsi_ep_connect \n");
494 if (shost)
495 phba = iscsi_host_priv(shost);
496 else {
497 ret = -ENXIO;
498 SE_DEBUG(DBG_LVL_1, "shost is NULL \n");
499 return ERR_PTR(ret);
500 }
501 ep = iscsi_create_endpoint(sizeof(struct beiscsi_endpoint));
502 if (!ep) {
503 ret = -ENOMEM;
504 return ERR_PTR(ret);
505 }
506
507 beiscsi_ep = ep->dd_data;
508 beiscsi_ep->phba = phba;
509
510 if (beiscsi_open_conn(ep, NULL, dst_addr, non_blocking)) {
511 SE_DEBUG(DBG_LVL_1, "Failed in allocate iscsi cid\n");
512 ret = -ENOMEM;
513 goto free_ep;
514 }
515
516 return ep;
517
518free_ep:
519 beiscsi_free_ep(ep);
520 return ERR_PTR(ret);
521}
522
523/**
524 * beiscsi_ep_poll - Poll to see if connection is established
525 * @ep: endpoint to be used
526 * @timeout_ms: timeout specified in millisecs
527 *
528 * Poll to see if TCP connection established
529 */
530int beiscsi_ep_poll(struct iscsi_endpoint *ep, int timeout_ms)
531{
532 struct beiscsi_endpoint *beiscsi_ep = ep->dd_data;
533
534 SE_DEBUG(DBG_LVL_8, "In beiscsi_ep_poll\n");
535 if (beiscsi_ep->cid_vld == 1)
536 return 1;
537 else
538 return 0;
539}
540
541/**
542 * beiscsi_close_conn - Upload the connection
543 * @ep: The iscsi endpoint
544 * @flag: The type of connection closure
545 */
546static int beiscsi_close_conn(struct iscsi_endpoint *ep, int flag)
547{
548 int ret = 0;
549 struct beiscsi_endpoint *beiscsi_ep = ep->dd_data;
550 struct beiscsi_hba *phba = beiscsi_ep->phba;
551
552 if (MGMT_STATUS_SUCCESS !=
553 mgmt_upload_connection(phba, beiscsi_ep->ep_cid,
554 CONNECTION_UPLOAD_GRACEFUL)) {
555 SE_DEBUG(DBG_LVL_8, "upload failed for cid 0x%x",
556 beiscsi_ep->ep_cid);
557 ret = -1;
558 }
559
560 return ret;
561}
562
563/**
564 * beiscsi_ep_disconnect - Tears down the TCP connection
565 * @ep: endpoint to be used
566 *
567 * Tears down the TCP connection
568 */
569void beiscsi_ep_disconnect(struct iscsi_endpoint *ep)
570{
571 struct beiscsi_conn *beiscsi_conn;
572 struct beiscsi_endpoint *beiscsi_ep;
573 struct beiscsi_hba *phba;
574 int flag = 0;
575
576 beiscsi_ep = ep->dd_data;
577 phba = beiscsi_ep->phba;
578 SE_DEBUG(DBG_LVL_8, "In beiscsi_ep_disconnect\n");
579
580 if (beiscsi_ep->conn) {
581 beiscsi_conn = beiscsi_ep->conn;
582 iscsi_suspend_queue(beiscsi_conn->conn);
583 beiscsi_close_conn(ep, flag);
584 }
585
586 beiscsi_free_ep(ep);
587}
588
589/**
590 * beiscsi_unbind_conn_to_cid - Unbind the beiscsi_conn from phba conn table
591 * @phba: The phba instance
592 * @cid: The cid to free
593 */
594static int beiscsi_unbind_conn_to_cid(struct beiscsi_hba *phba,
595 unsigned int cid)
596{
597 if (phba->conn_table[cid])
598 phba->conn_table[cid] = NULL;
599 else {
600 SE_DEBUG(DBG_LVL_8, "Connection table Not occupied. \n");
601 return -EINVAL;
602 }
603 return 0;
604}
605
606/**
607 * beiscsi_conn_stop - Invalidate and stop the connection
608 * @cls_conn: pointer to get iscsi_conn
609 * @flag: The type of connection closure
610 */
611void beiscsi_conn_stop(struct iscsi_cls_conn *cls_conn, int flag)
612{
613 struct iscsi_conn *conn = cls_conn->dd_data;
614 struct beiscsi_conn *beiscsi_conn = conn->dd_data;
615 struct beiscsi_endpoint *beiscsi_ep;
616 struct iscsi_session *session = conn->session;
617 struct Scsi_Host *shost = iscsi_session_to_shost(session->cls_session);
618 struct beiscsi_hba *phba = iscsi_host_priv(shost);
619 unsigned int status;
620 unsigned short savecfg_flag = CMD_ISCSI_SESSION_SAVE_CFG_ON_FLASH;
621
622 SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_stop\n");
623 beiscsi_ep = beiscsi_conn->ep;
624 if (!beiscsi_ep) {
625 SE_DEBUG(DBG_LVL_8, "In beiscsi_conn_stop , no beiscsi_ep\n");
626 return;
627 }
628 status = mgmt_invalidate_connection(phba, beiscsi_ep,
629 beiscsi_ep->ep_cid, 1,
630 savecfg_flag);
631 if (status != MGMT_STATUS_SUCCESS) {
632 SE_DEBUG(DBG_LVL_1,
633 "mgmt_invalidate_connection Failed for cid=%d \n",
634 beiscsi_ep->ep_cid);
635 }
636 beiscsi_unbind_conn_to_cid(phba, beiscsi_ep->ep_cid);
637 iscsi_conn_stop(cls_conn, flag);
638}
diff --git a/drivers/scsi/be2iscsi/be_iscsi.h b/drivers/scsi/be2iscsi/be_iscsi.h
new file mode 100644
index 000000000000..f92ffc5349fb
--- /dev/null
+++ b/drivers/scsi/be2iscsi/be_iscsi.h
@@ -0,0 +1,75 @@
1/**
2 * Copyright (C) 2005 - 2009 ServerEngines
3 * All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License version 2
7 * as published by the Free Software Foundation. The full GNU General
8 * Public License is included in this distribution in the file called COPYING.
9 *
10 * Written by: Jayamohan Kallickal (jayamohank@serverengines.com)
11 *
12 * Contact Information:
13 * linux-drivers@serverengines.com
14 *
15 * ServerEngines
16 * 209 N. Fair Oaks Ave
17 * Sunnyvale, CA 94085
18 *
19 */
20
21#ifndef _BE_ISCSI_
22#define _BE_ISCSI_
23
24#include "be_main.h"
25#include "be_mgmt.h"
26
27#define BE2_IPV4 0x1
28#define BE2_IPV6 0x10
29
30void beiscsi_offload_connection(struct beiscsi_conn *beiscsi_conn,
31 struct beiscsi_offload_params *params);
32
33void beiscsi_offload_iscsi(struct beiscsi_hba *phba, struct iscsi_conn *conn,
34 struct beiscsi_conn *beiscsi_conn,
35 unsigned int fw_handle);
36
37struct iscsi_cls_session *beiscsi_session_create(struct iscsi_endpoint *ep,
38 uint16_t cmds_max,
39 uint16_t qdepth,
40 uint32_t initial_cmdsn);
41
42void beiscsi_session_destroy(struct iscsi_cls_session *cls_session);
43
44struct iscsi_cls_conn *beiscsi_conn_create(struct iscsi_cls_session
45 *cls_session, uint32_t cid);
46
47int beiscsi_conn_bind(struct iscsi_cls_session *cls_session,
48 struct iscsi_cls_conn *cls_conn,
49 uint64_t transport_fd, int is_leading);
50
51int beiscsi_conn_get_param(struct iscsi_cls_conn *cls_conn,
52 enum iscsi_param param, char *buf);
53
54int beiscsi_get_host_param(struct Scsi_Host *shost,
55 enum iscsi_host_param param, char *buf);
56
57int beiscsi_set_param(struct iscsi_cls_conn *cls_conn,
58 enum iscsi_param param, char *buf, int buflen);
59
60int beiscsi_conn_start(struct iscsi_cls_conn *cls_conn);
61
62void beiscsi_conn_stop(struct iscsi_cls_conn *cls_conn, int flag);
63
64struct iscsi_endpoint *beiscsi_ep_connect(struct Scsi_Host *shost,
65 struct sockaddr *dst_addr,
66 int non_blocking);
67
68int beiscsi_ep_poll(struct iscsi_endpoint *ep, int timeout_ms);
69
70void beiscsi_ep_disconnect(struct iscsi_endpoint *ep);
71
72void beiscsi_conn_get_stats(struct iscsi_cls_conn *cls_conn,
73 struct iscsi_stats *stats);
74
75#endif
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
new file mode 100644
index 000000000000..4f1aca346e38
--- /dev/null
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -0,0 +1,3390 @@
1/**
2 * Copyright (C) 2005 - 2009 ServerEngines
3 * All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License version 2
7 * as published by the Free Software Foundation. The full GNU General
8 * Public License is included in this distribution in the file called COPYING.
9 *
10 * Written by: Jayamohan Kallickal (jayamohank@serverengines.com)
11 *
12 * Contact Information:
13 * linux-drivers@serverengines.com
14 *
15 * ServerEngines
16 * 209 N. Fair Oaks Ave
17 * Sunnyvale, CA 94085
18 *
19 */
20#include <linux/reboot.h>
21#include <linux/delay.h>
22#include <linux/interrupt.h>
23#include <linux/blkdev.h>
24#include <linux/pci.h>
25#include <linux/string.h>
26#include <linux/kernel.h>
27#include <linux/semaphore.h>
28
29#include <scsi/libiscsi.h>
30#include <scsi/scsi_transport_iscsi.h>
31#include <scsi/scsi_transport.h>
32#include <scsi/scsi_cmnd.h>
33#include <scsi/scsi_device.h>
34#include <scsi/scsi_host.h>
35#include <scsi/scsi.h>
36#include "be_main.h"
37#include "be_iscsi.h"
38#include "be_mgmt.h"
39
40static unsigned int be_iopoll_budget = 10;
41static unsigned int be_max_phys_size = 64;
42static unsigned int enable_msix;
43
44MODULE_DEVICE_TABLE(pci, beiscsi_pci_id_table);
45MODULE_DESCRIPTION(DRV_DESC " " BUILD_STR);
46MODULE_AUTHOR("ServerEngines Corporation");
47MODULE_LICENSE("GPL");
48module_param(be_iopoll_budget, int, 0);
49module_param(enable_msix, int, 0);
50module_param(be_max_phys_size, uint, S_IRUGO);
51MODULE_PARM_DESC(be_max_phys_size, "Maximum Size (In Kilobytes) of physically"
52 "contiguous memory that can be allocated."
53 "Range is 16 - 128");
54
55static int beiscsi_slave_configure(struct scsi_device *sdev)
56{
57 blk_queue_max_segment_size(sdev->request_queue, 65536);
58 return 0;
59}
60
61static struct scsi_host_template beiscsi_sht = {
62 .module = THIS_MODULE,
63 .name = "ServerEngines 10Gbe open-iscsi Initiator Driver",
64 .proc_name = DRV_NAME,
65 .queuecommand = iscsi_queuecommand,
66 .eh_abort_handler = iscsi_eh_abort,
67 .change_queue_depth = iscsi_change_queue_depth,
68 .slave_configure = beiscsi_slave_configure,
69 .target_alloc = iscsi_target_alloc,
70 .eh_device_reset_handler = iscsi_eh_device_reset,
71 .eh_target_reset_handler = iscsi_eh_target_reset,
72 .sg_tablesize = BEISCSI_SGLIST_ELEMENTS,
73 .can_queue = BE2_IO_DEPTH,
74 .this_id = -1,
75 .max_sectors = BEISCSI_MAX_SECTORS,
76 .cmd_per_lun = BEISCSI_CMD_PER_LUN,
77 .use_clustering = ENABLE_CLUSTERING,
78};
79static struct scsi_transport_template *beiscsi_scsi_transport;
80
81/*------------------- PCI Driver operations and data ----------------- */
82static DEFINE_PCI_DEVICE_TABLE(beiscsi_pci_id_table) = {
83 { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) },
84 { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID1) },
85 { PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID2) },
86 { 0 }
87};
88MODULE_DEVICE_TABLE(pci, beiscsi_pci_id_table);
89
90static struct beiscsi_hba *beiscsi_hba_alloc(struct pci_dev *pcidev)
91{
92 struct beiscsi_hba *phba;
93 struct Scsi_Host *shost;
94
95 shost = iscsi_host_alloc(&beiscsi_sht, sizeof(*phba), 0);
96 if (!shost) {
97 dev_err(&pcidev->dev, "beiscsi_hba_alloc -"
98 "iscsi_host_alloc failed \n");
99 return NULL;
100 }
101 shost->dma_boundary = pcidev->dma_mask;
102 shost->max_id = BE2_MAX_SESSIONS;
103 shost->max_channel = 0;
104 shost->max_cmd_len = BEISCSI_MAX_CMD_LEN;
105 shost->max_lun = BEISCSI_NUM_MAX_LUN;
106 shost->transportt = beiscsi_scsi_transport;
107
108 phba = iscsi_host_priv(shost);
109 memset(phba, 0, sizeof(*phba));
110 phba->shost = shost;
111 phba->pcidev = pci_dev_get(pcidev);
112
113 if (iscsi_host_add(shost, &phba->pcidev->dev))
114 goto free_devices;
115 return phba;
116
117free_devices:
118 pci_dev_put(phba->pcidev);
119 iscsi_host_free(phba->shost);
120 return NULL;
121}
122
123static void beiscsi_unmap_pci_function(struct beiscsi_hba *phba)
124{
125 if (phba->csr_va) {
126 iounmap(phba->csr_va);
127 phba->csr_va = NULL;
128 }
129 if (phba->db_va) {
130 iounmap(phba->db_va);
131 phba->db_va = NULL;
132 }
133 if (phba->pci_va) {
134 iounmap(phba->pci_va);
135 phba->pci_va = NULL;
136 }
137}
138
139static int beiscsi_map_pci_bars(struct beiscsi_hba *phba,
140 struct pci_dev *pcidev)
141{
142 u8 __iomem *addr;
143
144 addr = ioremap_nocache(pci_resource_start(pcidev, 2),
145 pci_resource_len(pcidev, 2));
146 if (addr == NULL)
147 return -ENOMEM;
148 phba->ctrl.csr = addr;
149 phba->csr_va = addr;
150 phba->csr_pa.u.a64.address = pci_resource_start(pcidev, 2);
151
152 addr = ioremap_nocache(pci_resource_start(pcidev, 4), 128 * 1024);
153 if (addr == NULL)
154 goto pci_map_err;
155 phba->ctrl.db = addr;
156 phba->db_va = addr;
157 phba->db_pa.u.a64.address = pci_resource_start(pcidev, 4);
158
159 addr = ioremap_nocache(pci_resource_start(pcidev, 1),
160 pci_resource_len(pcidev, 1));
161 if (addr == NULL)
162 goto pci_map_err;
163 phba->ctrl.pcicfg = addr;
164 phba->pci_va = addr;
165 phba->pci_pa.u.a64.address = pci_resource_start(pcidev, 1);
166 return 0;
167
168pci_map_err:
169 beiscsi_unmap_pci_function(phba);
170 return -ENOMEM;
171}
172
173static int beiscsi_enable_pci(struct pci_dev *pcidev)
174{
175 int ret;
176
177 ret = pci_enable_device(pcidev);
178 if (ret) {
179 dev_err(&pcidev->dev, "beiscsi_enable_pci - enable device "
180 "failed. Returning -ENODEV\n");
181 return ret;
182 }
183
184 if (pci_set_consistent_dma_mask(pcidev, DMA_BIT_MASK(64))) {
185 ret = pci_set_consistent_dma_mask(pcidev, DMA_BIT_MASK(32));
186 if (ret) {
187 dev_err(&pcidev->dev, "Could not set PCI DMA Mask\n");
188 pci_disable_device(pcidev);
189 return ret;
190 }
191 }
192 return 0;
193}
194
195static int be_ctrl_init(struct beiscsi_hba *phba, struct pci_dev *pdev)
196{
197 struct be_ctrl_info *ctrl = &phba->ctrl;
198 struct be_dma_mem *mbox_mem_alloc = &ctrl->mbox_mem_alloced;
199 struct be_dma_mem *mbox_mem_align = &ctrl->mbox_mem;
200 int status = 0;
201
202 ctrl->pdev = pdev;
203 status = beiscsi_map_pci_bars(phba, pdev);
204 if (status)
205 return status;
206
207 mbox_mem_alloc->size = sizeof(struct be_mcc_mailbox) + 16;
208 mbox_mem_alloc->va = pci_alloc_consistent(pdev,
209 mbox_mem_alloc->size,
210 &mbox_mem_alloc->dma);
211 if (!mbox_mem_alloc->va) {
212 beiscsi_unmap_pci_function(phba);
213 status = -ENOMEM;
214 return status;
215 }
216
217 mbox_mem_align->size = sizeof(struct be_mcc_mailbox);
218 mbox_mem_align->va = PTR_ALIGN(mbox_mem_alloc->va, 16);
219 mbox_mem_align->dma = PTR_ALIGN(mbox_mem_alloc->dma, 16);
220 memset(mbox_mem_align->va, 0, sizeof(struct be_mcc_mailbox));
221 spin_lock_init(&ctrl->mbox_lock);
222 return status;
223}
224
225static void beiscsi_get_params(struct beiscsi_hba *phba)
226{
227 phba->params.ios_per_ctrl = BE2_IO_DEPTH;
228 phba->params.cxns_per_ctrl = BE2_MAX_SESSIONS;
229 phba->params.asyncpdus_per_ctrl = BE2_ASYNCPDUS;
230 phba->params.icds_per_ctrl = BE2_MAX_ICDS / 2;
231 phba->params.num_sge_per_io = BE2_SGE;
232 phba->params.defpdu_hdr_sz = BE2_DEFPDU_HDR_SZ;
233 phba->params.defpdu_data_sz = BE2_DEFPDU_DATA_SZ;
234 phba->params.eq_timer = 64;
235 phba->params.num_eq_entries =
236 (((BE2_CMDS_PER_CXN * 2 + BE2_LOGOUTS + BE2_TMFS + BE2_ASYNCPDUS) /
237 512) + 1) * 512;
238 phba->params.num_eq_entries = (phba->params.num_eq_entries < 1024)
239 ? 1024 : phba->params.num_eq_entries;
240 SE_DEBUG(DBG_LVL_8, "phba->params.num_eq_entries=%d \n",
241 phba->params.num_eq_entries);
242 phba->params.num_cq_entries =
243 (((BE2_CMDS_PER_CXN * 2 + BE2_LOGOUTS + BE2_TMFS + BE2_ASYNCPDUS) /
244 512) + 1) * 512;
245 SE_DEBUG(DBG_LVL_8,
246 "phba->params.num_cq_entries=%d BE2_CMDS_PER_CXN=%d"
247 "BE2_LOGOUTS=%d BE2_TMFS=%d BE2_ASYNCPDUS=%d \n",
248 phba->params.num_cq_entries, BE2_CMDS_PER_CXN,
249 BE2_LOGOUTS, BE2_TMFS, BE2_ASYNCPDUS);
250 phba->params.wrbs_per_cxn = 256;
251}
252
253static void hwi_ring_eq_db(struct beiscsi_hba *phba,
254 unsigned int id, unsigned int clr_interrupt,
255 unsigned int num_processed,
256 unsigned char rearm, unsigned char event)
257{
258 u32 val = 0;
259 val |= id & DB_EQ_RING_ID_MASK;
260 if (rearm)
261 val |= 1 << DB_EQ_REARM_SHIFT;
262 if (clr_interrupt)
263 val |= 1 << DB_EQ_CLR_SHIFT;
264 if (event)
265 val |= 1 << DB_EQ_EVNT_SHIFT;
266 val |= num_processed << DB_EQ_NUM_POPPED_SHIFT;
267 iowrite32(val, phba->db_va + DB_EQ_OFFSET);
268}
269
270/**
271 * be_isr - The isr routine of the driver.
272 * @irq: Not used
273 * @dev_id: Pointer to host adapter structure
274 */
275static irqreturn_t be_isr(int irq, void *dev_id)
276{
277 struct beiscsi_hba *phba;
278 struct hwi_controller *phwi_ctrlr;
279 struct hwi_context_memory *phwi_context;
280 struct be_eq_entry *eqe = NULL;
281 struct be_queue_info *eq;
282 struct be_queue_info *cq;
283 unsigned long flags, index;
284 unsigned int num_eq_processed;
285 struct be_ctrl_info *ctrl;
286 int isr;
287
288 phba = dev_id;
289 if (!enable_msix) {
290 ctrl = &phba->ctrl;;
291 isr = ioread32(ctrl->csr + CEV_ISR0_OFFSET +
292 (PCI_FUNC(ctrl->pdev->devfn) * CEV_ISR_SIZE));
293 if (!isr)
294 return IRQ_NONE;
295 }
296
297 phwi_ctrlr = phba->phwi_ctrlr;
298 phwi_context = phwi_ctrlr->phwi_ctxt;
299 eq = &phwi_context->be_eq.q;
300 cq = &phwi_context->be_cq;
301 index = 0;
302 eqe = queue_tail_node(eq);
303 if (!eqe)
304 SE_DEBUG(DBG_LVL_1, "eqe is NULL\n");
305
306 num_eq_processed = 0;
307 if (blk_iopoll_enabled) {
308 while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32]
309 & EQE_VALID_MASK) {
310 if (!blk_iopoll_sched_prep(&phba->iopoll))
311 blk_iopoll_sched(&phba->iopoll);
312
313 AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0);
314 queue_tail_inc(eq);
315 eqe = queue_tail_node(eq);
316 num_eq_processed++;
317 SE_DEBUG(DBG_LVL_8, "Valid EQE\n");
318 }
319 if (num_eq_processed) {
320 hwi_ring_eq_db(phba, eq->id, 0, num_eq_processed, 0, 1);
321 return IRQ_HANDLED;
322 } else
323 return IRQ_NONE;
324 } else {
325 while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32]
326 & EQE_VALID_MASK) {
327
328 if (((eqe->dw[offsetof(struct amap_eq_entry,
329 resource_id) / 32] &
330 EQE_RESID_MASK) >> 16) != cq->id) {
331 spin_lock_irqsave(&phba->isr_lock, flags);
332 phba->todo_mcc_cq = 1;
333 spin_unlock_irqrestore(&phba->isr_lock, flags);
334 } else {
335 spin_lock_irqsave(&phba->isr_lock, flags);
336 phba->todo_cq = 1;
337 spin_unlock_irqrestore(&phba->isr_lock, flags);
338 }
339 AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0);
340 queue_tail_inc(eq);
341 eqe = queue_tail_node(eq);
342 num_eq_processed++;
343 }
344 if (phba->todo_cq || phba->todo_mcc_cq)
345 queue_work(phba->wq, &phba->work_cqs);
346
347 if (num_eq_processed) {
348 hwi_ring_eq_db(phba, eq->id, 0, num_eq_processed, 1, 1);
349 return IRQ_HANDLED;
350 } else
351 return IRQ_NONE;
352 }
353}
354
355static int beiscsi_init_irqs(struct beiscsi_hba *phba)
356{
357 struct pci_dev *pcidev = phba->pcidev;
358 int ret;
359
360 ret = request_irq(pcidev->irq, be_isr, IRQF_SHARED, "beiscsi", phba);
361 if (ret) {
362 shost_printk(KERN_ERR, phba->shost, "beiscsi_init_irqs-"
363 "Failed to register irq\\n");
364 return ret;
365 }
366 return 0;
367}
368
369static void hwi_ring_cq_db(struct beiscsi_hba *phba,
370 unsigned int id, unsigned int num_processed,
371 unsigned char rearm, unsigned char event)
372{
373 u32 val = 0;
374 val |= id & DB_CQ_RING_ID_MASK;
375 if (rearm)
376 val |= 1 << DB_CQ_REARM_SHIFT;
377 val |= num_processed << DB_CQ_NUM_POPPED_SHIFT;
378 iowrite32(val, phba->db_va + DB_CQ_OFFSET);
379}
380
381/*
382 * async pdus include
383 * a. unsolicited NOP-In (target initiated NOP-In)
384 * b. Async Messages
385 * c. Reject PDU
386 * d. Login response
387 * These headers arrive unprocessed by the EP firmware and iSCSI layer
388 * process them
389 */
390static unsigned int
391beiscsi_process_async_pdu(struct beiscsi_conn *beiscsi_conn,
392 struct beiscsi_hba *phba,
393 unsigned short cid,
394 struct pdu_base *ppdu,
395 unsigned long pdu_len,
396 void *pbuffer, unsigned long buf_len)
397{
398 struct iscsi_conn *conn = beiscsi_conn->conn;
399 struct iscsi_session *session = conn->session;
400
401 switch (ppdu->dw[offsetof(struct amap_pdu_base, opcode) / 32] &
402 PDUBASE_OPCODE_MASK) {
403 case ISCSI_OP_NOOP_IN:
404 pbuffer = NULL;
405 buf_len = 0;
406 break;
407 case ISCSI_OP_ASYNC_EVENT:
408 break;
409 case ISCSI_OP_REJECT:
410 WARN_ON(!pbuffer);
411 WARN_ON(!(buf_len == 48));
412 SE_DEBUG(DBG_LVL_1, "In ISCSI_OP_REJECT\n");
413 break;
414 case ISCSI_OP_LOGIN_RSP:
415 break;
416 default:
417 shost_printk(KERN_WARNING, phba->shost,
418 "Unrecognized opcode 0x%x in async msg \n",
419 (ppdu->
420 dw[offsetof(struct amap_pdu_base, opcode) / 32]
421 & PDUBASE_OPCODE_MASK));
422 return 1;
423 }
424
425 spin_lock_bh(&session->lock);
426 __iscsi_complete_pdu(conn, (struct iscsi_hdr *)ppdu, pbuffer, buf_len);
427 spin_unlock_bh(&session->lock);
428 return 0;
429}
430
431static struct sgl_handle *alloc_io_sgl_handle(struct beiscsi_hba *phba)
432{
433 struct sgl_handle *psgl_handle;
434
435 if (phba->io_sgl_hndl_avbl) {
436 SE_DEBUG(DBG_LVL_8,
437 "In alloc_io_sgl_handle,io_sgl_alloc_index=%d \n",
438 phba->io_sgl_alloc_index);
439 psgl_handle = phba->io_sgl_hndl_base[phba->
440 io_sgl_alloc_index];
441 phba->io_sgl_hndl_base[phba->io_sgl_alloc_index] = NULL;
442 phba->io_sgl_hndl_avbl--;
443 if (phba->io_sgl_alloc_index == (phba->params.ios_per_ctrl - 1))
444 phba->io_sgl_alloc_index = 0;
445 else
446 phba->io_sgl_alloc_index++;
447 } else
448 psgl_handle = NULL;
449 return psgl_handle;
450}
451
452static void
453free_io_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle)
454{
455 SE_DEBUG(DBG_LVL_8, "In free_,io_sgl_free_index=%d \n",
456 phba->io_sgl_free_index);
457 if (phba->io_sgl_hndl_base[phba->io_sgl_free_index]) {
458 /*
459 * this can happen if clean_task is called on a task that
460 * failed in xmit_task or alloc_pdu.
461 */
462 SE_DEBUG(DBG_LVL_8,
463 "Double Free in IO SGL io_sgl_free_index=%d,"
464 "value there=%p \n", phba->io_sgl_free_index,
465 phba->io_sgl_hndl_base[phba->io_sgl_free_index]);
466 return;
467 }
468 phba->io_sgl_hndl_base[phba->io_sgl_free_index] = psgl_handle;
469 phba->io_sgl_hndl_avbl++;
470 if (phba->io_sgl_free_index == (phba->params.ios_per_ctrl - 1))
471 phba->io_sgl_free_index = 0;
472 else
473 phba->io_sgl_free_index++;
474}
475
476/**
477 * alloc_wrb_handle - To allocate a wrb handle
478 * @phba: The hba pointer
479 * @cid: The cid to use for allocation
480 * @index: index allocation and wrb index
481 *
482 * This happens under session_lock until submission to chip
483 */
484struct wrb_handle *alloc_wrb_handle(struct beiscsi_hba *phba, unsigned int cid,
485 int index)
486{
487 struct hwi_wrb_context *pwrb_context;
488 struct hwi_controller *phwi_ctrlr;
489 struct wrb_handle *pwrb_handle;
490
491 phwi_ctrlr = phba->phwi_ctrlr;
492 pwrb_context = &phwi_ctrlr->wrb_context[cid];
493 pwrb_handle = pwrb_context->pwrb_handle_base[index];
494 pwrb_handle->wrb_index = index;
495 pwrb_handle->nxt_wrb_index = index;
496 return pwrb_handle;
497}
498
499/**
500 * free_wrb_handle - To free the wrb handle back to pool
501 * @phba: The hba pointer
502 * @pwrb_context: The context to free from
503 * @pwrb_handle: The wrb_handle to free
504 *
505 * This happens under session_lock until submission to chip
506 */
507static void
508free_wrb_handle(struct beiscsi_hba *phba, struct hwi_wrb_context *pwrb_context,
509 struct wrb_handle *pwrb_handle)
510{
511 SE_DEBUG(DBG_LVL_8,
512 "FREE WRB: pwrb_handle=%p free_index=%d=0x%x"
513 "wrb_handles_available=%d \n",
514 pwrb_handle, pwrb_context->free_index,
515 pwrb_context->free_index, pwrb_context->wrb_handles_available);
516}
517
518static struct sgl_handle *alloc_mgmt_sgl_handle(struct beiscsi_hba *phba)
519{
520 struct sgl_handle *psgl_handle;
521
522 if (phba->eh_sgl_hndl_avbl) {
523 psgl_handle = phba->eh_sgl_hndl_base[phba->eh_sgl_alloc_index];
524 phba->eh_sgl_hndl_base[phba->eh_sgl_alloc_index] = NULL;
525 SE_DEBUG(DBG_LVL_8, "mgmt_sgl_alloc_index=%d=0x%x \n",
526 phba->eh_sgl_alloc_index, phba->eh_sgl_alloc_index);
527 phba->eh_sgl_hndl_avbl--;
528 if (phba->eh_sgl_alloc_index ==
529 (phba->params.icds_per_ctrl - phba->params.ios_per_ctrl -
530 1))
531 phba->eh_sgl_alloc_index = 0;
532 else
533 phba->eh_sgl_alloc_index++;
534 } else
535 psgl_handle = NULL;
536 return psgl_handle;
537}
538
539void
540free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle)
541{
542
543 if (phba->eh_sgl_hndl_base[phba->eh_sgl_free_index]) {
544 /*
545 * this can happen if clean_task is called on a task that
546 * failed in xmit_task or alloc_pdu.
547 */
548 SE_DEBUG(DBG_LVL_8,
549 "Double Free in eh SGL ,eh_sgl_free_index=%d \n",
550 phba->eh_sgl_free_index);
551 return;
552 }
553 phba->eh_sgl_hndl_base[phba->eh_sgl_free_index] = psgl_handle;
554 phba->eh_sgl_hndl_avbl++;
555 if (phba->eh_sgl_free_index ==
556 (phba->params.icds_per_ctrl - phba->params.ios_per_ctrl - 1))
557 phba->eh_sgl_free_index = 0;
558 else
559 phba->eh_sgl_free_index++;
560}
561
562static void
563be_complete_io(struct beiscsi_conn *beiscsi_conn,
564 struct iscsi_task *task, struct sol_cqe *psol)
565{
566 struct beiscsi_io_task *io_task = task->dd_data;
567 struct be_status_bhs *sts_bhs =
568 (struct be_status_bhs *)io_task->cmd_bhs;
569 struct iscsi_conn *conn = beiscsi_conn->conn;
570 unsigned int sense_len;
571 unsigned char *sense;
572 u32 resid = 0, exp_cmdsn, max_cmdsn;
573 u8 rsp, status, flags;
574
575 exp_cmdsn = be32_to_cpu(psol->
576 dw[offsetof(struct amap_sol_cqe, i_exp_cmd_sn) / 32]
577 & SOL_EXP_CMD_SN_MASK);
578 max_cmdsn = be32_to_cpu((psol->
579 dw[offsetof(struct amap_sol_cqe, i_exp_cmd_sn) / 32]
580 & SOL_EXP_CMD_SN_MASK) +
581 ((psol->dw[offsetof(struct amap_sol_cqe, i_cmd_wnd)
582 / 32] & SOL_CMD_WND_MASK) >> 24) - 1);
583 rsp = ((psol->dw[offsetof(struct amap_sol_cqe, i_resp) / 32]
584 & SOL_RESP_MASK) >> 16);
585 status = ((psol->dw[offsetof(struct amap_sol_cqe, i_sts) / 32]
586 & SOL_STS_MASK) >> 8);
587 flags = ((psol->dw[offsetof(struct amap_sol_cqe, i_flags) / 32]
588 & SOL_FLAGS_MASK) >> 24) | 0x80;
589
590 task->sc->result = (DID_OK << 16) | status;
591 if (rsp != ISCSI_STATUS_CMD_COMPLETED) {
592 task->sc->result = DID_ERROR << 16;
593 goto unmap;
594 }
595
596 /* bidi not initially supported */
597 if (flags & (ISCSI_FLAG_CMD_UNDERFLOW | ISCSI_FLAG_CMD_OVERFLOW)) {
598 resid = (psol->dw[offsetof(struct amap_sol_cqe, i_res_cnt) /
599 32] & SOL_RES_CNT_MASK);
600
601 if (!status && (flags & ISCSI_FLAG_CMD_OVERFLOW))
602 task->sc->result = DID_ERROR << 16;
603
604 if (flags & ISCSI_FLAG_CMD_UNDERFLOW) {
605 scsi_set_resid(task->sc, resid);
606 if (!status && (scsi_bufflen(task->sc) - resid <
607 task->sc->underflow))
608 task->sc->result = DID_ERROR << 16;
609 }
610 }
611
612 if (status == SAM_STAT_CHECK_CONDITION) {
613 sense = sts_bhs->sense_info + sizeof(unsigned short);
614 sense_len =
615 cpu_to_be16((unsigned short)(sts_bhs->sense_info[0]));
616 memcpy(task->sc->sense_buffer, sense,
617 min_t(u16, sense_len, SCSI_SENSE_BUFFERSIZE));
618 }
619 if (io_task->cmd_bhs->iscsi_hdr.flags & ISCSI_FLAG_CMD_READ) {
620 if (psol->dw[offsetof(struct amap_sol_cqe, i_res_cnt) / 32]
621 & SOL_RES_CNT_MASK)
622 conn->rxdata_octets += (psol->
623 dw[offsetof(struct amap_sol_cqe, i_res_cnt) / 32]
624 & SOL_RES_CNT_MASK);
625 }
626unmap:
627 scsi_dma_unmap(io_task->scsi_cmnd);
628 iscsi_complete_scsi_task(task, exp_cmdsn, max_cmdsn);
629}
630
631static void
632be_complete_logout(struct beiscsi_conn *beiscsi_conn,
633 struct iscsi_task *task, struct sol_cqe *psol)
634{
635 struct iscsi_logout_rsp *hdr;
636 struct iscsi_conn *conn = beiscsi_conn->conn;
637
638 hdr = (struct iscsi_logout_rsp *)task->hdr;
639 hdr->t2wait = 5;
640 hdr->t2retain = 0;
641 hdr->flags = ((psol->dw[offsetof(struct amap_sol_cqe, i_flags) / 32]
642 & SOL_FLAGS_MASK) >> 24) | 0x80;
643 hdr->response = (psol->dw[offsetof(struct amap_sol_cqe, i_resp) /
644 32] & SOL_RESP_MASK);
645 hdr->exp_cmdsn = cpu_to_be32(psol->
646 dw[offsetof(struct amap_sol_cqe, i_exp_cmd_sn) / 32]
647 & SOL_EXP_CMD_SN_MASK);
648 hdr->max_cmdsn = be32_to_cpu((psol->
649 dw[offsetof(struct amap_sol_cqe, i_exp_cmd_sn) / 32]
650 & SOL_EXP_CMD_SN_MASK) +
651 ((psol->dw[offsetof(struct amap_sol_cqe, i_cmd_wnd)
652 / 32] & SOL_CMD_WND_MASK) >> 24) - 1);
653 hdr->hlength = 0;
654
655 __iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0);
656}
657
658static void
659be_complete_tmf(struct beiscsi_conn *beiscsi_conn,
660 struct iscsi_task *task, struct sol_cqe *psol)
661{
662 struct iscsi_tm_rsp *hdr;
663 struct iscsi_conn *conn = beiscsi_conn->conn;
664
665 hdr = (struct iscsi_tm_rsp *)task->hdr;
666 hdr->flags = ((psol->dw[offsetof(struct amap_sol_cqe, i_flags) / 32]
667 & SOL_FLAGS_MASK) >> 24) | 0x80;
668 hdr->response = (psol->dw[offsetof(struct amap_sol_cqe, i_resp) /
669 32] & SOL_RESP_MASK);
670 hdr->exp_cmdsn = cpu_to_be32(psol->dw[offsetof(struct amap_sol_cqe,
671 i_exp_cmd_sn) / 32] & SOL_EXP_CMD_SN_MASK);
672 hdr->max_cmdsn = be32_to_cpu((psol->dw[offsetof(struct amap_sol_cqe,
673 i_exp_cmd_sn) / 32] & SOL_EXP_CMD_SN_MASK) +
674 ((psol->dw[offsetof(struct amap_sol_cqe, i_cmd_wnd)
675 / 32] & SOL_CMD_WND_MASK) >> 24) - 1);
676 __iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0);
677}
678
679static void
680hwi_complete_drvr_msgs(struct beiscsi_conn *beiscsi_conn,
681 struct beiscsi_hba *phba, struct sol_cqe *psol)
682{
683 struct hwi_wrb_context *pwrb_context;
684 struct wrb_handle *pwrb_handle;
685 struct hwi_controller *phwi_ctrlr;
686 struct iscsi_conn *conn = beiscsi_conn->conn;
687 struct iscsi_session *session = conn->session;
688
689 phwi_ctrlr = phba->phwi_ctrlr;
690 pwrb_context = &phwi_ctrlr->wrb_context[((psol->
691 dw[offsetof(struct amap_sol_cqe, cid) / 32] &
692 SOL_CID_MASK) >> 6)];
693 pwrb_handle = pwrb_context->pwrb_handle_basestd[((psol->
694 dw[offsetof(struct amap_sol_cqe, wrb_index) /
695 32] & SOL_WRB_INDEX_MASK) >> 16)];
696 spin_lock_bh(&session->lock);
697 free_wrb_handle(phba, pwrb_context, pwrb_handle);
698 spin_unlock_bh(&session->lock);
699}
700
701static void
702be_complete_nopin_resp(struct beiscsi_conn *beiscsi_conn,
703 struct iscsi_task *task, struct sol_cqe *psol)
704{
705 struct iscsi_nopin *hdr;
706 struct iscsi_conn *conn = beiscsi_conn->conn;
707
708 hdr = (struct iscsi_nopin *)task->hdr;
709 hdr->flags = ((psol->dw[offsetof(struct amap_sol_cqe, i_flags) / 32]
710 & SOL_FLAGS_MASK) >> 24) | 0x80;
711 hdr->exp_cmdsn = cpu_to_be32(psol->dw[offsetof(struct amap_sol_cqe,
712 i_exp_cmd_sn) / 32] & SOL_EXP_CMD_SN_MASK);
713 hdr->max_cmdsn = be32_to_cpu((psol->dw[offsetof(struct amap_sol_cqe,
714 i_exp_cmd_sn) / 32] & SOL_EXP_CMD_SN_MASK) +
715 ((psol->dw[offsetof(struct amap_sol_cqe, i_cmd_wnd)
716 / 32] & SOL_CMD_WND_MASK) >> 24) - 1);
717 hdr->opcode = ISCSI_OP_NOOP_IN;
718 __iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0);
719}
720
721static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn,
722 struct beiscsi_hba *phba, struct sol_cqe *psol)
723{
724 struct hwi_wrb_context *pwrb_context;
725 struct wrb_handle *pwrb_handle;
726 struct iscsi_wrb *pwrb = NULL;
727 struct hwi_controller *phwi_ctrlr;
728 struct iscsi_task *task;
729 struct beiscsi_io_task *io_task;
730 struct iscsi_conn *conn = beiscsi_conn->conn;
731 struct iscsi_session *session = conn->session;
732
733 phwi_ctrlr = phba->phwi_ctrlr;
734
735 pwrb_context = &phwi_ctrlr->
736 wrb_context[((psol->dw[offsetof(struct amap_sol_cqe, cid) / 32]
737 & SOL_CID_MASK) >> 6)];
738 pwrb_handle = pwrb_context->pwrb_handle_basestd[((psol->
739 dw[offsetof(struct amap_sol_cqe, wrb_index) /
740 32] & SOL_WRB_INDEX_MASK) >> 16)];
741
742 task = pwrb_handle->pio_handle;
743 io_task = task->dd_data;
744 spin_lock_bh(&session->lock);
745 pwrb = pwrb_handle->pwrb;
746 switch ((pwrb->dw[offsetof(struct amap_iscsi_wrb, type) / 32] &
747 WRB_TYPE_MASK) >> 28) {
748 case HWH_TYPE_IO:
749 case HWH_TYPE_IO_RD:
750 if ((task->hdr->opcode & ISCSI_OPCODE_MASK) ==
751 ISCSI_OP_NOOP_OUT) {
752 be_complete_nopin_resp(beiscsi_conn, task, psol);
753 } else
754 be_complete_io(beiscsi_conn, task, psol);
755 break;
756
757 case HWH_TYPE_LOGOUT:
758 be_complete_logout(beiscsi_conn, task, psol);
759 break;
760
761 case HWH_TYPE_LOGIN:
762 SE_DEBUG(DBG_LVL_1,
763 "\t\t No HWH_TYPE_LOGIN Expected in hwi_complete_cmd"
764 "- Solicited path \n");
765 break;
766
767 case HWH_TYPE_TMF:
768 be_complete_tmf(beiscsi_conn, task, psol);
769 break;
770
771 case HWH_TYPE_NOP:
772 be_complete_nopin_resp(beiscsi_conn, task, psol);
773 break;
774
775 default:
776 shost_printk(KERN_WARNING, phba->shost,
777 "wrb_index 0x%x CID 0x%x\n",
778 ((psol->dw[offsetof(struct amap_iscsi_wrb, type) /
779 32] & SOL_WRB_INDEX_MASK) >> 16),
780 ((psol->dw[offsetof(struct amap_sol_cqe, cid) / 32]
781 & SOL_CID_MASK) >> 6));
782 break;
783 }
784
785 spin_unlock_bh(&session->lock);
786}
787
788static struct list_head *hwi_get_async_busy_list(struct hwi_async_pdu_context
789 *pasync_ctx, unsigned int is_header,
790 unsigned int host_write_ptr)
791{
792 if (is_header)
793 return &pasync_ctx->async_entry[host_write_ptr].
794 header_busy_list;
795 else
796 return &pasync_ctx->async_entry[host_write_ptr].data_busy_list;
797}
798
799static struct async_pdu_handle *
800hwi_get_async_handle(struct beiscsi_hba *phba,
801 struct beiscsi_conn *beiscsi_conn,
802 struct hwi_async_pdu_context *pasync_ctx,
803 struct i_t_dpdu_cqe *pdpdu_cqe, unsigned int *pcq_index)
804{
805 struct be_bus_address phys_addr;
806 struct list_head *pbusy_list;
807 struct async_pdu_handle *pasync_handle = NULL;
808 int buffer_len = 0;
809 unsigned char buffer_index = -1;
810 unsigned char is_header = 0;
811
812 phys_addr.u.a32.address_lo =
813 pdpdu_cqe->dw[offsetof(struct amap_i_t_dpdu_cqe, db_addr_lo) / 32] -
814 ((pdpdu_cqe->dw[offsetof(struct amap_i_t_dpdu_cqe, dpl) / 32]
815 & PDUCQE_DPL_MASK) >> 16);
816 phys_addr.u.a32.address_hi =
817 pdpdu_cqe->dw[offsetof(struct amap_i_t_dpdu_cqe, db_addr_hi) / 32];
818
819 phys_addr.u.a64.address =
820 *((unsigned long long *)(&phys_addr.u.a64.address));
821
822 switch (pdpdu_cqe->dw[offsetof(struct amap_i_t_dpdu_cqe, code) / 32]
823 & PDUCQE_CODE_MASK) {
824 case UNSOL_HDR_NOTIFY:
825 is_header = 1;
826
827 pbusy_list = hwi_get_async_busy_list(pasync_ctx, 1,
828 (pdpdu_cqe->dw[offsetof(struct amap_i_t_dpdu_cqe,
829 index) / 32] & PDUCQE_INDEX_MASK));
830
831 buffer_len = (unsigned int)(phys_addr.u.a64.address -
832 pasync_ctx->async_header.pa_base.u.a64.address);
833
834 buffer_index = buffer_len /
835 pasync_ctx->async_header.buffer_size;
836
837 break;
838 case UNSOL_DATA_NOTIFY:
839 pbusy_list = hwi_get_async_busy_list(pasync_ctx, 0, (pdpdu_cqe->
840 dw[offsetof(struct amap_i_t_dpdu_cqe,
841 index) / 32] & PDUCQE_INDEX_MASK));
842 buffer_len = (unsigned long)(phys_addr.u.a64.address -
843 pasync_ctx->async_data.pa_base.u.
844 a64.address);
845 buffer_index = buffer_len / pasync_ctx->async_data.buffer_size;
846 break;
847 default:
848 pbusy_list = NULL;
849 shost_printk(KERN_WARNING, phba->shost,
850 "Unexpected code=%d \n",
851 pdpdu_cqe->dw[offsetof(struct amap_i_t_dpdu_cqe,
852 code) / 32] & PDUCQE_CODE_MASK);
853 return NULL;
854 }
855
856 WARN_ON(!(buffer_index <= pasync_ctx->async_data.num_entries));
857 WARN_ON(list_empty(pbusy_list));
858 list_for_each_entry(pasync_handle, pbusy_list, link) {
859 WARN_ON(pasync_handle->consumed);
860 if (pasync_handle->index == buffer_index)
861 break;
862 }
863
864 WARN_ON(!pasync_handle);
865
866 pasync_handle->cri = (unsigned short)beiscsi_conn->beiscsi_conn_cid;
867 pasync_handle->is_header = is_header;
868 pasync_handle->buffer_len = ((pdpdu_cqe->
869 dw[offsetof(struct amap_i_t_dpdu_cqe, dpl) / 32]
870 & PDUCQE_DPL_MASK) >> 16);
871
872 *pcq_index = (pdpdu_cqe->dw[offsetof(struct amap_i_t_dpdu_cqe,
873 index) / 32] & PDUCQE_INDEX_MASK);
874 return pasync_handle;
875}
876
877static unsigned int
878hwi_update_async_writables(struct hwi_async_pdu_context *pasync_ctx,
879 unsigned int is_header, unsigned int cq_index)
880{
881 struct list_head *pbusy_list;
882 struct async_pdu_handle *pasync_handle;
883 unsigned int num_entries, writables = 0;
884 unsigned int *pep_read_ptr, *pwritables;
885
886
887 if (is_header) {
888 pep_read_ptr = &pasync_ctx->async_header.ep_read_ptr;
889 pwritables = &pasync_ctx->async_header.writables;
890 num_entries = pasync_ctx->async_header.num_entries;
891 } else {
892 pep_read_ptr = &pasync_ctx->async_data.ep_read_ptr;
893 pwritables = &pasync_ctx->async_data.writables;
894 num_entries = pasync_ctx->async_data.num_entries;
895 }
896
897 while ((*pep_read_ptr) != cq_index) {
898 (*pep_read_ptr)++;
899 *pep_read_ptr = (*pep_read_ptr) % num_entries;
900
901 pbusy_list = hwi_get_async_busy_list(pasync_ctx, is_header,
902 *pep_read_ptr);
903 if (writables == 0)
904 WARN_ON(list_empty(pbusy_list));
905
906 if (!list_empty(pbusy_list)) {
907 pasync_handle = list_entry(pbusy_list->next,
908 struct async_pdu_handle,
909 link);
910 WARN_ON(!pasync_handle);
911 pasync_handle->consumed = 1;
912 }
913
914 writables++;
915 }
916
917 if (!writables) {
918 SE_DEBUG(DBG_LVL_1,
919 "Duplicate notification received - index 0x%x!!\n",
920 cq_index);
921 WARN_ON(1);
922 }
923
924 *pwritables = *pwritables + writables;
925 return 0;
926}
927
928static unsigned int hwi_free_async_msg(struct beiscsi_hba *phba,
929 unsigned int cri)
930{
931 struct hwi_controller *phwi_ctrlr;
932 struct hwi_async_pdu_context *pasync_ctx;
933 struct async_pdu_handle *pasync_handle, *tmp_handle;
934 struct list_head *plist;
935 unsigned int i = 0;
936
937 phwi_ctrlr = phba->phwi_ctrlr;
938 pasync_ctx = HWI_GET_ASYNC_PDU_CTX(phwi_ctrlr);
939
940 plist = &pasync_ctx->async_entry[cri].wait_queue.list;
941
942 list_for_each_entry_safe(pasync_handle, tmp_handle, plist, link) {
943 list_del(&pasync_handle->link);
944
945 if (i == 0) {
946 list_add_tail(&pasync_handle->link,
947 &pasync_ctx->async_header.free_list);
948 pasync_ctx->async_header.free_entries++;
949 i++;
950 } else {
951 list_add_tail(&pasync_handle->link,
952 &pasync_ctx->async_data.free_list);
953 pasync_ctx->async_data.free_entries++;
954 i++;
955 }
956 }
957
958 INIT_LIST_HEAD(&pasync_ctx->async_entry[cri].wait_queue.list);
959 pasync_ctx->async_entry[cri].wait_queue.hdr_received = 0;
960 pasync_ctx->async_entry[cri].wait_queue.bytes_received = 0;
961 return 0;
962}
963
964static struct phys_addr *
965hwi_get_ring_address(struct hwi_async_pdu_context *pasync_ctx,
966 unsigned int is_header, unsigned int host_write_ptr)
967{
968 struct phys_addr *pasync_sge = NULL;
969
970 if (is_header)
971 pasync_sge = pasync_ctx->async_header.ring_base;
972 else
973 pasync_sge = pasync_ctx->async_data.ring_base;
974
975 return pasync_sge + host_write_ptr;
976}
977
978static void hwi_post_async_buffers(struct beiscsi_hba *phba,
979 unsigned int is_header)
980{
981 struct hwi_controller *phwi_ctrlr;
982 struct hwi_async_pdu_context *pasync_ctx;
983 struct async_pdu_handle *pasync_handle;
984 struct list_head *pfree_link, *pbusy_list;
985 struct phys_addr *pasync_sge;
986 unsigned int ring_id, num_entries;
987 unsigned int host_write_num;
988 unsigned int writables;
989 unsigned int i = 0;
990 u32 doorbell = 0;
991
992 phwi_ctrlr = phba->phwi_ctrlr;
993 pasync_ctx = HWI_GET_ASYNC_PDU_CTX(phwi_ctrlr);
994
995 if (is_header) {
996 num_entries = pasync_ctx->async_header.num_entries;
997 writables = min(pasync_ctx->async_header.writables,
998 pasync_ctx->async_header.free_entries);
999 pfree_link = pasync_ctx->async_header.free_list.next;
1000 host_write_num = pasync_ctx->async_header.host_write_ptr;
1001 ring_id = phwi_ctrlr->default_pdu_hdr.id;
1002 } else {
1003 num_entries = pasync_ctx->async_data.num_entries;
1004 writables = min(pasync_ctx->async_data.writables,
1005 pasync_ctx->async_data.free_entries);
1006 pfree_link = pasync_ctx->async_data.free_list.next;
1007 host_write_num = pasync_ctx->async_data.host_write_ptr;
1008 ring_id = phwi_ctrlr->default_pdu_data.id;
1009 }
1010
1011 writables = (writables / 8) * 8;
1012 if (writables) {
1013 for (i = 0; i < writables; i++) {
1014 pbusy_list =
1015 hwi_get_async_busy_list(pasync_ctx, is_header,
1016 host_write_num);
1017 pasync_handle =
1018 list_entry(pfree_link, struct async_pdu_handle,
1019 link);
1020 WARN_ON(!pasync_handle);
1021 pasync_handle->consumed = 0;
1022
1023 pfree_link = pfree_link->next;
1024
1025 pasync_sge = hwi_get_ring_address(pasync_ctx,
1026 is_header, host_write_num);
1027
1028 pasync_sge->hi = pasync_handle->pa.u.a32.address_lo;
1029 pasync_sge->lo = pasync_handle->pa.u.a32.address_hi;
1030
1031 list_move(&pasync_handle->link, pbusy_list);
1032
1033 host_write_num++;
1034 host_write_num = host_write_num % num_entries;
1035 }
1036
1037 if (is_header) {
1038 pasync_ctx->async_header.host_write_ptr =
1039 host_write_num;
1040 pasync_ctx->async_header.free_entries -= writables;
1041 pasync_ctx->async_header.writables -= writables;
1042 pasync_ctx->async_header.busy_entries += writables;
1043 } else {
1044 pasync_ctx->async_data.host_write_ptr = host_write_num;
1045 pasync_ctx->async_data.free_entries -= writables;
1046 pasync_ctx->async_data.writables -= writables;
1047 pasync_ctx->async_data.busy_entries += writables;
1048 }
1049
1050 doorbell |= ring_id & DB_DEF_PDU_RING_ID_MASK;
1051 doorbell |= 1 << DB_DEF_PDU_REARM_SHIFT;
1052 doorbell |= 0 << DB_DEF_PDU_EVENT_SHIFT;
1053 doorbell |= (writables & DB_DEF_PDU_CQPROC_MASK)
1054 << DB_DEF_PDU_CQPROC_SHIFT;
1055
1056 iowrite32(doorbell, phba->db_va + DB_RXULP0_OFFSET);
1057 }
1058}
1059
1060static void hwi_flush_default_pdu_buffer(struct beiscsi_hba *phba,
1061 struct beiscsi_conn *beiscsi_conn,
1062 struct i_t_dpdu_cqe *pdpdu_cqe)
1063{
1064 struct hwi_controller *phwi_ctrlr;
1065 struct hwi_async_pdu_context *pasync_ctx;
1066 struct async_pdu_handle *pasync_handle = NULL;
1067 unsigned int cq_index = -1;
1068
1069 phwi_ctrlr = phba->phwi_ctrlr;
1070 pasync_ctx = HWI_GET_ASYNC_PDU_CTX(phwi_ctrlr);
1071
1072 pasync_handle = hwi_get_async_handle(phba, beiscsi_conn, pasync_ctx,
1073 pdpdu_cqe, &cq_index);
1074 BUG_ON(pasync_handle->is_header != 0);
1075 if (pasync_handle->consumed == 0)
1076 hwi_update_async_writables(pasync_ctx, pasync_handle->is_header,
1077 cq_index);
1078
1079 hwi_free_async_msg(phba, pasync_handle->cri);
1080 hwi_post_async_buffers(phba, pasync_handle->is_header);
1081}
1082
1083static unsigned int
1084hwi_fwd_async_msg(struct beiscsi_conn *beiscsi_conn,
1085 struct beiscsi_hba *phba,
1086 struct hwi_async_pdu_context *pasync_ctx, unsigned short cri)
1087{
1088 struct list_head *plist;
1089 struct async_pdu_handle *pasync_handle;
1090 void *phdr = NULL;
1091 unsigned int hdr_len = 0, buf_len = 0;
1092 unsigned int status, index = 0, offset = 0;
1093 void *pfirst_buffer = NULL;
1094 unsigned int num_buf = 0;
1095
1096 plist = &pasync_ctx->async_entry[cri].wait_queue.list;
1097
1098 list_for_each_entry(pasync_handle, plist, link) {
1099 if (index == 0) {
1100 phdr = pasync_handle->pbuffer;
1101 hdr_len = pasync_handle->buffer_len;
1102 } else {
1103 buf_len = pasync_handle->buffer_len;
1104 if (!num_buf) {
1105 pfirst_buffer = pasync_handle->pbuffer;
1106 num_buf++;
1107 }
1108 memcpy(pfirst_buffer + offset,
1109 pasync_handle->pbuffer, buf_len);
1110 offset = buf_len;
1111 }
1112 index++;
1113 }
1114
1115 status = beiscsi_process_async_pdu(beiscsi_conn, phba,
1116 beiscsi_conn->beiscsi_conn_cid,
1117 phdr, hdr_len, pfirst_buffer,
1118 buf_len);
1119
1120 if (status == 0)
1121 hwi_free_async_msg(phba, cri);
1122 return 0;
1123}
1124
1125static unsigned int
1126hwi_gather_async_pdu(struct beiscsi_conn *beiscsi_conn,
1127 struct beiscsi_hba *phba,
1128 struct async_pdu_handle *pasync_handle)
1129{
1130 struct hwi_async_pdu_context *pasync_ctx;
1131 struct hwi_controller *phwi_ctrlr;
1132 unsigned int bytes_needed = 0, status = 0;
1133 unsigned short cri = pasync_handle->cri;
1134 struct pdu_base *ppdu;
1135
1136 phwi_ctrlr = phba->phwi_ctrlr;
1137 pasync_ctx = HWI_GET_ASYNC_PDU_CTX(phwi_ctrlr);
1138
1139 list_del(&pasync_handle->link);
1140 if (pasync_handle->is_header) {
1141 pasync_ctx->async_header.busy_entries--;
1142 if (pasync_ctx->async_entry[cri].wait_queue.hdr_received) {
1143 hwi_free_async_msg(phba, cri);
1144 BUG();
1145 }
1146
1147 pasync_ctx->async_entry[cri].wait_queue.bytes_received = 0;
1148 pasync_ctx->async_entry[cri].wait_queue.hdr_received = 1;
1149 pasync_ctx->async_entry[cri].wait_queue.hdr_len =
1150 (unsigned short)pasync_handle->buffer_len;
1151 list_add_tail(&pasync_handle->link,
1152 &pasync_ctx->async_entry[cri].wait_queue.list);
1153
1154 ppdu = pasync_handle->pbuffer;
1155 bytes_needed = ((((ppdu->dw[offsetof(struct amap_pdu_base,
1156 data_len_hi) / 32] & PDUBASE_DATALENHI_MASK) << 8) &
1157 0xFFFF0000) | ((be16_to_cpu((ppdu->
1158 dw[offsetof(struct amap_pdu_base, data_len_lo) / 32]
1159 & PDUBASE_DATALENLO_MASK) >> 16)) & 0x0000FFFF));
1160
1161 if (status == 0) {
1162 pasync_ctx->async_entry[cri].wait_queue.bytes_needed =
1163 bytes_needed;
1164
1165 if (bytes_needed == 0)
1166 status = hwi_fwd_async_msg(beiscsi_conn, phba,
1167 pasync_ctx, cri);
1168 }
1169 } else {
1170 pasync_ctx->async_data.busy_entries--;
1171 if (pasync_ctx->async_entry[cri].wait_queue.hdr_received) {
1172 list_add_tail(&pasync_handle->link,
1173 &pasync_ctx->async_entry[cri].wait_queue.
1174 list);
1175 pasync_ctx->async_entry[cri].wait_queue.
1176 bytes_received +=
1177 (unsigned short)pasync_handle->buffer_len;
1178
1179 if (pasync_ctx->async_entry[cri].wait_queue.
1180 bytes_received >=
1181 pasync_ctx->async_entry[cri].wait_queue.
1182 bytes_needed)
1183 status = hwi_fwd_async_msg(beiscsi_conn, phba,
1184 pasync_ctx, cri);
1185 }
1186 }
1187 return status;
1188}
1189
1190static void hwi_process_default_pdu_ring(struct beiscsi_conn *beiscsi_conn,
1191 struct beiscsi_hba *phba,
1192 struct i_t_dpdu_cqe *pdpdu_cqe)
1193{
1194 struct hwi_controller *phwi_ctrlr;
1195 struct hwi_async_pdu_context *pasync_ctx;
1196 struct async_pdu_handle *pasync_handle = NULL;
1197 unsigned int cq_index = -1;
1198
1199 phwi_ctrlr = phba->phwi_ctrlr;
1200 pasync_ctx = HWI_GET_ASYNC_PDU_CTX(phwi_ctrlr);
1201 pasync_handle = hwi_get_async_handle(phba, beiscsi_conn, pasync_ctx,
1202 pdpdu_cqe, &cq_index);
1203
1204 if (pasync_handle->consumed == 0)
1205 hwi_update_async_writables(pasync_ctx, pasync_handle->is_header,
1206 cq_index);
1207 hwi_gather_async_pdu(beiscsi_conn, phba, pasync_handle);
1208 hwi_post_async_buffers(phba, pasync_handle->is_header);
1209}
1210
1211static unsigned int beiscsi_process_cq(struct beiscsi_hba *phba)
1212{
1213 struct hwi_controller *phwi_ctrlr;
1214 struct hwi_context_memory *phwi_context;
1215 struct be_queue_info *cq;
1216 struct sol_cqe *sol;
1217 struct dmsg_cqe *dmsg;
1218 unsigned int num_processed = 0;
1219 unsigned int tot_nump = 0;
1220 struct beiscsi_conn *beiscsi_conn;
1221
1222 phwi_ctrlr = phba->phwi_ctrlr;
1223 phwi_context = phwi_ctrlr->phwi_ctxt;
1224 cq = &phwi_context->be_cq;
1225 sol = queue_tail_node(cq);
1226
1227 while (sol->dw[offsetof(struct amap_sol_cqe, valid) / 32] &
1228 CQE_VALID_MASK) {
1229 be_dws_le_to_cpu(sol, sizeof(struct sol_cqe));
1230
1231 beiscsi_conn = phba->conn_table[(u32) (sol->
1232 dw[offsetof(struct amap_sol_cqe, cid) / 32] &
1233 SOL_CID_MASK) >> 6];
1234
1235 if (!beiscsi_conn || !beiscsi_conn->ep) {
1236 shost_printk(KERN_WARNING, phba->shost,
1237 "Connection table empty for cid = %d\n",
1238 (u32)(sol->dw[offsetof(struct amap_sol_cqe,
1239 cid) / 32] & SOL_CID_MASK) >> 6);
1240 return 0;
1241 }
1242
1243 if (num_processed >= 32) {
1244 hwi_ring_cq_db(phba, phwi_context->be_cq.id,
1245 num_processed, 0, 0);
1246 tot_nump += num_processed;
1247 num_processed = 0;
1248 }
1249
1250 switch ((u32) sol->dw[offsetof(struct amap_sol_cqe, code) /
1251 32] & CQE_CODE_MASK) {
1252 case SOL_CMD_COMPLETE:
1253 hwi_complete_cmd(beiscsi_conn, phba, sol);
1254 break;
1255 case DRIVERMSG_NOTIFY:
1256 SE_DEBUG(DBG_LVL_8, "Received DRIVERMSG_NOTIFY \n");
1257 dmsg = (struct dmsg_cqe *)sol;
1258 hwi_complete_drvr_msgs(beiscsi_conn, phba, sol);
1259 break;
1260 case UNSOL_HDR_NOTIFY:
1261 case UNSOL_DATA_NOTIFY:
1262 SE_DEBUG(DBG_LVL_8, "Received UNSOL_HDR/DATA_NOTIFY\n");
1263 hwi_process_default_pdu_ring(beiscsi_conn, phba,
1264 (struct i_t_dpdu_cqe *)sol);
1265 break;
1266 case CXN_INVALIDATE_INDEX_NOTIFY:
1267 case CMD_INVALIDATED_NOTIFY:
1268 case CXN_INVALIDATE_NOTIFY:
1269 SE_DEBUG(DBG_LVL_1,
1270 "Ignoring CQ Error notification for cmd/cxn"
1271 "invalidate\n");
1272 break;
1273 case SOL_CMD_KILLED_DATA_DIGEST_ERR:
1274 case CMD_KILLED_INVALID_STATSN_RCVD:
1275 case CMD_KILLED_INVALID_R2T_RCVD:
1276 case CMD_CXN_KILLED_LUN_INVALID:
1277 case CMD_CXN_KILLED_ICD_INVALID:
1278 case CMD_CXN_KILLED_ITT_INVALID:
1279 case CMD_CXN_KILLED_SEQ_OUTOFORDER:
1280 case CMD_CXN_KILLED_INVALID_DATASN_RCVD:
1281 SE_DEBUG(DBG_LVL_1,
1282 "CQ Error notification for cmd.. "
1283 "code %d cid 0x%x\n",
1284 sol->dw[offsetof(struct amap_sol_cqe, code) /
1285 32] & CQE_CODE_MASK,
1286 (sol->dw[offsetof(struct amap_sol_cqe, cid) /
1287 32] & SOL_CID_MASK));
1288 break;
1289 case UNSOL_DATA_DIGEST_ERROR_NOTIFY:
1290 SE_DEBUG(DBG_LVL_1,
1291 "Digest error on def pdu ring, dropping..\n");
1292 hwi_flush_default_pdu_buffer(phba, beiscsi_conn,
1293 (struct i_t_dpdu_cqe *) sol);
1294 break;
1295 case CXN_KILLED_PDU_SIZE_EXCEEDS_DSL:
1296 case CXN_KILLED_BURST_LEN_MISMATCH:
1297 case CXN_KILLED_AHS_RCVD:
1298 case CXN_KILLED_HDR_DIGEST_ERR:
1299 case CXN_KILLED_UNKNOWN_HDR:
1300 case CXN_KILLED_STALE_ITT_TTT_RCVD:
1301 case CXN_KILLED_INVALID_ITT_TTT_RCVD:
1302 case CXN_KILLED_TIMED_OUT:
1303 case CXN_KILLED_FIN_RCVD:
1304 case CXN_KILLED_BAD_UNSOL_PDU_RCVD:
1305 case CXN_KILLED_BAD_WRB_INDEX_ERROR:
1306 case CXN_KILLED_OVER_RUN_RESIDUAL:
1307 case CXN_KILLED_UNDER_RUN_RESIDUAL:
1308 case CXN_KILLED_CMND_DATA_NOT_ON_SAME_CONN:
1309 SE_DEBUG(DBG_LVL_1, "CQ Error %d, resetting CID "
1310 "0x%x...\n",
1311 sol->dw[offsetof(struct amap_sol_cqe, code) /
1312 32] & CQE_CODE_MASK,
1313 sol->dw[offsetof(struct amap_sol_cqe, cid) /
1314 32] & CQE_CID_MASK);
1315 iscsi_conn_failure(beiscsi_conn->conn,
1316 ISCSI_ERR_CONN_FAILED);
1317 break;
1318 case CXN_KILLED_RST_SENT:
1319 case CXN_KILLED_RST_RCVD:
1320 SE_DEBUG(DBG_LVL_1, "CQ Error %d, reset received/sent "
1321 "on CID 0x%x...\n",
1322 sol->dw[offsetof(struct amap_sol_cqe, code) /
1323 32] & CQE_CODE_MASK,
1324 sol->dw[offsetof(struct amap_sol_cqe, cid) /
1325 32] & CQE_CID_MASK);
1326 iscsi_conn_failure(beiscsi_conn->conn,
1327 ISCSI_ERR_CONN_FAILED);
1328 break;
1329 default:
1330 SE_DEBUG(DBG_LVL_1, "CQ Error Invalid code= %d "
1331 "received on CID 0x%x...\n",
1332 sol->dw[offsetof(struct amap_sol_cqe, code) /
1333 32] & CQE_CODE_MASK,
1334 sol->dw[offsetof(struct amap_sol_cqe, cid) /
1335 32] & CQE_CID_MASK);
1336 break;
1337 }
1338
1339 AMAP_SET_BITS(struct amap_sol_cqe, valid, sol, 0);
1340 queue_tail_inc(cq);
1341 sol = queue_tail_node(cq);
1342 num_processed++;
1343 }
1344
1345 if (num_processed > 0) {
1346 tot_nump += num_processed;
1347 hwi_ring_cq_db(phba, phwi_context->be_cq.id, num_processed,
1348 1, 0);
1349 }
1350 return tot_nump;
1351}
1352
1353static void beiscsi_process_all_cqs(struct work_struct *work)
1354{
1355 unsigned long flags;
1356 struct beiscsi_hba *phba =
1357 container_of(work, struct beiscsi_hba, work_cqs);
1358
1359 if (phba->todo_mcc_cq) {
1360 spin_lock_irqsave(&phba->isr_lock, flags);
1361 phba->todo_mcc_cq = 0;
1362 spin_unlock_irqrestore(&phba->isr_lock, flags);
1363 SE_DEBUG(DBG_LVL_1, "MCC Interrupt Not expected \n");
1364 }
1365
1366 if (phba->todo_cq) {
1367 spin_lock_irqsave(&phba->isr_lock, flags);
1368 phba->todo_cq = 0;
1369 spin_unlock_irqrestore(&phba->isr_lock, flags);
1370 beiscsi_process_cq(phba);
1371 }
1372}
1373
1374static int be_iopoll(struct blk_iopoll *iop, int budget)
1375{
1376 static unsigned int ret;
1377 struct beiscsi_hba *phba;
1378
1379 phba = container_of(iop, struct beiscsi_hba, iopoll);
1380
1381 ret = beiscsi_process_cq(phba);
1382 if (ret < budget) {
1383 struct hwi_controller *phwi_ctrlr;
1384 struct hwi_context_memory *phwi_context;
1385
1386 phwi_ctrlr = phba->phwi_ctrlr;
1387 phwi_context = phwi_ctrlr->phwi_ctxt;
1388 blk_iopoll_complete(iop);
1389 hwi_ring_eq_db(phba, phwi_context->be_eq.q.id, 0,
1390 0, 1, 1);
1391 }
1392 return ret;
1393}
1394
1395static void
1396hwi_write_sgl(struct iscsi_wrb *pwrb, struct scatterlist *sg,
1397 unsigned int num_sg, struct beiscsi_io_task *io_task)
1398{
1399 struct iscsi_sge *psgl;
1400 unsigned short sg_len, index;
1401 unsigned int sge_len = 0;
1402 unsigned long long addr;
1403 struct scatterlist *l_sg;
1404 unsigned int offset;
1405
1406 AMAP_SET_BITS(struct amap_iscsi_wrb, iscsi_bhs_addr_lo, pwrb,
1407 io_task->bhs_pa.u.a32.address_lo);
1408 AMAP_SET_BITS(struct amap_iscsi_wrb, iscsi_bhs_addr_hi, pwrb,
1409 io_task->bhs_pa.u.a32.address_hi);
1410
1411 l_sg = sg;
1412 for (index = 0; (index < num_sg) && (index < 2); index++, sg_next(sg)) {
1413 if (index == 0) {
1414 sg_len = sg_dma_len(sg);
1415 addr = (u64) sg_dma_address(sg);
1416 AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_addr_lo, pwrb,
1417 (addr & 0xFFFFFFFF));
1418 AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_addr_hi, pwrb,
1419 (addr >> 32));
1420 AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_len, pwrb,
1421 sg_len);
1422 sge_len = sg_len;
1423 AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_last, pwrb,
1424 1);
1425 } else {
1426 AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_last, pwrb,
1427 0);
1428 AMAP_SET_BITS(struct amap_iscsi_wrb, sge1_r2t_offset,
1429 pwrb, sge_len);
1430 sg_len = sg_dma_len(sg);
1431 addr = (u64) sg_dma_address(sg);
1432 AMAP_SET_BITS(struct amap_iscsi_wrb, sge1_addr_lo, pwrb,
1433 (addr & 0xFFFFFFFF));
1434 AMAP_SET_BITS(struct amap_iscsi_wrb, sge1_addr_hi, pwrb,
1435 (addr >> 32));
1436 AMAP_SET_BITS(struct amap_iscsi_wrb, sge1_len, pwrb,
1437 sg_len);
1438 }
1439 }
1440 psgl = (struct iscsi_sge *)io_task->psgl_handle->pfrag;
1441 memset(psgl, 0, sizeof(*psgl) * BE2_SGE);
1442
1443 AMAP_SET_BITS(struct amap_iscsi_sge, len, psgl, io_task->bhs_len - 2);
1444
1445 AMAP_SET_BITS(struct amap_iscsi_sge, addr_hi, psgl,
1446 io_task->bhs_pa.u.a32.address_hi);
1447 AMAP_SET_BITS(struct amap_iscsi_sge, addr_lo, psgl,
1448 io_task->bhs_pa.u.a32.address_lo);
1449
1450 if (num_sg == 2)
1451 AMAP_SET_BITS(struct amap_iscsi_wrb, sge1_last, pwrb, 1);
1452 sg = l_sg;
1453 psgl++;
1454 psgl++;
1455 offset = 0;
1456 for (index = 0; index < num_sg; index++, sg_next(sg), psgl++) {
1457 sg_len = sg_dma_len(sg);
1458 addr = (u64) sg_dma_address(sg);
1459 AMAP_SET_BITS(struct amap_iscsi_sge, addr_lo, psgl,
1460 (addr & 0xFFFFFFFF));
1461 AMAP_SET_BITS(struct amap_iscsi_sge, addr_hi, psgl,
1462 (addr >> 32));
1463 AMAP_SET_BITS(struct amap_iscsi_sge, len, psgl, sg_len);
1464 AMAP_SET_BITS(struct amap_iscsi_sge, sge_offset, psgl, offset);
1465 AMAP_SET_BITS(struct amap_iscsi_sge, last_sge, psgl, 0);
1466 offset += sg_len;
1467 }
1468 psgl--;
1469 AMAP_SET_BITS(struct amap_iscsi_sge, last_sge, psgl, 1);
1470}
1471
1472static void hwi_write_buffer(struct iscsi_wrb *pwrb, struct iscsi_task *task)
1473{
1474 struct iscsi_sge *psgl;
1475 unsigned long long addr;
1476 struct beiscsi_io_task *io_task = task->dd_data;
1477 struct beiscsi_conn *beiscsi_conn = io_task->conn;
1478 struct beiscsi_hba *phba = beiscsi_conn->phba;
1479
1480 io_task->bhs_len = sizeof(struct be_nonio_bhs) - 2;
1481 AMAP_SET_BITS(struct amap_iscsi_wrb, iscsi_bhs_addr_lo, pwrb,
1482 io_task->bhs_pa.u.a32.address_lo);
1483 AMAP_SET_BITS(struct amap_iscsi_wrb, iscsi_bhs_addr_hi, pwrb,
1484 io_task->bhs_pa.u.a32.address_hi);
1485
1486 if (task->data) {
1487 if (task->data_count) {
1488 AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 1);
1489 addr = (u64) pci_map_single(phba->pcidev,
1490 task->data,
1491 task->data_count, 1);
1492 } else {
1493 AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 0);
1494 addr = 0;
1495 }
1496 AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_addr_lo, pwrb,
1497 (addr & 0xFFFFFFFF));
1498 AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_addr_hi, pwrb,
1499 (addr >> 32));
1500 AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_len, pwrb,
1501 task->data_count);
1502
1503 AMAP_SET_BITS(struct amap_iscsi_wrb, sge0_last, pwrb, 1);
1504 } else {
1505 AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 0);
1506 addr = 0;
1507 }
1508
1509 psgl = (struct iscsi_sge *)io_task->psgl_handle->pfrag;
1510
1511 AMAP_SET_BITS(struct amap_iscsi_sge, len, psgl, io_task->bhs_len);
1512
1513 AMAP_SET_BITS(struct amap_iscsi_sge, addr_hi, psgl,
1514 io_task->bhs_pa.u.a32.address_hi);
1515 AMAP_SET_BITS(struct amap_iscsi_sge, addr_lo, psgl,
1516 io_task->bhs_pa.u.a32.address_lo);
1517 if (task->data) {
1518 psgl++;
1519 AMAP_SET_BITS(struct amap_iscsi_sge, addr_hi, psgl, 0);
1520 AMAP_SET_BITS(struct amap_iscsi_sge, addr_lo, psgl, 0);
1521 AMAP_SET_BITS(struct amap_iscsi_sge, len, psgl, 0);
1522 AMAP_SET_BITS(struct amap_iscsi_sge, sge_offset, psgl, 0);
1523 AMAP_SET_BITS(struct amap_iscsi_sge, rsvd0, psgl, 0);
1524 AMAP_SET_BITS(struct amap_iscsi_sge, last_sge, psgl, 0);
1525
1526 psgl++;
1527 if (task->data) {
1528 AMAP_SET_BITS(struct amap_iscsi_sge, addr_lo, psgl,
1529 (addr & 0xFFFFFFFF));
1530 AMAP_SET_BITS(struct amap_iscsi_sge, addr_hi, psgl,
1531 (addr >> 32));
1532 }
1533 AMAP_SET_BITS(struct amap_iscsi_sge, len, psgl, 0x106);
1534 }
1535 AMAP_SET_BITS(struct amap_iscsi_sge, last_sge, psgl, 1);
1536}
1537
1538static void beiscsi_find_mem_req(struct beiscsi_hba *phba)
1539{
1540 unsigned int num_cq_pages, num_eq_pages, num_async_pdu_buf_pages;
1541 unsigned int num_async_pdu_data_pages, wrb_sz_per_cxn;
1542 unsigned int num_async_pdu_buf_sgl_pages, num_async_pdu_data_sgl_pages;
1543
1544 num_cq_pages = PAGES_REQUIRED(phba->params.num_cq_entries * \
1545 sizeof(struct sol_cqe));
1546 num_eq_pages = PAGES_REQUIRED(phba->params.num_eq_entries * \
1547 sizeof(struct be_eq_entry));
1548 num_async_pdu_buf_pages =
1549 PAGES_REQUIRED(phba->params.asyncpdus_per_ctrl * \
1550 phba->params.defpdu_hdr_sz);
1551 num_async_pdu_buf_sgl_pages =
1552 PAGES_REQUIRED(phba->params.asyncpdus_per_ctrl * \
1553 sizeof(struct phys_addr));
1554 num_async_pdu_data_pages =
1555 PAGES_REQUIRED(phba->params.asyncpdus_per_ctrl * \
1556 phba->params.defpdu_data_sz);
1557 num_async_pdu_data_sgl_pages =
1558 PAGES_REQUIRED(phba->params.asyncpdus_per_ctrl * \
1559 sizeof(struct phys_addr));
1560
1561 phba->params.hwi_ws_sz = sizeof(struct hwi_controller);
1562
1563 phba->mem_req[ISCSI_MEM_GLOBAL_HEADER] = 2 *
1564 BE_ISCSI_PDU_HEADER_SIZE;
1565 phba->mem_req[HWI_MEM_ADDN_CONTEXT] =
1566 sizeof(struct hwi_context_memory);
1567
1568 phba->mem_req[HWI_MEM_CQ] = num_cq_pages * PAGE_SIZE;
1569 phba->mem_req[HWI_MEM_EQ] = num_eq_pages * PAGE_SIZE;
1570
1571 phba->mem_req[HWI_MEM_WRB] = sizeof(struct iscsi_wrb)
1572 * (phba->params.wrbs_per_cxn)
1573 * phba->params.cxns_per_ctrl;
1574 wrb_sz_per_cxn = sizeof(struct wrb_handle) *
1575 (phba->params.wrbs_per_cxn);
1576 phba->mem_req[HWI_MEM_WRBH] = roundup_pow_of_two((wrb_sz_per_cxn) *
1577 phba->params.cxns_per_ctrl);
1578
1579 phba->mem_req[HWI_MEM_SGLH] = sizeof(struct sgl_handle) *
1580 phba->params.icds_per_ctrl;
1581 phba->mem_req[HWI_MEM_SGE] = sizeof(struct iscsi_sge) *
1582 phba->params.num_sge_per_io * phba->params.icds_per_ctrl;
1583
1584 phba->mem_req[HWI_MEM_ASYNC_HEADER_BUF] =
1585 num_async_pdu_buf_pages * PAGE_SIZE;
1586 phba->mem_req[HWI_MEM_ASYNC_DATA_BUF] =
1587 num_async_pdu_data_pages * PAGE_SIZE;
1588 phba->mem_req[HWI_MEM_ASYNC_HEADER_RING] =
1589 num_async_pdu_buf_sgl_pages * PAGE_SIZE;
1590 phba->mem_req[HWI_MEM_ASYNC_DATA_RING] =
1591 num_async_pdu_data_sgl_pages * PAGE_SIZE;
1592 phba->mem_req[HWI_MEM_ASYNC_HEADER_HANDLE] =
1593 phba->params.asyncpdus_per_ctrl *
1594 sizeof(struct async_pdu_handle);
1595 phba->mem_req[HWI_MEM_ASYNC_DATA_HANDLE] =
1596 phba->params.asyncpdus_per_ctrl *
1597 sizeof(struct async_pdu_handle);
1598 phba->mem_req[HWI_MEM_ASYNC_PDU_CONTEXT] =
1599 sizeof(struct hwi_async_pdu_context) +
1600 (phba->params.cxns_per_ctrl * sizeof(struct hwi_async_entry));
1601}
1602
1603static int beiscsi_alloc_mem(struct beiscsi_hba *phba)
1604{
1605 struct be_mem_descriptor *mem_descr;
1606 dma_addr_t bus_add;
1607 struct mem_array *mem_arr, *mem_arr_orig;
1608 unsigned int i, j, alloc_size, curr_alloc_size;
1609
1610 phba->phwi_ctrlr = kmalloc(phba->params.hwi_ws_sz, GFP_KERNEL);
1611 if (!phba->phwi_ctrlr)
1612 return -ENOMEM;
1613
1614 phba->init_mem = kcalloc(SE_MEM_MAX, sizeof(*mem_descr),
1615 GFP_KERNEL);
1616 if (!phba->init_mem) {
1617 kfree(phba->phwi_ctrlr);
1618 return -ENOMEM;
1619 }
1620
1621 mem_arr_orig = kmalloc(sizeof(*mem_arr_orig) * BEISCSI_MAX_FRAGS_INIT,
1622 GFP_KERNEL);
1623 if (!mem_arr_orig) {
1624 kfree(phba->init_mem);
1625 kfree(phba->phwi_ctrlr);
1626 return -ENOMEM;
1627 }
1628
1629 mem_descr = phba->init_mem;
1630 for (i = 0; i < SE_MEM_MAX; i++) {
1631 j = 0;
1632 mem_arr = mem_arr_orig;
1633 alloc_size = phba->mem_req[i];
1634 memset(mem_arr, 0, sizeof(struct mem_array) *
1635 BEISCSI_MAX_FRAGS_INIT);
1636 curr_alloc_size = min(be_max_phys_size * 1024, alloc_size);
1637 do {
1638 mem_arr->virtual_address = pci_alloc_consistent(
1639 phba->pcidev,
1640 curr_alloc_size,
1641 &bus_add);
1642 if (!mem_arr->virtual_address) {
1643 if (curr_alloc_size <= BE_MIN_MEM_SIZE)
1644 goto free_mem;
1645 if (curr_alloc_size -
1646 rounddown_pow_of_two(curr_alloc_size))
1647 curr_alloc_size = rounddown_pow_of_two
1648 (curr_alloc_size);
1649 else
1650 curr_alloc_size = curr_alloc_size / 2;
1651 } else {
1652 mem_arr->bus_address.u.
1653 a64.address = (__u64) bus_add;
1654 mem_arr->size = curr_alloc_size;
1655 alloc_size -= curr_alloc_size;
1656 curr_alloc_size = min(be_max_phys_size *
1657 1024, alloc_size);
1658 j++;
1659 mem_arr++;
1660 }
1661 } while (alloc_size);
1662 mem_descr->num_elements = j;
1663 mem_descr->size_in_bytes = phba->mem_req[i];
1664 mem_descr->mem_array = kmalloc(sizeof(*mem_arr) * j,
1665 GFP_KERNEL);
1666 if (!mem_descr->mem_array)
1667 goto free_mem;
1668
1669 memcpy(mem_descr->mem_array, mem_arr_orig,
1670 sizeof(struct mem_array) * j);
1671 mem_descr++;
1672 }
1673 kfree(mem_arr_orig);
1674 return 0;
1675free_mem:
1676 mem_descr->num_elements = j;
1677 while ((i) || (j)) {
1678 for (j = mem_descr->num_elements; j > 0; j--) {
1679 pci_free_consistent(phba->pcidev,
1680 mem_descr->mem_array[j - 1].size,
1681 mem_descr->mem_array[j - 1].
1682 virtual_address,
1683 mem_descr->mem_array[j - 1].
1684 bus_address.u.a64.address);
1685 }
1686 if (i) {
1687 i--;
1688 kfree(mem_descr->mem_array);
1689 mem_descr--;
1690 }
1691 }
1692 kfree(mem_arr_orig);
1693 kfree(phba->init_mem);
1694 kfree(phba->phwi_ctrlr);
1695 return -ENOMEM;
1696}
1697
1698static int beiscsi_get_memory(struct beiscsi_hba *phba)
1699{
1700 beiscsi_find_mem_req(phba);
1701 return beiscsi_alloc_mem(phba);
1702}
1703
1704static void iscsi_init_global_templates(struct beiscsi_hba *phba)
1705{
1706 struct pdu_data_out *pdata_out;
1707 struct pdu_nop_out *pnop_out;
1708 struct be_mem_descriptor *mem_descr;
1709
1710 mem_descr = phba->init_mem;
1711 mem_descr += ISCSI_MEM_GLOBAL_HEADER;
1712 pdata_out =
1713 (struct pdu_data_out *)mem_descr->mem_array[0].virtual_address;
1714 memset(pdata_out, 0, BE_ISCSI_PDU_HEADER_SIZE);
1715
1716 AMAP_SET_BITS(struct amap_pdu_data_out, opcode, pdata_out,
1717 IIOC_SCSI_DATA);
1718
1719 pnop_out =
1720 (struct pdu_nop_out *)((unsigned char *)mem_descr->mem_array[0].
1721 virtual_address + BE_ISCSI_PDU_HEADER_SIZE);
1722
1723 memset(pnop_out, 0, BE_ISCSI_PDU_HEADER_SIZE);
1724 AMAP_SET_BITS(struct amap_pdu_nop_out, ttt, pnop_out, 0xFFFFFFFF);
1725 AMAP_SET_BITS(struct amap_pdu_nop_out, f_bit, pnop_out, 1);
1726 AMAP_SET_BITS(struct amap_pdu_nop_out, i_bit, pnop_out, 0);
1727}
1728
1729static void beiscsi_init_wrb_handle(struct beiscsi_hba *phba)
1730{
1731 struct be_mem_descriptor *mem_descr_wrbh, *mem_descr_wrb;
1732 struct wrb_handle *pwrb_handle;
1733 struct hwi_controller *phwi_ctrlr;
1734 struct hwi_wrb_context *pwrb_context;
1735 struct iscsi_wrb *pwrb;
1736 unsigned int num_cxn_wrbh;
1737 unsigned int num_cxn_wrb, j, idx, index;
1738
1739 mem_descr_wrbh = phba->init_mem;
1740 mem_descr_wrbh += HWI_MEM_WRBH;
1741
1742 mem_descr_wrb = phba->init_mem;
1743 mem_descr_wrb += HWI_MEM_WRB;
1744
1745 idx = 0;
1746 pwrb_handle = mem_descr_wrbh->mem_array[idx].virtual_address;
1747 num_cxn_wrbh = ((mem_descr_wrbh->mem_array[idx].size) /
1748 ((sizeof(struct wrb_handle)) *
1749 phba->params.wrbs_per_cxn));
1750 phwi_ctrlr = phba->phwi_ctrlr;
1751
1752 for (index = 0; index < phba->params.cxns_per_ctrl * 2; index += 2) {
1753 pwrb_context = &phwi_ctrlr->wrb_context[index];
1754 SE_DEBUG(DBG_LVL_8, "cid=%d pwrb_context=%p \n", index,
1755 pwrb_context);
1756 pwrb_context->pwrb_handle_base =
1757 kzalloc(sizeof(struct wrb_handle *) *
1758 phba->params.wrbs_per_cxn, GFP_KERNEL);
1759 pwrb_context->pwrb_handle_basestd =
1760 kzalloc(sizeof(struct wrb_handle *) *
1761 phba->params.wrbs_per_cxn, GFP_KERNEL);
1762 if (num_cxn_wrbh) {
1763 pwrb_context->alloc_index = 0;
1764 pwrb_context->wrb_handles_available = 0;
1765 for (j = 0; j < phba->params.wrbs_per_cxn; j++) {
1766 pwrb_context->pwrb_handle_base[j] = pwrb_handle;
1767 pwrb_context->pwrb_handle_basestd[j] =
1768 pwrb_handle;
1769 pwrb_context->wrb_handles_available++;
1770 pwrb_handle++;
1771 }
1772 pwrb_context->free_index = 0;
1773 num_cxn_wrbh--;
1774 } else {
1775 idx++;
1776 pwrb_handle =
1777 mem_descr_wrbh->mem_array[idx].virtual_address;
1778 num_cxn_wrbh =
1779 ((mem_descr_wrbh->mem_array[idx].size) /
1780 ((sizeof(struct wrb_handle)) *
1781 phba->params.wrbs_per_cxn));
1782 pwrb_context->alloc_index = 0;
1783 for (j = 0; j < phba->params.wrbs_per_cxn; j++) {
1784 pwrb_context->pwrb_handle_base[j] = pwrb_handle;
1785 pwrb_context->pwrb_handle_basestd[j] =
1786 pwrb_handle;
1787 pwrb_context->wrb_handles_available++;
1788 pwrb_handle++;
1789 }
1790 pwrb_context->free_index = 0;
1791 num_cxn_wrbh--;
1792 }
1793 }
1794 idx = 0;
1795 pwrb = mem_descr_wrb->mem_array[idx].virtual_address;
1796 num_cxn_wrb =
1797 ((mem_descr_wrb->mem_array[idx].size) / (sizeof(struct iscsi_wrb)) *
1798 phba->params.wrbs_per_cxn);
1799
1800 for (index = 0; index < phba->params.cxns_per_ctrl; index += 2) {
1801 pwrb_context = &phwi_ctrlr->wrb_context[index];
1802 if (num_cxn_wrb) {
1803 for (j = 0; j < phba->params.wrbs_per_cxn; j++) {
1804 pwrb_handle = pwrb_context->pwrb_handle_base[j];
1805 pwrb_handle->pwrb = pwrb;
1806 pwrb++;
1807 }
1808 num_cxn_wrb--;
1809 } else {
1810 idx++;
1811 pwrb = mem_descr_wrb->mem_array[idx].virtual_address;
1812 num_cxn_wrb = ((mem_descr_wrb->mem_array[idx].size) /
1813 (sizeof(struct iscsi_wrb)) *
1814 phba->params.wrbs_per_cxn);
1815 for (j = 0; j < phba->params.wrbs_per_cxn; j++) {
1816 pwrb_handle = pwrb_context->pwrb_handle_base[j];
1817 pwrb_handle->pwrb = pwrb;
1818 pwrb++;
1819 }
1820 num_cxn_wrb--;
1821 }
1822 }
1823}
1824
1825static void hwi_init_async_pdu_ctx(struct beiscsi_hba *phba)
1826{
1827 struct hwi_controller *phwi_ctrlr;
1828 struct hba_parameters *p = &phba->params;
1829 struct hwi_async_pdu_context *pasync_ctx;
1830 struct async_pdu_handle *pasync_header_h, *pasync_data_h;
1831 unsigned int index;
1832 struct be_mem_descriptor *mem_descr;
1833
1834 mem_descr = (struct be_mem_descriptor *)phba->init_mem;
1835 mem_descr += HWI_MEM_ASYNC_PDU_CONTEXT;
1836
1837 phwi_ctrlr = phba->phwi_ctrlr;
1838 phwi_ctrlr->phwi_ctxt->pasync_ctx = (struct hwi_async_pdu_context *)
1839 mem_descr->mem_array[0].virtual_address;
1840 pasync_ctx = phwi_ctrlr->phwi_ctxt->pasync_ctx;
1841 memset(pasync_ctx, 0, sizeof(*pasync_ctx));
1842
1843 pasync_ctx->async_header.num_entries = p->asyncpdus_per_ctrl;
1844 pasync_ctx->async_header.buffer_size = p->defpdu_hdr_sz;
1845 pasync_ctx->async_data.buffer_size = p->defpdu_data_sz;
1846 pasync_ctx->async_data.num_entries = p->asyncpdus_per_ctrl;
1847
1848 mem_descr = (struct be_mem_descriptor *)phba->init_mem;
1849 mem_descr += HWI_MEM_ASYNC_HEADER_BUF;
1850 if (mem_descr->mem_array[0].virtual_address) {
1851 SE_DEBUG(DBG_LVL_8,
1852 "hwi_init_async_pdu_ctx HWI_MEM_ASYNC_HEADER_BUF"
1853 "va=%p \n", mem_descr->mem_array[0].virtual_address);
1854 } else
1855 shost_printk(KERN_WARNING, phba->shost,
1856 "No Virtual address \n");
1857
1858 pasync_ctx->async_header.va_base =
1859 mem_descr->mem_array[0].virtual_address;
1860
1861 pasync_ctx->async_header.pa_base.u.a64.address =
1862 mem_descr->mem_array[0].bus_address.u.a64.address;
1863
1864 mem_descr = (struct be_mem_descriptor *)phba->init_mem;
1865 mem_descr += HWI_MEM_ASYNC_HEADER_RING;
1866 if (mem_descr->mem_array[0].virtual_address) {
1867 SE_DEBUG(DBG_LVL_8,
1868 "hwi_init_async_pdu_ctx HWI_MEM_ASYNC_HEADER_RING"
1869 "va=%p \n", mem_descr->mem_array[0].virtual_address);
1870 } else
1871 shost_printk(KERN_WARNING, phba->shost,
1872 "No Virtual address \n");
1873 pasync_ctx->async_header.ring_base =
1874 mem_descr->mem_array[0].virtual_address;
1875
1876 mem_descr = (struct be_mem_descriptor *)phba->init_mem;
1877 mem_descr += HWI_MEM_ASYNC_HEADER_HANDLE;
1878 if (mem_descr->mem_array[0].virtual_address) {
1879 SE_DEBUG(DBG_LVL_8,
1880 "hwi_init_async_pdu_ctx HWI_MEM_ASYNC_HEADER_HANDLE"
1881 "va=%p \n", mem_descr->mem_array[0].virtual_address);
1882 } else
1883 shost_printk(KERN_WARNING, phba->shost,
1884 "No Virtual address \n");
1885
1886 pasync_ctx->async_header.handle_base =
1887 mem_descr->mem_array[0].virtual_address;
1888 pasync_ctx->async_header.writables = 0;
1889 INIT_LIST_HEAD(&pasync_ctx->async_header.free_list);
1890
1891 mem_descr = (struct be_mem_descriptor *)phba->init_mem;
1892 mem_descr += HWI_MEM_ASYNC_DATA_BUF;
1893 if (mem_descr->mem_array[0].virtual_address) {
1894 SE_DEBUG(DBG_LVL_8,
1895 "hwi_init_async_pdu_ctx HWI_MEM_ASYNC_DATA_BUF"
1896 "va=%p \n", mem_descr->mem_array[0].virtual_address);
1897 } else
1898 shost_printk(KERN_WARNING, phba->shost,
1899 "No Virtual address \n");
1900 pasync_ctx->async_data.va_base =
1901 mem_descr->mem_array[0].virtual_address;
1902 pasync_ctx->async_data.pa_base.u.a64.address =
1903 mem_descr->mem_array[0].bus_address.u.a64.address;
1904
1905 mem_descr = (struct be_mem_descriptor *)phba->init_mem;
1906 mem_descr += HWI_MEM_ASYNC_DATA_RING;
1907 if (mem_descr->mem_array[0].virtual_address) {
1908 SE_DEBUG(DBG_LVL_8,
1909 "hwi_init_async_pdu_ctx HWI_MEM_ASYNC_DATA_RING"
1910 "va=%p \n", mem_descr->mem_array[0].virtual_address);
1911 } else
1912 shost_printk(KERN_WARNING, phba->shost,
1913 "No Virtual address \n");
1914
1915 pasync_ctx->async_data.ring_base =
1916 mem_descr->mem_array[0].virtual_address;
1917
1918 mem_descr = (struct be_mem_descriptor *)phba->init_mem;
1919 mem_descr += HWI_MEM_ASYNC_DATA_HANDLE;
1920 if (!mem_descr->mem_array[0].virtual_address)
1921 shost_printk(KERN_WARNING, phba->shost,
1922 "No Virtual address \n");
1923
1924 pasync_ctx->async_data.handle_base =
1925 mem_descr->mem_array[0].virtual_address;
1926 pasync_ctx->async_data.writables = 0;
1927 INIT_LIST_HEAD(&pasync_ctx->async_data.free_list);
1928
1929 pasync_header_h =
1930 (struct async_pdu_handle *)pasync_ctx->async_header.handle_base;
1931 pasync_data_h =
1932 (struct async_pdu_handle *)pasync_ctx->async_data.handle_base;
1933
1934 for (index = 0; index < p->asyncpdus_per_ctrl; index++) {
1935 pasync_header_h->cri = -1;
1936 pasync_header_h->index = (char)index;
1937 INIT_LIST_HEAD(&pasync_header_h->link);
1938 pasync_header_h->pbuffer =
1939 (void *)((unsigned long)
1940 (pasync_ctx->async_header.va_base) +
1941 (p->defpdu_hdr_sz * index));
1942
1943 pasync_header_h->pa.u.a64.address =
1944 pasync_ctx->async_header.pa_base.u.a64.address +
1945 (p->defpdu_hdr_sz * index);
1946
1947 list_add_tail(&pasync_header_h->link,
1948 &pasync_ctx->async_header.free_list);
1949 pasync_header_h++;
1950 pasync_ctx->async_header.free_entries++;
1951 pasync_ctx->async_header.writables++;
1952
1953 INIT_LIST_HEAD(&pasync_ctx->async_entry[index].wait_queue.list);
1954 INIT_LIST_HEAD(&pasync_ctx->async_entry[index].
1955 header_busy_list);
1956 pasync_data_h->cri = -1;
1957 pasync_data_h->index = (char)index;
1958 INIT_LIST_HEAD(&pasync_data_h->link);
1959 pasync_data_h->pbuffer =
1960 (void *)((unsigned long)
1961 (pasync_ctx->async_data.va_base) +
1962 (p->defpdu_data_sz * index));
1963
1964 pasync_data_h->pa.u.a64.address =
1965 pasync_ctx->async_data.pa_base.u.a64.address +
1966 (p->defpdu_data_sz * index);
1967
1968 list_add_tail(&pasync_data_h->link,
1969 &pasync_ctx->async_data.free_list);
1970 pasync_data_h++;
1971 pasync_ctx->async_data.free_entries++;
1972 pasync_ctx->async_data.writables++;
1973
1974 INIT_LIST_HEAD(&pasync_ctx->async_entry[index].data_busy_list);
1975 }
1976
1977 pasync_ctx->async_header.host_write_ptr = 0;
1978 pasync_ctx->async_header.ep_read_ptr = -1;
1979 pasync_ctx->async_data.host_write_ptr = 0;
1980 pasync_ctx->async_data.ep_read_ptr = -1;
1981}
1982
1983static int
1984be_sgl_create_contiguous(void *virtual_address,
1985 u64 physical_address, u32 length,
1986 struct be_dma_mem *sgl)
1987{
1988 WARN_ON(!virtual_address);
1989 WARN_ON(!physical_address);
1990 WARN_ON(!length > 0);
1991 WARN_ON(!sgl);
1992
1993 sgl->va = virtual_address;
1994 sgl->dma = physical_address;
1995 sgl->size = length;
1996
1997 return 0;
1998}
1999
2000static void be_sgl_destroy_contiguous(struct be_dma_mem *sgl)
2001{
2002 memset(sgl, 0, sizeof(*sgl));
2003}
2004
2005static void
2006hwi_build_be_sgl_arr(struct beiscsi_hba *phba,
2007 struct mem_array *pmem, struct be_dma_mem *sgl)
2008{
2009 if (sgl->va)
2010 be_sgl_destroy_contiguous(sgl);
2011
2012 be_sgl_create_contiguous(pmem->virtual_address,
2013 pmem->bus_address.u.a64.address,
2014 pmem->size, sgl);
2015}
2016
2017static void
2018hwi_build_be_sgl_by_offset(struct beiscsi_hba *phba,
2019 struct mem_array *pmem, struct be_dma_mem *sgl)
2020{
2021 if (sgl->va)
2022 be_sgl_destroy_contiguous(sgl);
2023
2024 be_sgl_create_contiguous((unsigned char *)pmem->virtual_address,
2025 pmem->bus_address.u.a64.address,
2026 pmem->size, sgl);
2027}
2028
2029static int be_fill_queue(struct be_queue_info *q,
2030 u16 len, u16 entry_size, void *vaddress)
2031{
2032 struct be_dma_mem *mem = &q->dma_mem;
2033
2034 memset(q, 0, sizeof(*q));
2035 q->len = len;
2036 q->entry_size = entry_size;
2037 mem->size = len * entry_size;
2038 mem->va = vaddress;
2039 if (!mem->va)
2040 return -ENOMEM;
2041 memset(mem->va, 0, mem->size);
2042 return 0;
2043}
2044
2045static int beiscsi_create_eq(struct beiscsi_hba *phba,
2046 struct hwi_context_memory *phwi_context)
2047{
2048 unsigned int idx;
2049 int ret;
2050 struct be_queue_info *eq;
2051 struct be_dma_mem *mem;
2052 struct be_mem_descriptor *mem_descr;
2053 void *eq_vaddress;
2054
2055 idx = 0;
2056 eq = &phwi_context->be_eq.q;
2057 mem = &eq->dma_mem;
2058 mem_descr = phba->init_mem;
2059 mem_descr += HWI_MEM_EQ;
2060 eq_vaddress = mem_descr->mem_array[idx].virtual_address;
2061
2062 ret = be_fill_queue(eq, phba->params.num_eq_entries,
2063 sizeof(struct be_eq_entry), eq_vaddress);
2064 if (ret) {
2065 shost_printk(KERN_ERR, phba->shost,
2066 "be_fill_queue Failed for EQ \n");
2067 return ret;
2068 }
2069
2070 mem->dma = mem_descr->mem_array[idx].bus_address.u.a64.address;
2071
2072 ret = beiscsi_cmd_eq_create(&phba->ctrl, eq,
2073 phwi_context->be_eq.cur_eqd);
2074 if (ret) {
2075 shost_printk(KERN_ERR, phba->shost, "beiscsi_cmd_eq_create"
2076 "Failedfor EQ \n");
2077 return ret;
2078 }
2079 SE_DEBUG(DBG_LVL_8, "eq id is %d\n", phwi_context->be_eq.q.id);
2080 return 0;
2081}
2082
2083static int beiscsi_create_cq(struct beiscsi_hba *phba,
2084 struct hwi_context_memory *phwi_context)
2085{
2086 unsigned int idx;
2087 int ret;
2088 struct be_queue_info *cq, *eq;
2089 struct be_dma_mem *mem;
2090 struct be_mem_descriptor *mem_descr;
2091 void *cq_vaddress;
2092
2093 idx = 0;
2094 cq = &phwi_context->be_cq;
2095 eq = &phwi_context->be_eq.q;
2096 mem = &cq->dma_mem;
2097 mem_descr = phba->init_mem;
2098 mem_descr += HWI_MEM_CQ;
2099 cq_vaddress = mem_descr->mem_array[idx].virtual_address;
2100 ret = be_fill_queue(cq, phba->params.icds_per_ctrl / 2,
2101 sizeof(struct sol_cqe), cq_vaddress);
2102 if (ret) {
2103 shost_printk(KERN_ERR, phba->shost,
2104 "be_fill_queue Failed for ISCSI CQ \n");
2105 return ret;
2106 }
2107
2108 mem->dma = mem_descr->mem_array[idx].bus_address.u.a64.address;
2109 ret = beiscsi_cmd_cq_create(&phba->ctrl, cq, eq, false, false, 0);
2110 if (ret) {
2111 shost_printk(KERN_ERR, phba->shost,
2112 "beiscsi_cmd_eq_create Failed for ISCSI CQ \n");
2113 return ret;
2114 }
2115 SE_DEBUG(DBG_LVL_8, "iscsi cq id is %d\n", phwi_context->be_cq.id);
2116 SE_DEBUG(DBG_LVL_8, "ISCSI CQ CREATED\n");
2117 return 0;
2118}
2119
2120static int
2121beiscsi_create_def_hdr(struct beiscsi_hba *phba,
2122 struct hwi_context_memory *phwi_context,
2123 struct hwi_controller *phwi_ctrlr,
2124 unsigned int def_pdu_ring_sz)
2125{
2126 unsigned int idx;
2127 int ret;
2128 struct be_queue_info *dq, *cq;
2129 struct be_dma_mem *mem;
2130 struct be_mem_descriptor *mem_descr;
2131 void *dq_vaddress;
2132
2133 idx = 0;
2134 dq = &phwi_context->be_def_hdrq;
2135 cq = &phwi_context->be_cq;
2136 mem = &dq->dma_mem;
2137 mem_descr = phba->init_mem;
2138 mem_descr += HWI_MEM_ASYNC_HEADER_RING;
2139 dq_vaddress = mem_descr->mem_array[idx].virtual_address;
2140 ret = be_fill_queue(dq, mem_descr->mem_array[0].size /
2141 sizeof(struct phys_addr),
2142 sizeof(struct phys_addr), dq_vaddress);
2143 if (ret) {
2144 shost_printk(KERN_ERR, phba->shost,
2145 "be_fill_queue Failed for DEF PDU HDR\n");
2146 return ret;
2147 }
2148 mem->dma = mem_descr->mem_array[idx].bus_address.u.a64.address;
2149 ret = be_cmd_create_default_pdu_queue(&phba->ctrl, cq, dq,
2150 def_pdu_ring_sz,
2151 phba->params.defpdu_hdr_sz);
2152 if (ret) {
2153 shost_printk(KERN_ERR, phba->shost,
2154 "be_cmd_create_default_pdu_queue Failed DEFHDR\n");
2155 return ret;
2156 }
2157 phwi_ctrlr->default_pdu_hdr.id = phwi_context->be_def_hdrq.id;
2158 SE_DEBUG(DBG_LVL_8, "iscsi def pdu id is %d\n",
2159 phwi_context->be_def_hdrq.id);
2160 hwi_post_async_buffers(phba, 1);
2161 return 0;
2162}
2163
2164static int
2165beiscsi_create_def_data(struct beiscsi_hba *phba,
2166 struct hwi_context_memory *phwi_context,
2167 struct hwi_controller *phwi_ctrlr,
2168 unsigned int def_pdu_ring_sz)
2169{
2170 unsigned int idx;
2171 int ret;
2172 struct be_queue_info *dataq, *cq;
2173 struct be_dma_mem *mem;
2174 struct be_mem_descriptor *mem_descr;
2175 void *dq_vaddress;
2176
2177 idx = 0;
2178 dataq = &phwi_context->be_def_dataq;
2179 cq = &phwi_context->be_cq;
2180 mem = &dataq->dma_mem;
2181 mem_descr = phba->init_mem;
2182 mem_descr += HWI_MEM_ASYNC_DATA_RING;
2183 dq_vaddress = mem_descr->mem_array[idx].virtual_address;
2184 ret = be_fill_queue(dataq, mem_descr->mem_array[0].size /
2185 sizeof(struct phys_addr),
2186 sizeof(struct phys_addr), dq_vaddress);
2187 if (ret) {
2188 shost_printk(KERN_ERR, phba->shost,
2189 "be_fill_queue Failed for DEF PDU DATA\n");
2190 return ret;
2191 }
2192 mem->dma = mem_descr->mem_array[idx].bus_address.u.a64.address;
2193 ret = be_cmd_create_default_pdu_queue(&phba->ctrl, cq, dataq,
2194 def_pdu_ring_sz,
2195 phba->params.defpdu_data_sz);
2196 if (ret) {
2197 shost_printk(KERN_ERR, phba->shost,
2198 "be_cmd_create_default_pdu_queue Failed"
2199 " for DEF PDU DATA\n");
2200 return ret;
2201 }
2202 phwi_ctrlr->default_pdu_data.id = phwi_context->be_def_dataq.id;
2203 SE_DEBUG(DBG_LVL_8, "iscsi def data id is %d\n",
2204 phwi_context->be_def_dataq.id);
2205 hwi_post_async_buffers(phba, 0);
2206 SE_DEBUG(DBG_LVL_8, "DEFAULT PDU DATA RING CREATED \n");
2207 return 0;
2208}
2209
2210static int
2211beiscsi_post_pages(struct beiscsi_hba *phba)
2212{
2213 struct be_mem_descriptor *mem_descr;
2214 struct mem_array *pm_arr;
2215 unsigned int page_offset, i;
2216 struct be_dma_mem sgl;
2217 int status;
2218
2219 mem_descr = phba->init_mem;
2220 mem_descr += HWI_MEM_SGE;
2221 pm_arr = mem_descr->mem_array;
2222
2223 page_offset = (sizeof(struct iscsi_sge) * phba->params.num_sge_per_io *
2224 phba->fw_config.iscsi_icd_start) / PAGE_SIZE;
2225 for (i = 0; i < mem_descr->num_elements; i++) {
2226 hwi_build_be_sgl_arr(phba, pm_arr, &sgl);
2227 status = be_cmd_iscsi_post_sgl_pages(&phba->ctrl, &sgl,
2228 page_offset,
2229 (pm_arr->size / PAGE_SIZE));
2230 page_offset += pm_arr->size / PAGE_SIZE;
2231 if (status != 0) {
2232 shost_printk(KERN_ERR, phba->shost,
2233 "post sgl failed.\n");
2234 return status;
2235 }
2236 pm_arr++;
2237 }
2238 SE_DEBUG(DBG_LVL_8, "POSTED PAGES \n");
2239 return 0;
2240}
2241
2242static int
2243beiscsi_create_wrb_rings(struct beiscsi_hba *phba,
2244 struct hwi_context_memory *phwi_context,
2245 struct hwi_controller *phwi_ctrlr)
2246{
2247 unsigned int wrb_mem_index, offset, size, num_wrb_rings;
2248 u64 pa_addr_lo;
2249 unsigned int idx, num, i;
2250 struct mem_array *pwrb_arr;
2251 void *wrb_vaddr;
2252 struct be_dma_mem sgl;
2253 struct be_mem_descriptor *mem_descr;
2254 int status;
2255
2256 idx = 0;
2257 mem_descr = phba->init_mem;
2258 mem_descr += HWI_MEM_WRB;
2259 pwrb_arr = kmalloc(sizeof(*pwrb_arr) * phba->params.cxns_per_ctrl,
2260 GFP_KERNEL);
2261 if (!pwrb_arr) {
2262 shost_printk(KERN_ERR, phba->shost,
2263 "Memory alloc failed in create wrb ring.\n");
2264 return -ENOMEM;
2265 }
2266 wrb_vaddr = mem_descr->mem_array[idx].virtual_address;
2267 pa_addr_lo = mem_descr->mem_array[idx].bus_address.u.a64.address;
2268 num_wrb_rings = mem_descr->mem_array[idx].size /
2269 (phba->params.wrbs_per_cxn * sizeof(struct iscsi_wrb));
2270
2271 for (num = 0; num < phba->params.cxns_per_ctrl; num++) {
2272 if (num_wrb_rings) {
2273 pwrb_arr[num].virtual_address = wrb_vaddr;
2274 pwrb_arr[num].bus_address.u.a64.address = pa_addr_lo;
2275 pwrb_arr[num].size = phba->params.wrbs_per_cxn *
2276 sizeof(struct iscsi_wrb);
2277 wrb_vaddr += pwrb_arr[num].size;
2278 pa_addr_lo += pwrb_arr[num].size;
2279 num_wrb_rings--;
2280 } else {
2281 idx++;
2282 wrb_vaddr = mem_descr->mem_array[idx].virtual_address;
2283 pa_addr_lo = mem_descr->mem_array[idx].\
2284 bus_address.u.a64.address;
2285 num_wrb_rings = mem_descr->mem_array[idx].size /
2286 (phba->params.wrbs_per_cxn *
2287 sizeof(struct iscsi_wrb));
2288 pwrb_arr[num].virtual_address = wrb_vaddr;
2289 pwrb_arr[num].bus_address.u.a64.address\
2290 = pa_addr_lo;
2291 pwrb_arr[num].size = phba->params.wrbs_per_cxn *
2292 sizeof(struct iscsi_wrb);
2293 wrb_vaddr += pwrb_arr[num].size;
2294 pa_addr_lo += pwrb_arr[num].size;
2295 num_wrb_rings--;
2296 }
2297 }
2298 for (i = 0; i < phba->params.cxns_per_ctrl; i++) {
2299 wrb_mem_index = 0;
2300 offset = 0;
2301 size = 0;
2302
2303 hwi_build_be_sgl_by_offset(phba, &pwrb_arr[i], &sgl);
2304 status = be_cmd_wrbq_create(&phba->ctrl, &sgl,
2305 &phwi_context->be_wrbq[i]);
2306 if (status != 0) {
2307 shost_printk(KERN_ERR, phba->shost,
2308 "wrbq create failed.");
2309 return status;
2310 }
2311 phwi_ctrlr->wrb_context[i].cid = phwi_context->be_wrbq[i].id;
2312 }
2313 kfree(pwrb_arr);
2314 return 0;
2315}
2316
2317static void free_wrb_handles(struct beiscsi_hba *phba)
2318{
2319 unsigned int index;
2320 struct hwi_controller *phwi_ctrlr;
2321 struct hwi_wrb_context *pwrb_context;
2322
2323 phwi_ctrlr = phba->phwi_ctrlr;
2324 for (index = 0; index < phba->params.cxns_per_ctrl * 2; index += 2) {
2325 pwrb_context = &phwi_ctrlr->wrb_context[index];
2326 kfree(pwrb_context->pwrb_handle_base);
2327 kfree(pwrb_context->pwrb_handle_basestd);
2328 }
2329}
2330
2331static void hwi_cleanup(struct beiscsi_hba *phba)
2332{
2333 struct be_queue_info *q;
2334 struct be_ctrl_info *ctrl = &phba->ctrl;
2335 struct hwi_controller *phwi_ctrlr;
2336 struct hwi_context_memory *phwi_context;
2337 int i;
2338
2339 phwi_ctrlr = phba->phwi_ctrlr;
2340 phwi_context = phwi_ctrlr->phwi_ctxt;
2341 for (i = 0; i < phba->params.cxns_per_ctrl; i++) {
2342 q = &phwi_context->be_wrbq[i];
2343 if (q->created)
2344 beiscsi_cmd_q_destroy(ctrl, q, QTYPE_WRBQ);
2345 }
2346
2347 free_wrb_handles(phba);
2348
2349 q = &phwi_context->be_def_hdrq;
2350 if (q->created)
2351 beiscsi_cmd_q_destroy(ctrl, q, QTYPE_DPDUQ);
2352
2353 q = &phwi_context->be_def_dataq;
2354 if (q->created)
2355 beiscsi_cmd_q_destroy(ctrl, q, QTYPE_DPDUQ);
2356
2357 beiscsi_cmd_q_destroy(ctrl, NULL, QTYPE_SGL);
2358
2359 q = &phwi_context->be_cq;
2360 if (q->created)
2361 beiscsi_cmd_q_destroy(ctrl, q, QTYPE_CQ);
2362
2363 q = &phwi_context->be_eq.q;
2364 if (q->created)
2365 beiscsi_cmd_q_destroy(ctrl, q, QTYPE_EQ);
2366}
2367
2368static int hwi_init_port(struct beiscsi_hba *phba)
2369{
2370 struct hwi_controller *phwi_ctrlr;
2371 struct hwi_context_memory *phwi_context;
2372 unsigned int def_pdu_ring_sz;
2373 struct be_ctrl_info *ctrl = &phba->ctrl;
2374 int status;
2375
2376 def_pdu_ring_sz =
2377 phba->params.asyncpdus_per_ctrl * sizeof(struct phys_addr);
2378 phwi_ctrlr = phba->phwi_ctrlr;
2379
2380 phwi_context = phwi_ctrlr->phwi_ctxt;
2381 phwi_context->be_eq.max_eqd = 0;
2382 phwi_context->be_eq.min_eqd = 0;
2383 phwi_context->be_eq.cur_eqd = 64;
2384 phwi_context->be_eq.enable_aic = false;
2385 be_cmd_fw_initialize(&phba->ctrl);
2386 status = beiscsi_create_eq(phba, phwi_context);
2387 if (status != 0) {
2388 shost_printk(KERN_ERR, phba->shost, "EQ not created \n");
2389 goto error;
2390 }
2391
2392 status = mgmt_check_supported_fw(ctrl);
2393 if (status != 0) {
2394 shost_printk(KERN_ERR, phba->shost,
2395 "Unsupported fw version \n");
2396 goto error;
2397 }
2398
2399 status = mgmt_get_fw_config(ctrl, phba);
2400 if (status != 0) {
2401 shost_printk(KERN_ERR, phba->shost,
2402 "Error getting fw config\n");
2403 goto error;
2404 }
2405
2406 status = beiscsi_create_cq(phba, phwi_context);
2407 if (status != 0) {
2408 shost_printk(KERN_ERR, phba->shost, "CQ not created\n");
2409 goto error;
2410 }
2411
2412 status = beiscsi_create_def_hdr(phba, phwi_context, phwi_ctrlr,
2413 def_pdu_ring_sz);
2414 if (status != 0) {
2415 shost_printk(KERN_ERR, phba->shost,
2416 "Default Header not created\n");
2417 goto error;
2418 }
2419
2420 status = beiscsi_create_def_data(phba, phwi_context,
2421 phwi_ctrlr, def_pdu_ring_sz);
2422 if (status != 0) {
2423 shost_printk(KERN_ERR, phba->shost,
2424 "Default Data not created\n");
2425 goto error;
2426 }
2427
2428 status = beiscsi_post_pages(phba);
2429 if (status != 0) {
2430 shost_printk(KERN_ERR, phba->shost, "Post SGL Pages Failed\n");
2431 goto error;
2432 }
2433
2434 status = beiscsi_create_wrb_rings(phba, phwi_context, phwi_ctrlr);
2435 if (status != 0) {
2436 shost_printk(KERN_ERR, phba->shost,
2437 "WRB Rings not created\n");
2438 goto error;
2439 }
2440
2441 SE_DEBUG(DBG_LVL_8, "hwi_init_port success\n");
2442 return 0;
2443
2444error:
2445 shost_printk(KERN_ERR, phba->shost, "hwi_init_port failed");
2446 hwi_cleanup(phba);
2447 return -ENOMEM;
2448}
2449
2450
2451static int hwi_init_controller(struct beiscsi_hba *phba)
2452{
2453 struct hwi_controller *phwi_ctrlr;
2454
2455 phwi_ctrlr = phba->phwi_ctrlr;
2456 if (1 == phba->init_mem[HWI_MEM_ADDN_CONTEXT].num_elements) {
2457 phwi_ctrlr->phwi_ctxt = (struct hwi_context_memory *)phba->
2458 init_mem[HWI_MEM_ADDN_CONTEXT].mem_array[0].virtual_address;
2459 SE_DEBUG(DBG_LVL_8, " phwi_ctrlr->phwi_ctxt=%p \n",
2460 phwi_ctrlr->phwi_ctxt);
2461 } else {
2462 shost_printk(KERN_ERR, phba->shost,
2463 "HWI_MEM_ADDN_CONTEXT is more than one element."
2464 "Failing to load\n");
2465 return -ENOMEM;
2466 }
2467
2468 iscsi_init_global_templates(phba);
2469 beiscsi_init_wrb_handle(phba);
2470 hwi_init_async_pdu_ctx(phba);
2471 if (hwi_init_port(phba) != 0) {
2472 shost_printk(KERN_ERR, phba->shost,
2473 "hwi_init_controller failed\n");
2474 return -ENOMEM;
2475 }
2476 return 0;
2477}
2478
2479static void beiscsi_free_mem(struct beiscsi_hba *phba)
2480{
2481 struct be_mem_descriptor *mem_descr;
2482 int i, j;
2483
2484 mem_descr = phba->init_mem;
2485 i = 0;
2486 j = 0;
2487 for (i = 0; i < SE_MEM_MAX; i++) {
2488 for (j = mem_descr->num_elements; j > 0; j--) {
2489 pci_free_consistent(phba->pcidev,
2490 mem_descr->mem_array[j - 1].size,
2491 mem_descr->mem_array[j - 1].virtual_address,
2492 mem_descr->mem_array[j - 1].bus_address.
2493 u.a64.address);
2494 }
2495 kfree(mem_descr->mem_array);
2496 mem_descr++;
2497 }
2498 kfree(phba->init_mem);
2499 kfree(phba->phwi_ctrlr);
2500}
2501
2502static int beiscsi_init_controller(struct beiscsi_hba *phba)
2503{
2504 int ret = -ENOMEM;
2505
2506 ret = beiscsi_get_memory(phba);
2507 if (ret < 0) {
2508 shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe -"
2509 "Failed in beiscsi_alloc_memory \n");
2510 return ret;
2511 }
2512
2513 ret = hwi_init_controller(phba);
2514 if (ret)
2515 goto free_init;
2516 SE_DEBUG(DBG_LVL_8, "Return success from beiscsi_init_controller");
2517 return 0;
2518
2519free_init:
2520 beiscsi_free_mem(phba);
2521 return -ENOMEM;
2522}
2523
2524static int beiscsi_init_sgl_handle(struct beiscsi_hba *phba)
2525{
2526 struct be_mem_descriptor *mem_descr_sglh, *mem_descr_sg;
2527 struct sgl_handle *psgl_handle;
2528 struct iscsi_sge *pfrag;
2529 unsigned int arr_index, i, idx;
2530
2531 phba->io_sgl_hndl_avbl = 0;
2532 phba->eh_sgl_hndl_avbl = 0;
2533 mem_descr_sglh = phba->init_mem;
2534 mem_descr_sglh += HWI_MEM_SGLH;
2535 if (1 == mem_descr_sglh->num_elements) {
2536 phba->io_sgl_hndl_base = kzalloc(sizeof(struct sgl_handle *) *
2537 phba->params.ios_per_ctrl,
2538 GFP_KERNEL);
2539 if (!phba->io_sgl_hndl_base) {
2540 shost_printk(KERN_ERR, phba->shost,
2541 "Mem Alloc Failed. Failing to load\n");
2542 return -ENOMEM;
2543 }
2544 phba->eh_sgl_hndl_base = kzalloc(sizeof(struct sgl_handle *) *
2545 (phba->params.icds_per_ctrl -
2546 phba->params.ios_per_ctrl),
2547 GFP_KERNEL);
2548 if (!phba->eh_sgl_hndl_base) {
2549 kfree(phba->io_sgl_hndl_base);
2550 shost_printk(KERN_ERR, phba->shost,
2551 "Mem Alloc Failed. Failing to load\n");
2552 return -ENOMEM;
2553 }
2554 } else {
2555 shost_printk(KERN_ERR, phba->shost,
2556 "HWI_MEM_SGLH is more than one element."
2557 "Failing to load\n");
2558 return -ENOMEM;
2559 }
2560
2561 arr_index = 0;
2562 idx = 0;
2563 while (idx < mem_descr_sglh->num_elements) {
2564 psgl_handle = mem_descr_sglh->mem_array[idx].virtual_address;
2565
2566 for (i = 0; i < (mem_descr_sglh->mem_array[idx].size /
2567 sizeof(struct sgl_handle)); i++) {
2568 if (arr_index < phba->params.ios_per_ctrl) {
2569 phba->io_sgl_hndl_base[arr_index] = psgl_handle;
2570 phba->io_sgl_hndl_avbl++;
2571 arr_index++;
2572 } else {
2573 phba->eh_sgl_hndl_base[arr_index -
2574 phba->params.ios_per_ctrl] =
2575 psgl_handle;
2576 arr_index++;
2577 phba->eh_sgl_hndl_avbl++;
2578 }
2579 psgl_handle++;
2580 }
2581 idx++;
2582 }
2583 SE_DEBUG(DBG_LVL_8,
2584 "phba->io_sgl_hndl_avbl=%d"
2585 "phba->eh_sgl_hndl_avbl=%d \n",
2586 phba->io_sgl_hndl_avbl,
2587 phba->eh_sgl_hndl_avbl);
2588 mem_descr_sg = phba->init_mem;
2589 mem_descr_sg += HWI_MEM_SGE;
2590 SE_DEBUG(DBG_LVL_8, "\n mem_descr_sg->num_elements=%d \n",
2591 mem_descr_sg->num_elements);
2592 arr_index = 0;
2593 idx = 0;
2594 while (idx < mem_descr_sg->num_elements) {
2595 pfrag = mem_descr_sg->mem_array[idx].virtual_address;
2596
2597 for (i = 0;
2598 i < (mem_descr_sg->mem_array[idx].size) /
2599 (sizeof(struct iscsi_sge) * phba->params.num_sge_per_io);
2600 i++) {
2601 if (arr_index < phba->params.ios_per_ctrl)
2602 psgl_handle = phba->io_sgl_hndl_base[arr_index];
2603 else
2604 psgl_handle = phba->eh_sgl_hndl_base[arr_index -
2605 phba->params.ios_per_ctrl];
2606 psgl_handle->pfrag = pfrag;
2607 AMAP_SET_BITS(struct amap_iscsi_sge, addr_hi, pfrag, 0);
2608 AMAP_SET_BITS(struct amap_iscsi_sge, addr_lo, pfrag, 0);
2609 pfrag += phba->params.num_sge_per_io;
2610 psgl_handle->sgl_index =
2611 phba->fw_config.iscsi_cid_start + arr_index++;
2612 }
2613 idx++;
2614 }
2615 phba->io_sgl_free_index = 0;
2616 phba->io_sgl_alloc_index = 0;
2617 phba->eh_sgl_free_index = 0;
2618 phba->eh_sgl_alloc_index = 0;
2619 return 0;
2620}
2621
2622static int hba_setup_cid_tbls(struct beiscsi_hba *phba)
2623{
2624 int i, new_cid;
2625
2626 phba->cid_array = kmalloc(sizeof(void *) * phba->params.cxns_per_ctrl,
2627 GFP_KERNEL);
2628 if (!phba->cid_array) {
2629 shost_printk(KERN_ERR, phba->shost,
2630 "Failed to allocate memory in "
2631 "hba_setup_cid_tbls\n");
2632 return -ENOMEM;
2633 }
2634 phba->ep_array = kmalloc(sizeof(struct iscsi_endpoint *) *
2635 phba->params.cxns_per_ctrl * 2, GFP_KERNEL);
2636 if (!phba->ep_array) {
2637 shost_printk(KERN_ERR, phba->shost,
2638 "Failed to allocate memory in "
2639 "hba_setup_cid_tbls \n");
2640 kfree(phba->cid_array);
2641 return -ENOMEM;
2642 }
2643 new_cid = phba->fw_config.iscsi_icd_start;
2644 for (i = 0; i < phba->params.cxns_per_ctrl; i++) {
2645 phba->cid_array[i] = new_cid;
2646 new_cid += 2;
2647 }
2648 phba->avlbl_cids = phba->params.cxns_per_ctrl;
2649 return 0;
2650}
2651
2652static unsigned char hwi_enable_intr(struct beiscsi_hba *phba)
2653{
2654 struct be_ctrl_info *ctrl = &phba->ctrl;
2655 struct hwi_controller *phwi_ctrlr;
2656 struct hwi_context_memory *phwi_context;
2657 struct be_queue_info *eq;
2658 u8 __iomem *addr;
2659 u32 reg;
2660 u32 enabled;
2661
2662 phwi_ctrlr = phba->phwi_ctrlr;
2663 phwi_context = phwi_ctrlr->phwi_ctxt;
2664
2665 eq = &phwi_context->be_eq.q;
2666 addr = (u8 __iomem *) ((u8 __iomem *) ctrl->pcicfg +
2667 PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET);
2668 reg = ioread32(addr);
2669 SE_DEBUG(DBG_LVL_8, "reg =x%08x \n", reg);
2670
2671 enabled = reg & MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK;
2672 if (!enabled) {
2673 reg |= MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK;
2674 SE_DEBUG(DBG_LVL_8, "reg =x%08x addr=%p \n", reg, addr);
2675 iowrite32(reg, addr);
2676 SE_DEBUG(DBG_LVL_8, "eq->id=%d \n", eq->id);
2677
2678 hwi_ring_eq_db(phba, eq->id, 0, 0, 1, 1);
2679 } else
2680 shost_printk(KERN_WARNING, phba->shost,
2681 "In hwi_enable_intr, Not Enabled \n");
2682 return true;
2683}
2684
2685static void hwi_disable_intr(struct beiscsi_hba *phba)
2686{
2687 struct be_ctrl_info *ctrl = &phba->ctrl;
2688
2689 u8 __iomem *addr = ctrl->pcicfg + PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET;
2690 u32 reg = ioread32(addr);
2691
2692 u32 enabled = reg & MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK;
2693 if (enabled) {
2694 reg &= ~MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK;
2695 iowrite32(reg, addr);
2696 } else
2697 shost_printk(KERN_WARNING, phba->shost,
2698 "In hwi_disable_intr, Already Disabled \n");
2699}
2700
2701static int beiscsi_init_port(struct beiscsi_hba *phba)
2702{
2703 int ret;
2704
2705 ret = beiscsi_init_controller(phba);
2706 if (ret < 0) {
2707 shost_printk(KERN_ERR, phba->shost,
2708 "beiscsi_dev_probe - Failed in"
2709 "beiscsi_init_controller \n");
2710 return ret;
2711 }
2712 ret = beiscsi_init_sgl_handle(phba);
2713 if (ret < 0) {
2714 shost_printk(KERN_ERR, phba->shost,
2715 "beiscsi_dev_probe - Failed in"
2716 "beiscsi_init_sgl_handle \n");
2717 goto do_cleanup_ctrlr;
2718 }
2719
2720 if (hba_setup_cid_tbls(phba)) {
2721 shost_printk(KERN_ERR, phba->shost,
2722 "Failed in hba_setup_cid_tbls\n");
2723 kfree(phba->io_sgl_hndl_base);
2724 kfree(phba->eh_sgl_hndl_base);
2725 goto do_cleanup_ctrlr;
2726 }
2727
2728 return ret;
2729
2730do_cleanup_ctrlr:
2731 hwi_cleanup(phba);
2732 return ret;
2733}
2734
2735static void hwi_purge_eq(struct beiscsi_hba *phba)
2736{
2737 struct hwi_controller *phwi_ctrlr;
2738 struct hwi_context_memory *phwi_context;
2739 struct be_queue_info *eq;
2740 struct be_eq_entry *eqe = NULL;
2741
2742 phwi_ctrlr = phba->phwi_ctrlr;
2743 phwi_context = phwi_ctrlr->phwi_ctxt;
2744 eq = &phwi_context->be_eq.q;
2745 eqe = queue_tail_node(eq);
2746
2747 while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32]
2748 & EQE_VALID_MASK) {
2749 AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0);
2750 queue_tail_inc(eq);
2751 eqe = queue_tail_node(eq);
2752 }
2753}
2754
2755static void beiscsi_clean_port(struct beiscsi_hba *phba)
2756{
2757 unsigned char mgmt_status;
2758
2759 mgmt_status = mgmt_epfw_cleanup(phba, CMD_CONNECTION_CHUTE_0);
2760 if (mgmt_status)
2761 shost_printk(KERN_WARNING, phba->shost,
2762 "mgmt_epfw_cleanup FAILED \n");
2763 hwi_cleanup(phba);
2764 hwi_purge_eq(phba);
2765 kfree(phba->io_sgl_hndl_base);
2766 kfree(phba->eh_sgl_hndl_base);
2767 kfree(phba->cid_array);
2768 kfree(phba->ep_array);
2769}
2770
2771void
2772beiscsi_offload_connection(struct beiscsi_conn *beiscsi_conn,
2773 struct beiscsi_offload_params *params)
2774{
2775 struct wrb_handle *pwrb_handle;
2776 struct iscsi_target_context_update_wrb *pwrb = NULL;
2777 struct be_mem_descriptor *mem_descr;
2778 struct beiscsi_hba *phba = beiscsi_conn->phba;
2779 u32 doorbell = 0;
2780
2781 /*
2782 * We can always use 0 here because it is reserved by libiscsi for
2783 * login/startup related tasks.
2784 */
2785 pwrb_handle = alloc_wrb_handle(phba, beiscsi_conn->beiscsi_conn_cid, 0);
2786 pwrb = (struct iscsi_target_context_update_wrb *)pwrb_handle->pwrb;
2787 memset(pwrb, 0, sizeof(*pwrb));
2788 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
2789 max_burst_length, pwrb, params->dw[offsetof
2790 (struct amap_beiscsi_offload_params,
2791 max_burst_length) / 32]);
2792 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
2793 max_send_data_segment_length, pwrb,
2794 params->dw[offsetof(struct amap_beiscsi_offload_params,
2795 max_send_data_segment_length) / 32]);
2796 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
2797 first_burst_length,
2798 pwrb,
2799 params->dw[offsetof(struct amap_beiscsi_offload_params,
2800 first_burst_length) / 32]);
2801
2802 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, erl, pwrb,
2803 (params->dw[offsetof(struct amap_beiscsi_offload_params,
2804 erl) / 32] & OFFLD_PARAMS_ERL));
2805 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, dde, pwrb,
2806 (params->dw[offsetof(struct amap_beiscsi_offload_params,
2807 dde) / 32] & OFFLD_PARAMS_DDE) >> 2);
2808 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, hde, pwrb,
2809 (params->dw[offsetof(struct amap_beiscsi_offload_params,
2810 hde) / 32] & OFFLD_PARAMS_HDE) >> 3);
2811 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, ir2t, pwrb,
2812 (params->dw[offsetof(struct amap_beiscsi_offload_params,
2813 ir2t) / 32] & OFFLD_PARAMS_IR2T) >> 4);
2814 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, imd, pwrb,
2815 (params->dw[offsetof(struct amap_beiscsi_offload_params,
2816 imd) / 32] & OFFLD_PARAMS_IMD) >> 5);
2817 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, stat_sn,
2818 pwrb,
2819 (params->dw[offsetof(struct amap_beiscsi_offload_params,
2820 exp_statsn) / 32] + 1));
2821 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, type, pwrb,
2822 0x7);
2823 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, wrb_idx,
2824 pwrb, pwrb_handle->wrb_index);
2825 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, ptr2nextwrb,
2826 pwrb, pwrb_handle->nxt_wrb_index);
2827 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
2828 session_state, pwrb, 0);
2829 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, compltonack,
2830 pwrb, 1);
2831 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, notpredblq,
2832 pwrb, 0);
2833 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb, mode, pwrb,
2834 0);
2835
2836 mem_descr = phba->init_mem;
2837 mem_descr += ISCSI_MEM_GLOBAL_HEADER;
2838
2839 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
2840 pad_buffer_addr_hi, pwrb,
2841 mem_descr->mem_array[0].bus_address.u.a32.address_hi);
2842 AMAP_SET_BITS(struct amap_iscsi_target_context_update_wrb,
2843 pad_buffer_addr_lo, pwrb,
2844 mem_descr->mem_array[0].bus_address.u.a32.address_lo);
2845
2846 be_dws_le_to_cpu(pwrb, sizeof(struct iscsi_target_context_update_wrb));
2847
2848 doorbell |= beiscsi_conn->beiscsi_conn_cid & DB_WRB_POST_CID_MASK;
2849 doorbell |= (pwrb_handle->wrb_index & DB_DEF_PDU_WRB_INDEX_MASK) <<
2850 DB_DEF_PDU_WRB_INDEX_SHIFT;
2851 doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT;
2852
2853 iowrite32(doorbell, phba->db_va + DB_TXULP0_OFFSET);
2854}
2855
2856static void beiscsi_parse_pdu(struct iscsi_conn *conn, itt_t itt,
2857 int *index, int *age)
2858{
2859 *index = be32_to_cpu(itt) >> 16;
2860 if (age)
2861 *age = conn->session->age;
2862}
2863
2864/**
2865 * beiscsi_alloc_pdu - allocates pdu and related resources
2866 * @task: libiscsi task
2867 * @opcode: opcode of pdu for task
2868 *
2869 * This is called with the session lock held. It will allocate
2870 * the wrb and sgl if needed for the command. And it will prep
2871 * the pdu's itt. beiscsi_parse_pdu will later translate
2872 * the pdu itt to the libiscsi task itt.
2873 */
2874static int beiscsi_alloc_pdu(struct iscsi_task *task, uint8_t opcode)
2875{
2876 struct beiscsi_io_task *io_task = task->dd_data;
2877 struct iscsi_conn *conn = task->conn;
2878 struct beiscsi_conn *beiscsi_conn = conn->dd_data;
2879 struct beiscsi_hba *phba = beiscsi_conn->phba;
2880 struct hwi_wrb_context *pwrb_context;
2881 struct hwi_controller *phwi_ctrlr;
2882 itt_t itt;
2883 struct beiscsi_session *beiscsi_sess = beiscsi_conn->beiscsi_sess;
2884 dma_addr_t paddr;
2885
2886 io_task->cmd_bhs = pci_pool_alloc(beiscsi_sess->bhs_pool,
2887 GFP_KERNEL, &paddr);
2888
2889 if (!io_task->cmd_bhs)
2890 return -ENOMEM;
2891
2892 io_task->bhs_pa.u.a64.address = paddr;
2893 io_task->pwrb_handle = alloc_wrb_handle(phba,
2894 beiscsi_conn->beiscsi_conn_cid,
2895 task->itt);
2896 io_task->pwrb_handle->pio_handle = task;
2897 io_task->conn = beiscsi_conn;
2898
2899 task->hdr = (struct iscsi_hdr *)&io_task->cmd_bhs->iscsi_hdr;
2900 task->hdr_max = sizeof(struct be_cmd_bhs);
2901
2902 if (task->sc) {
2903 spin_lock(&phba->io_sgl_lock);
2904 io_task->psgl_handle = alloc_io_sgl_handle(phba);
2905 spin_unlock(&phba->io_sgl_lock);
2906 if (!io_task->psgl_handle)
2907 goto free_hndls;
2908
2909 } else {
2910 io_task->scsi_cmnd = NULL;
2911 if ((task->hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGIN) {
2912 if (!beiscsi_conn->login_in_progress) {
2913 spin_lock(&phba->mgmt_sgl_lock);
2914 io_task->psgl_handle = (struct sgl_handle *)
2915 alloc_mgmt_sgl_handle(phba);
2916 spin_unlock(&phba->mgmt_sgl_lock);
2917 if (!io_task->psgl_handle)
2918 goto free_hndls;
2919
2920 beiscsi_conn->login_in_progress = 1;
2921 beiscsi_conn->plogin_sgl_handle =
2922 io_task->psgl_handle;
2923 } else {
2924 io_task->psgl_handle =
2925 beiscsi_conn->plogin_sgl_handle;
2926 }
2927 } else {
2928 spin_lock(&phba->mgmt_sgl_lock);
2929 io_task->psgl_handle = alloc_mgmt_sgl_handle(phba);
2930 spin_unlock(&phba->mgmt_sgl_lock);
2931 if (!io_task->psgl_handle)
2932 goto free_hndls;
2933 }
2934 }
2935 itt = (itt_t) cpu_to_be32(((unsigned int)task->itt << 16) |
2936 (unsigned int)(io_task->psgl_handle->sgl_index));
2937 io_task->cmd_bhs->iscsi_hdr.itt = itt;
2938 return 0;
2939
2940free_hndls:
2941 phwi_ctrlr = phba->phwi_ctrlr;
2942 pwrb_context = &phwi_ctrlr->wrb_context[beiscsi_conn->beiscsi_conn_cid];
2943 free_wrb_handle(phba, pwrb_context, io_task->pwrb_handle);
2944 io_task->pwrb_handle = NULL;
2945 pci_pool_free(beiscsi_sess->bhs_pool, io_task->cmd_bhs,
2946 io_task->bhs_pa.u.a64.address);
2947 SE_DEBUG(DBG_LVL_1, "Alloc of SGL_ICD Failed \n");
2948 return -ENOMEM;
2949}
2950
2951static void beiscsi_cleanup_task(struct iscsi_task *task)
2952{
2953 struct beiscsi_io_task *io_task = task->dd_data;
2954 struct iscsi_conn *conn = task->conn;
2955 struct beiscsi_conn *beiscsi_conn = conn->dd_data;
2956 struct beiscsi_hba *phba = beiscsi_conn->phba;
2957 struct beiscsi_session *beiscsi_sess = beiscsi_conn->beiscsi_sess;
2958 struct hwi_wrb_context *pwrb_context;
2959 struct hwi_controller *phwi_ctrlr;
2960
2961 phwi_ctrlr = phba->phwi_ctrlr;
2962 pwrb_context = &phwi_ctrlr->wrb_context[beiscsi_conn->beiscsi_conn_cid];
2963 if (io_task->pwrb_handle) {
2964 free_wrb_handle(phba, pwrb_context, io_task->pwrb_handle);
2965 io_task->pwrb_handle = NULL;
2966 }
2967
2968 if (io_task->cmd_bhs) {
2969 pci_pool_free(beiscsi_sess->bhs_pool, io_task->cmd_bhs,
2970 io_task->bhs_pa.u.a64.address);
2971 }
2972
2973 if (task->sc) {
2974 if (io_task->psgl_handle) {
2975 spin_lock(&phba->io_sgl_lock);
2976 free_io_sgl_handle(phba, io_task->psgl_handle);
2977 spin_unlock(&phba->io_sgl_lock);
2978 io_task->psgl_handle = NULL;
2979 }
2980 } else {
2981 if ((task->hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGIN)
2982 return;
2983 if (io_task->psgl_handle) {
2984 spin_lock(&phba->mgmt_sgl_lock);
2985 free_mgmt_sgl_handle(phba, io_task->psgl_handle);
2986 spin_unlock(&phba->mgmt_sgl_lock);
2987 io_task->psgl_handle = NULL;
2988 }
2989 }
2990}
2991
2992static int beiscsi_iotask(struct iscsi_task *task, struct scatterlist *sg,
2993 unsigned int num_sg, unsigned int xferlen,
2994 unsigned int writedir)
2995{
2996
2997 struct beiscsi_io_task *io_task = task->dd_data;
2998 struct iscsi_conn *conn = task->conn;
2999 struct beiscsi_conn *beiscsi_conn = conn->dd_data;
3000 struct beiscsi_hba *phba = beiscsi_conn->phba;
3001 struct iscsi_wrb *pwrb = NULL;
3002 unsigned int doorbell = 0;
3003
3004 pwrb = io_task->pwrb_handle->pwrb;
3005 io_task->cmd_bhs->iscsi_hdr.exp_statsn = 0;
3006 io_task->bhs_len = sizeof(struct be_cmd_bhs);
3007
3008 if (writedir) {
3009 SE_DEBUG(DBG_LVL_4, " WRITE Command \t");
3010 memset(&io_task->cmd_bhs->iscsi_data_pdu, 0, 48);
3011 AMAP_SET_BITS(struct amap_pdu_data_out, itt,
3012 &io_task->cmd_bhs->iscsi_data_pdu,
3013 (unsigned int)io_task->cmd_bhs->iscsi_hdr.itt);
3014 AMAP_SET_BITS(struct amap_pdu_data_out, opcode,
3015 &io_task->cmd_bhs->iscsi_data_pdu,
3016 ISCSI_OPCODE_SCSI_DATA_OUT);
3017 AMAP_SET_BITS(struct amap_pdu_data_out, final_bit,
3018 &io_task->cmd_bhs->iscsi_data_pdu, 1);
3019 AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, INI_WR_CMD);
3020 AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 1);
3021 } else {
3022 SE_DEBUG(DBG_LVL_4, "READ Command \t");
3023 AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, INI_RD_CMD);
3024 AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 0);
3025 }
3026 memcpy(&io_task->cmd_bhs->iscsi_data_pdu.
3027 dw[offsetof(struct amap_pdu_data_out, lun) / 32],
3028 io_task->cmd_bhs->iscsi_hdr.lun, sizeof(struct scsi_lun));
3029
3030 AMAP_SET_BITS(struct amap_iscsi_wrb, lun, pwrb,
3031 cpu_to_be16((unsigned short)io_task->cmd_bhs->iscsi_hdr.
3032 lun[0]));
3033 AMAP_SET_BITS(struct amap_iscsi_wrb, r2t_exp_dtl, pwrb, xferlen);
3034 AMAP_SET_BITS(struct amap_iscsi_wrb, wrb_idx, pwrb,
3035 io_task->pwrb_handle->wrb_index);
3036 AMAP_SET_BITS(struct amap_iscsi_wrb, cmdsn_itt, pwrb,
3037 be32_to_cpu(task->cmdsn));
3038 AMAP_SET_BITS(struct amap_iscsi_wrb, sgl_icd_idx, pwrb,
3039 io_task->psgl_handle->sgl_index);
3040
3041 hwi_write_sgl(pwrb, sg, num_sg, io_task);
3042
3043 AMAP_SET_BITS(struct amap_iscsi_wrb, ptr2nextwrb, pwrb,
3044 io_task->pwrb_handle->nxt_wrb_index);
3045 be_dws_le_to_cpu(pwrb, sizeof(struct iscsi_wrb));
3046
3047 doorbell |= beiscsi_conn->beiscsi_conn_cid & DB_WRB_POST_CID_MASK;
3048 doorbell |= (io_task->pwrb_handle->wrb_index &
3049 DB_DEF_PDU_WRB_INDEX_MASK) << DB_DEF_PDU_WRB_INDEX_SHIFT;
3050 doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT;
3051
3052 iowrite32(doorbell, phba->db_va + DB_TXULP0_OFFSET);
3053 return 0;
3054}
3055
3056static int beiscsi_mtask(struct iscsi_task *task)
3057{
3058 struct beiscsi_io_task *aborted_io_task, *io_task = task->dd_data;
3059 struct iscsi_conn *conn = task->conn;
3060 struct beiscsi_conn *beiscsi_conn = conn->dd_data;
3061 struct beiscsi_hba *phba = beiscsi_conn->phba;
3062 struct iscsi_wrb *pwrb = NULL;
3063 unsigned int doorbell = 0;
3064 struct iscsi_task *aborted_task;
3065
3066 pwrb = io_task->pwrb_handle->pwrb;
3067 AMAP_SET_BITS(struct amap_iscsi_wrb, cmdsn_itt, pwrb,
3068 be32_to_cpu(task->cmdsn));
3069 AMAP_SET_BITS(struct amap_iscsi_wrb, wrb_idx, pwrb,
3070 io_task->pwrb_handle->wrb_index);
3071 AMAP_SET_BITS(struct amap_iscsi_wrb, sgl_icd_idx, pwrb,
3072 io_task->psgl_handle->sgl_index);
3073
3074 switch (task->hdr->opcode & ISCSI_OPCODE_MASK) {
3075 case ISCSI_OP_LOGIN:
3076 AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, TGT_DM_CMD);
3077 AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0);
3078 AMAP_SET_BITS(struct amap_iscsi_wrb, cmdsn_itt, pwrb, 1);
3079 hwi_write_buffer(pwrb, task);
3080 break;
3081 case ISCSI_OP_NOOP_OUT:
3082 AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, INI_RD_CMD);
3083 hwi_write_buffer(pwrb, task);
3084 break;
3085 case ISCSI_OP_TEXT:
3086 AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, INI_WR_CMD);
3087 AMAP_SET_BITS(struct amap_iscsi_wrb, dsp, pwrb, 1);
3088 hwi_write_buffer(pwrb, task);
3089 break;
3090 case ISCSI_OP_SCSI_TMFUNC:
3091 aborted_task = iscsi_itt_to_task(conn,
3092 ((struct iscsi_tm *)task->hdr)->rtt);
3093 if (!aborted_task)
3094 return 0;
3095 aborted_io_task = aborted_task->dd_data;
3096 if (!aborted_io_task->scsi_cmnd)
3097 return 0;
3098
3099 mgmt_invalidate_icds(phba,
3100 aborted_io_task->psgl_handle->sgl_index,
3101 beiscsi_conn->beiscsi_conn_cid);
3102 AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, INI_TMF_CMD);
3103 AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0);
3104 hwi_write_buffer(pwrb, task);
3105 break;
3106 case ISCSI_OP_LOGOUT:
3107 AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0);
3108 AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
3109 HWH_TYPE_LOGOUT);
3110 hwi_write_buffer(pwrb, task);
3111 break;
3112
3113 default:
3114 SE_DEBUG(DBG_LVL_1, "opcode =%d Not supported \n",
3115 task->hdr->opcode & ISCSI_OPCODE_MASK);
3116 return -EINVAL;
3117 }
3118
3119 AMAP_SET_BITS(struct amap_iscsi_wrb, r2t_exp_dtl, pwrb,
3120 be32_to_cpu(task->data_count));
3121 AMAP_SET_BITS(struct amap_iscsi_wrb, ptr2nextwrb, pwrb,
3122 io_task->pwrb_handle->nxt_wrb_index);
3123 be_dws_le_to_cpu(pwrb, sizeof(struct iscsi_wrb));
3124
3125 doorbell |= beiscsi_conn->beiscsi_conn_cid & DB_WRB_POST_CID_MASK;
3126 doorbell |= (io_task->pwrb_handle->wrb_index &
3127 DB_DEF_PDU_WRB_INDEX_MASK) << DB_DEF_PDU_WRB_INDEX_SHIFT;
3128 doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT;
3129 iowrite32(doorbell, phba->db_va + DB_TXULP0_OFFSET);
3130 return 0;
3131}
3132
3133static int beiscsi_task_xmit(struct iscsi_task *task)
3134{
3135 struct iscsi_conn *conn = task->conn;
3136 struct beiscsi_io_task *io_task = task->dd_data;
3137 struct scsi_cmnd *sc = task->sc;
3138 struct beiscsi_conn *beiscsi_conn = conn->dd_data;
3139 struct scatterlist *sg;
3140 int num_sg;
3141 unsigned int writedir = 0, xferlen = 0;
3142
3143 SE_DEBUG(DBG_LVL_4, "\n cid=%d In beiscsi_task_xmit task=%p conn=%p \t"
3144 "beiscsi_conn=%p \n", beiscsi_conn->beiscsi_conn_cid,
3145 task, conn, beiscsi_conn);
3146 if (!sc)
3147 return beiscsi_mtask(task);
3148
3149 io_task->scsi_cmnd = sc;
3150 num_sg = scsi_dma_map(sc);
3151 if (num_sg < 0) {
3152 SE_DEBUG(DBG_LVL_1, " scsi_dma_map Failed\n")
3153 return num_sg;
3154 }
3155 SE_DEBUG(DBG_LVL_4, "xferlen=0x%08x scmd=%p num_sg=%d sernum=%lu\n",
3156 (scsi_bufflen(sc)), sc, num_sg, sc->serial_number);
3157 xferlen = scsi_bufflen(sc);
3158 sg = scsi_sglist(sc);
3159 if (sc->sc_data_direction == DMA_TO_DEVICE) {
3160 writedir = 1;
3161 SE_DEBUG(DBG_LVL_4, "task->imm_count=0x%08x \n",
3162 task->imm_count);
3163 } else
3164 writedir = 0;
3165 return beiscsi_iotask(task, sg, num_sg, xferlen, writedir);
3166}
3167
3168static void beiscsi_remove(struct pci_dev *pcidev)
3169{
3170 struct beiscsi_hba *phba = NULL;
3171
3172 phba = (struct beiscsi_hba *)pci_get_drvdata(pcidev);
3173 if (!phba) {
3174 dev_err(&pcidev->dev, "beiscsi_remove called with no phba \n");
3175 return;
3176 }
3177
3178 hwi_disable_intr(phba);
3179 if (phba->pcidev->irq)
3180 free_irq(phba->pcidev->irq, phba);
3181 destroy_workqueue(phba->wq);
3182 if (blk_iopoll_enabled)
3183 blk_iopoll_disable(&phba->iopoll);
3184
3185 beiscsi_clean_port(phba);
3186 beiscsi_free_mem(phba);
3187 beiscsi_unmap_pci_function(phba);
3188 pci_free_consistent(phba->pcidev,
3189 phba->ctrl.mbox_mem_alloced.size,
3190 phba->ctrl.mbox_mem_alloced.va,
3191 phba->ctrl.mbox_mem_alloced.dma);
3192 iscsi_host_remove(phba->shost);
3193 pci_dev_put(phba->pcidev);
3194 iscsi_host_free(phba->shost);
3195}
3196
3197static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
3198 const struct pci_device_id *id)
3199{
3200 struct beiscsi_hba *phba = NULL;
3201 int ret;
3202
3203 ret = beiscsi_enable_pci(pcidev);
3204 if (ret < 0) {
3205 shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-"
3206 "Failed to enable pci device \n");
3207 return ret;
3208 }
3209
3210 phba = beiscsi_hba_alloc(pcidev);
3211 if (!phba) {
3212 dev_err(&pcidev->dev, "beiscsi_dev_probe-"
3213 " Failed in beiscsi_hba_alloc \n");
3214 goto disable_pci;
3215 }
3216
3217 pci_set_drvdata(pcidev, phba);
3218 ret = be_ctrl_init(phba, pcidev);
3219 if (ret) {
3220 shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-"
3221 "Failed in be_ctrl_init\n");
3222 goto hba_free;
3223 }
3224
3225 spin_lock_init(&phba->io_sgl_lock);
3226 spin_lock_init(&phba->mgmt_sgl_lock);
3227 spin_lock_init(&phba->isr_lock);
3228 beiscsi_get_params(phba);
3229 ret = beiscsi_init_port(phba);
3230 if (ret < 0) {
3231 shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-"
3232 "Failed in beiscsi_init_port\n");
3233 goto free_port;
3234 }
3235
3236 snprintf(phba->wq_name, sizeof(phba->wq_name), "beiscsi_q_irq%u",
3237 phba->shost->host_no);
3238 phba->wq = create_singlethread_workqueue(phba->wq_name);
3239 if (!phba->wq) {
3240 shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-"
3241 "Failed to allocate work queue\n");
3242 goto free_twq;
3243 }
3244
3245 INIT_WORK(&phba->work_cqs, beiscsi_process_all_cqs);
3246
3247 if (blk_iopoll_enabled) {
3248 blk_iopoll_init(&phba->iopoll, be_iopoll_budget, be_iopoll);
3249 blk_iopoll_enable(&phba->iopoll);
3250 }
3251
3252 ret = beiscsi_init_irqs(phba);
3253 if (ret < 0) {
3254 shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-"
3255 "Failed to beiscsi_init_irqs\n");
3256 goto free_blkenbld;
3257 }
3258 ret = hwi_enable_intr(phba);
3259 if (ret < 0) {
3260 shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-"
3261 "Failed to hwi_enable_intr\n");
3262 goto free_ctrlr;
3263 }
3264
3265 SE_DEBUG(DBG_LVL_8, "\n\n\n SUCCESS - DRIVER LOADED \n\n\n");
3266 return 0;
3267
3268free_ctrlr:
3269 if (phba->pcidev->irq)
3270 free_irq(phba->pcidev->irq, phba);
3271free_blkenbld:
3272 destroy_workqueue(phba->wq);
3273 if (blk_iopoll_enabled)
3274 blk_iopoll_disable(&phba->iopoll);
3275free_twq:
3276 beiscsi_clean_port(phba);
3277 beiscsi_free_mem(phba);
3278free_port:
3279 pci_free_consistent(phba->pcidev,
3280 phba->ctrl.mbox_mem_alloced.size,
3281 phba->ctrl.mbox_mem_alloced.va,
3282 phba->ctrl.mbox_mem_alloced.dma);
3283 beiscsi_unmap_pci_function(phba);
3284hba_free:
3285 iscsi_host_remove(phba->shost);
3286 pci_dev_put(phba->pcidev);
3287 iscsi_host_free(phba->shost);
3288disable_pci:
3289 pci_disable_device(pcidev);
3290 return ret;
3291}
3292
3293struct iscsi_transport beiscsi_iscsi_transport = {
3294 .owner = THIS_MODULE,
3295 .name = DRV_NAME,
3296 .caps = CAP_RECOVERY_L0 | CAP_HDRDGST |
3297 CAP_MULTI_R2T | CAP_DATADGST | CAP_DATA_PATH_OFFLOAD,
3298 .param_mask = ISCSI_MAX_RECV_DLENGTH |
3299 ISCSI_MAX_XMIT_DLENGTH |
3300 ISCSI_HDRDGST_EN |
3301 ISCSI_DATADGST_EN |
3302 ISCSI_INITIAL_R2T_EN |
3303 ISCSI_MAX_R2T |
3304 ISCSI_IMM_DATA_EN |
3305 ISCSI_FIRST_BURST |
3306 ISCSI_MAX_BURST |
3307 ISCSI_PDU_INORDER_EN |
3308 ISCSI_DATASEQ_INORDER_EN |
3309 ISCSI_ERL |
3310 ISCSI_CONN_PORT |
3311 ISCSI_CONN_ADDRESS |
3312 ISCSI_EXP_STATSN |
3313 ISCSI_PERSISTENT_PORT |
3314 ISCSI_PERSISTENT_ADDRESS |
3315 ISCSI_TARGET_NAME | ISCSI_TPGT |
3316 ISCSI_USERNAME | ISCSI_PASSWORD |
3317 ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN |
3318 ISCSI_FAST_ABORT | ISCSI_ABORT_TMO |
3319 ISCSI_LU_RESET_TMO |
3320 ISCSI_PING_TMO | ISCSI_RECV_TMO |
3321 ISCSI_IFACE_NAME | ISCSI_INITIATOR_NAME,
3322 .host_param_mask = ISCSI_HOST_HWADDRESS | ISCSI_HOST_IPADDRESS |
3323 ISCSI_HOST_INITIATOR_NAME,
3324 .create_session = beiscsi_session_create,
3325 .destroy_session = beiscsi_session_destroy,
3326 .create_conn = beiscsi_conn_create,
3327 .bind_conn = beiscsi_conn_bind,
3328 .destroy_conn = iscsi_conn_teardown,
3329 .set_param = beiscsi_set_param,
3330 .get_conn_param = beiscsi_conn_get_param,
3331 .get_session_param = iscsi_session_get_param,
3332 .get_host_param = beiscsi_get_host_param,
3333 .start_conn = beiscsi_conn_start,
3334 .stop_conn = beiscsi_conn_stop,
3335 .send_pdu = iscsi_conn_send_pdu,
3336 .xmit_task = beiscsi_task_xmit,
3337 .cleanup_task = beiscsi_cleanup_task,
3338 .alloc_pdu = beiscsi_alloc_pdu,
3339 .parse_pdu_itt = beiscsi_parse_pdu,
3340 .get_stats = beiscsi_conn_get_stats,
3341 .ep_connect = beiscsi_ep_connect,
3342 .ep_poll = beiscsi_ep_poll,
3343 .ep_disconnect = beiscsi_ep_disconnect,
3344 .session_recovery_timedout = iscsi_session_recovery_timedout,
3345};
3346
3347static struct pci_driver beiscsi_pci_driver = {
3348 .name = DRV_NAME,
3349 .probe = beiscsi_dev_probe,
3350 .remove = beiscsi_remove,
3351 .id_table = beiscsi_pci_id_table
3352};
3353
3354static int __init beiscsi_module_init(void)
3355{
3356 int ret;
3357
3358 beiscsi_scsi_transport =
3359 iscsi_register_transport(&beiscsi_iscsi_transport);
3360 if (!beiscsi_scsi_transport) {
3361 SE_DEBUG(DBG_LVL_1,
3362 "beiscsi_module_init - Unable to register beiscsi"
3363 "transport.\n");
3364 ret = -ENOMEM;
3365 }
3366 SE_DEBUG(DBG_LVL_8, "In beiscsi_module_init, tt=%p \n",
3367 &beiscsi_iscsi_transport);
3368
3369 ret = pci_register_driver(&beiscsi_pci_driver);
3370 if (ret) {
3371 SE_DEBUG(DBG_LVL_1,
3372 "beiscsi_module_init - Unable to register"
3373 "beiscsi pci driver.\n");
3374 goto unregister_iscsi_transport;
3375 }
3376 return 0;
3377
3378unregister_iscsi_transport:
3379 iscsi_unregister_transport(&beiscsi_iscsi_transport);
3380 return ret;
3381}
3382
3383static void __exit beiscsi_module_exit(void)
3384{
3385 pci_unregister_driver(&beiscsi_pci_driver);
3386 iscsi_unregister_transport(&beiscsi_iscsi_transport);
3387}
3388
3389module_init(beiscsi_module_init);
3390module_exit(beiscsi_module_exit);
diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h
new file mode 100644
index 000000000000..53c9b70ac7ac
--- /dev/null
+++ b/drivers/scsi/be2iscsi/be_main.h
@@ -0,0 +1,837 @@
1/**
2 * Copyright (C) 2005 - 2009 ServerEngines
3 * All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License version 2
7 * as published by the Free Software Foundation. The full GNU General
8 * Public License is included in this distribution in the file called COPYING.
9 *
10 * Written by: Jayamohan Kallickal (jayamohank@serverengines.com)
11 *
12 * Contact Information:
13 * linux-drivers@serverengines.com
14 *
15 * ServerEngines
16 * 209 N. Fair Oaks Ave
17 * Sunnyvale, CA 94085
18 *
19 */
20
21#ifndef _BEISCSI_MAIN_
22#define _BEISCSI_MAIN_
23
24
25#include <linux/kernel.h>
26#include <linux/pci.h>
27#include <linux/in.h>
28#include <linux/blk-iopoll.h>
29#include <scsi/scsi.h>
30#include <scsi/scsi_cmnd.h>
31#include <scsi/scsi_device.h>
32#include <scsi/scsi_host.h>
33#include <scsi/iscsi_proto.h>
34#include <scsi/libiscsi.h>
35#include <scsi/scsi_transport_iscsi.h>
36
37#include "be.h"
38
39
40
41#define DRV_NAME "be2iscsi"
42#define BUILD_STR "2.0.527.0"
43
44#define BE_NAME "ServerEngines BladeEngine2" \
45 "Linux iSCSI Driver version" BUILD_STR
46#define DRV_DESC BE_NAME " " "Driver"
47
48#define BE_VENDOR_ID 0x19A2
49#define BE_DEVICE_ID1 0x212
50#define OC_DEVICE_ID1 0x702
51#define OC_DEVICE_ID2 0x703
52
53#define BE2_MAX_SESSIONS 64
54#define BE2_CMDS_PER_CXN 128
55#define BE2_LOGOUTS BE2_MAX_SESSIONS
56#define BE2_TMFS 16
57#define BE2_NOPOUT_REQ 16
58#define BE2_ASYNCPDUS BE2_MAX_SESSIONS
59#define BE2_MAX_ICDS 2048
60#define BE2_SGE 32
61#define BE2_DEFPDU_HDR_SZ 64
62#define BE2_DEFPDU_DATA_SZ 8192
63#define BE2_IO_DEPTH \
64 (BE2_MAX_ICDS / 2 - (BE2_LOGOUTS + BE2_TMFS + BE2_NOPOUT_REQ))
65
66#define BEISCSI_SGLIST_ELEMENTS BE2_SGE
67
68#define BEISCSI_MAX_CMNDS 1024 /* Max IO's per Ctrlr sht->can_queue */
69#define BEISCSI_CMD_PER_LUN 128 /* scsi_host->cmd_per_lun */
70#define BEISCSI_MAX_SECTORS 2048 /* scsi_host->max_sectors */
71
72#define BEISCSI_MAX_CMD_LEN 16 /* scsi_host->max_cmd_len */
73#define BEISCSI_NUM_MAX_LUN 256 /* scsi_host->max_lun */
74#define BEISCSI_NUM_DEVICES_SUPPORTED 0x01
75#define BEISCSI_MAX_FRAGS_INIT 192
76#define BE_NUM_MSIX_ENTRIES 1
77#define MPU_EP_SEMAPHORE 0xac
78
79#define BE_SENSE_INFO_SIZE 258
80#define BE_ISCSI_PDU_HEADER_SIZE 64
81#define BE_MIN_MEM_SIZE 16384
82
83#define IIOC_SCSI_DATA 0x05 /* Write Operation */
84
85#define DBG_LVL 0x00000001
86#define DBG_LVL_1 0x00000001
87#define DBG_LVL_2 0x00000002
88#define DBG_LVL_3 0x00000004
89#define DBG_LVL_4 0x00000008
90#define DBG_LVL_5 0x00000010
91#define DBG_LVL_6 0x00000020
92#define DBG_LVL_7 0x00000040
93#define DBG_LVL_8 0x00000080
94
95#define SE_DEBUG(debug_mask, fmt, args...) \
96do { \
97 if (debug_mask & DBG_LVL) { \
98 printk(KERN_ERR "(%s():%d):", __func__, __LINE__);\
99 printk(fmt, ##args); \
100 } \
101} while (0);
102
103/**
104 * hardware needs the async PDU buffers to be posted in multiples of 8
105 * So have atleast 8 of them by default
106 */
107
108#define HWI_GET_ASYNC_PDU_CTX(phwi) (phwi->phwi_ctxt->pasync_ctx)
109
110/********* Memory BAR register ************/
111#define PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET 0xfc
112/**
113 * Host Interrupt Enable, if set interrupts are enabled although "PCI Interrupt
114 * Disable" may still globally block interrupts in addition to individual
115 * interrupt masks; a mechanism for the device driver to block all interrupts
116 * atomically without having to arbitrate for the PCI Interrupt Disable bit
117 * with the OS.
118 */
119#define MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK (1 << 29) /* bit 29 */
120
121/********* ISR0 Register offset **********/
122#define CEV_ISR0_OFFSET 0xC18
123#define CEV_ISR_SIZE 4
124
125/**
126 * Macros for reading/writing a protection domain or CSR registers
127 * in BladeEngine.
128 */
129
130#define DB_TXULP0_OFFSET 0x40
131#define DB_RXULP0_OFFSET 0xA0
132/********* Event Q door bell *************/
133#define DB_EQ_OFFSET DB_CQ_OFFSET
134#define DB_EQ_RING_ID_MASK 0x1FF /* bits 0 - 8 */
135/* Clear the interrupt for this eq */
136#define DB_EQ_CLR_SHIFT (9) /* bit 9 */
137/* Must be 1 */
138#define DB_EQ_EVNT_SHIFT (10) /* bit 10 */
139/* Number of event entries processed */
140#define DB_EQ_NUM_POPPED_SHIFT (16) /* bits 16 - 28 */
141/* Rearm bit */
142#define DB_EQ_REARM_SHIFT (29) /* bit 29 */
143
144/********* Compl Q door bell *************/
145#define DB_CQ_OFFSET 0x120
146#define DB_CQ_RING_ID_MASK 0x3FF /* bits 0 - 9 */
147/* Number of event entries processed */
148#define DB_CQ_NUM_POPPED_SHIFT (16) /* bits 16 - 28 */
149/* Rearm bit */
150#define DB_CQ_REARM_SHIFT (29) /* bit 29 */
151
152#define GET_HWI_CONTROLLER_WS(pc) (pc->phwi_ctrlr)
153#define HWI_GET_DEF_BUFQ_ID(pc) (((struct hwi_controller *)\
154 (GET_HWI_CONTROLLER_WS(pc)))->default_pdu_data.id)
155#define HWI_GET_DEF_HDRQ_ID(pc) (((struct hwi_controller *)\
156 (GET_HWI_CONTROLLER_WS(pc)))->default_pdu_hdr.id)
157
158#define PAGES_REQUIRED(x) \
159 ((x < PAGE_SIZE) ? 1 : ((x + PAGE_SIZE - 1) / PAGE_SIZE))
160
161enum be_mem_enum {
162 HWI_MEM_ADDN_CONTEXT,
163 HWI_MEM_CQ,
164 HWI_MEM_EQ,
165 HWI_MEM_WRB,
166 HWI_MEM_WRBH,
167 HWI_MEM_SGLH, /* 5 */
168 HWI_MEM_SGE,
169 HWI_MEM_ASYNC_HEADER_BUF,
170 HWI_MEM_ASYNC_DATA_BUF,
171 HWI_MEM_ASYNC_HEADER_RING,
172 HWI_MEM_ASYNC_DATA_RING, /* 10 */
173 HWI_MEM_ASYNC_HEADER_HANDLE,
174 HWI_MEM_ASYNC_DATA_HANDLE,
175 HWI_MEM_ASYNC_PDU_CONTEXT,
176 ISCSI_MEM_GLOBAL_HEADER,
177 SE_MEM_MAX /* 15 */
178};
179
180struct be_bus_address32 {
181 unsigned int address_lo;
182 unsigned int address_hi;
183};
184
185struct be_bus_address64 {
186 unsigned long long address;
187};
188
189struct be_bus_address {
190 union {
191 struct be_bus_address32 a32;
192 struct be_bus_address64 a64;
193 } u;
194};
195
196struct mem_array {
197 struct be_bus_address bus_address; /* Bus address of location */
198 void *virtual_address; /* virtual address to the location */
199 unsigned int size; /* Size required by memory block */
200};
201
202struct be_mem_descriptor {
203 unsigned int index; /* Index of this memory parameter */
204 unsigned int category; /* type indicates cached/non-cached */
205 unsigned int num_elements; /* number of elements in this
206 * descriptor
207 */
208 unsigned int alignment_mask; /* Alignment mask for this block */
209 unsigned int size_in_bytes; /* Size required by memory block */
210 struct mem_array *mem_array;
211};
212
213struct sgl_handle {
214 unsigned int sgl_index;
215 struct iscsi_sge *pfrag;
216};
217
218struct hba_parameters {
219 unsigned int ios_per_ctrl;
220 unsigned int cxns_per_ctrl;
221 unsigned int asyncpdus_per_ctrl;
222 unsigned int icds_per_ctrl;
223 unsigned int num_sge_per_io;
224 unsigned int defpdu_hdr_sz;
225 unsigned int defpdu_data_sz;
226 unsigned int num_cq_entries;
227 unsigned int num_eq_entries;
228 unsigned int wrbs_per_cxn;
229 unsigned int crashmode;
230 unsigned int hba_num;
231
232 unsigned int mgmt_ws_sz;
233 unsigned int hwi_ws_sz;
234
235 unsigned int eto;
236 unsigned int ldto;
237
238 unsigned int dbg_flags;
239 unsigned int num_cxn;
240
241 unsigned int eq_timer;
242 /**
243 * These are calculated from other params. They're here
244 * for debug purposes
245 */
246 unsigned int num_mcc_pages;
247 unsigned int num_mcc_cq_pages;
248 unsigned int num_cq_pages;
249 unsigned int num_eq_pages;
250
251 unsigned int num_async_pdu_buf_pages;
252 unsigned int num_async_pdu_buf_sgl_pages;
253 unsigned int num_async_pdu_buf_cq_pages;
254
255 unsigned int num_async_pdu_hdr_pages;
256 unsigned int num_async_pdu_hdr_sgl_pages;
257 unsigned int num_async_pdu_hdr_cq_pages;
258
259 unsigned int num_sge;
260};
261
262struct beiscsi_hba {
263 struct hba_parameters params;
264 struct hwi_controller *phwi_ctrlr;
265 unsigned int mem_req[SE_MEM_MAX];
266 /* PCI BAR mapped addresses */
267 u8 __iomem *csr_va; /* CSR */
268 u8 __iomem *db_va; /* Door Bell */
269 u8 __iomem *pci_va; /* PCI Config */
270 struct be_bus_address csr_pa; /* CSR */
271 struct be_bus_address db_pa; /* CSR */
272 struct be_bus_address pci_pa; /* CSR */
273 /* PCI representation of our HBA */
274 struct pci_dev *pcidev;
275 unsigned int state;
276 unsigned short asic_revision;
277 struct blk_iopoll iopoll;
278 struct be_mem_descriptor *init_mem;
279
280 unsigned short io_sgl_alloc_index;
281 unsigned short io_sgl_free_index;
282 unsigned short io_sgl_hndl_avbl;
283 struct sgl_handle **io_sgl_hndl_base;
284
285 unsigned short eh_sgl_alloc_index;
286 unsigned short eh_sgl_free_index;
287 unsigned short eh_sgl_hndl_avbl;
288 struct sgl_handle **eh_sgl_hndl_base;
289 spinlock_t io_sgl_lock;
290 spinlock_t mgmt_sgl_lock;
291 spinlock_t isr_lock;
292 unsigned int age;
293 unsigned short avlbl_cids;
294 unsigned short cid_alloc;
295 unsigned short cid_free;
296 struct beiscsi_conn *conn_table[BE2_MAX_SESSIONS * 2];
297 struct list_head hba_queue;
298 unsigned short *cid_array;
299 struct iscsi_endpoint **ep_array;
300 struct Scsi_Host *shost;
301 struct {
302 /**
303 * group together since they are used most frequently
304 * for cid to cri conversion
305 */
306 unsigned int iscsi_cid_start;
307 unsigned int phys_port;
308
309 unsigned int isr_offset;
310 unsigned int iscsi_icd_start;
311 unsigned int iscsi_cid_count;
312 unsigned int iscsi_icd_count;
313 unsigned int pci_function;
314
315 unsigned short cid_alloc;
316 unsigned short cid_free;
317 unsigned short avlbl_cids;
318 spinlock_t cid_lock;
319 } fw_config;
320
321 u8 mac_address[ETH_ALEN];
322 unsigned short todo_cq;
323 unsigned short todo_mcc_cq;
324 char wq_name[20];
325 struct workqueue_struct *wq; /* The actuak work queue */
326 struct work_struct work_cqs; /* The work being queued */
327 struct be_ctrl_info ctrl;
328};
329
330struct beiscsi_session {
331 struct pci_pool *bhs_pool;
332};
333
334/**
335 * struct beiscsi_conn - iscsi connection structure
336 */
337struct beiscsi_conn {
338 struct iscsi_conn *conn;
339 struct beiscsi_hba *phba;
340 u32 exp_statsn;
341 u32 beiscsi_conn_cid;
342 struct beiscsi_endpoint *ep;
343 unsigned short login_in_progress;
344 struct sgl_handle *plogin_sgl_handle;
345 struct beiscsi_session *beiscsi_sess;
346};
347
348/* This structure is used by the chip */
349struct pdu_data_out {
350 u32 dw[12];
351};
352/**
353 * Pseudo amap definition in which each bit of the actual structure is defined
354 * as a byte: used to calculate offset/shift/mask of each field
355 */
356struct amap_pdu_data_out {
357 u8 opcode[6]; /* opcode */
358 u8 rsvd0[2]; /* should be 0 */
359 u8 rsvd1[7];
360 u8 final_bit; /* F bit */
361 u8 rsvd2[16];
362 u8 ahs_length[8]; /* no AHS */
363 u8 data_len_hi[8];
364 u8 data_len_lo[16]; /* DataSegmentLength */
365 u8 lun[64];
366 u8 itt[32]; /* ITT; initiator task tag */
367 u8 ttt[32]; /* TTT; valid for R2T or 0xffffffff */
368 u8 rsvd3[32];
369 u8 exp_stat_sn[32];
370 u8 rsvd4[32];
371 u8 data_sn[32];
372 u8 buffer_offset[32];
373 u8 rsvd5[32];
374};
375
376struct be_cmd_bhs {
377 struct iscsi_cmd iscsi_hdr;
378 unsigned char pad1[16];
379 struct pdu_data_out iscsi_data_pdu;
380 unsigned char pad2[BE_SENSE_INFO_SIZE -
381 sizeof(struct pdu_data_out)];
382};
383
384struct beiscsi_io_task {
385 struct wrb_handle *pwrb_handle;
386 struct sgl_handle *psgl_handle;
387 struct beiscsi_conn *conn;
388 struct scsi_cmnd *scsi_cmnd;
389 unsigned int cmd_sn;
390 unsigned int flags;
391 unsigned short cid;
392 unsigned short header_len;
393
394 struct be_cmd_bhs *cmd_bhs;
395 struct be_bus_address bhs_pa;
396 unsigned short bhs_len;
397};
398
399struct be_nonio_bhs {
400 struct iscsi_hdr iscsi_hdr;
401 unsigned char pad1[16];
402 struct pdu_data_out iscsi_data_pdu;
403 unsigned char pad2[BE_SENSE_INFO_SIZE -
404 sizeof(struct pdu_data_out)];
405};
406
407struct be_status_bhs {
408 struct iscsi_cmd iscsi_hdr;
409 unsigned char pad1[16];
410 /**
411 * The plus 2 below is to hold the sense info length that gets
412 * DMA'ed by RxULP
413 */
414 unsigned char sense_info[BE_SENSE_INFO_SIZE];
415};
416
417struct iscsi_sge {
418 u32 dw[4];
419};
420
421/**
422 * Pseudo amap definition in which each bit of the actual structure is defined
423 * as a byte: used to calculate offset/shift/mask of each field
424 */
425struct amap_iscsi_sge {
426 u8 addr_hi[32];
427 u8 addr_lo[32];
428 u8 sge_offset[22]; /* DWORD 2 */
429 u8 rsvd0[9]; /* DWORD 2 */
430 u8 last_sge; /* DWORD 2 */
431 u8 len[17]; /* DWORD 3 */
432 u8 rsvd1[15]; /* DWORD 3 */
433};
434
435struct beiscsi_offload_params {
436 u32 dw[5];
437};
438
439#define OFFLD_PARAMS_ERL 0x00000003
440#define OFFLD_PARAMS_DDE 0x00000004
441#define OFFLD_PARAMS_HDE 0x00000008
442#define OFFLD_PARAMS_IR2T 0x00000010
443#define OFFLD_PARAMS_IMD 0x00000020
444
445/**
446 * Pseudo amap definition in which each bit of the actual structure is defined
447 * as a byte: used to calculate offset/shift/mask of each field
448 */
449struct amap_beiscsi_offload_params {
450 u8 max_burst_length[32];
451 u8 max_send_data_segment_length[32];
452 u8 first_burst_length[32];
453 u8 erl[2];
454 u8 dde[1];
455 u8 hde[1];
456 u8 ir2t[1];
457 u8 imd[1];
458 u8 pad[26];
459 u8 exp_statsn[32];
460};
461
462/* void hwi_complete_drvr_msgs(struct beiscsi_conn *beiscsi_conn,
463 struct beiscsi_hba *phba, struct sol_cqe *psol);*/
464
465struct async_pdu_handle {
466 struct list_head link;
467 struct be_bus_address pa;
468 void *pbuffer;
469 unsigned int consumed;
470 unsigned char index;
471 unsigned char is_header;
472 unsigned short cri;
473 unsigned long buffer_len;
474};
475
476struct hwi_async_entry {
477 struct {
478 unsigned char hdr_received;
479 unsigned char hdr_len;
480 unsigned short bytes_received;
481 unsigned int bytes_needed;
482 struct list_head list;
483 } wait_queue;
484
485 struct list_head header_busy_list;
486 struct list_head data_busy_list;
487};
488
489#define BE_MIN_ASYNC_ENTRIES 128
490
491struct hwi_async_pdu_context {
492 struct {
493 struct be_bus_address pa_base;
494 void *va_base;
495 void *ring_base;
496 struct async_pdu_handle *handle_base;
497
498 unsigned int host_write_ptr;
499 unsigned int ep_read_ptr;
500 unsigned int writables;
501
502 unsigned int free_entries;
503 unsigned int busy_entries;
504 unsigned int buffer_size;
505 unsigned int num_entries;
506
507 struct list_head free_list;
508 } async_header;
509
510 struct {
511 struct be_bus_address pa_base;
512 void *va_base;
513 void *ring_base;
514 struct async_pdu_handle *handle_base;
515
516 unsigned int host_write_ptr;
517 unsigned int ep_read_ptr;
518 unsigned int writables;
519
520 unsigned int free_entries;
521 unsigned int busy_entries;
522 unsigned int buffer_size;
523 struct list_head free_list;
524 unsigned int num_entries;
525 } async_data;
526
527 /**
528 * This is a varying size list! Do not add anything
529 * after this entry!!
530 */
531 struct hwi_async_entry async_entry[BE_MIN_ASYNC_ENTRIES];
532};
533
534#define PDUCQE_CODE_MASK 0x0000003F
535#define PDUCQE_DPL_MASK 0xFFFF0000
536#define PDUCQE_INDEX_MASK 0x0000FFFF
537
538struct i_t_dpdu_cqe {
539 u32 dw[4];
540} __packed;
541
542/**
543 * Pseudo amap definition in which each bit of the actual structure is defined
544 * as a byte: used to calculate offset/shift/mask of each field
545 */
546struct amap_i_t_dpdu_cqe {
547 u8 db_addr_hi[32];
548 u8 db_addr_lo[32];
549 u8 code[6];
550 u8 cid[10];
551 u8 dpl[16];
552 u8 index[16];
553 u8 num_cons[10];
554 u8 rsvd0[4];
555 u8 final;
556 u8 valid;
557} __packed;
558
559#define CQE_VALID_MASK 0x80000000
560#define CQE_CODE_MASK 0x0000003F
561#define CQE_CID_MASK 0x0000FFC0
562
563#define EQE_VALID_MASK 0x00000001
564#define EQE_MAJORCODE_MASK 0x0000000E
565#define EQE_RESID_MASK 0xFFFF0000
566
567struct be_eq_entry {
568 u32 dw[1];
569} __packed;
570
571/**
572 * Pseudo amap definition in which each bit of the actual structure is defined
573 * as a byte: used to calculate offset/shift/mask of each field
574 */
575struct amap_eq_entry {
576 u8 valid; /* DWORD 0 */
577 u8 major_code[3]; /* DWORD 0 */
578 u8 minor_code[12]; /* DWORD 0 */
579 u8 resource_id[16]; /* DWORD 0 */
580
581} __packed;
582
583struct cq_db {
584 u32 dw[1];
585} __packed;
586
587/**
588 * Pseudo amap definition in which each bit of the actual structure is defined
589 * as a byte: used to calculate offset/shift/mask of each field
590 */
591struct amap_cq_db {
592 u8 qid[10];
593 u8 event[1];
594 u8 rsvd0[5];
595 u8 num_popped[13];
596 u8 rearm[1];
597 u8 rsvd1[2];
598} __packed;
599
600void beiscsi_process_eq(struct beiscsi_hba *phba);
601
602
603struct iscsi_wrb {
604 u32 dw[16];
605} __packed;
606
607#define WRB_TYPE_MASK 0xF0000000
608
609/**
610 * Pseudo amap definition in which each bit of the actual structure is defined
611 * as a byte: used to calculate offset/shift/mask of each field
612 */
613struct amap_iscsi_wrb {
614 u8 lun[14]; /* DWORD 0 */
615 u8 lt; /* DWORD 0 */
616 u8 invld; /* DWORD 0 */
617 u8 wrb_idx[8]; /* DWORD 0 */
618 u8 dsp; /* DWORD 0 */
619 u8 dmsg; /* DWORD 0 */
620 u8 undr_run; /* DWORD 0 */
621 u8 over_run; /* DWORD 0 */
622 u8 type[4]; /* DWORD 0 */
623 u8 ptr2nextwrb[8]; /* DWORD 1 */
624 u8 r2t_exp_dtl[24]; /* DWORD 1 */
625 u8 sgl_icd_idx[12]; /* DWORD 2 */
626 u8 rsvd0[20]; /* DWORD 2 */
627 u8 exp_data_sn[32]; /* DWORD 3 */
628 u8 iscsi_bhs_addr_hi[32]; /* DWORD 4 */
629 u8 iscsi_bhs_addr_lo[32]; /* DWORD 5 */
630 u8 cmdsn_itt[32]; /* DWORD 6 */
631 u8 dif_ref_tag[32]; /* DWORD 7 */
632 u8 sge0_addr_hi[32]; /* DWORD 8 */
633 u8 sge0_addr_lo[32]; /* DWORD 9 */
634 u8 sge0_offset[22]; /* DWORD 10 */
635 u8 pbs; /* DWORD 10 */
636 u8 dif_mode[2]; /* DWORD 10 */
637 u8 rsvd1[6]; /* DWORD 10 */
638 u8 sge0_last; /* DWORD 10 */
639 u8 sge0_len[17]; /* DWORD 11 */
640 u8 dif_meta_tag[14]; /* DWORD 11 */
641 u8 sge0_in_ddr; /* DWORD 11 */
642 u8 sge1_addr_hi[32]; /* DWORD 12 */
643 u8 sge1_addr_lo[32]; /* DWORD 13 */
644 u8 sge1_r2t_offset[22]; /* DWORD 14 */
645 u8 rsvd2[9]; /* DWORD 14 */
646 u8 sge1_last; /* DWORD 14 */
647 u8 sge1_len[17]; /* DWORD 15 */
648 u8 ref_sgl_icd_idx[12]; /* DWORD 15 */
649 u8 rsvd3[2]; /* DWORD 15 */
650 u8 sge1_in_ddr; /* DWORD 15 */
651
652} __packed;
653
654struct wrb_handle *alloc_wrb_handle(struct beiscsi_hba *phba, unsigned int cid,
655 int index);
656void
657free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle);
658
659struct pdu_nop_out {
660 u32 dw[12];
661};
662
663/**
664 * Pseudo amap definition in which each bit of the actual structure is defined
665 * as a byte: used to calculate offset/shift/mask of each field
666 */
667struct amap_pdu_nop_out {
668 u8 opcode[6]; /* opcode 0x00 */
669 u8 i_bit; /* I Bit */
670 u8 x_bit; /* reserved; should be 0 */
671 u8 fp_bit_filler1[7];
672 u8 f_bit; /* always 1 */
673 u8 reserved1[16];
674 u8 ahs_length[8]; /* no AHS */
675 u8 data_len_hi[8];
676 u8 data_len_lo[16]; /* DataSegmentLength */
677 u8 lun[64];
678 u8 itt[32]; /* initiator id for ping or 0xffffffff */
679 u8 ttt[32]; /* target id for ping or 0xffffffff */
680 u8 cmd_sn[32];
681 u8 exp_stat_sn[32];
682 u8 reserved5[128];
683};
684
685#define PDUBASE_OPCODE_MASK 0x0000003F
686#define PDUBASE_DATALENHI_MASK 0x0000FF00
687#define PDUBASE_DATALENLO_MASK 0xFFFF0000
688
689struct pdu_base {
690 u32 dw[16];
691} __packed;
692
693/**
694 * Pseudo amap definition in which each bit of the actual structure is defined
695 * as a byte: used to calculate offset/shift/mask of each field
696 */
697struct amap_pdu_base {
698 u8 opcode[6];
699 u8 i_bit; /* immediate bit */
700 u8 x_bit; /* reserved, always 0 */
701 u8 reserved1[24]; /* opcode-specific fields */
702 u8 ahs_length[8]; /* length units is 4 byte words */
703 u8 data_len_hi[8];
704 u8 data_len_lo[16]; /* DatasegmentLength */
705 u8 lun[64]; /* lun or opcode-specific fields */
706 u8 itt[32]; /* initiator task tag */
707 u8 reserved4[224];
708};
709
710struct iscsi_target_context_update_wrb {
711 u32 dw[16];
712} __packed;
713
714/**
715 * Pseudo amap definition in which each bit of the actual structure is defined
716 * as a byte: used to calculate offset/shift/mask of each field
717 */
718struct amap_iscsi_target_context_update_wrb {
719 u8 lun[14]; /* DWORD 0 */
720 u8 lt; /* DWORD 0 */
721 u8 invld; /* DWORD 0 */
722 u8 wrb_idx[8]; /* DWORD 0 */
723 u8 dsp; /* DWORD 0 */
724 u8 dmsg; /* DWORD 0 */
725 u8 undr_run; /* DWORD 0 */
726 u8 over_run; /* DWORD 0 */
727 u8 type[4]; /* DWORD 0 */
728 u8 ptr2nextwrb[8]; /* DWORD 1 */
729 u8 max_burst_length[19]; /* DWORD 1 */
730 u8 rsvd0[5]; /* DWORD 1 */
731 u8 rsvd1[15]; /* DWORD 2 */
732 u8 max_send_data_segment_length[17]; /* DWORD 2 */
733 u8 first_burst_length[14]; /* DWORD 3 */
734 u8 rsvd2[2]; /* DWORD 3 */
735 u8 tx_wrbindex_drv_msg[8]; /* DWORD 3 */
736 u8 rsvd3[5]; /* DWORD 3 */
737 u8 session_state[3]; /* DWORD 3 */
738 u8 rsvd4[16]; /* DWORD 4 */
739 u8 tx_jumbo; /* DWORD 4 */
740 u8 hde; /* DWORD 4 */
741 u8 dde; /* DWORD 4 */
742 u8 erl[2]; /* DWORD 4 */
743 u8 domain_id[5]; /* DWORD 4 */
744 u8 mode; /* DWORD 4 */
745 u8 imd; /* DWORD 4 */
746 u8 ir2t; /* DWORD 4 */
747 u8 notpredblq[2]; /* DWORD 4 */
748 u8 compltonack; /* DWORD 4 */
749 u8 stat_sn[32]; /* DWORD 5 */
750 u8 pad_buffer_addr_hi[32]; /* DWORD 6 */
751 u8 pad_buffer_addr_lo[32]; /* DWORD 7 */
752 u8 pad_addr_hi[32]; /* DWORD 8 */
753 u8 pad_addr_lo[32]; /* DWORD 9 */
754 u8 rsvd5[32]; /* DWORD 10 */
755 u8 rsvd6[32]; /* DWORD 11 */
756 u8 rsvd7[32]; /* DWORD 12 */
757 u8 rsvd8[32]; /* DWORD 13 */
758 u8 rsvd9[32]; /* DWORD 14 */
759 u8 rsvd10[32]; /* DWORD 15 */
760
761} __packed;
762
763struct be_ring {
764 u32 pages; /* queue size in pages */
765 u32 id; /* queue id assigned by beklib */
766 u32 num; /* number of elements in queue */
767 u32 cidx; /* consumer index */
768 u32 pidx; /* producer index -- not used by most rings */
769 u32 item_size; /* size in bytes of one object */
770
771 void *va; /* The virtual address of the ring. This
772 * should be last to allow 32 & 64 bit debugger
773 * extensions to work.
774 */
775};
776
777struct hwi_wrb_context {
778 struct list_head wrb_handle_list;
779 struct list_head wrb_handle_drvr_list;
780 struct wrb_handle **pwrb_handle_base;
781 struct wrb_handle **pwrb_handle_basestd;
782 struct iscsi_wrb *plast_wrb;
783 unsigned short alloc_index;
784 unsigned short free_index;
785 unsigned short wrb_handles_available;
786 unsigned short cid;
787};
788
789struct hwi_controller {
790 struct list_head io_sgl_list;
791 struct list_head eh_sgl_list;
792 struct sgl_handle *psgl_handle_base;
793 unsigned int wrb_mem_index;
794
795 struct hwi_wrb_context wrb_context[BE2_MAX_SESSIONS * 2];
796 struct mcc_wrb *pmcc_wrb_base;
797 struct be_ring default_pdu_hdr;
798 struct be_ring default_pdu_data;
799 struct hwi_context_memory *phwi_ctxt;
800 unsigned short cq_errors[CXN_KILLED_CMND_DATA_NOT_ON_SAME_CONN];
801};
802
803enum hwh_type_enum {
804 HWH_TYPE_IO = 1,
805 HWH_TYPE_LOGOUT = 2,
806 HWH_TYPE_TMF = 3,
807 HWH_TYPE_NOP = 4,
808 HWH_TYPE_IO_RD = 5,
809 HWH_TYPE_LOGIN = 11,
810 HWH_TYPE_INVALID = 0xFFFFFFFF
811};
812
813struct wrb_handle {
814 enum hwh_type_enum type;
815 unsigned short wrb_index;
816 unsigned short nxt_wrb_index;
817
818 struct iscsi_task *pio_handle;
819 struct iscsi_wrb *pwrb;
820};
821
822struct hwi_context_memory {
823 struct be_eq_obj be_eq;
824 struct be_queue_info be_cq;
825 struct be_queue_info be_mcc_cq;
826 struct be_queue_info be_mcc;
827
828 struct be_queue_info be_def_hdrq;
829 struct be_queue_info be_def_dataq;
830
831 struct be_queue_info be_wrbq[BE2_MAX_SESSIONS];
832 struct be_mcc_wrb_context *pbe_mcc_context;
833
834 struct hwi_async_pdu_context *pasync_ctx;
835};
836
837#endif
diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c
new file mode 100644
index 000000000000..12e644fc746e
--- /dev/null
+++ b/drivers/scsi/be2iscsi/be_mgmt.c
@@ -0,0 +1,321 @@
1/**
2 * Copyright (C) 2005 - 2009 ServerEngines
3 * All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License version 2
7 * as published by the Free Software Foundation. The full GNU General
8 * Public License is included in this distribution in the file called COPYING.
9 *
10 * Written by: Jayamohan Kallickal (jayamohank@serverengines.com)
11 *
12 * Contact Information:
13 * linux-drivers@serverengines.com
14 *
15 * ServerEngines
16 * 209 N. Fair Oaks Ave
17 * Sunnyvale, CA 94085
18 *
19 */
20
21#include "be_mgmt.h"
22#include "be_iscsi.h"
23
24unsigned char mgmt_get_fw_config(struct be_ctrl_info *ctrl,
25 struct beiscsi_hba *phba)
26{
27 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
28 struct be_fw_cfg *req = embedded_payload(wrb);
29 int status = 0;
30
31 spin_lock(&ctrl->mbox_lock);
32 memset(wrb, 0, sizeof(*wrb));
33
34 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
35
36 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
37 OPCODE_COMMON_QUERY_FIRMWARE_CONFIG, sizeof(*req));
38
39 status = be_mbox_notify(ctrl);
40 if (!status) {
41 struct be_fw_cfg *pfw_cfg;
42 pfw_cfg = req;
43 phba->fw_config.phys_port = pfw_cfg->phys_port;
44 phba->fw_config.iscsi_icd_start =
45 pfw_cfg->ulp[0].icd_base;
46 phba->fw_config.iscsi_icd_count =
47 pfw_cfg->ulp[0].icd_count;
48 phba->fw_config.iscsi_cid_start =
49 pfw_cfg->ulp[0].sq_base;
50 phba->fw_config.iscsi_cid_count =
51 pfw_cfg->ulp[0].sq_count;
52 } else {
53 shost_printk(KERN_WARNING, phba->shost,
54 "Failed in mgmt_get_fw_config \n");
55 }
56
57 spin_unlock(&ctrl->mbox_lock);
58 return status;
59}
60
61unsigned char mgmt_check_supported_fw(struct be_ctrl_info *ctrl)
62{
63 struct be_dma_mem nonemb_cmd;
64 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
65 struct be_mgmt_controller_attributes *req;
66 struct be_sge *sge = nonembedded_sgl(wrb);
67 int status = 0;
68
69 nonemb_cmd.va = pci_alloc_consistent(ctrl->pdev,
70 sizeof(struct be_mgmt_controller_attributes),
71 &nonemb_cmd.dma);
72 if (nonemb_cmd.va == NULL) {
73 SE_DEBUG(DBG_LVL_1,
74 "Failed to allocate memory for mgmt_check_supported_fw"
75 "\n");
76 return -1;
77 }
78 nonemb_cmd.size = sizeof(struct be_mgmt_controller_attributes);
79 req = nonemb_cmd.va;
80 spin_lock(&ctrl->mbox_lock);
81 memset(wrb, 0, sizeof(*wrb));
82 be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
83 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
84 OPCODE_COMMON_GET_CNTL_ATTRIBUTES, sizeof(*req));
85 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd.dma));
86 sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF);
87 sge->len = cpu_to_le32(nonemb_cmd.size);
88
89 status = be_mbox_notify(ctrl);
90 if (!status) {
91 struct be_mgmt_controller_attributes_resp *resp = nonemb_cmd.va;
92 SE_DEBUG(DBG_LVL_8, "Firmware version of CMD: %s\n",
93 resp->params.hba_attribs.flashrom_version_string);
94 SE_DEBUG(DBG_LVL_8, "Firmware version is : %s\n",
95 resp->params.hba_attribs.firmware_version_string);
96 SE_DEBUG(DBG_LVL_8,
97 "Developer Build, not performing version check...\n");
98
99 } else
100 SE_DEBUG(DBG_LVL_1, " Failed in mgmt_check_supported_fw\n");
101 if (nonemb_cmd.va)
102 pci_free_consistent(ctrl->pdev, nonemb_cmd.size,
103 nonemb_cmd.va, nonemb_cmd.dma);
104
105 spin_unlock(&ctrl->mbox_lock);
106 return status;
107}
108
109unsigned char mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short chute)
110{
111 struct be_ctrl_info *ctrl = &phba->ctrl;
112 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
113 struct iscsi_cleanup_req *req = embedded_payload(wrb);
114 int status = 0;
115
116 spin_lock(&ctrl->mbox_lock);
117 memset(wrb, 0, sizeof(*wrb));
118
119 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
120 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
121 OPCODE_COMMON_ISCSI_CLEANUP, sizeof(*req));
122
123 req->chute = chute;
124 req->hdr_ring_id = 0;
125 req->data_ring_id = 0;
126
127 status = be_mbox_notify(ctrl);
128 if (status)
129 shost_printk(KERN_WARNING, phba->shost,
130 " mgmt_epfw_cleanup , FAILED\n");
131 spin_unlock(&ctrl->mbox_lock);
132 return status;
133}
134
135unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba,
136 unsigned int icd, unsigned int cid)
137{
138 struct be_dma_mem nonemb_cmd;
139 struct be_ctrl_info *ctrl = &phba->ctrl;
140 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
141 struct be_sge *sge = nonembedded_sgl(wrb);
142 struct invalidate_commands_params_in *req;
143 int status = 0;
144
145 nonemb_cmd.va = pci_alloc_consistent(ctrl->pdev,
146 sizeof(struct invalidate_commands_params_in),
147 &nonemb_cmd.dma);
148 if (nonemb_cmd.va == NULL) {
149 SE_DEBUG(DBG_LVL_1,
150 "Failed to allocate memory for"
151 "mgmt_invalidate_icds \n");
152 return -1;
153 }
154 nonemb_cmd.size = sizeof(struct invalidate_commands_params_in);
155 req = nonemb_cmd.va;
156 spin_lock(&ctrl->mbox_lock);
157 memset(wrb, 0, sizeof(*wrb));
158
159 be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
160 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
161 OPCODE_COMMON_ISCSI_ERROR_RECOVERY_INVALIDATE_COMMANDS,
162 sizeof(*req));
163 req->ref_handle = 0;
164 req->cleanup_type = CMD_ISCSI_COMMAND_INVALIDATE;
165 req->icd_count = 0;
166 req->table[req->icd_count].icd = icd;
167 req->table[req->icd_count].cid = cid;
168 sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd.dma));
169 sge->pa_lo = cpu_to_le32(nonemb_cmd.dma & 0xFFFFFFFF);
170 sge->len = cpu_to_le32(nonemb_cmd.size);
171
172 status = be_mbox_notify(ctrl);
173 if (status)
174 SE_DEBUG(DBG_LVL_1, "ICDS Invalidation Failed\n");
175 spin_unlock(&ctrl->mbox_lock);
176 if (nonemb_cmd.va)
177 pci_free_consistent(ctrl->pdev, nonemb_cmd.size,
178 nonemb_cmd.va, nonemb_cmd.dma);
179 return status;
180}
181
182unsigned char mgmt_invalidate_connection(struct beiscsi_hba *phba,
183 struct beiscsi_endpoint *beiscsi_ep,
184 unsigned short cid,
185 unsigned short issue_reset,
186 unsigned short savecfg_flag)
187{
188 struct be_ctrl_info *ctrl = &phba->ctrl;
189 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
190 struct iscsi_invalidate_connection_params_in *req =
191 embedded_payload(wrb);
192 int status = 0;
193
194 spin_lock(&ctrl->mbox_lock);
195 memset(wrb, 0, sizeof(*wrb));
196
197 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
198 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI,
199 OPCODE_ISCSI_INI_DRIVER_INVALIDATE_CONNECTION,
200 sizeof(*req));
201 req->session_handle = beiscsi_ep->fw_handle;
202 req->cid = cid;
203 if (issue_reset)
204 req->cleanup_type = CMD_ISCSI_CONNECTION_ISSUE_TCP_RST;
205 else
206 req->cleanup_type = CMD_ISCSI_CONNECTION_INVALIDATE;
207 req->save_cfg = savecfg_flag;
208 status = be_mbox_notify(ctrl);
209 if (status)
210 SE_DEBUG(DBG_LVL_1, "Invalidation Failed\n");
211
212 spin_unlock(&ctrl->mbox_lock);
213 return status;
214}
215
216unsigned char mgmt_upload_connection(struct beiscsi_hba *phba,
217 unsigned short cid, unsigned int upload_flag)
218{
219 struct be_ctrl_info *ctrl = &phba->ctrl;
220 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
221 struct tcp_upload_params_in *req = embedded_payload(wrb);
222 int status = 0;
223
224 spin_lock(&ctrl->mbox_lock);
225 memset(wrb, 0, sizeof(*wrb));
226
227 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
228 be_cmd_hdr_prepare(&req->hdr, CMD_COMMON_TCP_UPLOAD,
229 OPCODE_COMMON_TCP_UPLOAD, sizeof(*req));
230 req->id = (unsigned short)cid;
231 req->upload_type = (unsigned char)upload_flag;
232 status = be_mbox_notify(ctrl);
233 if (status)
234 SE_DEBUG(DBG_LVL_1, "mgmt_upload_connection Failed\n");
235 spin_unlock(&ctrl->mbox_lock);
236 return status;
237}
238
239int mgmt_open_connection(struct beiscsi_hba *phba,
240 struct sockaddr *dst_addr,
241 struct beiscsi_endpoint *beiscsi_ep)
242{
243 struct hwi_controller *phwi_ctrlr;
244 struct hwi_context_memory *phwi_context;
245 struct sockaddr_in *daddr_in = (struct sockaddr_in *)dst_addr;
246 struct sockaddr_in6 *daddr_in6 = (struct sockaddr_in6 *)dst_addr;
247 struct be_ctrl_info *ctrl = &phba->ctrl;
248 struct be_mcc_wrb *wrb = wrb_from_mbox(&ctrl->mbox_mem);
249 struct tcp_connect_and_offload_in *req = embedded_payload(wrb);
250 unsigned short def_hdr_id;
251 unsigned short def_data_id;
252 struct phys_addr template_address = { 0, 0 };
253 struct phys_addr *ptemplate_address;
254 int status = 0;
255 unsigned short cid = beiscsi_ep->ep_cid;
256
257 phwi_ctrlr = phba->phwi_ctrlr;
258 phwi_context = phwi_ctrlr->phwi_ctxt;
259 def_hdr_id = (unsigned short)HWI_GET_DEF_HDRQ_ID(phba);
260 def_data_id = (unsigned short)HWI_GET_DEF_BUFQ_ID(phba);
261
262 ptemplate_address = &template_address;
263 ISCSI_GET_PDU_TEMPLATE_ADDRESS(phba, ptemplate_address);
264 spin_lock(&ctrl->mbox_lock);
265 memset(wrb, 0, sizeof(*wrb));
266
267 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
268 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI,
269 OPCODE_COMMON_ISCSI_TCP_CONNECT_AND_OFFLOAD,
270 sizeof(*req));
271 if (dst_addr->sa_family == PF_INET) {
272 __be32 s_addr = daddr_in->sin_addr.s_addr;
273 req->ip_address.ip_type = BE2_IPV4;
274 req->ip_address.ip_address[0] = s_addr & 0x000000ff;
275 req->ip_address.ip_address[1] = (s_addr & 0x0000ff00) >> 8;
276 req->ip_address.ip_address[2] = (s_addr & 0x00ff0000) >> 16;
277 req->ip_address.ip_address[3] = (s_addr & 0xff000000) >> 24;
278 req->tcp_port = ntohs(daddr_in->sin_port);
279 beiscsi_ep->dst_addr = daddr_in->sin_addr.s_addr;
280 beiscsi_ep->dst_tcpport = ntohs(daddr_in->sin_port);
281 beiscsi_ep->ip_type = BE2_IPV4;
282 } else if (dst_addr->sa_family == PF_INET6) {
283 req->ip_address.ip_type = BE2_IPV6;
284 memcpy(&req->ip_address.ip_address,
285 &daddr_in6->sin6_addr.in6_u.u6_addr8, 16);
286 req->tcp_port = ntohs(daddr_in6->sin6_port);
287 beiscsi_ep->dst_tcpport = ntohs(daddr_in6->sin6_port);
288 memcpy(&beiscsi_ep->dst6_addr,
289 &daddr_in6->sin6_addr.in6_u.u6_addr8, 16);
290 beiscsi_ep->ip_type = BE2_IPV6;
291 } else{
292 shost_printk(KERN_ERR, phba->shost, "unknown addr family %d\n",
293 dst_addr->sa_family);
294 spin_unlock(&ctrl->mbox_lock);
295 return -EINVAL;
296
297 }
298 req->cid = cid;
299 req->cq_id = phwi_context->be_cq.id;
300 req->defq_id = def_hdr_id;
301 req->hdr_ring_id = def_hdr_id;
302 req->data_ring_id = def_data_id;
303 req->do_offload = 1;
304 req->dataout_template_pa.lo = ptemplate_address->lo;
305 req->dataout_template_pa.hi = ptemplate_address->hi;
306 status = be_mbox_notify(ctrl);
307 if (!status) {
308 struct iscsi_endpoint *ep;
309 struct tcp_connect_and_offload_out *ptcpcnct_out =
310 embedded_payload(wrb);
311
312 ep = phba->ep_array[ptcpcnct_out->cid];
313 beiscsi_ep = ep->dd_data;
314 beiscsi_ep->fw_handle = 0;
315 beiscsi_ep->cid_vld = 1;
316 SE_DEBUG(DBG_LVL_8, "mgmt_open_connection Success\n");
317 } else
318 SE_DEBUG(DBG_LVL_1, "mgmt_open_connection Failed\n");
319 spin_unlock(&ctrl->mbox_lock);
320 return status;
321}
diff --git a/drivers/scsi/be2iscsi/be_mgmt.h b/drivers/scsi/be2iscsi/be_mgmt.h
new file mode 100644
index 000000000000..00e816ee8070
--- /dev/null
+++ b/drivers/scsi/be2iscsi/be_mgmt.h
@@ -0,0 +1,249 @@
1/**
2 * Copyright (C) 2005 - 2009 ServerEngines
3 * All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License version 2
7 * as published by the Free Software Foundation. The full GNU General
8 * Public License is included in this distribution in the file called COPYING.
9 *
10 * Written by: Jayamohan Kallickal (jayamohank@serverengines.com)
11 *
12 * Contact Information:
13 * linux-drivers@serverengines.com
14 *
15 * ServerEngines
16 * 209 N. Fair Oaks Ave
17 * Sunnyvale, CA 94085
18 *
19 */
20
21#ifndef _BEISCSI_MGMT_
22#define _BEISCSI_MGMT_
23
24#include <linux/types.h>
25#include <linux/list.h>
26#include "be_iscsi.h"
27#include "be_main.h"
28
29/**
30 * Pseudo amap definition in which each bit of the actual structure is defined
31 * as a byte: used to calculate offset/shift/mask of each field
32 */
33struct amap_mcc_sge {
34 u8 pa_lo[32]; /* dword 0 */
35 u8 pa_hi[32]; /* dword 1 */
36 u8 length[32]; /* DWORD 2 */
37} __packed;
38
39/**
40 * Pseudo amap definition in which each bit of the actual structure is defined
41 * as a byte: used to calculate offset/shift/mask of each field
42 */
43struct amap_mcc_wrb_payload {
44 union {
45 struct amap_mcc_sge sgl[19];
46 u8 embedded[59 * 32]; /* DWORDS 57 to 115 */
47 } u;
48} __packed;
49
50/**
51 * Pseudo amap definition in which each bit of the actual structure is defined
52 * as a byte: used to calculate offset/shift/mask of each field
53 */
54struct amap_mcc_wrb {
55 u8 embedded; /* DWORD 0 */
56 u8 rsvd0[2]; /* DWORD 0 */
57 u8 sge_count[5]; /* DWORD 0 */
58 u8 rsvd1[16]; /* DWORD 0 */
59 u8 special[8]; /* DWORD 0 */
60 u8 payload_length[32];
61 u8 tag[64]; /* DWORD 2 */
62 u8 rsvd2[32]; /* DWORD 4 */
63 struct amap_mcc_wrb_payload payload;
64};
65
66struct mcc_sge {
67 u32 pa_lo; /* dword 0 */
68 u32 pa_hi; /* dword 1 */
69 u32 length; /* DWORD 2 */
70} __packed;
71
72struct mcc_wrb_payload {
73 union {
74 struct mcc_sge sgl[19];
75 u32 embedded[59]; /* DWORDS 57 to 115 */
76 } u;
77} __packed;
78
79#define MCC_WRB_EMBEDDED_MASK 0x00000001
80
81struct mcc_wrb {
82 u32 dw[0]; /* DWORD 0 */
83 u32 payload_length;
84 u32 tag[2]; /* DWORD 2 */
85 u32 rsvd2[1]; /* DWORD 4 */
86 struct mcc_wrb_payload payload;
87};
88
89unsigned char mgmt_epfw_cleanup(struct beiscsi_hba *phba, unsigned short chute);
90int mgmt_open_connection(struct beiscsi_hba *phba, struct sockaddr *dst_addr,
91 struct beiscsi_endpoint *beiscsi_ep);
92
93unsigned char mgmt_upload_connection(struct beiscsi_hba *phba,
94 unsigned short cid,
95 unsigned int upload_flag);
96unsigned char mgmt_invalidate_icds(struct beiscsi_hba *phba,
97 unsigned int icd, unsigned int cid);
98
99struct iscsi_invalidate_connection_params_in {
100 struct be_cmd_req_hdr hdr;
101 unsigned int session_handle;
102 unsigned short cid;
103 unsigned short unused;
104 unsigned short cleanup_type;
105 unsigned short save_cfg;
106} __packed;
107
108struct iscsi_invalidate_connection_params_out {
109 unsigned int session_handle;
110 unsigned short cid;
111 unsigned short unused;
112} __packed;
113
114union iscsi_invalidate_connection_params {
115 struct iscsi_invalidate_connection_params_in request;
116 struct iscsi_invalidate_connection_params_out response;
117} __packed;
118
119struct invalidate_command_table {
120 unsigned short icd;
121 unsigned short cid;
122} __packed;
123
124struct invalidate_commands_params_in {
125 struct be_cmd_req_hdr hdr;
126 unsigned int ref_handle;
127 unsigned int icd_count;
128 struct invalidate_command_table table[128];
129 unsigned short cleanup_type;
130 unsigned short unused;
131} __packed;
132
133struct invalidate_commands_params_out {
134 unsigned int ref_handle;
135 unsigned int icd_count;
136 unsigned int icd_status[128];
137} __packed;
138
139union invalidate_commands_params {
140 struct invalidate_commands_params_in request;
141 struct invalidate_commands_params_out response;
142} __packed;
143
144struct mgmt_hba_attributes {
145 u8 flashrom_version_string[32];
146 u8 manufacturer_name[32];
147 u32 supported_modes;
148 u8 seeprom_version_lo;
149 u8 seeprom_version_hi;
150 u8 rsvd0[2];
151 u32 fw_cmd_data_struct_version;
152 u32 ep_fw_data_struct_version;
153 u32 future_reserved[12];
154 u32 default_extended_timeout;
155 u8 controller_model_number[32];
156 u8 controller_description[64];
157 u8 controller_serial_number[32];
158 u8 ip_version_string[32];
159 u8 firmware_version_string[32];
160 u8 bios_version_string[32];
161 u8 redboot_version_string[32];
162 u8 driver_version_string[32];
163 u8 fw_on_flash_version_string[32];
164 u32 functionalities_supported;
165 u16 max_cdblength;
166 u8 asic_revision;
167 u8 generational_guid[16];
168 u8 hba_port_count;
169 u16 default_link_down_timeout;
170 u8 iscsi_ver_min_max;
171 u8 multifunction_device;
172 u8 cache_valid;
173 u8 hba_status;
174 u8 max_domains_supported;
175 u8 phy_port;
176 u32 firmware_post_status;
177 u32 hba_mtu[8];
178 u32 future_u32[4];
179} __packed;
180
181struct mgmt_controller_attributes {
182 struct mgmt_hba_attributes hba_attribs;
183 u16 pci_vendor_id;
184 u16 pci_device_id;
185 u16 pci_sub_vendor_id;
186 u16 pci_sub_system_id;
187 u8 pci_bus_number;
188 u8 pci_device_number;
189 u8 pci_function_number;
190 u8 interface_type;
191 u64 unique_identifier;
192 u8 netfilters;
193 u8 rsvd0[3];
194 u8 future_u32[4];
195} __packed;
196
197struct be_mgmt_controller_attributes {
198 struct be_cmd_req_hdr hdr;
199 struct mgmt_controller_attributes params;
200} __packed;
201
202struct be_mgmt_controller_attributes_resp {
203 struct be_cmd_resp_hdr hdr;
204 struct mgmt_controller_attributes params;
205} __packed;
206
207/* configuration management */
208
209#define GET_MGMT_CONTROLLER_WS(phba) (phba->pmgmt_ws)
210
211/* MGMT CMD flags */
212
213#define MGMT_CMDH_FREE (1<<0)
214
215/* --- MGMT_ERROR_CODES --- */
216/* Error Codes returned in the status field of the CMD response header */
217#define MGMT_STATUS_SUCCESS 0 /* The CMD completed without errors */
218#define MGMT_STATUS_FAILED 1 /* Error status in the Status field of */
219 /* the CMD_RESPONSE_HEADER */
220
221#define ISCSI_GET_PDU_TEMPLATE_ADDRESS(pc, pa) {\
222 pa->lo = phba->init_mem[ISCSI_MEM_GLOBAL_HEADER].mem_array[0].\
223 bus_address.u.a32.address_lo; \
224 pa->hi = phba->init_mem[ISCSI_MEM_GLOBAL_HEADER].mem_array[0].\
225 bus_address.u.a32.address_hi; \
226}
227
228struct beiscsi_endpoint {
229 struct beiscsi_hba *phba;
230 struct beiscsi_sess *sess;
231 struct beiscsi_conn *conn;
232 unsigned short ip_type;
233 char dst6_addr[ISCSI_ADDRESS_BUF_LEN];
234 unsigned long dst_addr;
235 unsigned short ep_cid;
236 unsigned int fw_handle;
237 u16 dst_tcpport;
238 u16 cid_vld;
239};
240
241unsigned char mgmt_get_fw_config(struct be_ctrl_info *ctrl,
242 struct beiscsi_hba *phba);
243
244unsigned char mgmt_invalidate_connection(struct beiscsi_hba *phba,
245 struct beiscsi_endpoint *beiscsi_ep,
246 unsigned short cid,
247 unsigned short issue_reset,
248 unsigned short savecfg_flag);
249#endif
diff --git a/drivers/scsi/bfa/Makefile b/drivers/scsi/bfa/Makefile
new file mode 100644
index 000000000000..1d6009490d1c
--- /dev/null
+++ b/drivers/scsi/bfa/Makefile
@@ -0,0 +1,15 @@
1obj-$(CONFIG_SCSI_BFA_FC) := bfa.o
2
3bfa-y := bfad.o bfad_intr.o bfad_os.o bfad_im.o bfad_attr.o bfad_fwimg.o
4
5bfa-y += bfa_core.o bfa_ioc.o bfa_iocfc.o bfa_fcxp.o bfa_lps.o
6bfa-y += bfa_hw_cb.o bfa_hw_ct.o bfa_intr.o bfa_timer.o bfa_rport.o
7bfa-y += bfa_fcport.o bfa_port.o bfa_uf.o bfa_sgpg.o bfa_module.o bfa_ioim.o
8bfa-y += bfa_itnim.o bfa_fcpim.o bfa_tskim.o bfa_log.o bfa_log_module.o
9bfa-y += bfa_csdebug.o bfa_sm.o plog.o
10
11bfa-y += fcbuild.o fabric.o fcpim.o vfapi.o fcptm.o bfa_fcs.o bfa_fcs_port.o
12bfa-y += bfa_fcs_uf.o bfa_fcs_lport.o fab.o fdmi.o ms.o ns.o scn.o loop.o
13bfa-y += lport_api.o n2n.o rport.o rport_api.o rport_ftrs.o vport.o
14
15ccflags-y := -I$(obj) -I$(obj)/include -I$(obj)/include/cna
diff --git a/drivers/scsi/bfa/bfa_callback_priv.h b/drivers/scsi/bfa/bfa_callback_priv.h
new file mode 100644
index 000000000000..1e3265c9f7d4
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_callback_priv.h
@@ -0,0 +1,57 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFA_CALLBACK_PRIV_H__
19#define __BFA_CALLBACK_PRIV_H__
20
21#include <cs/bfa_q.h>
22
23typedef void (*bfa_cb_cbfn_t) (void *cbarg, bfa_boolean_t complete);
24
25/**
26 * Generic BFA callback element.
27 */
28struct bfa_cb_qe_s {
29 struct list_head qe;
30 bfa_cb_cbfn_t cbfn;
31 bfa_boolean_t once;
32 u32 rsvd;
33 void *cbarg;
34};
35
36#define bfa_cb_queue(__bfa, __hcb_qe, __cbfn, __cbarg) do { \
37 (__hcb_qe)->cbfn = (__cbfn); \
38 (__hcb_qe)->cbarg = (__cbarg); \
39 list_add_tail(&(__hcb_qe)->qe, &(__bfa)->comp_q); \
40} while (0)
41
42#define bfa_cb_dequeue(__hcb_qe) list_del(&(__hcb_qe)->qe)
43
44#define bfa_cb_queue_once(__bfa, __hcb_qe, __cbfn, __cbarg) do { \
45 (__hcb_qe)->cbfn = (__cbfn); \
46 (__hcb_qe)->cbarg = (__cbarg); \
47 if (!(__hcb_qe)->once) { \
48 list_add_tail((__hcb_qe), &(__bfa)->comp_q); \
49 (__hcb_qe)->once = BFA_TRUE; \
50 } \
51} while (0)
52
53#define bfa_cb_queue_done(__hcb_qe) do { \
54 (__hcb_qe)->once = BFA_FALSE; \
55} while (0)
56
57#endif /* __BFA_CALLBACK_PRIV_H__ */
diff --git a/drivers/scsi/bfa/bfa_cb_ioim_macros.h b/drivers/scsi/bfa/bfa_cb_ioim_macros.h
new file mode 100644
index 000000000000..0050c838c358
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_cb_ioim_macros.h
@@ -0,0 +1,205 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * bfa_cb_ioim_macros.h BFA IOIM driver interface macros.
20 */
21
22#ifndef __BFA_HCB_IOIM_MACROS_H__
23#define __BFA_HCB_IOIM_MACROS_H__
24
25#include <bfa_os_inc.h>
26/*
27 * #include <linux/dma-mapping.h>
28 *
29 * #include <scsi/scsi.h> #include <scsi/scsi_cmnd.h> #include
30 * <scsi/scsi_device.h> #include <scsi/scsi_host.h>
31 */
32#include "bfad_im_compat.h"
33
34/*
35 * task attribute values in FCP-2 FCP_CMND IU
36 */
37#define SIMPLE_Q 0
38#define HEAD_OF_Q 1
39#define ORDERED_Q 2
40#define ACA_Q 4
41#define UNTAGGED 5
42
43static inline lun_t
44bfad_int_to_lun(u32 luno)
45{
46 union {
47 u16 scsi_lun[4];
48 lun_t bfa_lun;
49 } lun;
50
51 lun.bfa_lun = 0;
52 lun.scsi_lun[0] = bfa_os_htons(luno);
53
54 return (lun.bfa_lun);
55}
56
57/**
58 * Get LUN for the I/O request
59 */
60#define bfa_cb_ioim_get_lun(__dio) \
61 bfad_int_to_lun(((struct scsi_cmnd *)__dio)->device->lun)
62
63/**
64 * Get CDB for the I/O request
65 */
66static inline u8 *
67bfa_cb_ioim_get_cdb(struct bfad_ioim_s *dio)
68{
69 struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
70
71 return ((u8 *) cmnd->cmnd);
72}
73
74/**
75 * Get I/O direction (read/write) for the I/O request
76 */
77static inline enum fcp_iodir
78bfa_cb_ioim_get_iodir(struct bfad_ioim_s *dio)
79{
80 struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
81 enum dma_data_direction dmadir;
82
83 dmadir = cmnd->sc_data_direction;
84 if (dmadir == DMA_TO_DEVICE)
85 return FCP_IODIR_WRITE;
86 else if (dmadir == DMA_FROM_DEVICE)
87 return FCP_IODIR_READ;
88 else
89 return FCP_IODIR_NONE;
90}
91
92/**
93 * Get IO size in bytes for the I/O request
94 */
95static inline u32
96bfa_cb_ioim_get_size(struct bfad_ioim_s *dio)
97{
98 struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
99
100 return (scsi_bufflen(cmnd));
101}
102
103/**
104 * Get timeout for the I/O request
105 */
106static inline u8
107bfa_cb_ioim_get_timeout(struct bfad_ioim_s *dio)
108{
109 struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
110 /*
111 * TBD: need a timeout for scsi passthru
112 */
113 if (cmnd->device->host == NULL)
114 return 4;
115
116 return 0;
117}
118
119/**
120 * Get SG element for the I/O request given the SG element index
121 */
122static inline union bfi_addr_u
123bfa_cb_ioim_get_sgaddr(struct bfad_ioim_s *dio, int sgeid)
124{
125 struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
126 struct scatterlist *sge;
127 u64 addr;
128
129 sge = (struct scatterlist *)scsi_sglist(cmnd) + sgeid;
130 addr = (u64) sg_dma_address(sge);
131
132 return (*(union bfi_addr_u *) &addr);
133}
134
135static inline u32
136bfa_cb_ioim_get_sglen(struct bfad_ioim_s *dio, int sgeid)
137{
138 struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
139 struct scatterlist *sge;
140 u32 len;
141
142 sge = (struct scatterlist *)scsi_sglist(cmnd) + sgeid;
143 len = sg_dma_len(sge);
144
145 return len;
146}
147
148/**
149 * Get Command Reference Number for the I/O request. 0 if none.
150 */
151static inline u8
152bfa_cb_ioim_get_crn(struct bfad_ioim_s *dio)
153{
154 return 0;
155}
156
157/**
158 * Get SAM-3 priority for the I/O request. 0 is default.
159 */
160static inline u8
161bfa_cb_ioim_get_priority(struct bfad_ioim_s *dio)
162{
163 return 0;
164}
165
166/**
167 * Get task attributes for the I/O request. Default is FCP_TASK_ATTR_SIMPLE(0).
168 */
169static inline u8
170bfa_cb_ioim_get_taskattr(struct bfad_ioim_s *dio)
171{
172 struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
173 u8 task_attr = UNTAGGED;
174
175 if (cmnd->device->tagged_supported) {
176 switch (cmnd->tag) {
177 case HEAD_OF_QUEUE_TAG:
178 task_attr = HEAD_OF_Q;
179 break;
180 case ORDERED_QUEUE_TAG:
181 task_attr = ORDERED_Q;
182 break;
183 default:
184 task_attr = SIMPLE_Q;
185 break;
186 }
187 }
188
189 return task_attr;
190}
191
192/**
193 * Get CDB length in bytes for the I/O request. Default is FCP_CMND_CDB_LEN(16).
194 */
195static inline u8
196bfa_cb_ioim_get_cdblen(struct bfad_ioim_s *dio)
197{
198 struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
199
200 return (cmnd->cmd_len);
201}
202
203
204
205#endif /* __BFA_HCB_IOIM_MACROS_H__ */
diff --git a/drivers/scsi/bfa/bfa_cee.c b/drivers/scsi/bfa/bfa_cee.c
new file mode 100644
index 000000000000..7a959c34e789
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_cee.c
@@ -0,0 +1,492 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#include <defs/bfa_defs_cee.h>
19#include <cs/bfa_trc.h>
20#include <cs/bfa_log.h>
21#include <cs/bfa_debug.h>
22#include <cee/bfa_cee.h>
23#include <bfi/bfi_cee.h>
24#include <bfi/bfi.h>
25#include <bfa_ioc.h>
26#include <cna/bfa_cna_trcmod.h>
27
28BFA_TRC_FILE(CNA, CEE);
29
30#define bfa_ioc_portid(__ioc) ((__ioc)->port_id)
31#define bfa_lpuid(__arg) bfa_ioc_portid(&(__arg)->ioc)
32
33static void bfa_cee_format_lldp_cfg(struct bfa_cee_lldp_cfg_s *lldp_cfg);
34static void bfa_cee_format_dcbcx_stats(struct bfa_cee_dcbx_stats_s
35 *dcbcx_stats);
36static void bfa_cee_format_lldp_stats(struct bfa_cee_lldp_stats_s
37 *lldp_stats);
38static void bfa_cee_format_cfg_stats(struct bfa_cee_cfg_stats_s *cfg_stats);
39static void bfa_cee_format_cee_cfg(void *buffer);
40static void bfa_cee_format_cee_stats(void *buffer);
41
42static void
43bfa_cee_format_cee_stats(void *buffer)
44{
45 struct bfa_cee_stats_s *cee_stats = buffer;
46 bfa_cee_format_dcbcx_stats(&cee_stats->dcbx_stats);
47 bfa_cee_format_lldp_stats(&cee_stats->lldp_stats);
48 bfa_cee_format_cfg_stats(&cee_stats->cfg_stats);
49}
50
51static void
52bfa_cee_format_cee_cfg(void *buffer)
53{
54 struct bfa_cee_attr_s *cee_cfg = buffer;
55 bfa_cee_format_lldp_cfg(&cee_cfg->lldp_remote);
56}
57
58static void
59bfa_cee_format_dcbcx_stats(struct bfa_cee_dcbx_stats_s *dcbcx_stats)
60{
61 dcbcx_stats->subtlvs_unrecognized =
62 bfa_os_ntohl(dcbcx_stats->subtlvs_unrecognized);
63 dcbcx_stats->negotiation_failed =
64 bfa_os_ntohl(dcbcx_stats->negotiation_failed);
65 dcbcx_stats->remote_cfg_changed =
66 bfa_os_ntohl(dcbcx_stats->remote_cfg_changed);
67 dcbcx_stats->tlvs_received = bfa_os_ntohl(dcbcx_stats->tlvs_received);
68 dcbcx_stats->tlvs_invalid = bfa_os_ntohl(dcbcx_stats->tlvs_invalid);
69 dcbcx_stats->seqno = bfa_os_ntohl(dcbcx_stats->seqno);
70 dcbcx_stats->ackno = bfa_os_ntohl(dcbcx_stats->ackno);
71 dcbcx_stats->recvd_seqno = bfa_os_ntohl(dcbcx_stats->recvd_seqno);
72 dcbcx_stats->recvd_ackno = bfa_os_ntohl(dcbcx_stats->recvd_ackno);
73}
74
75static void
76bfa_cee_format_lldp_stats(struct bfa_cee_lldp_stats_s *lldp_stats)
77{
78 lldp_stats->frames_transmitted =
79 bfa_os_ntohl(lldp_stats->frames_transmitted);
80 lldp_stats->frames_aged_out = bfa_os_ntohl(lldp_stats->frames_aged_out);
81 lldp_stats->frames_discarded =
82 bfa_os_ntohl(lldp_stats->frames_discarded);
83 lldp_stats->frames_in_error = bfa_os_ntohl(lldp_stats->frames_in_error);
84 lldp_stats->frames_rcvd = bfa_os_ntohl(lldp_stats->frames_rcvd);
85 lldp_stats->tlvs_discarded = bfa_os_ntohl(lldp_stats->tlvs_discarded);
86 lldp_stats->tlvs_unrecognized =
87 bfa_os_ntohl(lldp_stats->tlvs_unrecognized);
88}
89
90static void
91bfa_cee_format_cfg_stats(struct bfa_cee_cfg_stats_s *cfg_stats)
92{
93 cfg_stats->cee_status_down = bfa_os_ntohl(cfg_stats->cee_status_down);
94 cfg_stats->cee_status_up = bfa_os_ntohl(cfg_stats->cee_status_up);
95 cfg_stats->cee_hw_cfg_changed =
96 bfa_os_ntohl(cfg_stats->cee_hw_cfg_changed);
97 cfg_stats->recvd_invalid_cfg =
98 bfa_os_ntohl(cfg_stats->recvd_invalid_cfg);
99}
100
101static void
102bfa_cee_format_lldp_cfg(struct bfa_cee_lldp_cfg_s *lldp_cfg)
103{
104 lldp_cfg->time_to_interval = bfa_os_ntohs(lldp_cfg->time_to_interval);
105 lldp_cfg->enabled_system_cap =
106 bfa_os_ntohs(lldp_cfg->enabled_system_cap);
107}
108
109/**
110 * bfa_cee_attr_meminfo()
111 *
112 *
113 * @param[in] void
114 *
115 * @return Size of DMA region
116 */
117static u32
118bfa_cee_attr_meminfo(void)
119{
120 return BFA_ROUNDUP(sizeof(struct bfa_cee_attr_s), BFA_DMA_ALIGN_SZ);
121}
122
123/**
124 * bfa_cee_stats_meminfo()
125 *
126 *
127 * @param[in] void
128 *
129 * @return Size of DMA region
130 */
131static u32
132bfa_cee_stats_meminfo(void)
133{
134 return BFA_ROUNDUP(sizeof(struct bfa_cee_stats_s), BFA_DMA_ALIGN_SZ);
135}
136
137/**
138 * bfa_cee_get_attr_isr()
139 *
140 *
141 * @param[in] cee - Pointer to the CEE module
142 * status - Return status from the f/w
143 *
144 * @return void
145 */
146static void
147bfa_cee_get_attr_isr(struct bfa_cee_s *cee, bfa_status_t status)
148{
149 cee->get_attr_status = status;
150 bfa_trc(cee, 0);
151 if (status == BFA_STATUS_OK) {
152 bfa_trc(cee, 0);
153 /*
154 * The requested data has been copied to the DMA area, *process
155 * it.
156 */
157 memcpy(cee->attr, cee->attr_dma.kva,
158 sizeof(struct bfa_cee_attr_s));
159 bfa_cee_format_cee_cfg(cee->attr);
160 }
161 cee->get_attr_pending = BFA_FALSE;
162 if (cee->cbfn.get_attr_cbfn) {
163 bfa_trc(cee, 0);
164 cee->cbfn.get_attr_cbfn(cee->cbfn.get_attr_cbarg, status);
165 }
166 bfa_trc(cee, 0);
167}
168
169/**
170 * bfa_cee_get_attr_isr()
171 *
172 *
173 * @param[in] cee - Pointer to the CEE module
174 * status - Return status from the f/w
175 *
176 * @return void
177 */
178static void
179bfa_cee_get_stats_isr(struct bfa_cee_s *cee, bfa_status_t status)
180{
181 cee->get_stats_status = status;
182 bfa_trc(cee, 0);
183 if (status == BFA_STATUS_OK) {
184 bfa_trc(cee, 0);
185 /*
186 * The requested data has been copied to the DMA area, process
187 * it.
188 */
189 memcpy(cee->stats, cee->stats_dma.kva,
190 sizeof(struct bfa_cee_stats_s));
191 bfa_cee_format_cee_stats(cee->stats);
192 }
193 cee->get_stats_pending = BFA_FALSE;
194 bfa_trc(cee, 0);
195 if (cee->cbfn.get_stats_cbfn) {
196 bfa_trc(cee, 0);
197 cee->cbfn.get_stats_cbfn(cee->cbfn.get_stats_cbarg, status);
198 }
199 bfa_trc(cee, 0);
200}
201
202/**
203 * bfa_cee_get_attr_isr()
204 *
205 *
206 * @param[in] cee - Pointer to the CEE module
207 * status - Return status from the f/w
208 *
209 * @return void
210 */
211static void
212bfa_cee_reset_stats_isr(struct bfa_cee_s *cee, bfa_status_t status)
213{
214 cee->reset_stats_status = status;
215 cee->reset_stats_pending = BFA_FALSE;
216 if (cee->cbfn.reset_stats_cbfn)
217 cee->cbfn.reset_stats_cbfn(cee->cbfn.reset_stats_cbarg, status);
218}
219
220/**
221 * bfa_cee_meminfo()
222 *
223 *
224 * @param[in] void
225 *
226 * @return Size of DMA region
227 */
228u32
229bfa_cee_meminfo(void)
230{
231 return (bfa_cee_attr_meminfo() + bfa_cee_stats_meminfo());
232}
233
234/**
235 * bfa_cee_mem_claim()
236 *
237 *
238 * @param[in] cee CEE module pointer
239 * dma_kva Kernel Virtual Address of CEE DMA Memory
240 * dma_pa Physical Address of CEE DMA Memory
241 *
242 * @return void
243 */
244void
245bfa_cee_mem_claim(struct bfa_cee_s *cee, u8 *dma_kva, u64 dma_pa)
246{
247 cee->attr_dma.kva = dma_kva;
248 cee->attr_dma.pa = dma_pa;
249 cee->stats_dma.kva = dma_kva + bfa_cee_attr_meminfo();
250 cee->stats_dma.pa = dma_pa + bfa_cee_attr_meminfo();
251 cee->attr = (struct bfa_cee_attr_s *)dma_kva;
252 cee->stats =
253 (struct bfa_cee_stats_s *)(dma_kva + bfa_cee_attr_meminfo());
254}
255
256/**
257 * bfa_cee_get_attr()
258 *
259 * Send the request to the f/w to fetch CEE attributes.
260 *
261 * @param[in] Pointer to the CEE module data structure.
262 *
263 * @return Status
264 */
265
266bfa_status_t
267bfa_cee_get_attr(struct bfa_cee_s *cee, struct bfa_cee_attr_s *attr,
268 bfa_cee_get_attr_cbfn_t cbfn, void *cbarg)
269{
270 struct bfi_cee_get_req_s *cmd;
271
272 bfa_assert((cee != NULL) && (cee->ioc != NULL));
273 bfa_trc(cee, 0);
274 if (!bfa_ioc_is_operational(cee->ioc)) {
275 bfa_trc(cee, 0);
276 return BFA_STATUS_IOC_FAILURE;
277 }
278 if (cee->get_attr_pending == BFA_TRUE) {
279 bfa_trc(cee, 0);
280 return BFA_STATUS_DEVBUSY;
281 }
282 cee->get_attr_pending = BFA_TRUE;
283 cmd = (struct bfi_cee_get_req_s *)cee->get_cfg_mb.msg;
284 cee->attr = attr;
285 cee->cbfn.get_attr_cbfn = cbfn;
286 cee->cbfn.get_attr_cbarg = cbarg;
287 bfi_h2i_set(cmd->mh, BFI_MC_CEE, BFI_CEE_H2I_GET_CFG_REQ,
288 bfa_ioc_portid(cee->ioc));
289 bfa_dma_be_addr_set(cmd->dma_addr, cee->attr_dma.pa);
290 bfa_ioc_mbox_queue(cee->ioc, &cee->get_cfg_mb);
291 bfa_trc(cee, 0);
292
293 return BFA_STATUS_OK;
294}
295
296/**
297 * bfa_cee_get_stats()
298 *
299 * Send the request to the f/w to fetch CEE statistics.
300 *
301 * @param[in] Pointer to the CEE module data structure.
302 *
303 * @return Status
304 */
305
306bfa_status_t
307bfa_cee_get_stats(struct bfa_cee_s *cee, struct bfa_cee_stats_s *stats,
308 bfa_cee_get_stats_cbfn_t cbfn, void *cbarg)
309{
310 struct bfi_cee_get_req_s *cmd;
311
312 bfa_assert((cee != NULL) && (cee->ioc != NULL));
313
314 if (!bfa_ioc_is_operational(cee->ioc)) {
315 bfa_trc(cee, 0);
316 return BFA_STATUS_IOC_FAILURE;
317 }
318 if (cee->get_stats_pending == BFA_TRUE) {
319 bfa_trc(cee, 0);
320 return BFA_STATUS_DEVBUSY;
321 }
322 cee->get_stats_pending = BFA_TRUE;
323 cmd = (struct bfi_cee_get_req_s *)cee->get_stats_mb.msg;
324 cee->stats = stats;
325 cee->cbfn.get_stats_cbfn = cbfn;
326 cee->cbfn.get_stats_cbarg = cbarg;
327 bfi_h2i_set(cmd->mh, BFI_MC_CEE, BFI_CEE_H2I_GET_STATS_REQ,
328 bfa_ioc_portid(cee->ioc));
329 bfa_dma_be_addr_set(cmd->dma_addr, cee->stats_dma.pa);
330 bfa_ioc_mbox_queue(cee->ioc, &cee->get_stats_mb);
331 bfa_trc(cee, 0);
332
333 return BFA_STATUS_OK;
334}
335
336/**
337 * bfa_cee_reset_stats()
338 *
339 *
340 * @param[in] Pointer to the CEE module data structure.
341 *
342 * @return Status
343 */
344
345bfa_status_t
346bfa_cee_reset_stats(struct bfa_cee_s *cee, bfa_cee_reset_stats_cbfn_t cbfn,
347 void *cbarg)
348{
349 struct bfi_cee_reset_stats_s *cmd;
350
351 bfa_assert((cee != NULL) && (cee->ioc != NULL));
352 if (!bfa_ioc_is_operational(cee->ioc)) {
353 bfa_trc(cee, 0);
354 return BFA_STATUS_IOC_FAILURE;
355 }
356 if (cee->reset_stats_pending == BFA_TRUE) {
357 bfa_trc(cee, 0);
358 return BFA_STATUS_DEVBUSY;
359 }
360 cee->reset_stats_pending = BFA_TRUE;
361 cmd = (struct bfi_cee_reset_stats_s *)cee->reset_stats_mb.msg;
362 cee->cbfn.reset_stats_cbfn = cbfn;
363 cee->cbfn.reset_stats_cbarg = cbarg;
364 bfi_h2i_set(cmd->mh, BFI_MC_CEE, BFI_CEE_H2I_RESET_STATS,
365 bfa_ioc_portid(cee->ioc));
366 bfa_ioc_mbox_queue(cee->ioc, &cee->reset_stats_mb);
367 bfa_trc(cee, 0);
368 return BFA_STATUS_OK;
369}
370
371/**
372 * bfa_cee_isrs()
373 *
374 *
375 * @param[in] Pointer to the CEE module data structure.
376 *
377 * @return void
378 */
379
380void
381bfa_cee_isr(void *cbarg, struct bfi_mbmsg_s *m)
382{
383 union bfi_cee_i2h_msg_u *msg;
384 struct bfi_cee_get_rsp_s *get_rsp;
385 struct bfa_cee_s *cee = (struct bfa_cee_s *)cbarg;
386 msg = (union bfi_cee_i2h_msg_u *)m;
387 get_rsp = (struct bfi_cee_get_rsp_s *)m;
388 bfa_trc(cee, msg->mh.msg_id);
389 switch (msg->mh.msg_id) {
390 case BFI_CEE_I2H_GET_CFG_RSP:
391 bfa_trc(cee, get_rsp->cmd_status);
392 bfa_cee_get_attr_isr(cee, get_rsp->cmd_status);
393 break;
394 case BFI_CEE_I2H_GET_STATS_RSP:
395 bfa_cee_get_stats_isr(cee, get_rsp->cmd_status);
396 break;
397 case BFI_CEE_I2H_RESET_STATS_RSP:
398 bfa_cee_reset_stats_isr(cee, get_rsp->cmd_status);
399 break;
400 default:
401 bfa_assert(0);
402 }
403}
404
405/**
406 * bfa_cee_hbfail()
407 *
408 *
409 * @param[in] Pointer to the CEE module data structure.
410 *
411 * @return void
412 */
413
414void
415bfa_cee_hbfail(void *arg)
416{
417 struct bfa_cee_s *cee;
418 cee = (struct bfa_cee_s *)arg;
419
420 if (cee->get_attr_pending == BFA_TRUE) {
421 cee->get_attr_status = BFA_STATUS_FAILED;
422 cee->get_attr_pending = BFA_FALSE;
423 if (cee->cbfn.get_attr_cbfn) {
424 cee->cbfn.get_attr_cbfn(cee->cbfn.get_attr_cbarg,
425 BFA_STATUS_FAILED);
426 }
427 }
428 if (cee->get_stats_pending == BFA_TRUE) {
429 cee->get_stats_status = BFA_STATUS_FAILED;
430 cee->get_stats_pending = BFA_FALSE;
431 if (cee->cbfn.get_stats_cbfn) {
432 cee->cbfn.get_stats_cbfn(cee->cbfn.get_stats_cbarg,
433 BFA_STATUS_FAILED);
434 }
435 }
436 if (cee->reset_stats_pending == BFA_TRUE) {
437 cee->reset_stats_status = BFA_STATUS_FAILED;
438 cee->reset_stats_pending = BFA_FALSE;
439 if (cee->cbfn.reset_stats_cbfn) {
440 cee->cbfn.reset_stats_cbfn(cee->cbfn.reset_stats_cbarg,
441 BFA_STATUS_FAILED);
442 }
443 }
444}
445
446/**
447 * bfa_cee_attach()
448 *
449 *
450 * @param[in] cee - Pointer to the CEE module data structure
451 * ioc - Pointer to the ioc module data structure
452 * dev - Pointer to the device driver module data structure
453 * The device driver specific mbox ISR functions have
454 * this pointer as one of the parameters.
455 * trcmod -
456 * logmod -
457 *
458 * @return void
459 */
460void
461bfa_cee_attach(struct bfa_cee_s *cee, struct bfa_ioc_s *ioc, void *dev,
462 struct bfa_trc_mod_s *trcmod, struct bfa_log_mod_s *logmod)
463{
464 bfa_assert(cee != NULL);
465 cee->dev = dev;
466 cee->trcmod = trcmod;
467 cee->logmod = logmod;
468 cee->ioc = ioc;
469
470 bfa_ioc_mbox_regisr(cee->ioc, BFI_MC_CEE, bfa_cee_isr, cee);
471 bfa_ioc_hbfail_init(&cee->hbfail, bfa_cee_hbfail, cee);
472 bfa_ioc_hbfail_register(cee->ioc, &cee->hbfail);
473 bfa_trc(cee, 0);
474}
475
476/**
477 * bfa_cee_detach()
478 *
479 *
480 * @param[in] cee - Pointer to the CEE module data structure
481 *
482 * @return void
483 */
484void
485bfa_cee_detach(struct bfa_cee_s *cee)
486{
487 /*
488 * For now, just check if there is some ioctl pending and mark that as
489 * failed?
490 */
491 /* bfa_cee_hbfail(cee); */
492}
diff --git a/drivers/scsi/bfa/bfa_core.c b/drivers/scsi/bfa/bfa_core.c
new file mode 100644
index 000000000000..44e2d1155c51
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_core.c
@@ -0,0 +1,402 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#include <bfa.h>
19#include <defs/bfa_defs_pci.h>
20#include <cs/bfa_debug.h>
21#include <bfa_iocfc.h>
22
23#define DEF_CFG_NUM_FABRICS 1
24#define DEF_CFG_NUM_LPORTS 256
25#define DEF_CFG_NUM_CQS 4
26#define DEF_CFG_NUM_IOIM_REQS (BFA_IOIM_MAX)
27#define DEF_CFG_NUM_TSKIM_REQS 128
28#define DEF_CFG_NUM_FCXP_REQS 64
29#define DEF_CFG_NUM_UF_BUFS 64
30#define DEF_CFG_NUM_RPORTS 1024
31#define DEF_CFG_NUM_ITNIMS (DEF_CFG_NUM_RPORTS)
32#define DEF_CFG_NUM_TINS 256
33
34#define DEF_CFG_NUM_SGPGS 2048
35#define DEF_CFG_NUM_REQQ_ELEMS 256
36#define DEF_CFG_NUM_RSPQ_ELEMS 64
37#define DEF_CFG_NUM_SBOOT_TGTS 16
38#define DEF_CFG_NUM_SBOOT_LUNS 16
39
40/**
41 * Use this function query the memory requirement of the BFA library.
42 * This function needs to be called before bfa_attach() to get the
43 * memory required of the BFA layer for a given driver configuration.
44 *
45 * This call will fail, if the cap is out of range compared to pre-defined
46 * values within the BFA library
47 *
48 * @param[in] cfg - pointer to bfa_ioc_cfg_t. Driver layer should indicate
49 * its configuration in this structure.
50 * The default values for struct bfa_iocfc_cfg_s can be
51 * fetched using bfa_cfg_get_default() API.
52 *
53 * If cap's boundary check fails, the library will use
54 * the default bfa_cap_t values (and log a warning msg).
55 *
56 * @param[out] meminfo - pointer to bfa_meminfo_t. This content
57 * indicates the memory type (see bfa_mem_type_t) and
58 * amount of memory required.
59 *
60 * Driver should allocate the memory, populate the
61 * starting address for each block and provide the same
62 * structure as input parameter to bfa_attach() call.
63 *
64 * @return void
65 *
66 * Special Considerations: @note
67 */
68void
69bfa_cfg_get_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo)
70{
71 int i;
72 u32 km_len = 0, dm_len = 0;
73
74 bfa_assert((cfg != NULL) && (meminfo != NULL));
75
76 bfa_os_memset((void *)meminfo, 0, sizeof(struct bfa_meminfo_s));
77 meminfo->meminfo[BFA_MEM_TYPE_KVA - 1].mem_type =
78 BFA_MEM_TYPE_KVA;
79 meminfo->meminfo[BFA_MEM_TYPE_DMA - 1].mem_type =
80 BFA_MEM_TYPE_DMA;
81
82 bfa_iocfc_meminfo(cfg, &km_len, &dm_len);
83
84 for (i = 0; hal_mods[i]; i++)
85 hal_mods[i]->meminfo(cfg, &km_len, &dm_len);
86
87
88 meminfo->meminfo[BFA_MEM_TYPE_KVA - 1].mem_len = km_len;
89 meminfo->meminfo[BFA_MEM_TYPE_DMA - 1].mem_len = dm_len;
90}
91
92/**
93 * Use this function to do attach the driver instance with the BFA
94 * library. This function will not trigger any HW initialization
95 * process (which will be done in bfa_init() call)
96 *
97 * This call will fail, if the cap is out of range compared to
98 * pre-defined values within the BFA library
99 *
100 * @param[out] bfa Pointer to bfa_t.
101 * @param[in] bfad Opaque handle back to the driver's IOC structure
102 * @param[in] cfg Pointer to bfa_ioc_cfg_t. Should be same structure
103 * that was used in bfa_cfg_get_meminfo().
104 * @param[in] meminfo Pointer to bfa_meminfo_t. The driver should
105 * use the bfa_cfg_get_meminfo() call to
106 * find the memory blocks required, allocate the
107 * required memory and provide the starting addresses.
108 * @param[in] pcidev pointer to struct bfa_pcidev_s
109 *
110 * @return
111 * void
112 *
113 * Special Considerations:
114 *
115 * @note
116 *
117 */
118void
119bfa_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
120 struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev)
121{
122 int i;
123 struct bfa_mem_elem_s *melem;
124
125 bfa->fcs = BFA_FALSE;
126
127 bfa_assert((cfg != NULL) && (meminfo != NULL));
128
129 /**
130 * initialize all memory pointers for iterative allocation
131 */
132 for (i = 0; i < BFA_MEM_TYPE_MAX; i++) {
133 melem = meminfo->meminfo + i;
134 melem->kva_curp = melem->kva;
135 melem->dma_curp = melem->dma;
136 }
137
138 bfa_iocfc_attach(bfa, bfad, cfg, meminfo, pcidev);
139
140 for (i = 0; hal_mods[i]; i++)
141 hal_mods[i]->attach(bfa, bfad, cfg, meminfo, pcidev);
142
143}
144
145/**
146 * Use this function to delete a BFA IOC. IOC should be stopped (by
147 * calling bfa_stop()) before this function call.
148 *
149 * @param[in] bfa - pointer to bfa_t.
150 *
151 * @return
152 * void
153 *
154 * Special Considerations:
155 *
156 * @note
157 */
158void
159bfa_detach(struct bfa_s *bfa)
160{
161 int i;
162
163 for (i = 0; hal_mods[i]; i++)
164 hal_mods[i]->detach(bfa);
165
166 bfa_iocfc_detach(bfa);
167}
168
169
170void
171bfa_init_trc(struct bfa_s *bfa, struct bfa_trc_mod_s *trcmod)
172{
173 bfa->trcmod = trcmod;
174}
175
176
177void
178bfa_init_log(struct bfa_s *bfa, struct bfa_log_mod_s *logmod)
179{
180 bfa->logm = logmod;
181}
182
183
184void
185bfa_init_aen(struct bfa_s *bfa, struct bfa_aen_s *aen)
186{
187 bfa->aen = aen;
188}
189
190void
191bfa_init_plog(struct bfa_s *bfa, struct bfa_plog_s *plog)
192{
193 bfa->plog = plog;
194}
195
196/**
197 * Initialize IOC.
198 *
199 * This function will return immediately, when the IOC initialization is
200 * completed, the bfa_cb_init() will be called.
201 *
202 * @param[in] bfa instance
203 *
204 * @return void
205 *
206 * Special Considerations:
207 *
208 * @note
209 * When this function returns, the driver should register the interrupt service
210 * routine(s) and enable the device interrupts. If this is not done,
211 * bfa_cb_init() will never get called
212 */
213void
214bfa_init(struct bfa_s *bfa)
215{
216 bfa_iocfc_init(bfa);
217}
218
219/**
220 * Use this function initiate the IOC configuration setup. This function
221 * will return immediately.
222 *
223 * @param[in] bfa instance
224 *
225 * @return None
226 */
227void
228bfa_start(struct bfa_s *bfa)
229{
230 bfa_iocfc_start(bfa);
231}
232
233/**
234 * Use this function quiese the IOC. This function will return immediately,
235 * when the IOC is actually stopped, the bfa_cb_stop() will be called.
236 *
237 * @param[in] bfa - pointer to bfa_t.
238 *
239 * @return None
240 *
241 * Special Considerations:
242 * bfa_cb_stop() could be called before or after bfa_stop() returns.
243 *
244 * @note
245 * In case of any failure, we could handle it automatically by doing a
246 * reset and then succeed the bfa_stop() call.
247 */
248void
249bfa_stop(struct bfa_s *bfa)
250{
251 bfa_iocfc_stop(bfa);
252}
253
254void
255bfa_comp_deq(struct bfa_s *bfa, struct list_head *comp_q)
256{
257 INIT_LIST_HEAD(comp_q);
258 list_splice_tail_init(&bfa->comp_q, comp_q);
259}
260
261void
262bfa_comp_process(struct bfa_s *bfa, struct list_head *comp_q)
263{
264 struct list_head *qe;
265 struct list_head *qen;
266 struct bfa_cb_qe_s *hcb_qe;
267
268 list_for_each_safe(qe, qen, comp_q) {
269 hcb_qe = (struct bfa_cb_qe_s *) qe;
270 hcb_qe->cbfn(hcb_qe->cbarg, BFA_TRUE);
271 }
272}
273
274void
275bfa_comp_free(struct bfa_s *bfa, struct list_head *comp_q)
276{
277 struct list_head *qe;
278 struct bfa_cb_qe_s *hcb_qe;
279
280 while (!list_empty(comp_q)) {
281 bfa_q_deq(comp_q, &qe);
282 hcb_qe = (struct bfa_cb_qe_s *) qe;
283 hcb_qe->cbfn(hcb_qe->cbarg, BFA_FALSE);
284 }
285}
286
287void
288bfa_attach_fcs(struct bfa_s *bfa)
289{
290 bfa->fcs = BFA_TRUE;
291}
292
293/**
294 * Periodic timer heart beat from driver
295 */
296void
297bfa_timer_tick(struct bfa_s *bfa)
298{
299 bfa_timer_beat(&bfa->timer_mod);
300}
301
302#ifndef BFA_BIOS_BUILD
303/**
304 * Return the list of PCI vendor/device id lists supported by this
305 * BFA instance.
306 */
307void
308bfa_get_pciids(struct bfa_pciid_s **pciids, int *npciids)
309{
310 static struct bfa_pciid_s __pciids[] = {
311 {BFA_PCI_VENDOR_ID_BROCADE, BFA_PCI_DEVICE_ID_FC_8G2P},
312 {BFA_PCI_VENDOR_ID_BROCADE, BFA_PCI_DEVICE_ID_FC_8G1P},
313 {BFA_PCI_VENDOR_ID_BROCADE, BFA_PCI_DEVICE_ID_CT},
314 };
315
316 *npciids = sizeof(__pciids) / sizeof(__pciids[0]);
317 *pciids = __pciids;
318}
319
320/**
321 * Use this function query the default struct bfa_iocfc_cfg_s value (compiled
322 * into BFA layer). The OS driver can then turn back and overwrite entries that
323 * have been configured by the user.
324 *
325 * @param[in] cfg - pointer to bfa_ioc_cfg_t
326 *
327 * @return
328 * void
329 *
330 * Special Considerations:
331 * note
332 */
333void
334bfa_cfg_get_default(struct bfa_iocfc_cfg_s *cfg)
335{
336 cfg->fwcfg.num_fabrics = DEF_CFG_NUM_FABRICS;
337 cfg->fwcfg.num_lports = DEF_CFG_NUM_LPORTS;
338 cfg->fwcfg.num_rports = DEF_CFG_NUM_RPORTS;
339 cfg->fwcfg.num_ioim_reqs = DEF_CFG_NUM_IOIM_REQS;
340 cfg->fwcfg.num_tskim_reqs = DEF_CFG_NUM_TSKIM_REQS;
341 cfg->fwcfg.num_fcxp_reqs = DEF_CFG_NUM_FCXP_REQS;
342 cfg->fwcfg.num_uf_bufs = DEF_CFG_NUM_UF_BUFS;
343 cfg->fwcfg.num_cqs = DEF_CFG_NUM_CQS;
344
345 cfg->drvcfg.num_reqq_elems = DEF_CFG_NUM_REQQ_ELEMS;
346 cfg->drvcfg.num_rspq_elems = DEF_CFG_NUM_RSPQ_ELEMS;
347 cfg->drvcfg.num_sgpgs = DEF_CFG_NUM_SGPGS;
348 cfg->drvcfg.num_sboot_tgts = DEF_CFG_NUM_SBOOT_TGTS;
349 cfg->drvcfg.num_sboot_luns = DEF_CFG_NUM_SBOOT_LUNS;
350 cfg->drvcfg.path_tov = BFA_FCPIM_PATHTOV_DEF;
351 cfg->drvcfg.ioc_recover = BFA_FALSE;
352 cfg->drvcfg.delay_comp = BFA_FALSE;
353
354}
355
356void
357bfa_cfg_get_min(struct bfa_iocfc_cfg_s *cfg)
358{
359 bfa_cfg_get_default(cfg);
360 cfg->fwcfg.num_ioim_reqs = BFA_IOIM_MIN;
361 cfg->fwcfg.num_tskim_reqs = BFA_TSKIM_MIN;
362 cfg->fwcfg.num_fcxp_reqs = BFA_FCXP_MIN;
363 cfg->fwcfg.num_uf_bufs = BFA_UF_MIN;
364 cfg->fwcfg.num_rports = BFA_RPORT_MIN;
365
366 cfg->drvcfg.num_sgpgs = BFA_SGPG_MIN;
367 cfg->drvcfg.num_reqq_elems = BFA_REQQ_NELEMS_MIN;
368 cfg->drvcfg.num_rspq_elems = BFA_RSPQ_NELEMS_MIN;
369 cfg->drvcfg.min_cfg = BFA_TRUE;
370}
371
372void
373bfa_get_attr(struct bfa_s *bfa, struct bfa_ioc_attr_s *ioc_attr)
374{
375 bfa_ioc_get_attr(&bfa->ioc, ioc_attr);
376}
377
378/**
379 * Retrieve firmware trace information on IOC failure.
380 */
381bfa_status_t
382bfa_debug_fwsave(struct bfa_s *bfa, void *trcdata, int *trclen)
383{
384 return bfa_ioc_debug_fwsave(&bfa->ioc, trcdata, trclen);
385}
386
387/**
388 * Fetch firmware trace data.
389 *
390 * @param[in] bfa BFA instance
391 * @param[out] trcdata Firmware trace buffer
392 * @param[in,out] trclen Firmware trace buffer len
393 *
394 * @retval BFA_STATUS_OK Firmware trace is fetched.
395 * @retval BFA_STATUS_INPROGRESS Firmware trace fetch is in progress.
396 */
397bfa_status_t
398bfa_debug_fwtrc(struct bfa_s *bfa, void *trcdata, int *trclen)
399{
400 return bfa_ioc_debug_fwtrc(&bfa->ioc, trcdata, trclen);
401}
402#endif
diff --git a/drivers/scsi/bfa/bfa_csdebug.c b/drivers/scsi/bfa/bfa_csdebug.c
new file mode 100644
index 000000000000..1b71d349451a
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_csdebug.c
@@ -0,0 +1,58 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#include <cs/bfa_debug.h>
19#include <bfa_os_inc.h>
20#include <cs/bfa_q.h>
21#include <log/bfa_log_hal.h>
22
23/**
24 * cs_debug_api
25 */
26
27
28void
29bfa_panic(int line, char *file, char *panicstr)
30{
31 bfa_log(NULL, BFA_LOG_HAL_ASSERT, file, line, panicstr);
32 bfa_os_panic();
33}
34
35void
36bfa_sm_panic(struct bfa_log_mod_s *logm, int line, char *file, int event)
37{
38 bfa_log(logm, BFA_LOG_HAL_SM_ASSERT, file, line, event);
39 bfa_os_panic();
40}
41
42int
43bfa_q_is_on_q_func(struct list_head *q, struct list_head *qe)
44{
45 struct list_head *tqe;
46
47 tqe = bfa_q_next(q);
48 while (tqe != q) {
49 if (tqe == qe)
50 return (1);
51 tqe = bfa_q_next(tqe);
52 if (tqe == NULL)
53 break;
54 }
55 return (0);
56}
57
58
diff --git a/drivers/scsi/bfa/bfa_fcpim.c b/drivers/scsi/bfa/bfa_fcpim.c
new file mode 100644
index 000000000000..401babe3494e
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_fcpim.c
@@ -0,0 +1,175 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#include <bfa.h>
19#include <log/bfa_log_hal.h>
20
21BFA_TRC_FILE(HAL, FCPIM);
22BFA_MODULE(fcpim);
23
24/**
25 * hal_fcpim_mod BFA FCP Initiator Mode module
26 */
27
28/**
29 * Compute and return memory needed by FCP(im) module.
30 */
31static void
32bfa_fcpim_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len,
33 u32 *dm_len)
34{
35 bfa_itnim_meminfo(cfg, km_len, dm_len);
36
37 /**
38 * IO memory
39 */
40 if (cfg->fwcfg.num_ioim_reqs < BFA_IOIM_MIN)
41 cfg->fwcfg.num_ioim_reqs = BFA_IOIM_MIN;
42 else if (cfg->fwcfg.num_ioim_reqs > BFA_IOIM_MAX)
43 cfg->fwcfg.num_ioim_reqs = BFA_IOIM_MAX;
44
45 *km_len += cfg->fwcfg.num_ioim_reqs *
46 (sizeof(struct bfa_ioim_s) + sizeof(struct bfa_ioim_sp_s));
47
48 *dm_len += cfg->fwcfg.num_ioim_reqs * BFI_IOIM_SNSLEN;
49
50 /**
51 * task management command memory
52 */
53 if (cfg->fwcfg.num_tskim_reqs < BFA_TSKIM_MIN)
54 cfg->fwcfg.num_tskim_reqs = BFA_TSKIM_MIN;
55 *km_len += cfg->fwcfg.num_tskim_reqs * sizeof(struct bfa_tskim_s);
56}
57
58
59static void
60bfa_fcpim_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
61 struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev)
62{
63 struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
64
65 bfa_trc(bfa, cfg->drvcfg.path_tov);
66 bfa_trc(bfa, cfg->fwcfg.num_rports);
67 bfa_trc(bfa, cfg->fwcfg.num_ioim_reqs);
68 bfa_trc(bfa, cfg->fwcfg.num_tskim_reqs);
69
70 fcpim->bfa = bfa;
71 fcpim->num_itnims = cfg->fwcfg.num_rports;
72 fcpim->num_ioim_reqs = cfg->fwcfg.num_ioim_reqs;
73 fcpim->num_tskim_reqs = cfg->fwcfg.num_tskim_reqs;
74 fcpim->path_tov = cfg->drvcfg.path_tov;
75 fcpim->delay_comp = cfg->drvcfg.delay_comp;
76
77 bfa_itnim_attach(fcpim, meminfo);
78 bfa_tskim_attach(fcpim, meminfo);
79 bfa_ioim_attach(fcpim, meminfo);
80}
81
82static void
83bfa_fcpim_initdone(struct bfa_s *bfa)
84{
85}
86
87static void
88bfa_fcpim_detach(struct bfa_s *bfa)
89{
90 struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
91
92 bfa_ioim_detach(fcpim);
93 bfa_tskim_detach(fcpim);
94}
95
96static void
97bfa_fcpim_start(struct bfa_s *bfa)
98{
99}
100
101static void
102bfa_fcpim_stop(struct bfa_s *bfa)
103{
104}
105
106static void
107bfa_fcpim_iocdisable(struct bfa_s *bfa)
108{
109 struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
110 struct bfa_itnim_s *itnim;
111 struct list_head *qe, *qen;
112
113 list_for_each_safe(qe, qen, &fcpim->itnim_q) {
114 itnim = (struct bfa_itnim_s *) qe;
115 bfa_itnim_iocdisable(itnim);
116 }
117}
118
119void
120bfa_fcpim_path_tov_set(struct bfa_s *bfa, u16 path_tov)
121{
122 struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
123
124 fcpim->path_tov = path_tov * 1000;
125 if (fcpim->path_tov > BFA_FCPIM_PATHTOV_MAX)
126 fcpim->path_tov = BFA_FCPIM_PATHTOV_MAX;
127}
128
129u16
130bfa_fcpim_path_tov_get(struct bfa_s *bfa)
131{
132 struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
133
134 return (fcpim->path_tov / 1000);
135}
136
137bfa_status_t
138bfa_fcpim_get_modstats(struct bfa_s *bfa, struct bfa_fcpim_stats_s *modstats)
139{
140 struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
141
142 *modstats = fcpim->stats;
143
144 return BFA_STATUS_OK;
145}
146
147bfa_status_t
148bfa_fcpim_clr_modstats(struct bfa_s *bfa)
149{
150 struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
151
152 memset(&fcpim->stats, 0, sizeof(struct bfa_fcpim_stats_s));
153
154 return BFA_STATUS_OK;
155}
156
157void
158bfa_fcpim_qdepth_set(struct bfa_s *bfa, u16 q_depth)
159{
160 struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
161
162 bfa_assert(q_depth <= BFA_IOCFC_QDEPTH_MAX);
163
164 fcpim->q_depth = q_depth;
165}
166
167u16
168bfa_fcpim_qdepth_get(struct bfa_s *bfa)
169{
170 struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
171
172 return (fcpim->q_depth);
173}
174
175
diff --git a/drivers/scsi/bfa/bfa_fcpim_priv.h b/drivers/scsi/bfa/bfa_fcpim_priv.h
new file mode 100644
index 000000000000..153206cfb37a
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_fcpim_priv.h
@@ -0,0 +1,188 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFA_FCPIM_PRIV_H__
19#define __BFA_FCPIM_PRIV_H__
20
21#include <bfa_fcpim.h>
22#include <defs/bfa_defs_fcpim.h>
23#include <cs/bfa_wc.h>
24#include "bfa_sgpg_priv.h"
25
26#define BFA_ITNIM_MIN 32
27#define BFA_ITNIM_MAX 1024
28
29#define BFA_IOIM_MIN 8
30#define BFA_IOIM_MAX 2000
31
32#define BFA_TSKIM_MIN 4
33#define BFA_TSKIM_MAX 512
34#define BFA_FCPIM_PATHTOV_DEF (30 * 1000) /* in millisecs */
35#define BFA_FCPIM_PATHTOV_MAX (90 * 1000) /* in millisecs */
36
37#define bfa_fcpim_stats(__fcpim, __stats) \
38 (__fcpim)->stats.__stats ++
39
40struct bfa_fcpim_mod_s {
41 struct bfa_s *bfa;
42 struct bfa_itnim_s *itnim_arr;
43 struct bfa_ioim_s *ioim_arr;
44 struct bfa_ioim_sp_s *ioim_sp_arr;
45 struct bfa_tskim_s *tskim_arr;
46 struct bfa_dma_s snsbase;
47 int num_itnims;
48 int num_ioim_reqs;
49 int num_tskim_reqs;
50 u32 path_tov;
51 u16 q_depth;
52 u16 rsvd;
53 struct list_head itnim_q; /* queue of active itnim */
54 struct list_head ioim_free_q; /* free IO resources */
55 struct list_head ioim_resfree_q; /* IOs waiting for f/w */
56 struct list_head ioim_comp_q; /* IO global comp Q */
57 struct list_head tskim_free_q;
58 u32 ios_active; /* current active IOs */
59 u32 delay_comp;
60 struct bfa_fcpim_stats_s stats;
61};
62
63struct bfa_ioim_s;
64struct bfa_tskim_s;
65
66/**
67 * BFA IO (initiator mode)
68 */
69struct bfa_ioim_s {
70 struct list_head qe; /* queue elememt */
71 bfa_sm_t sm; /* BFA ioim state machine */
72 struct bfa_s *bfa; /* BFA module */
73 struct bfa_fcpim_mod_s *fcpim; /* parent fcpim module */
74 struct bfa_itnim_s *itnim; /* i-t-n nexus for this IO */
75 struct bfad_ioim_s *dio; /* driver IO handle */
76 u16 iotag; /* FWI IO tag */
77 u16 abort_tag; /* unqiue abort request tag */
78 u16 nsges; /* number of SG elements */
79 u16 nsgpgs; /* number of SG pages */
80 struct bfa_sgpg_s *sgpg; /* first SG page */
81 struct list_head sgpg_q; /* allocated SG pages */
82 struct bfa_cb_qe_s hcb_qe; /* bfa callback qelem */
83 bfa_cb_cbfn_t io_cbfn; /* IO completion handler */
84 struct bfa_ioim_sp_s *iosp; /* slow-path IO handling */
85};
86
87struct bfa_ioim_sp_s {
88 struct bfi_msg_s comp_rspmsg; /* IO comp f/w response */
89 u8 *snsinfo; /* sense info for this IO */
90 struct bfa_sgpg_wqe_s sgpg_wqe; /* waitq elem for sgpg */
91 struct bfa_reqq_wait_s reqq_wait; /* to wait for room in reqq */
92 bfa_boolean_t abort_explicit; /* aborted by OS */
93 struct bfa_tskim_s *tskim; /* Relevant TM cmd */
94};
95
96/**
97 * BFA Task management command (initiator mode)
98 */
99struct bfa_tskim_s {
100 struct list_head qe;
101 bfa_sm_t sm;
102 struct bfa_s *bfa; /* BFA module */
103 struct bfa_fcpim_mod_s *fcpim; /* parent fcpim module */
104 struct bfa_itnim_s *itnim; /* i-t-n nexus for this IO */
105 struct bfad_tskim_s *dtsk; /* driver task mgmt cmnd */
106 bfa_boolean_t notify; /* notify itnim on TM comp */
107 lun_t lun; /* lun if applicable */
108 enum fcp_tm_cmnd tm_cmnd; /* task management command */
109 u16 tsk_tag; /* FWI IO tag */
110 u8 tsecs; /* timeout in seconds */
111 struct bfa_reqq_wait_s reqq_wait; /* to wait for room in reqq */
112 struct list_head io_q; /* queue of affected IOs */
113 struct bfa_wc_s wc; /* waiting counter */
114 struct bfa_cb_qe_s hcb_qe; /* bfa callback qelem */
115 enum bfi_tskim_status tsk_status; /* TM status */
116};
117
118/**
119 * BFA i-t-n (initiator mode)
120 */
121struct bfa_itnim_s {
122 struct list_head qe; /* queue element */
123 bfa_sm_t sm; /* i-t-n im BFA state machine */
124 struct bfa_s *bfa; /* bfa instance */
125 struct bfa_rport_s *rport; /* bfa rport */
126 void *ditn; /* driver i-t-n structure */
127 struct bfi_mhdr_s mhdr; /* pre-built mhdr */
128 u8 msg_no; /* itnim/rport firmware handle */
129 u8 reqq; /* CQ for requests */
130 struct bfa_cb_qe_s hcb_qe; /* bfa callback qelem */
131 struct list_head pending_q; /* queue of pending IO requests*/
132 struct list_head io_q; /* queue of active IO requests */
133 struct list_head io_cleanup_q; /* IO being cleaned up */
134 struct list_head tsk_q; /* queue of active TM commands */
135 struct list_head delay_comp_q;/* queue of failed inflight cmds */
136 bfa_boolean_t seq_rec; /* SQER supported */
137 bfa_boolean_t is_online; /* itnim is ONLINE for IO */
138 bfa_boolean_t iotov_active; /* IO TOV timer is active */
139 struct bfa_wc_s wc; /* waiting counter */
140 struct bfa_timer_s timer; /* pending IO TOV */
141 struct bfa_reqq_wait_s reqq_wait; /* to wait for room in reqq */
142 struct bfa_fcpim_mod_s *fcpim; /* fcpim module */
143 struct bfa_itnim_hal_stats_s stats;
144};
145
146#define bfa_itnim_is_online(_itnim) (_itnim)->is_online
147#define BFA_FCPIM_MOD(_hal) (&(_hal)->modules.fcpim_mod)
148#define BFA_IOIM_FROM_TAG(_fcpim, _iotag) \
149 (&fcpim->ioim_arr[_iotag])
150#define BFA_TSKIM_FROM_TAG(_fcpim, _tmtag) \
151 (&fcpim->tskim_arr[_tmtag & (fcpim->num_tskim_reqs - 1)])
152
153/*
154 * function prototypes
155 */
156void bfa_ioim_attach(struct bfa_fcpim_mod_s *fcpim,
157 struct bfa_meminfo_s *minfo);
158void bfa_ioim_detach(struct bfa_fcpim_mod_s *fcpim);
159void bfa_ioim_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
160void bfa_ioim_good_comp_isr(struct bfa_s *bfa,
161 struct bfi_msg_s *msg);
162void bfa_ioim_cleanup(struct bfa_ioim_s *ioim);
163void bfa_ioim_cleanup_tm(struct bfa_ioim_s *ioim,
164 struct bfa_tskim_s *tskim);
165void bfa_ioim_iocdisable(struct bfa_ioim_s *ioim);
166void bfa_ioim_tov(struct bfa_ioim_s *ioim);
167
168void bfa_tskim_attach(struct bfa_fcpim_mod_s *fcpim,
169 struct bfa_meminfo_s *minfo);
170void bfa_tskim_detach(struct bfa_fcpim_mod_s *fcpim);
171void bfa_tskim_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
172void bfa_tskim_iodone(struct bfa_tskim_s *tskim);
173void bfa_tskim_iocdisable(struct bfa_tskim_s *tskim);
174void bfa_tskim_cleanup(struct bfa_tskim_s *tskim);
175
176void bfa_itnim_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len,
177 u32 *dm_len);
178void bfa_itnim_attach(struct bfa_fcpim_mod_s *fcpim,
179 struct bfa_meminfo_s *minfo);
180void bfa_itnim_detach(struct bfa_fcpim_mod_s *fcpim);
181void bfa_itnim_iocdisable(struct bfa_itnim_s *itnim);
182void bfa_itnim_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
183void bfa_itnim_iodone(struct bfa_itnim_s *itnim);
184void bfa_itnim_tskdone(struct bfa_itnim_s *itnim);
185bfa_boolean_t bfa_itnim_hold_io(struct bfa_itnim_s *itnim);
186
187#endif /* __BFA_FCPIM_PRIV_H__ */
188
diff --git a/drivers/scsi/bfa/bfa_fcport.c b/drivers/scsi/bfa/bfa_fcport.c
new file mode 100644
index 000000000000..992435987deb
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_fcport.c
@@ -0,0 +1,1671 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#include <bfa.h>
19#include <bfa_svc.h>
20#include <bfi/bfi_pport.h>
21#include <cs/bfa_debug.h>
22#include <aen/bfa_aen.h>
23#include <cs/bfa_plog.h>
24#include <aen/bfa_aen_port.h>
25
26BFA_TRC_FILE(HAL, PPORT);
27BFA_MODULE(pport);
28
29#define bfa_pport_callback(__pport, __event) do { \
30 if ((__pport)->bfa->fcs) { \
31 (__pport)->event_cbfn((__pport)->event_cbarg, (__event)); \
32 } else { \
33 (__pport)->hcb_event = (__event); \
34 bfa_cb_queue((__pport)->bfa, &(__pport)->hcb_qe, \
35 __bfa_cb_port_event, (__pport)); \
36 } \
37} while (0)
38
39/*
40 * The port is considered disabled if corresponding physical port or IOC are
41 * disabled explicitly
42 */
43#define BFA_PORT_IS_DISABLED(bfa) \
44 ((bfa_pport_is_disabled(bfa) == BFA_TRUE) || \
45 (bfa_ioc_is_disabled(&bfa->ioc) == BFA_TRUE))
46
47/*
48 * forward declarations
49 */
50static bfa_boolean_t bfa_pport_send_enable(struct bfa_pport_s *port);
51static bfa_boolean_t bfa_pport_send_disable(struct bfa_pport_s *port);
52static void bfa_pport_update_linkinfo(struct bfa_pport_s *pport);
53static void bfa_pport_reset_linkinfo(struct bfa_pport_s *pport);
54static void bfa_pport_set_wwns(struct bfa_pport_s *port);
55static void __bfa_cb_port_event(void *cbarg, bfa_boolean_t complete);
56static void __bfa_cb_port_stats(void *cbarg, bfa_boolean_t complete);
57static void __bfa_cb_port_stats_clr(void *cbarg, bfa_boolean_t complete);
58static void bfa_port_stats_timeout(void *cbarg);
59static void bfa_port_stats_clr_timeout(void *cbarg);
60
61/**
62 * bfa_pport_private
63 */
64
65/**
66 * BFA port state machine events
67 */
68enum bfa_pport_sm_event {
69 BFA_PPORT_SM_START = 1, /* start port state machine */
70 BFA_PPORT_SM_STOP = 2, /* stop port state machine */
71 BFA_PPORT_SM_ENABLE = 3, /* enable port */
72 BFA_PPORT_SM_DISABLE = 4, /* disable port state machine */
73 BFA_PPORT_SM_FWRSP = 5, /* firmware enable/disable rsp */
74 BFA_PPORT_SM_LINKUP = 6, /* firmware linkup event */
75 BFA_PPORT_SM_LINKDOWN = 7, /* firmware linkup down */
76 BFA_PPORT_SM_QRESUME = 8, /* CQ space available */
77 BFA_PPORT_SM_HWFAIL = 9, /* IOC h/w failure */
78};
79
80static void bfa_pport_sm_uninit(struct bfa_pport_s *pport,
81 enum bfa_pport_sm_event event);
82static void bfa_pport_sm_enabling_qwait(struct bfa_pport_s *pport,
83 enum bfa_pport_sm_event event);
84static void bfa_pport_sm_enabling(struct bfa_pport_s *pport,
85 enum bfa_pport_sm_event event);
86static void bfa_pport_sm_linkdown(struct bfa_pport_s *pport,
87 enum bfa_pport_sm_event event);
88static void bfa_pport_sm_linkup(struct bfa_pport_s *pport,
89 enum bfa_pport_sm_event event);
90static void bfa_pport_sm_disabling(struct bfa_pport_s *pport,
91 enum bfa_pport_sm_event event);
92static void bfa_pport_sm_disabling_qwait(struct bfa_pport_s *pport,
93 enum bfa_pport_sm_event event);
94static void bfa_pport_sm_disabled(struct bfa_pport_s *pport,
95 enum bfa_pport_sm_event event);
96static void bfa_pport_sm_stopped(struct bfa_pport_s *pport,
97 enum bfa_pport_sm_event event);
98static void bfa_pport_sm_iocdown(struct bfa_pport_s *pport,
99 enum bfa_pport_sm_event event);
100static void bfa_pport_sm_iocfail(struct bfa_pport_s *pport,
101 enum bfa_pport_sm_event event);
102
103static struct bfa_sm_table_s hal_pport_sm_table[] = {
104 {BFA_SM(bfa_pport_sm_uninit), BFA_PPORT_ST_UNINIT},
105 {BFA_SM(bfa_pport_sm_enabling_qwait), BFA_PPORT_ST_ENABLING_QWAIT},
106 {BFA_SM(bfa_pport_sm_enabling), BFA_PPORT_ST_ENABLING},
107 {BFA_SM(bfa_pport_sm_linkdown), BFA_PPORT_ST_LINKDOWN},
108 {BFA_SM(bfa_pport_sm_linkup), BFA_PPORT_ST_LINKUP},
109 {BFA_SM(bfa_pport_sm_disabling_qwait),
110 BFA_PPORT_ST_DISABLING_QWAIT},
111 {BFA_SM(bfa_pport_sm_disabling), BFA_PPORT_ST_DISABLING},
112 {BFA_SM(bfa_pport_sm_disabled), BFA_PPORT_ST_DISABLED},
113 {BFA_SM(bfa_pport_sm_stopped), BFA_PPORT_ST_STOPPED},
114 {BFA_SM(bfa_pport_sm_iocdown), BFA_PPORT_ST_IOCDOWN},
115 {BFA_SM(bfa_pport_sm_iocfail), BFA_PPORT_ST_IOCDOWN},
116};
117
118static void
119bfa_pport_aen_post(struct bfa_pport_s *pport, enum bfa_port_aen_event event)
120{
121 union bfa_aen_data_u aen_data;
122 struct bfa_log_mod_s *logmod = pport->bfa->logm;
123 wwn_t pwwn = pport->pwwn;
124 char pwwn_ptr[BFA_STRING_32];
125 struct bfa_ioc_attr_s ioc_attr;
126
127 wwn2str(pwwn_ptr, pwwn);
128 switch (event) {
129 case BFA_PORT_AEN_ONLINE:
130 bfa_log(logmod, BFA_AEN_PORT_ONLINE, pwwn_ptr);
131 break;
132 case BFA_PORT_AEN_OFFLINE:
133 bfa_log(logmod, BFA_AEN_PORT_OFFLINE, pwwn_ptr);
134 break;
135 case BFA_PORT_AEN_ENABLE:
136 bfa_log(logmod, BFA_AEN_PORT_ENABLE, pwwn_ptr);
137 break;
138 case BFA_PORT_AEN_DISABLE:
139 bfa_log(logmod, BFA_AEN_PORT_DISABLE, pwwn_ptr);
140 break;
141 case BFA_PORT_AEN_DISCONNECT:
142 bfa_log(logmod, BFA_AEN_PORT_DISCONNECT, pwwn_ptr);
143 break;
144 case BFA_PORT_AEN_QOS_NEG:
145 bfa_log(logmod, BFA_AEN_PORT_QOS_NEG, pwwn_ptr);
146 break;
147 default:
148 break;
149 }
150
151 bfa_ioc_get_attr(&pport->bfa->ioc, &ioc_attr);
152 aen_data.port.ioc_type = ioc_attr.ioc_type;
153 aen_data.port.pwwn = pwwn;
154}
155
156static void
157bfa_pport_sm_uninit(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
158{
159 bfa_trc(pport->bfa, event);
160
161 switch (event) {
162 case BFA_PPORT_SM_START:
163 /**
164 * Start event after IOC is configured and BFA is started.
165 */
166 if (bfa_pport_send_enable(pport))
167 bfa_sm_set_state(pport, bfa_pport_sm_enabling);
168 else
169 bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait);
170 break;
171
172 case BFA_PPORT_SM_ENABLE:
173 /**
174 * Port is persistently configured to be in enabled state. Do
175 * not change state. Port enabling is done when START event is
176 * received.
177 */
178 break;
179
180 case BFA_PPORT_SM_DISABLE:
181 /**
182 * If a port is persistently configured to be disabled, the
183 * first event will a port disable request.
184 */
185 bfa_sm_set_state(pport, bfa_pport_sm_disabled);
186 break;
187
188 case BFA_PPORT_SM_HWFAIL:
189 bfa_sm_set_state(pport, bfa_pport_sm_iocdown);
190 break;
191
192 default:
193 bfa_sm_fault(pport->bfa, event);
194 }
195}
196
197static void
198bfa_pport_sm_enabling_qwait(struct bfa_pport_s *pport,
199 enum bfa_pport_sm_event event)
200{
201 bfa_trc(pport->bfa, event);
202
203 switch (event) {
204 case BFA_PPORT_SM_QRESUME:
205 bfa_sm_set_state(pport, bfa_pport_sm_enabling);
206 bfa_pport_send_enable(pport);
207 break;
208
209 case BFA_PPORT_SM_STOP:
210 bfa_reqq_wcancel(&pport->reqq_wait);
211 bfa_sm_set_state(pport, bfa_pport_sm_stopped);
212 break;
213
214 case BFA_PPORT_SM_ENABLE:
215 /**
216 * Already enable is in progress.
217 */
218 break;
219
220 case BFA_PPORT_SM_DISABLE:
221 /**
222 * Just send disable request to firmware when room becomes
223 * available in request queue.
224 */
225 bfa_sm_set_state(pport, bfa_pport_sm_disabled);
226 bfa_reqq_wcancel(&pport->reqq_wait);
227 bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
228 BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
229 bfa_pport_aen_post(pport, BFA_PORT_AEN_DISABLE);
230 break;
231
232 case BFA_PPORT_SM_LINKUP:
233 case BFA_PPORT_SM_LINKDOWN:
234 /**
235 * Possible to get link events when doing back-to-back
236 * enable/disables.
237 */
238 break;
239
240 case BFA_PPORT_SM_HWFAIL:
241 bfa_reqq_wcancel(&pport->reqq_wait);
242 bfa_sm_set_state(pport, bfa_pport_sm_iocdown);
243 break;
244
245 default:
246 bfa_sm_fault(pport->bfa, event);
247 }
248}
249
250static void
251bfa_pport_sm_enabling(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
252{
253 bfa_trc(pport->bfa, event);
254
255 switch (event) {
256 case BFA_PPORT_SM_FWRSP:
257 case BFA_PPORT_SM_LINKDOWN:
258 bfa_sm_set_state(pport, bfa_pport_sm_linkdown);
259 break;
260
261 case BFA_PPORT_SM_LINKUP:
262 bfa_pport_update_linkinfo(pport);
263 bfa_sm_set_state(pport, bfa_pport_sm_linkup);
264
265 bfa_assert(pport->event_cbfn);
266 bfa_pport_callback(pport, BFA_PPORT_LINKUP);
267 break;
268
269 case BFA_PPORT_SM_ENABLE:
270 /**
271 * Already being enabled.
272 */
273 break;
274
275 case BFA_PPORT_SM_DISABLE:
276 if (bfa_pport_send_disable(pport))
277 bfa_sm_set_state(pport, bfa_pport_sm_disabling);
278 else
279 bfa_sm_set_state(pport, bfa_pport_sm_disabling_qwait);
280
281 bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
282 BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
283 bfa_pport_aen_post(pport, BFA_PORT_AEN_DISABLE);
284 break;
285
286 case BFA_PPORT_SM_STOP:
287 bfa_sm_set_state(pport, bfa_pport_sm_stopped);
288 break;
289
290 case BFA_PPORT_SM_HWFAIL:
291 bfa_sm_set_state(pport, bfa_pport_sm_iocdown);
292 break;
293
294 default:
295 bfa_sm_fault(pport->bfa, event);
296 }
297}
298
299static void
300bfa_pport_sm_linkdown(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
301{
302 bfa_trc(pport->bfa, event);
303
304 switch (event) {
305 case BFA_PPORT_SM_LINKUP:
306 bfa_pport_update_linkinfo(pport);
307 bfa_sm_set_state(pport, bfa_pport_sm_linkup);
308 bfa_assert(pport->event_cbfn);
309 bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
310 BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkup");
311 bfa_pport_callback(pport, BFA_PPORT_LINKUP);
312 bfa_pport_aen_post(pport, BFA_PORT_AEN_ONLINE);
313 /**
314 * If QoS is enabled and it is not online,
315 * Send a separate event.
316 */
317 if ((pport->cfg.qos_enabled)
318 && (bfa_os_ntohl(pport->qos_attr.state) != BFA_QOS_ONLINE))
319 bfa_pport_aen_post(pport, BFA_PORT_AEN_QOS_NEG);
320
321 break;
322
323 case BFA_PPORT_SM_LINKDOWN:
324 /**
325 * Possible to get link down event.
326 */
327 break;
328
329 case BFA_PPORT_SM_ENABLE:
330 /**
331 * Already enabled.
332 */
333 break;
334
335 case BFA_PPORT_SM_DISABLE:
336 if (bfa_pport_send_disable(pport))
337 bfa_sm_set_state(pport, bfa_pport_sm_disabling);
338 else
339 bfa_sm_set_state(pport, bfa_pport_sm_disabling_qwait);
340
341 bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
342 BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
343 bfa_pport_aen_post(pport, BFA_PORT_AEN_DISABLE);
344 break;
345
346 case BFA_PPORT_SM_STOP:
347 bfa_sm_set_state(pport, bfa_pport_sm_stopped);
348 break;
349
350 case BFA_PPORT_SM_HWFAIL:
351 bfa_sm_set_state(pport, bfa_pport_sm_iocdown);
352 break;
353
354 default:
355 bfa_sm_fault(pport->bfa, event);
356 }
357}
358
359static void
360bfa_pport_sm_linkup(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
361{
362 bfa_trc(pport->bfa, event);
363
364 switch (event) {
365 case BFA_PPORT_SM_ENABLE:
366 /**
367 * Already enabled.
368 */
369 break;
370
371 case BFA_PPORT_SM_DISABLE:
372 if (bfa_pport_send_disable(pport))
373 bfa_sm_set_state(pport, bfa_pport_sm_disabling);
374 else
375 bfa_sm_set_state(pport, bfa_pport_sm_disabling_qwait);
376
377 bfa_pport_reset_linkinfo(pport);
378 bfa_pport_callback(pport, BFA_PPORT_LINKDOWN);
379 bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
380 BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
381 bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE);
382 bfa_pport_aen_post(pport, BFA_PORT_AEN_DISABLE);
383 break;
384
385 case BFA_PPORT_SM_LINKDOWN:
386 bfa_sm_set_state(pport, bfa_pport_sm_linkdown);
387 bfa_pport_reset_linkinfo(pport);
388 bfa_pport_callback(pport, BFA_PPORT_LINKDOWN);
389 bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
390 BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkdown");
391 if (BFA_PORT_IS_DISABLED(pport->bfa)) {
392 bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE);
393 } else {
394 bfa_pport_aen_post(pport, BFA_PORT_AEN_DISCONNECT);
395 }
396 break;
397
398 case BFA_PPORT_SM_STOP:
399 bfa_sm_set_state(pport, bfa_pport_sm_stopped);
400 bfa_pport_reset_linkinfo(pport);
401 if (BFA_PORT_IS_DISABLED(pport->bfa)) {
402 bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE);
403 } else {
404 bfa_pport_aen_post(pport, BFA_PORT_AEN_DISCONNECT);
405 }
406 break;
407
408 case BFA_PPORT_SM_HWFAIL:
409 bfa_sm_set_state(pport, bfa_pport_sm_iocdown);
410 bfa_pport_reset_linkinfo(pport);
411 bfa_pport_callback(pport, BFA_PPORT_LINKDOWN);
412 if (BFA_PORT_IS_DISABLED(pport->bfa)) {
413 bfa_pport_aen_post(pport, BFA_PORT_AEN_OFFLINE);
414 } else {
415 bfa_pport_aen_post(pport, BFA_PORT_AEN_DISCONNECT);
416 }
417 break;
418
419 default:
420 bfa_sm_fault(pport->bfa, event);
421 }
422}
423
424static void
425bfa_pport_sm_disabling_qwait(struct bfa_pport_s *pport,
426 enum bfa_pport_sm_event event)
427{
428 bfa_trc(pport->bfa, event);
429
430 switch (event) {
431 case BFA_PPORT_SM_QRESUME:
432 bfa_sm_set_state(pport, bfa_pport_sm_disabling);
433 bfa_pport_send_disable(pport);
434 break;
435
436 case BFA_PPORT_SM_STOP:
437 bfa_sm_set_state(pport, bfa_pport_sm_stopped);
438 bfa_reqq_wcancel(&pport->reqq_wait);
439 break;
440
441 case BFA_PPORT_SM_DISABLE:
442 /**
443 * Already being disabled.
444 */
445 break;
446
447 case BFA_PPORT_SM_LINKUP:
448 case BFA_PPORT_SM_LINKDOWN:
449 /**
450 * Possible to get link events when doing back-to-back
451 * enable/disables.
452 */
453 break;
454
455 case BFA_PPORT_SM_HWFAIL:
456 bfa_sm_set_state(pport, bfa_pport_sm_iocfail);
457 bfa_reqq_wcancel(&pport->reqq_wait);
458 break;
459
460 default:
461 bfa_sm_fault(pport->bfa, event);
462 }
463}
464
465static void
466bfa_pport_sm_disabling(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
467{
468 bfa_trc(pport->bfa, event);
469
470 switch (event) {
471 case BFA_PPORT_SM_FWRSP:
472 bfa_sm_set_state(pport, bfa_pport_sm_disabled);
473 break;
474
475 case BFA_PPORT_SM_DISABLE:
476 /**
477 * Already being disabled.
478 */
479 break;
480
481 case BFA_PPORT_SM_ENABLE:
482 if (bfa_pport_send_enable(pport))
483 bfa_sm_set_state(pport, bfa_pport_sm_enabling);
484 else
485 bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait);
486
487 bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
488 BFA_PL_EID_PORT_ENABLE, 0, "Port Enable");
489 bfa_pport_aen_post(pport, BFA_PORT_AEN_ENABLE);
490 break;
491
492 case BFA_PPORT_SM_STOP:
493 bfa_sm_set_state(pport, bfa_pport_sm_stopped);
494 break;
495
496 case BFA_PPORT_SM_LINKUP:
497 case BFA_PPORT_SM_LINKDOWN:
498 /**
499 * Possible to get link events when doing back-to-back
500 * enable/disables.
501 */
502 break;
503
504 case BFA_PPORT_SM_HWFAIL:
505 bfa_sm_set_state(pport, bfa_pport_sm_iocfail);
506 break;
507
508 default:
509 bfa_sm_fault(pport->bfa, event);
510 }
511}
512
513static void
514bfa_pport_sm_disabled(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
515{
516 bfa_trc(pport->bfa, event);
517
518 switch (event) {
519 case BFA_PPORT_SM_START:
520 /**
521 * Ignore start event for a port that is disabled.
522 */
523 break;
524
525 case BFA_PPORT_SM_STOP:
526 bfa_sm_set_state(pport, bfa_pport_sm_stopped);
527 break;
528
529 case BFA_PPORT_SM_ENABLE:
530 if (bfa_pport_send_enable(pport))
531 bfa_sm_set_state(pport, bfa_pport_sm_enabling);
532 else
533 bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait);
534
535 bfa_plog_str(pport->bfa->plog, BFA_PL_MID_HAL,
536 BFA_PL_EID_PORT_ENABLE, 0, "Port Enable");
537 bfa_pport_aen_post(pport, BFA_PORT_AEN_ENABLE);
538 break;
539
540 case BFA_PPORT_SM_DISABLE:
541 /**
542 * Already disabled.
543 */
544 break;
545
546 case BFA_PPORT_SM_HWFAIL:
547 bfa_sm_set_state(pport, bfa_pport_sm_iocfail);
548 break;
549
550 default:
551 bfa_sm_fault(pport->bfa, event);
552 }
553}
554
555static void
556bfa_pport_sm_stopped(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
557{
558 bfa_trc(pport->bfa, event);
559
560 switch (event) {
561 case BFA_PPORT_SM_START:
562 if (bfa_pport_send_enable(pport))
563 bfa_sm_set_state(pport, bfa_pport_sm_enabling);
564 else
565 bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait);
566 break;
567
568 default:
569 /**
570 * Ignore all other events.
571 */
572 ;
573 }
574}
575
576/**
577 * Port is enabled. IOC is down/failed.
578 */
579static void
580bfa_pport_sm_iocdown(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
581{
582 bfa_trc(pport->bfa, event);
583
584 switch (event) {
585 case BFA_PPORT_SM_START:
586 if (bfa_pport_send_enable(pport))
587 bfa_sm_set_state(pport, bfa_pport_sm_enabling);
588 else
589 bfa_sm_set_state(pport, bfa_pport_sm_enabling_qwait);
590 break;
591
592 default:
593 /**
594 * Ignore all events.
595 */
596 ;
597 }
598}
599
600/**
601 * Port is disabled. IOC is down/failed.
602 */
603static void
604bfa_pport_sm_iocfail(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
605{
606 bfa_trc(pport->bfa, event);
607
608 switch (event) {
609 case BFA_PPORT_SM_START:
610 bfa_sm_set_state(pport, bfa_pport_sm_disabled);
611 break;
612
613 case BFA_PPORT_SM_ENABLE:
614 bfa_sm_set_state(pport, bfa_pport_sm_iocdown);
615 break;
616
617 default:
618 /**
619 * Ignore all events.
620 */
621 ;
622 }
623}
624
625
626
627/**
628 * bfa_pport_private
629 */
630
631static void
632__bfa_cb_port_event(void *cbarg, bfa_boolean_t complete)
633{
634 struct bfa_pport_s *pport = cbarg;
635
636 if (complete)
637 pport->event_cbfn(pport->event_cbarg, pport->hcb_event);
638}
639
640#define PPORT_STATS_DMA_SZ (BFA_ROUNDUP(sizeof(union bfa_pport_stats_u), \
641 BFA_CACHELINE_SZ))
642
643static void
644bfa_pport_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len,
645 u32 *dm_len)
646{
647 *dm_len += PPORT_STATS_DMA_SZ;
648}
649
650static void
651bfa_pport_qresume(void *cbarg)
652{
653 struct bfa_pport_s *port = cbarg;
654
655 bfa_sm_send_event(port, BFA_PPORT_SM_QRESUME);
656}
657
658static void
659bfa_pport_mem_claim(struct bfa_pport_s *pport, struct bfa_meminfo_s *meminfo)
660{
661 u8 *dm_kva;
662 u64 dm_pa;
663
664 dm_kva = bfa_meminfo_dma_virt(meminfo);
665 dm_pa = bfa_meminfo_dma_phys(meminfo);
666
667 pport->stats_kva = dm_kva;
668 pport->stats_pa = dm_pa;
669 pport->stats = (union bfa_pport_stats_u *)dm_kva;
670
671 dm_kva += PPORT_STATS_DMA_SZ;
672 dm_pa += PPORT_STATS_DMA_SZ;
673
674 bfa_meminfo_dma_virt(meminfo) = dm_kva;
675 bfa_meminfo_dma_phys(meminfo) = dm_pa;
676}
677
678/**
679 * Memory initialization.
680 */
681static void
682bfa_pport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
683 struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev)
684{
685 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
686 struct bfa_pport_cfg_s *port_cfg = &pport->cfg;
687
688 bfa_os_memset(pport, 0, sizeof(struct bfa_pport_s));
689 pport->bfa = bfa;
690
691 bfa_pport_mem_claim(pport, meminfo);
692
693 bfa_sm_set_state(pport, bfa_pport_sm_uninit);
694
695 /**
696 * initialize and set default configuration
697 */
698 port_cfg->topology = BFA_PPORT_TOPOLOGY_P2P;
699 port_cfg->speed = BFA_PPORT_SPEED_AUTO;
700 port_cfg->trunked = BFA_FALSE;
701 port_cfg->maxfrsize = 0;
702
703 port_cfg->trl_def_speed = BFA_PPORT_SPEED_1GBPS;
704
705 bfa_reqq_winit(&pport->reqq_wait, bfa_pport_qresume, pport);
706}
707
708static void
709bfa_pport_initdone(struct bfa_s *bfa)
710{
711 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
712
713 /**
714 * Initialize port attributes from IOC hardware data.
715 */
716 bfa_pport_set_wwns(pport);
717 if (pport->cfg.maxfrsize == 0)
718 pport->cfg.maxfrsize = bfa_ioc_maxfrsize(&bfa->ioc);
719 pport->cfg.rx_bbcredit = bfa_ioc_rx_bbcredit(&bfa->ioc);
720 pport->speed_sup = bfa_ioc_speed_sup(&bfa->ioc);
721
722 bfa_assert(pport->cfg.maxfrsize);
723 bfa_assert(pport->cfg.rx_bbcredit);
724 bfa_assert(pport->speed_sup);
725}
726
727static void
728bfa_pport_detach(struct bfa_s *bfa)
729{
730}
731
732/**
733 * Called when IOC is ready.
734 */
735static void
736bfa_pport_start(struct bfa_s *bfa)
737{
738 bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_START);
739}
740
741/**
742 * Called before IOC is stopped.
743 */
744static void
745bfa_pport_stop(struct bfa_s *bfa)
746{
747 bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_STOP);
748}
749
750/**
751 * Called when IOC failure is detected.
752 */
753static void
754bfa_pport_iocdisable(struct bfa_s *bfa)
755{
756 bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_HWFAIL);
757}
758
759static void
760bfa_pport_update_linkinfo(struct bfa_pport_s *pport)
761{
762 struct bfi_pport_event_s *pevent = pport->event_arg.i2hmsg.event;
763
764 pport->speed = pevent->link_state.speed;
765 pport->topology = pevent->link_state.topology;
766
767 if (pport->topology == BFA_PPORT_TOPOLOGY_LOOP)
768 pport->myalpa = pevent->link_state.tl.loop_info.myalpa;
769
770 /*
771 * QoS Details
772 */
773 bfa_os_assign(pport->qos_attr, pevent->link_state.qos_attr);
774 bfa_os_assign(pport->qos_vc_attr, pevent->link_state.qos_vc_attr);
775
776 bfa_trc(pport->bfa, pport->speed);
777 bfa_trc(pport->bfa, pport->topology);
778}
779
780static void
781bfa_pport_reset_linkinfo(struct bfa_pport_s *pport)
782{
783 pport->speed = BFA_PPORT_SPEED_UNKNOWN;
784 pport->topology = BFA_PPORT_TOPOLOGY_NONE;
785}
786
787/**
788 * Send port enable message to firmware.
789 */
790static bfa_boolean_t
791bfa_pport_send_enable(struct bfa_pport_s *port)
792{
793 struct bfi_pport_enable_req_s *m;
794
795 /**
796 * Increment message tag before queue check, so that responses to old
797 * requests are discarded.
798 */
799 port->msgtag++;
800
801 /**
802 * check for room in queue to send request now
803 */
804 m = bfa_reqq_next(port->bfa, BFA_REQQ_PORT);
805 if (!m) {
806 bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->reqq_wait);
807 return BFA_FALSE;
808 }
809
810 bfi_h2i_set(m->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_ENABLE_REQ,
811 bfa_lpuid(port->bfa));
812 m->nwwn = port->nwwn;
813 m->pwwn = port->pwwn;
814 m->port_cfg = port->cfg;
815 m->msgtag = port->msgtag;
816 m->port_cfg.maxfrsize = bfa_os_htons(port->cfg.maxfrsize);
817 bfa_dma_be_addr_set(m->stats_dma_addr, port->stats_pa);
818 bfa_trc(port->bfa, m->stats_dma_addr.a32.addr_lo);
819 bfa_trc(port->bfa, m->stats_dma_addr.a32.addr_hi);
820
821 /**
822 * queue I/O message to firmware
823 */
824 bfa_reqq_produce(port->bfa, BFA_REQQ_PORT);
825 return BFA_TRUE;
826}
827
828/**
829 * Send port disable message to firmware.
830 */
831static bfa_boolean_t
832bfa_pport_send_disable(struct bfa_pport_s *port)
833{
834 bfi_pport_disable_req_t *m;
835
836 /**
837 * Increment message tag before queue check, so that responses to old
838 * requests are discarded.
839 */
840 port->msgtag++;
841
842 /**
843 * check for room in queue to send request now
844 */
845 m = bfa_reqq_next(port->bfa, BFA_REQQ_PORT);
846 if (!m) {
847 bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->reqq_wait);
848 return BFA_FALSE;
849 }
850
851 bfi_h2i_set(m->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_DISABLE_REQ,
852 bfa_lpuid(port->bfa));
853 m->msgtag = port->msgtag;
854
855 /**
856 * queue I/O message to firmware
857 */
858 bfa_reqq_produce(port->bfa, BFA_REQQ_PORT);
859
860 return BFA_TRUE;
861}
862
863static void
864bfa_pport_set_wwns(struct bfa_pport_s *port)
865{
866 port->pwwn = bfa_ioc_get_pwwn(&port->bfa->ioc);
867 port->nwwn = bfa_ioc_get_nwwn(&port->bfa->ioc);
868
869 bfa_trc(port->bfa, port->pwwn);
870 bfa_trc(port->bfa, port->nwwn);
871}
872
873static void
874bfa_port_send_txcredit(void *port_cbarg)
875{
876
877 struct bfa_pport_s *port = port_cbarg;
878 struct bfi_pport_set_svc_params_req_s *m;
879
880 /**
881 * check for room in queue to send request now
882 */
883 m = bfa_reqq_next(port->bfa, BFA_REQQ_PORT);
884 if (!m) {
885 bfa_trc(port->bfa, port->cfg.tx_bbcredit);
886 return;
887 }
888
889 bfi_h2i_set(m->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_SET_SVC_PARAMS_REQ,
890 bfa_lpuid(port->bfa));
891 m->tx_bbcredit = bfa_os_htons((u16) port->cfg.tx_bbcredit);
892
893 /**
894 * queue I/O message to firmware
895 */
896 bfa_reqq_produce(port->bfa, BFA_REQQ_PORT);
897}
898
899
900
901/**
902 * bfa_pport_public
903 */
904
905/**
906 * Firmware message handler.
907 */
908void
909bfa_pport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
910{
911 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
912 union bfi_pport_i2h_msg_u i2hmsg;
913
914 i2hmsg.msg = msg;
915 pport->event_arg.i2hmsg = i2hmsg;
916
917 switch (msg->mhdr.msg_id) {
918 case BFI_PPORT_I2H_ENABLE_RSP:
919 if (pport->msgtag == i2hmsg.enable_rsp->msgtag)
920 bfa_sm_send_event(pport, BFA_PPORT_SM_FWRSP);
921 break;
922
923 case BFI_PPORT_I2H_DISABLE_RSP:
924 if (pport->msgtag == i2hmsg.enable_rsp->msgtag)
925 bfa_sm_send_event(pport, BFA_PPORT_SM_FWRSP);
926 break;
927
928 case BFI_PPORT_I2H_EVENT:
929 switch (i2hmsg.event->link_state.linkstate) {
930 case BFA_PPORT_LINKUP:
931 bfa_sm_send_event(pport, BFA_PPORT_SM_LINKUP);
932 break;
933 case BFA_PPORT_LINKDOWN:
934 bfa_sm_send_event(pport, BFA_PPORT_SM_LINKDOWN);
935 break;
936 case BFA_PPORT_TRUNK_LINKDOWN:
937 /** todo: event notification */
938 break;
939 }
940 break;
941
942 case BFI_PPORT_I2H_GET_STATS_RSP:
943 case BFI_PPORT_I2H_GET_QOS_STATS_RSP:
944 /*
945 * check for timer pop before processing the rsp
946 */
947 if (pport->stats_busy == BFA_FALSE
948 || pport->stats_status == BFA_STATUS_ETIMER)
949 break;
950
951 bfa_timer_stop(&pport->timer);
952 pport->stats_status = i2hmsg.getstats_rsp->status;
953 bfa_cb_queue(pport->bfa, &pport->hcb_qe, __bfa_cb_port_stats,
954 pport);
955 break;
956 case BFI_PPORT_I2H_CLEAR_STATS_RSP:
957 case BFI_PPORT_I2H_CLEAR_QOS_STATS_RSP:
958 /*
959 * check for timer pop before processing the rsp
960 */
961 if (pport->stats_busy == BFA_FALSE
962 || pport->stats_status == BFA_STATUS_ETIMER)
963 break;
964
965 bfa_timer_stop(&pport->timer);
966 pport->stats_status = BFA_STATUS_OK;
967 bfa_cb_queue(pport->bfa, &pport->hcb_qe,
968 __bfa_cb_port_stats_clr, pport);
969 break;
970
971 default:
972 bfa_assert(0);
973 }
974}
975
976
977
978/**
979 * bfa_pport_api
980 */
981
982/**
983 * Registered callback for port events.
984 */
985void
986bfa_pport_event_register(struct bfa_s *bfa,
987 void (*cbfn) (void *cbarg, bfa_pport_event_t event),
988 void *cbarg)
989{
990 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
991
992 pport->event_cbfn = cbfn;
993 pport->event_cbarg = cbarg;
994}
995
996bfa_status_t
997bfa_pport_enable(struct bfa_s *bfa)
998{
999 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1000
1001 if (pport->diag_busy)
1002 return (BFA_STATUS_DIAG_BUSY);
1003 else if (bfa_sm_cmp_state
1004 (BFA_PORT_MOD(bfa), bfa_pport_sm_disabling_qwait))
1005 return (BFA_STATUS_DEVBUSY);
1006
1007 bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_ENABLE);
1008 return BFA_STATUS_OK;
1009}
1010
1011bfa_status_t
1012bfa_pport_disable(struct bfa_s *bfa)
1013{
1014 bfa_sm_send_event(BFA_PORT_MOD(bfa), BFA_PPORT_SM_DISABLE);
1015 return BFA_STATUS_OK;
1016}
1017
1018/**
1019 * Configure port speed.
1020 */
1021bfa_status_t
1022bfa_pport_cfg_speed(struct bfa_s *bfa, enum bfa_pport_speed speed)
1023{
1024 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1025
1026 bfa_trc(bfa, speed);
1027
1028 if ((speed != BFA_PPORT_SPEED_AUTO) && (speed > pport->speed_sup)) {
1029 bfa_trc(bfa, pport->speed_sup);
1030 return BFA_STATUS_UNSUPP_SPEED;
1031 }
1032
1033 pport->cfg.speed = speed;
1034
1035 return (BFA_STATUS_OK);
1036}
1037
1038/**
1039 * Get current speed.
1040 */
1041enum bfa_pport_speed
1042bfa_pport_get_speed(struct bfa_s *bfa)
1043{
1044 struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
1045
1046 return port->speed;
1047}
1048
1049/**
1050 * Configure port topology.
1051 */
1052bfa_status_t
1053bfa_pport_cfg_topology(struct bfa_s *bfa, enum bfa_pport_topology topology)
1054{
1055 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1056
1057 bfa_trc(bfa, topology);
1058 bfa_trc(bfa, pport->cfg.topology);
1059
1060 switch (topology) {
1061 case BFA_PPORT_TOPOLOGY_P2P:
1062 case BFA_PPORT_TOPOLOGY_LOOP:
1063 case BFA_PPORT_TOPOLOGY_AUTO:
1064 break;
1065
1066 default:
1067 return BFA_STATUS_EINVAL;
1068 }
1069
1070 pport->cfg.topology = topology;
1071 return (BFA_STATUS_OK);
1072}
1073
1074/**
1075 * Get current topology.
1076 */
1077enum bfa_pport_topology
1078bfa_pport_get_topology(struct bfa_s *bfa)
1079{
1080 struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
1081
1082 return port->topology;
1083}
1084
1085bfa_status_t
1086bfa_pport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa)
1087{
1088 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1089
1090 bfa_trc(bfa, alpa);
1091 bfa_trc(bfa, pport->cfg.cfg_hardalpa);
1092 bfa_trc(bfa, pport->cfg.hardalpa);
1093
1094 pport->cfg.cfg_hardalpa = BFA_TRUE;
1095 pport->cfg.hardalpa = alpa;
1096
1097 return (BFA_STATUS_OK);
1098}
1099
1100bfa_status_t
1101bfa_pport_clr_hardalpa(struct bfa_s *bfa)
1102{
1103 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1104
1105 bfa_trc(bfa, pport->cfg.cfg_hardalpa);
1106 bfa_trc(bfa, pport->cfg.hardalpa);
1107
1108 pport->cfg.cfg_hardalpa = BFA_FALSE;
1109 return (BFA_STATUS_OK);
1110}
1111
1112bfa_boolean_t
1113bfa_pport_get_hardalpa(struct bfa_s *bfa, u8 *alpa)
1114{
1115 struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
1116
1117 *alpa = port->cfg.hardalpa;
1118 return port->cfg.cfg_hardalpa;
1119}
1120
1121u8
1122bfa_pport_get_myalpa(struct bfa_s *bfa)
1123{
1124 struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
1125
1126 return port->myalpa;
1127}
1128
1129bfa_status_t
1130bfa_pport_cfg_maxfrsize(struct bfa_s *bfa, u16 maxfrsize)
1131{
1132 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1133
1134 bfa_trc(bfa, maxfrsize);
1135 bfa_trc(bfa, pport->cfg.maxfrsize);
1136
1137 /*
1138 * with in range
1139 */
1140 if ((maxfrsize > FC_MAX_PDUSZ) || (maxfrsize < FC_MIN_PDUSZ))
1141 return (BFA_STATUS_INVLD_DFSZ);
1142
1143 /*
1144 * power of 2, if not the max frame size of 2112
1145 */
1146 if ((maxfrsize != FC_MAX_PDUSZ) && (maxfrsize & (maxfrsize - 1)))
1147 return (BFA_STATUS_INVLD_DFSZ);
1148
1149 pport->cfg.maxfrsize = maxfrsize;
1150 return (BFA_STATUS_OK);
1151}
1152
1153u16
1154bfa_pport_get_maxfrsize(struct bfa_s *bfa)
1155{
1156 struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
1157
1158 return port->cfg.maxfrsize;
1159}
1160
1161u32
1162bfa_pport_mypid(struct bfa_s *bfa)
1163{
1164 struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
1165
1166 return port->mypid;
1167}
1168
1169u8
1170bfa_pport_get_rx_bbcredit(struct bfa_s *bfa)
1171{
1172 struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
1173
1174 return port->cfg.rx_bbcredit;
1175}
1176
1177void
1178bfa_pport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit)
1179{
1180 struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
1181
1182 port->cfg.tx_bbcredit = (u8) tx_bbcredit;
1183 bfa_port_send_txcredit(port);
1184}
1185
1186/**
1187 * Get port attributes.
1188 */
1189
1190wwn_t
1191bfa_pport_get_wwn(struct bfa_s *bfa, bfa_boolean_t node)
1192{
1193 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1194 if (node)
1195 return pport->nwwn;
1196 else
1197 return pport->pwwn;
1198}
1199
1200void
1201bfa_pport_get_attr(struct bfa_s *bfa, struct bfa_pport_attr_s *attr)
1202{
1203 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1204
1205 bfa_os_memset(attr, 0, sizeof(struct bfa_pport_attr_s));
1206
1207 attr->nwwn = pport->nwwn;
1208 attr->pwwn = pport->pwwn;
1209
1210 bfa_os_memcpy(&attr->pport_cfg, &pport->cfg,
1211 sizeof(struct bfa_pport_cfg_s));
1212 /*
1213 * speed attributes
1214 */
1215 attr->pport_cfg.speed = pport->cfg.speed;
1216 attr->speed_supported = pport->speed_sup;
1217 attr->speed = pport->speed;
1218 attr->cos_supported = FC_CLASS_3;
1219
1220 /*
1221 * topology attributes
1222 */
1223 attr->pport_cfg.topology = pport->cfg.topology;
1224 attr->topology = pport->topology;
1225
1226 /*
1227 * beacon attributes
1228 */
1229 attr->beacon = pport->beacon;
1230 attr->link_e2e_beacon = pport->link_e2e_beacon;
1231 attr->plog_enabled = bfa_plog_get_setting(pport->bfa->plog);
1232
1233 attr->pport_cfg.path_tov = bfa_fcpim_path_tov_get(bfa);
1234 attr->pport_cfg.q_depth = bfa_fcpim_qdepth_get(bfa);
1235 attr->port_state = bfa_sm_to_state(hal_pport_sm_table, pport->sm);
1236 if (bfa_ioc_is_disabled(&pport->bfa->ioc))
1237 attr->port_state = BFA_PPORT_ST_IOCDIS;
1238 else if (bfa_ioc_fw_mismatch(&pport->bfa->ioc))
1239 attr->port_state = BFA_PPORT_ST_FWMISMATCH;
1240}
1241
1242static void
1243bfa_port_stats_query(void *cbarg)
1244{
1245 struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg;
1246 bfi_pport_get_stats_req_t *msg;
1247
1248 msg = bfa_reqq_next(port->bfa, BFA_REQQ_PORT);
1249
1250 if (!msg) {
1251 port->stats_qfull = BFA_TRUE;
1252 bfa_reqq_winit(&port->stats_reqq_wait, bfa_port_stats_query,
1253 port);
1254 bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->stats_reqq_wait);
1255 return;
1256 }
1257 port->stats_qfull = BFA_FALSE;
1258
1259 bfa_os_memset(msg, 0, sizeof(bfi_pport_get_stats_req_t));
1260 bfi_h2i_set(msg->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_GET_STATS_REQ,
1261 bfa_lpuid(port->bfa));
1262 bfa_reqq_produce(port->bfa, BFA_REQQ_PORT);
1263
1264 return;
1265}
1266
1267static void
1268bfa_port_stats_clear(void *cbarg)
1269{
1270 struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg;
1271 bfi_pport_clear_stats_req_t *msg;
1272
1273 msg = bfa_reqq_next(port->bfa, BFA_REQQ_PORT);
1274
1275 if (!msg) {
1276 port->stats_qfull = BFA_TRUE;
1277 bfa_reqq_winit(&port->stats_reqq_wait, bfa_port_stats_clear,
1278 port);
1279 bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->stats_reqq_wait);
1280 return;
1281 }
1282 port->stats_qfull = BFA_FALSE;
1283
1284 bfa_os_memset(msg, 0, sizeof(bfi_pport_clear_stats_req_t));
1285 bfi_h2i_set(msg->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_CLEAR_STATS_REQ,
1286 bfa_lpuid(port->bfa));
1287 bfa_reqq_produce(port->bfa, BFA_REQQ_PORT);
1288 return;
1289}
1290
1291static void
1292bfa_port_qos_stats_clear(void *cbarg)
1293{
1294 struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg;
1295 bfi_pport_clear_qos_stats_req_t *msg;
1296
1297 msg = bfa_reqq_next(port->bfa, BFA_REQQ_PORT);
1298
1299 if (!msg) {
1300 port->stats_qfull = BFA_TRUE;
1301 bfa_reqq_winit(&port->stats_reqq_wait, bfa_port_qos_stats_clear,
1302 port);
1303 bfa_reqq_wait(port->bfa, BFA_REQQ_PORT, &port->stats_reqq_wait);
1304 return;
1305 }
1306 port->stats_qfull = BFA_FALSE;
1307
1308 bfa_os_memset(msg, 0, sizeof(bfi_pport_clear_qos_stats_req_t));
1309 bfi_h2i_set(msg->mh, BFI_MC_FC_PORT, BFI_PPORT_H2I_CLEAR_QOS_STATS_REQ,
1310 bfa_lpuid(port->bfa));
1311 bfa_reqq_produce(port->bfa, BFA_REQQ_PORT);
1312 return;
1313}
1314
1315static void
1316bfa_pport_stats_swap(union bfa_pport_stats_u *d, union bfa_pport_stats_u *s)
1317{
1318 u32 *dip = (u32 *) d;
1319 u32 *sip = (u32 *) s;
1320 int i;
1321
1322 /*
1323 * Do 64 bit fields swap first
1324 */
1325 for (i = 0;
1326 i <
1327 ((sizeof(union bfa_pport_stats_u) -
1328 sizeof(struct bfa_qos_stats_s)) / sizeof(u32)); i = i + 2) {
1329#ifdef __BIGENDIAN
1330 dip[i] = bfa_os_ntohl(sip[i]);
1331 dip[i + 1] = bfa_os_ntohl(sip[i + 1]);
1332#else
1333 dip[i] = bfa_os_ntohl(sip[i + 1]);
1334 dip[i + 1] = bfa_os_ntohl(sip[i]);
1335#endif
1336 }
1337
1338 /*
1339 * Now swap the 32 bit fields
1340 */
1341 for (; i < (sizeof(union bfa_pport_stats_u) / sizeof(u32)); ++i)
1342 dip[i] = bfa_os_ntohl(sip[i]);
1343}
1344
1345static void
1346__bfa_cb_port_stats_clr(void *cbarg, bfa_boolean_t complete)
1347{
1348 struct bfa_pport_s *port = cbarg;
1349
1350 if (complete) {
1351 port->stats_cbfn(port->stats_cbarg, port->stats_status);
1352 } else {
1353 port->stats_busy = BFA_FALSE;
1354 port->stats_status = BFA_STATUS_OK;
1355 }
1356}
1357
1358static void
1359bfa_port_stats_clr_timeout(void *cbarg)
1360{
1361 struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg;
1362
1363 bfa_trc(port->bfa, port->stats_qfull);
1364
1365 if (port->stats_qfull) {
1366 bfa_reqq_wcancel(&port->stats_reqq_wait);
1367 port->stats_qfull = BFA_FALSE;
1368 }
1369
1370 port->stats_status = BFA_STATUS_ETIMER;
1371 bfa_cb_queue(port->bfa, &port->hcb_qe, __bfa_cb_port_stats_clr, port);
1372}
1373
1374static void
1375__bfa_cb_port_stats(void *cbarg, bfa_boolean_t complete)
1376{
1377 struct bfa_pport_s *port = cbarg;
1378
1379 if (complete) {
1380 if (port->stats_status == BFA_STATUS_OK)
1381 bfa_pport_stats_swap(port->stats_ret, port->stats);
1382 port->stats_cbfn(port->stats_cbarg, port->stats_status);
1383 } else {
1384 port->stats_busy = BFA_FALSE;
1385 port->stats_status = BFA_STATUS_OK;
1386 }
1387}
1388
1389static void
1390bfa_port_stats_timeout(void *cbarg)
1391{
1392 struct bfa_pport_s *port = (struct bfa_pport_s *)cbarg;
1393
1394 bfa_trc(port->bfa, port->stats_qfull);
1395
1396 if (port->stats_qfull) {
1397 bfa_reqq_wcancel(&port->stats_reqq_wait);
1398 port->stats_qfull = BFA_FALSE;
1399 }
1400
1401 port->stats_status = BFA_STATUS_ETIMER;
1402 bfa_cb_queue(port->bfa, &port->hcb_qe, __bfa_cb_port_stats, port);
1403}
1404
1405#define BFA_PORT_STATS_TOV 1000
1406
1407/**
1408 * Fetch port attributes.
1409 */
1410bfa_status_t
1411bfa_pport_get_stats(struct bfa_s *bfa, union bfa_pport_stats_u *stats,
1412 bfa_cb_pport_t cbfn, void *cbarg)
1413{
1414 struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
1415
1416 if (port->stats_busy) {
1417 bfa_trc(bfa, port->stats_busy);
1418 return (BFA_STATUS_DEVBUSY);
1419 }
1420
1421 port->stats_busy = BFA_TRUE;
1422 port->stats_ret = stats;
1423 port->stats_cbfn = cbfn;
1424 port->stats_cbarg = cbarg;
1425
1426 bfa_port_stats_query(port);
1427
1428 bfa_timer_start(bfa, &port->timer, bfa_port_stats_timeout, port,
1429 BFA_PORT_STATS_TOV);
1430 return (BFA_STATUS_OK);
1431}
1432
1433bfa_status_t
1434bfa_pport_clear_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg)
1435{
1436 struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
1437
1438 if (port->stats_busy) {
1439 bfa_trc(bfa, port->stats_busy);
1440 return (BFA_STATUS_DEVBUSY);
1441 }
1442
1443 port->stats_busy = BFA_TRUE;
1444 port->stats_cbfn = cbfn;
1445 port->stats_cbarg = cbarg;
1446
1447 bfa_port_stats_clear(port);
1448
1449 bfa_timer_start(bfa, &port->timer, bfa_port_stats_clr_timeout, port,
1450 BFA_PORT_STATS_TOV);
1451 return (BFA_STATUS_OK);
1452}
1453
1454bfa_status_t
1455bfa_pport_trunk_enable(struct bfa_s *bfa, u8 bitmap)
1456{
1457 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1458
1459 bfa_trc(bfa, bitmap);
1460 bfa_trc(bfa, pport->cfg.trunked);
1461 bfa_trc(bfa, pport->cfg.trunk_ports);
1462
1463 if (!bitmap || (bitmap & (bitmap - 1)))
1464 return BFA_STATUS_EINVAL;
1465
1466 pport->cfg.trunked = BFA_TRUE;
1467 pport->cfg.trunk_ports = bitmap;
1468
1469 return BFA_STATUS_OK;
1470}
1471
1472void
1473bfa_pport_qos_get_attr(struct bfa_s *bfa, struct bfa_qos_attr_s *qos_attr)
1474{
1475 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1476
1477 qos_attr->state = bfa_os_ntohl(pport->qos_attr.state);
1478 qos_attr->total_bb_cr = bfa_os_ntohl(pport->qos_attr.total_bb_cr);
1479}
1480
1481void
1482bfa_pport_qos_get_vc_attr(struct bfa_s *bfa,
1483 struct bfa_qos_vc_attr_s *qos_vc_attr)
1484{
1485 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1486 struct bfa_qos_vc_attr_s *bfa_vc_attr = &pport->qos_vc_attr;
1487 u32 i = 0;
1488
1489 qos_vc_attr->total_vc_count = bfa_os_ntohs(bfa_vc_attr->total_vc_count);
1490 qos_vc_attr->shared_credit = bfa_os_ntohs(bfa_vc_attr->shared_credit);
1491 qos_vc_attr->elp_opmode_flags =
1492 bfa_os_ntohl(bfa_vc_attr->elp_opmode_flags);
1493
1494 /*
1495 * Individual VC info
1496 */
1497 while (i < qos_vc_attr->total_vc_count) {
1498 qos_vc_attr->vc_info[i].vc_credit =
1499 bfa_vc_attr->vc_info[i].vc_credit;
1500 qos_vc_attr->vc_info[i].borrow_credit =
1501 bfa_vc_attr->vc_info[i].borrow_credit;
1502 qos_vc_attr->vc_info[i].priority =
1503 bfa_vc_attr->vc_info[i].priority;
1504 ++i;
1505 }
1506}
1507
1508/**
1509 * Fetch QoS Stats.
1510 */
1511bfa_status_t
1512bfa_pport_get_qos_stats(struct bfa_s *bfa, union bfa_pport_stats_u *stats,
1513 bfa_cb_pport_t cbfn, void *cbarg)
1514{
1515 /*
1516 * QoS stats is embedded in port stats
1517 */
1518 return (bfa_pport_get_stats(bfa, stats, cbfn, cbarg));
1519}
1520
1521bfa_status_t
1522bfa_pport_clear_qos_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn, void *cbarg)
1523{
1524 struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
1525
1526 if (port->stats_busy) {
1527 bfa_trc(bfa, port->stats_busy);
1528 return (BFA_STATUS_DEVBUSY);
1529 }
1530
1531 port->stats_busy = BFA_TRUE;
1532 port->stats_cbfn = cbfn;
1533 port->stats_cbarg = cbarg;
1534
1535 bfa_port_qos_stats_clear(port);
1536
1537 bfa_timer_start(bfa, &port->timer, bfa_port_stats_clr_timeout, port,
1538 BFA_PORT_STATS_TOV);
1539 return (BFA_STATUS_OK);
1540}
1541
1542/**
1543 * Fetch port attributes.
1544 */
1545bfa_status_t
1546bfa_pport_trunk_disable(struct bfa_s *bfa)
1547{
1548 return (BFA_STATUS_OK);
1549}
1550
1551bfa_boolean_t
1552bfa_pport_trunk_query(struct bfa_s *bfa, u32 *bitmap)
1553{
1554 struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
1555
1556 *bitmap = port->cfg.trunk_ports;
1557 return port->cfg.trunked;
1558}
1559
1560bfa_boolean_t
1561bfa_pport_is_disabled(struct bfa_s *bfa)
1562{
1563 struct bfa_pport_s *port = BFA_PORT_MOD(bfa);
1564
1565 return (bfa_sm_to_state(hal_pport_sm_table, port->sm) ==
1566 BFA_PPORT_ST_DISABLED);
1567
1568}
1569
1570bfa_boolean_t
1571bfa_pport_is_ratelim(struct bfa_s *bfa)
1572{
1573 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1574
1575return (pport->cfg.ratelimit ? BFA_TRUE : BFA_FALSE);
1576
1577}
1578
1579void
1580bfa_pport_cfg_qos(struct bfa_s *bfa, bfa_boolean_t on_off)
1581{
1582 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1583
1584 bfa_trc(bfa, on_off);
1585 bfa_trc(bfa, pport->cfg.qos_enabled);
1586
1587 pport->cfg.qos_enabled = on_off;
1588}
1589
1590void
1591bfa_pport_cfg_ratelim(struct bfa_s *bfa, bfa_boolean_t on_off)
1592{
1593 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1594
1595 bfa_trc(bfa, on_off);
1596 bfa_trc(bfa, pport->cfg.ratelimit);
1597
1598 pport->cfg.ratelimit = on_off;
1599 if (pport->cfg.trl_def_speed == BFA_PPORT_SPEED_UNKNOWN)
1600 pport->cfg.trl_def_speed = BFA_PPORT_SPEED_1GBPS;
1601}
1602
1603/**
1604 * Configure default minimum ratelim speed
1605 */
1606bfa_status_t
1607bfa_pport_cfg_ratelim_speed(struct bfa_s *bfa, enum bfa_pport_speed speed)
1608{
1609 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1610
1611 bfa_trc(bfa, speed);
1612
1613 /*
1614 * Auto and speeds greater than the supported speed, are invalid
1615 */
1616 if ((speed == BFA_PPORT_SPEED_AUTO) || (speed > pport->speed_sup)) {
1617 bfa_trc(bfa, pport->speed_sup);
1618 return BFA_STATUS_UNSUPP_SPEED;
1619 }
1620
1621 pport->cfg.trl_def_speed = speed;
1622
1623 return (BFA_STATUS_OK);
1624}
1625
1626/**
1627 * Get default minimum ratelim speed
1628 */
1629enum bfa_pport_speed
1630bfa_pport_get_ratelim_speed(struct bfa_s *bfa)
1631{
1632 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1633
1634 bfa_trc(bfa, pport->cfg.trl_def_speed);
1635 return (pport->cfg.trl_def_speed);
1636
1637}
1638
1639void
1640bfa_pport_busy(struct bfa_s *bfa, bfa_boolean_t status)
1641{
1642 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1643
1644 bfa_trc(bfa, status);
1645 bfa_trc(bfa, pport->diag_busy);
1646
1647 pport->diag_busy = status;
1648}
1649
1650void
1651bfa_pport_beacon(struct bfa_s *bfa, bfa_boolean_t beacon,
1652 bfa_boolean_t link_e2e_beacon)
1653{
1654 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
1655
1656 bfa_trc(bfa, beacon);
1657 bfa_trc(bfa, link_e2e_beacon);
1658 bfa_trc(bfa, pport->beacon);
1659 bfa_trc(bfa, pport->link_e2e_beacon);
1660
1661 pport->beacon = beacon;
1662 pport->link_e2e_beacon = link_e2e_beacon;
1663}
1664
1665bfa_boolean_t
1666bfa_pport_is_linkup(struct bfa_s *bfa)
1667{
1668 return bfa_sm_cmp_state(BFA_PORT_MOD(bfa), bfa_pport_sm_linkup);
1669}
1670
1671
diff --git a/drivers/scsi/bfa/bfa_fcs.c b/drivers/scsi/bfa/bfa_fcs.c
new file mode 100644
index 000000000000..7cb39a306ea9
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_fcs.c
@@ -0,0 +1,182 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * bfa_fcs.c BFA FCS main
20 */
21
22#include <fcs/bfa_fcs.h>
23#include "fcs_port.h"
24#include "fcs_uf.h"
25#include "fcs_vport.h"
26#include "fcs_rport.h"
27#include "fcs_fabric.h"
28#include "fcs_fcpim.h"
29#include "fcs_fcptm.h"
30#include "fcbuild.h"
31#include "fcs.h"
32#include "bfad_drv.h"
33#include <fcb/bfa_fcb.h>
34
35/**
36 * FCS sub-modules
37 */
38struct bfa_fcs_mod_s {
39 void (*modinit) (struct bfa_fcs_s *fcs);
40 void (*modexit) (struct bfa_fcs_s *fcs);
41};
42
43#define BFA_FCS_MODULE(_mod) { _mod ## _modinit, _mod ## _modexit }
44
45static struct bfa_fcs_mod_s fcs_modules[] = {
46 BFA_FCS_MODULE(bfa_fcs_pport),
47 BFA_FCS_MODULE(bfa_fcs_uf),
48 BFA_FCS_MODULE(bfa_fcs_fabric),
49 BFA_FCS_MODULE(bfa_fcs_vport),
50 BFA_FCS_MODULE(bfa_fcs_rport),
51 BFA_FCS_MODULE(bfa_fcs_fcpim),
52};
53
54/**
55 * fcs_api BFA FCS API
56 */
57
58static void
59bfa_fcs_exit_comp(void *fcs_cbarg)
60{
61 struct bfa_fcs_s *fcs = fcs_cbarg;
62 struct bfad_s *bfad = fcs->bfad;
63
64 complete(&bfad->comp);
65}
66
67
68
69/**
70 * fcs_api BFA FCS API
71 */
72
73/**
74 * FCS instance initialization.
75 *
76 * param[in] fcs FCS instance
77 * param[in] bfa BFA instance
78 * param[in] bfad BFA driver instance
79 *
80 * return None
81 */
82void
83bfa_fcs_init(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad,
84 bfa_boolean_t min_cfg)
85{
86 int i;
87 struct bfa_fcs_mod_s *mod;
88
89 fcs->bfa = bfa;
90 fcs->bfad = bfad;
91 fcs->min_cfg = min_cfg;
92
93 bfa_attach_fcs(bfa);
94 fcbuild_init();
95
96 for (i = 0; i < sizeof(fcs_modules) / sizeof(fcs_modules[0]); i++) {
97 mod = &fcs_modules[i];
98 mod->modinit(fcs);
99 }
100}
101
102/**
103 * Start FCS operations.
104 */
105void
106bfa_fcs_start(struct bfa_fcs_s *fcs)
107{
108 bfa_fcs_fabric_modstart(fcs);
109}
110
111/**
112 * FCS driver details initialization.
113 *
114 * param[in] fcs FCS instance
115 * param[in] driver_info Driver Details
116 *
117 * return None
118 */
119void
120bfa_fcs_driver_info_init(struct bfa_fcs_s *fcs,
121 struct bfa_fcs_driver_info_s *driver_info)
122{
123
124 fcs->driver_info = *driver_info;
125
126 bfa_fcs_fabric_psymb_init(&fcs->fabric);
127}
128
129/**
130 * FCS instance cleanup and exit.
131 *
132 * param[in] fcs FCS instance
133 * return None
134 */
135void
136bfa_fcs_exit(struct bfa_fcs_s *fcs)
137{
138 struct bfa_fcs_mod_s *mod;
139 int nmods, i;
140
141 bfa_wc_init(&fcs->wc, bfa_fcs_exit_comp, fcs);
142
143 nmods = sizeof(fcs_modules) / sizeof(fcs_modules[0]);
144
145 for (i = 0; i < nmods; i++) {
146 bfa_wc_up(&fcs->wc);
147
148 mod = &fcs_modules[i];
149 mod->modexit(fcs);
150 }
151
152 bfa_wc_wait(&fcs->wc);
153}
154
155
156void
157bfa_fcs_trc_init(struct bfa_fcs_s *fcs, struct bfa_trc_mod_s *trcmod)
158{
159 fcs->trcmod = trcmod;
160}
161
162
163void
164bfa_fcs_log_init(struct bfa_fcs_s *fcs, struct bfa_log_mod_s *logmod)
165{
166 fcs->logm = logmod;
167}
168
169
170void
171bfa_fcs_aen_init(struct bfa_fcs_s *fcs, struct bfa_aen_s *aen)
172{
173 fcs->aen = aen;
174}
175
176void
177bfa_fcs_modexit_comp(struct bfa_fcs_s *fcs)
178{
179 bfa_wc_down(&fcs->wc);
180}
181
182
diff --git a/drivers/scsi/bfa/bfa_fcs_lport.c b/drivers/scsi/bfa/bfa_fcs_lport.c
new file mode 100644
index 000000000000..8975ed041dc0
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_fcs_lport.c
@@ -0,0 +1,940 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * bfa_fcs_port.c BFA FCS port
20 */
21
22#include <fcs/bfa_fcs.h>
23#include <fcs/bfa_fcs_lport.h>
24#include <fcs/bfa_fcs_rport.h>
25#include <fcb/bfa_fcb_port.h>
26#include <bfa_svc.h>
27#include <log/bfa_log_fcs.h>
28#include "fcs.h"
29#include "fcs_lport.h"
30#include "fcs_vport.h"
31#include "fcs_rport.h"
32#include "fcs_fcxp.h"
33#include "fcs_trcmod.h"
34#include "lport_priv.h"
35#include <aen/bfa_aen_lport.h>
36
37BFA_TRC_FILE(FCS, PORT);
38
39/**
40 * Forward declarations
41 */
42
43static void bfa_fcs_port_aen_post(struct bfa_fcs_port_s *port,
44 enum bfa_lport_aen_event event);
45static void bfa_fcs_port_send_ls_rjt(struct bfa_fcs_port_s *port,
46 struct fchs_s *rx_fchs, u8 reason_code,
47 u8 reason_code_expl);
48static void bfa_fcs_port_plogi(struct bfa_fcs_port_s *port,
49 struct fchs_s *rx_fchs,
50 struct fc_logi_s *plogi);
51static void bfa_fcs_port_online_actions(struct bfa_fcs_port_s *port);
52static void bfa_fcs_port_offline_actions(struct bfa_fcs_port_s *port);
53static void bfa_fcs_port_unknown_init(struct bfa_fcs_port_s *port);
54static void bfa_fcs_port_unknown_online(struct bfa_fcs_port_s *port);
55static void bfa_fcs_port_unknown_offline(struct bfa_fcs_port_s *port);
56static void bfa_fcs_port_deleted(struct bfa_fcs_port_s *port);
57static void bfa_fcs_port_echo(struct bfa_fcs_port_s *port,
58 struct fchs_s *rx_fchs,
59 struct fc_echo_s *echo, u16 len);
60static void bfa_fcs_port_rnid(struct bfa_fcs_port_s *port,
61 struct fchs_s *rx_fchs,
62 struct fc_rnid_cmd_s *rnid, u16 len);
63static void bfa_fs_port_get_gen_topo_data(struct bfa_fcs_port_s *port,
64 struct fc_rnid_general_topology_data_s *gen_topo_data);
65
66static struct {
67 void (*init) (struct bfa_fcs_port_s *port);
68 void (*online) (struct bfa_fcs_port_s *port);
69 void (*offline) (struct bfa_fcs_port_s *port);
70} __port_action[] = {
71 {
72 bfa_fcs_port_unknown_init, bfa_fcs_port_unknown_online,
73 bfa_fcs_port_unknown_offline}, {
74 bfa_fcs_port_fab_init, bfa_fcs_port_fab_online,
75 bfa_fcs_port_fab_offline}, {
76 bfa_fcs_port_loop_init, bfa_fcs_port_loop_online,
77 bfa_fcs_port_loop_offline}, {
78bfa_fcs_port_n2n_init, bfa_fcs_port_n2n_online,
79 bfa_fcs_port_n2n_offline},};
80
81/**
82 * fcs_port_sm FCS logical port state machine
83 */
84
85enum bfa_fcs_port_event {
86 BFA_FCS_PORT_SM_CREATE = 1,
87 BFA_FCS_PORT_SM_ONLINE = 2,
88 BFA_FCS_PORT_SM_OFFLINE = 3,
89 BFA_FCS_PORT_SM_DELETE = 4,
90 BFA_FCS_PORT_SM_DELRPORT = 5,
91};
92
93static void bfa_fcs_port_sm_uninit(struct bfa_fcs_port_s *port,
94 enum bfa_fcs_port_event event);
95static void bfa_fcs_port_sm_init(struct bfa_fcs_port_s *port,
96 enum bfa_fcs_port_event event);
97static void bfa_fcs_port_sm_online(struct bfa_fcs_port_s *port,
98 enum bfa_fcs_port_event event);
99static void bfa_fcs_port_sm_offline(struct bfa_fcs_port_s *port,
100 enum bfa_fcs_port_event event);
101static void bfa_fcs_port_sm_deleting(struct bfa_fcs_port_s *port,
102 enum bfa_fcs_port_event event);
103
104static void
105bfa_fcs_port_sm_uninit(struct bfa_fcs_port_s *port,
106 enum bfa_fcs_port_event event)
107{
108 bfa_trc(port->fcs, port->port_cfg.pwwn);
109 bfa_trc(port->fcs, event);
110
111 switch (event) {
112 case BFA_FCS_PORT_SM_CREATE:
113 bfa_sm_set_state(port, bfa_fcs_port_sm_init);
114 break;
115
116 default:
117 bfa_assert(0);
118 }
119}
120
121static void
122bfa_fcs_port_sm_init(struct bfa_fcs_port_s *port, enum bfa_fcs_port_event event)
123{
124 bfa_trc(port->fcs, port->port_cfg.pwwn);
125 bfa_trc(port->fcs, event);
126
127 switch (event) {
128 case BFA_FCS_PORT_SM_ONLINE:
129 bfa_sm_set_state(port, bfa_fcs_port_sm_online);
130 bfa_fcs_port_online_actions(port);
131 break;
132
133 case BFA_FCS_PORT_SM_DELETE:
134 bfa_sm_set_state(port, bfa_fcs_port_sm_uninit);
135 bfa_fcs_port_deleted(port);
136 break;
137
138 default:
139 bfa_assert(0);
140 }
141}
142
143static void
144bfa_fcs_port_sm_online(struct bfa_fcs_port_s *port,
145 enum bfa_fcs_port_event event)
146{
147 struct bfa_fcs_rport_s *rport;
148 struct list_head *qe, *qen;
149
150 bfa_trc(port->fcs, port->port_cfg.pwwn);
151 bfa_trc(port->fcs, event);
152
153 switch (event) {
154 case BFA_FCS_PORT_SM_OFFLINE:
155 bfa_sm_set_state(port, bfa_fcs_port_sm_offline);
156 bfa_fcs_port_offline_actions(port);
157 break;
158
159 case BFA_FCS_PORT_SM_DELETE:
160
161 __port_action[port->fabric->fab_type].offline(port);
162
163 if (port->num_rports == 0) {
164 bfa_sm_set_state(port, bfa_fcs_port_sm_uninit);
165 bfa_fcs_port_deleted(port);
166 } else {
167 bfa_sm_set_state(port, bfa_fcs_port_sm_deleting);
168 list_for_each_safe(qe, qen, &port->rport_q) {
169 rport = (struct bfa_fcs_rport_s *)qe;
170 bfa_fcs_rport_delete(rport);
171 }
172 }
173 break;
174
175 case BFA_FCS_PORT_SM_DELRPORT:
176 break;
177
178 default:
179 bfa_assert(0);
180 }
181}
182
183static void
184bfa_fcs_port_sm_offline(struct bfa_fcs_port_s *port,
185 enum bfa_fcs_port_event event)
186{
187 struct bfa_fcs_rport_s *rport;
188 struct list_head *qe, *qen;
189
190 bfa_trc(port->fcs, port->port_cfg.pwwn);
191 bfa_trc(port->fcs, event);
192
193 switch (event) {
194 case BFA_FCS_PORT_SM_ONLINE:
195 bfa_sm_set_state(port, bfa_fcs_port_sm_online);
196 bfa_fcs_port_online_actions(port);
197 break;
198
199 case BFA_FCS_PORT_SM_DELETE:
200 if (port->num_rports == 0) {
201 bfa_sm_set_state(port, bfa_fcs_port_sm_uninit);
202 bfa_fcs_port_deleted(port);
203 } else {
204 bfa_sm_set_state(port, bfa_fcs_port_sm_deleting);
205 list_for_each_safe(qe, qen, &port->rport_q) {
206 rport = (struct bfa_fcs_rport_s *)qe;
207 bfa_fcs_rport_delete(rport);
208 }
209 }
210 break;
211
212 case BFA_FCS_PORT_SM_DELRPORT:
213 case BFA_FCS_PORT_SM_OFFLINE:
214 break;
215
216 default:
217 bfa_assert(0);
218 }
219}
220
221static void
222bfa_fcs_port_sm_deleting(struct bfa_fcs_port_s *port,
223 enum bfa_fcs_port_event event)
224{
225 bfa_trc(port->fcs, port->port_cfg.pwwn);
226 bfa_trc(port->fcs, event);
227
228 switch (event) {
229 case BFA_FCS_PORT_SM_DELRPORT:
230 if (port->num_rports == 0) {
231 bfa_sm_set_state(port, bfa_fcs_port_sm_uninit);
232 bfa_fcs_port_deleted(port);
233 }
234 break;
235
236 default:
237 bfa_assert(0);
238 }
239}
240
241
242
243/**
244 * fcs_port_pvt
245 */
246
247/**
248 * Send AEN notification
249 */
250static void
251bfa_fcs_port_aen_post(struct bfa_fcs_port_s *port,
252 enum bfa_lport_aen_event event)
253{
254 union bfa_aen_data_u aen_data;
255 struct bfa_log_mod_s *logmod = port->fcs->logm;
256 enum bfa_port_role role = port->port_cfg.roles;
257 wwn_t lpwwn = bfa_fcs_port_get_pwwn(port);
258 char lpwwn_ptr[BFA_STRING_32];
259 char *role_str[BFA_PORT_ROLE_FCP_MAX / 2 + 1] =
260 { "Initiator", "Target", "IPFC" };
261
262 wwn2str(lpwwn_ptr, lpwwn);
263
264 bfa_assert(role <= BFA_PORT_ROLE_FCP_MAX);
265
266 switch (event) {
267 case BFA_LPORT_AEN_ONLINE:
268 bfa_log(logmod, BFA_AEN_LPORT_ONLINE, lpwwn_ptr,
269 role_str[role / 2]);
270 break;
271 case BFA_LPORT_AEN_OFFLINE:
272 bfa_log(logmod, BFA_AEN_LPORT_OFFLINE, lpwwn_ptr,
273 role_str[role / 2]);
274 break;
275 case BFA_LPORT_AEN_NEW:
276 bfa_log(logmod, BFA_AEN_LPORT_NEW, lpwwn_ptr,
277 role_str[role / 2]);
278 break;
279 case BFA_LPORT_AEN_DELETE:
280 bfa_log(logmod, BFA_AEN_LPORT_DELETE, lpwwn_ptr,
281 role_str[role / 2]);
282 break;
283 case BFA_LPORT_AEN_DISCONNECT:
284 bfa_log(logmod, BFA_AEN_LPORT_DISCONNECT, lpwwn_ptr,
285 role_str[role / 2]);
286 break;
287 default:
288 break;
289 }
290
291 aen_data.lport.vf_id = port->fabric->vf_id;
292 aen_data.lport.roles = role;
293 aen_data.lport.ppwwn =
294 bfa_fcs_port_get_pwwn(bfa_fcs_get_base_port(port->fcs));
295 aen_data.lport.lpwwn = lpwwn;
296}
297
298/*
299 * Send a LS reject
300 */
301static void
302bfa_fcs_port_send_ls_rjt(struct bfa_fcs_port_s *port, struct fchs_s *rx_fchs,
303 u8 reason_code, u8 reason_code_expl)
304{
305 struct fchs_s fchs;
306 struct bfa_fcxp_s *fcxp;
307 struct bfa_rport_s *bfa_rport = NULL;
308 int len;
309
310 bfa_trc(port->fcs, rx_fchs->s_id);
311
312 fcxp = bfa_fcs_fcxp_alloc(port->fcs);
313 if (!fcxp)
314 return;
315
316 len = fc_ls_rjt_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rx_fchs->s_id,
317 bfa_fcs_port_get_fcid(port), rx_fchs->ox_id,
318 reason_code, reason_code_expl);
319
320 bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag,
321 BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
322 FC_MAX_PDUSZ, 0);
323}
324
325/**
326 * Process incoming plogi from a remote port.
327 */
328static void
329bfa_fcs_port_plogi(struct bfa_fcs_port_s *port, struct fchs_s *rx_fchs,
330 struct fc_logi_s *plogi)
331{
332 struct bfa_fcs_rport_s *rport;
333
334 bfa_trc(port->fcs, rx_fchs->d_id);
335 bfa_trc(port->fcs, rx_fchs->s_id);
336
337 /*
338 * If min cfg mode is enabled, drop any incoming PLOGIs
339 */
340 if (__fcs_min_cfg(port->fcs)) {
341 bfa_trc(port->fcs, rx_fchs->s_id);
342 return;
343 }
344
345 if (fc_plogi_parse(rx_fchs) != FC_PARSE_OK) {
346 bfa_trc(port->fcs, rx_fchs->s_id);
347 /*
348 * send a LS reject
349 */
350 bfa_fcs_port_send_ls_rjt(port, rx_fchs,
351 FC_LS_RJT_RSN_PROTOCOL_ERROR,
352 FC_LS_RJT_EXP_SPARMS_ERR_OPTIONS);
353 return;
354 }
355
356 /**
357* Direct Attach P2P mode : verify address assigned by the r-port.
358 */
359 if ((!bfa_fcs_fabric_is_switched(port->fabric))
360 &&
361 (memcmp
362 ((void *)&bfa_fcs_port_get_pwwn(port), (void *)&plogi->port_name,
363 sizeof(wwn_t)) < 0)) {
364 if (BFA_FCS_PID_IS_WKA(rx_fchs->d_id)) {
365 /*
366 * Address assigned to us cannot be a WKA
367 */
368 bfa_fcs_port_send_ls_rjt(port, rx_fchs,
369 FC_LS_RJT_RSN_PROTOCOL_ERROR,
370 FC_LS_RJT_EXP_INVALID_NPORT_ID);
371 return;
372 }
373 port->pid = rx_fchs->d_id;
374 }
375
376 /**
377 * First, check if we know the device by pwwn.
378 */
379 rport = bfa_fcs_port_get_rport_by_pwwn(port, plogi->port_name);
380 if (rport) {
381 /**
382 * Direct Attach P2P mode: handle address assigned by the rport.
383 */
384 if ((!bfa_fcs_fabric_is_switched(port->fabric))
385 &&
386 (memcmp
387 ((void *)&bfa_fcs_port_get_pwwn(port),
388 (void *)&plogi->port_name, sizeof(wwn_t)) < 0)) {
389 port->pid = rx_fchs->d_id;
390 rport->pid = rx_fchs->s_id;
391 }
392 bfa_fcs_rport_plogi(rport, rx_fchs, plogi);
393 return;
394 }
395
396 /**
397 * Next, lookup rport by PID.
398 */
399 rport = bfa_fcs_port_get_rport_by_pid(port, rx_fchs->s_id);
400 if (!rport) {
401 /**
402 * Inbound PLOGI from a new device.
403 */
404 bfa_fcs_rport_plogi_create(port, rx_fchs, plogi);
405 return;
406 }
407
408 /**
409 * Rport is known only by PID.
410 */
411 if (rport->pwwn) {
412 /**
413 * This is a different device with the same pid. Old device
414 * disappeared. Send implicit LOGO to old device.
415 */
416 bfa_assert(rport->pwwn != plogi->port_name);
417 bfa_fcs_rport_logo_imp(rport);
418
419 /**
420 * Inbound PLOGI from a new device (with old PID).
421 */
422 bfa_fcs_rport_plogi_create(port, rx_fchs, plogi);
423 return;
424 }
425
426 /**
427 * PLOGI crossing each other.
428 */
429 bfa_assert(rport->pwwn == WWN_NULL);
430 bfa_fcs_rport_plogi(rport, rx_fchs, plogi);
431}
432
433/*
434 * Process incoming ECHO.
435 * Since it does not require a login, it is processed here.
436 */
437static void
438bfa_fcs_port_echo(struct bfa_fcs_port_s *port, struct fchs_s *rx_fchs,
439 struct fc_echo_s *echo, u16 rx_len)
440{
441 struct fchs_s fchs;
442 struct bfa_fcxp_s *fcxp;
443 struct bfa_rport_s *bfa_rport = NULL;
444 int len, pyld_len;
445
446 bfa_trc(port->fcs, rx_fchs->s_id);
447 bfa_trc(port->fcs, rx_fchs->d_id);
448 bfa_trc(port->fcs, rx_len);
449
450 fcxp = bfa_fcs_fcxp_alloc(port->fcs);
451 if (!fcxp)
452 return;
453
454 len = fc_ls_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rx_fchs->s_id,
455 bfa_fcs_port_get_fcid(port), rx_fchs->ox_id);
456
457 /*
458 * Copy the payload (if any) from the echo frame
459 */
460 pyld_len = rx_len - sizeof(struct fchs_s);
461 bfa_trc(port->fcs, pyld_len);
462
463 if (pyld_len > len)
464 memcpy(((u8 *) bfa_fcxp_get_reqbuf(fcxp)) +
465 sizeof(struct fc_echo_s), (echo + 1),
466 (pyld_len - sizeof(struct fc_echo_s)));
467
468 bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag,
469 BFA_FALSE, FC_CLASS_3, pyld_len, &fchs, NULL, NULL,
470 FC_MAX_PDUSZ, 0);
471}
472
473/*
474 * Process incoming RNID.
475 * Since it does not require a login, it is processed here.
476 */
477static void
478bfa_fcs_port_rnid(struct bfa_fcs_port_s *port, struct fchs_s *rx_fchs,
479 struct fc_rnid_cmd_s *rnid, u16 rx_len)
480{
481 struct fc_rnid_common_id_data_s common_id_data;
482 struct fc_rnid_general_topology_data_s gen_topo_data;
483 struct fchs_s fchs;
484 struct bfa_fcxp_s *fcxp;
485 struct bfa_rport_s *bfa_rport = NULL;
486 u16 len;
487 u32 data_format;
488
489 bfa_trc(port->fcs, rx_fchs->s_id);
490 bfa_trc(port->fcs, rx_fchs->d_id);
491 bfa_trc(port->fcs, rx_len);
492
493 fcxp = bfa_fcs_fcxp_alloc(port->fcs);
494 if (!fcxp)
495 return;
496
497 /*
498 * Check Node Indentification Data Format
499 * We only support General Topology Discovery Format.
500 * For any other requested Data Formats, we return Common Node Id Data
501 * only, as per FC-LS.
502 */
503 bfa_trc(port->fcs, rnid->node_id_data_format);
504 if (rnid->node_id_data_format == RNID_NODEID_DATA_FORMAT_DISCOVERY) {
505 data_format = RNID_NODEID_DATA_FORMAT_DISCOVERY;
506 /*
507 * Get General topology data for this port
508 */
509 bfa_fs_port_get_gen_topo_data(port, &gen_topo_data);
510 } else {
511 data_format = RNID_NODEID_DATA_FORMAT_COMMON;
512 }
513
514 /*
515 * Copy the Node Id Info
516 */
517 common_id_data.port_name = bfa_fcs_port_get_pwwn(port);
518 common_id_data.node_name = bfa_fcs_port_get_nwwn(port);
519
520 len = fc_rnid_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rx_fchs->s_id,
521 bfa_fcs_port_get_fcid(port), rx_fchs->ox_id,
522 data_format, &common_id_data, &gen_topo_data);
523
524 bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag,
525 BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
526 FC_MAX_PDUSZ, 0);
527
528 return;
529}
530
531/*
532 * Fill out General Topolpgy Discovery Data for RNID ELS.
533 */
534static void
535bfa_fs_port_get_gen_topo_data(struct bfa_fcs_port_s *port,
536 struct fc_rnid_general_topology_data_s *gen_topo_data)
537{
538
539 bfa_os_memset(gen_topo_data, 0,
540 sizeof(struct fc_rnid_general_topology_data_s));
541
542 gen_topo_data->asso_type = bfa_os_htonl(RNID_ASSOCIATED_TYPE_HOST);
543 gen_topo_data->phy_port_num = 0; /* @todo */
544 gen_topo_data->num_attached_nodes = bfa_os_htonl(1);
545}
546
547static void
548bfa_fcs_port_online_actions(struct bfa_fcs_port_s *port)
549{
550 bfa_trc(port->fcs, port->fabric->oper_type);
551
552 __port_action[port->fabric->fab_type].init(port);
553 __port_action[port->fabric->fab_type].online(port);
554
555 bfa_fcs_port_aen_post(port, BFA_LPORT_AEN_ONLINE);
556 bfa_fcb_port_online(port->fcs->bfad, port->port_cfg.roles,
557 port->fabric->vf_drv, (port->vport == NULL) ?
558 NULL : port->vport->vport_drv);
559}
560
561static void
562bfa_fcs_port_offline_actions(struct bfa_fcs_port_s *port)
563{
564 struct list_head *qe, *qen;
565 struct bfa_fcs_rport_s *rport;
566
567 bfa_trc(port->fcs, port->fabric->oper_type);
568
569 __port_action[port->fabric->fab_type].offline(port);
570
571 if (bfa_fcs_fabric_is_online(port->fabric) == BFA_TRUE) {
572 bfa_fcs_port_aen_post(port, BFA_LPORT_AEN_DISCONNECT);
573 } else {
574 bfa_fcs_port_aen_post(port, BFA_LPORT_AEN_OFFLINE);
575 }
576 bfa_fcb_port_offline(port->fcs->bfad, port->port_cfg.roles,
577 port->fabric->vf_drv,
578 (port->vport == NULL) ? NULL : port->vport->vport_drv);
579
580 list_for_each_safe(qe, qen, &port->rport_q) {
581 rport = (struct bfa_fcs_rport_s *)qe;
582 bfa_fcs_rport_offline(rport);
583 }
584}
585
586static void
587bfa_fcs_port_unknown_init(struct bfa_fcs_port_s *port)
588{
589 bfa_assert(0);
590}
591
592static void
593bfa_fcs_port_unknown_online(struct bfa_fcs_port_s *port)
594{
595 bfa_assert(0);
596}
597
598static void
599bfa_fcs_port_unknown_offline(struct bfa_fcs_port_s *port)
600{
601 bfa_assert(0);
602}
603
604static void
605bfa_fcs_port_deleted(struct bfa_fcs_port_s *port)
606{
607 bfa_fcs_port_aen_post(port, BFA_LPORT_AEN_DELETE);
608
609 /*
610 * Base port will be deleted by the OS driver
611 */
612 if (port->vport) {
613 bfa_fcb_port_delete(port->fcs->bfad, port->port_cfg.roles,
614 port->fabric->vf_drv,
615 port->vport ? port->vport->vport_drv : NULL);
616 bfa_fcs_vport_delete_comp(port->vport);
617 } else {
618 bfa_fcs_fabric_port_delete_comp(port->fabric);
619 }
620}
621
622
623
624/**
625 * fcs_lport_api BFA FCS port API
626 */
627/**
628 * Module initialization
629 */
630void
631bfa_fcs_port_modinit(struct bfa_fcs_s *fcs)
632{
633
634}
635
636/**
637 * Module cleanup
638 */
639void
640bfa_fcs_port_modexit(struct bfa_fcs_s *fcs)
641{
642 bfa_fcs_modexit_comp(fcs);
643}
644
645/**
646 * Unsolicited frame receive handling.
647 */
648void
649bfa_fcs_port_uf_recv(struct bfa_fcs_port_s *lport, struct fchs_s *fchs,
650 u16 len)
651{
652 u32 pid = fchs->s_id;
653 struct bfa_fcs_rport_s *rport = NULL;
654 struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
655
656 bfa_stats(lport, uf_recvs);
657
658 if (!bfa_fcs_port_is_online(lport)) {
659 bfa_stats(lport, uf_recv_drops);
660 return;
661 }
662
663 /**
664 * First, handle ELSs that donot require a login.
665 */
666 /*
667 * Handle PLOGI first
668 */
669 if ((fchs->type == FC_TYPE_ELS) &&
670 (els_cmd->els_code == FC_ELS_PLOGI)) {
671 bfa_fcs_port_plogi(lport, fchs, (struct fc_logi_s *) els_cmd);
672 return;
673 }
674
675 /*
676 * Handle ECHO separately.
677 */
678 if ((fchs->type == FC_TYPE_ELS) && (els_cmd->els_code == FC_ELS_ECHO)) {
679 bfa_fcs_port_echo(lport, fchs,
680 (struct fc_echo_s *) els_cmd, len);
681 return;
682 }
683
684 /*
685 * Handle RNID separately.
686 */
687 if ((fchs->type == FC_TYPE_ELS) && (els_cmd->els_code == FC_ELS_RNID)) {
688 bfa_fcs_port_rnid(lport, fchs,
689 (struct fc_rnid_cmd_s *) els_cmd, len);
690 return;
691 }
692
693 /**
694 * look for a matching remote port ID
695 */
696 rport = bfa_fcs_port_get_rport_by_pid(lport, pid);
697 if (rport) {
698 bfa_trc(rport->fcs, fchs->s_id);
699 bfa_trc(rport->fcs, fchs->d_id);
700 bfa_trc(rport->fcs, fchs->type);
701
702 bfa_fcs_rport_uf_recv(rport, fchs, len);
703 return;
704 }
705
706 /**
707 * Only handles ELS frames for now.
708 */
709 if (fchs->type != FC_TYPE_ELS) {
710 bfa_trc(lport->fcs, fchs->type);
711 bfa_assert(0);
712 return;
713 }
714
715 bfa_trc(lport->fcs, els_cmd->els_code);
716 if (els_cmd->els_code == FC_ELS_RSCN) {
717 bfa_fcs_port_scn_process_rscn(lport, fchs, len);
718 return;
719 }
720
721 if (els_cmd->els_code == FC_ELS_LOGO) {
722 /**
723 * @todo Handle LOGO frames received.
724 */
725 bfa_trc(lport->fcs, els_cmd->els_code);
726 return;
727 }
728
729 if (els_cmd->els_code == FC_ELS_PRLI) {
730 /**
731 * @todo Handle PRLI frames received.
732 */
733 bfa_trc(lport->fcs, els_cmd->els_code);
734 return;
735 }
736
737 /**
738 * Unhandled ELS frames. Send a LS_RJT.
739 */
740 bfa_fcs_port_send_ls_rjt(lport, fchs, FC_LS_RJT_RSN_CMD_NOT_SUPP,
741 FC_LS_RJT_EXP_NO_ADDL_INFO);
742
743}
744
745/**
746 * PID based Lookup for a R-Port in the Port R-Port Queue
747 */
748struct bfa_fcs_rport_s *
749bfa_fcs_port_get_rport_by_pid(struct bfa_fcs_port_s *port, u32 pid)
750{
751 struct bfa_fcs_rport_s *rport;
752 struct list_head *qe;
753
754 list_for_each(qe, &port->rport_q) {
755 rport = (struct bfa_fcs_rport_s *)qe;
756 if (rport->pid == pid)
757 return rport;
758 }
759
760 bfa_trc(port->fcs, pid);
761 return NULL;
762}
763
764/**
765 * PWWN based Lookup for a R-Port in the Port R-Port Queue
766 */
767struct bfa_fcs_rport_s *
768bfa_fcs_port_get_rport_by_pwwn(struct bfa_fcs_port_s *port, wwn_t pwwn)
769{
770 struct bfa_fcs_rport_s *rport;
771 struct list_head *qe;
772
773 list_for_each(qe, &port->rport_q) {
774 rport = (struct bfa_fcs_rport_s *)qe;
775 if (wwn_is_equal(rport->pwwn, pwwn))
776 return rport;
777 }
778
779 bfa_trc(port->fcs, pwwn);
780 return (NULL);
781}
782
783/**
784 * NWWN based Lookup for a R-Port in the Port R-Port Queue
785 */
786struct bfa_fcs_rport_s *
787bfa_fcs_port_get_rport_by_nwwn(struct bfa_fcs_port_s *port, wwn_t nwwn)
788{
789 struct bfa_fcs_rport_s *rport;
790 struct list_head *qe;
791
792 list_for_each(qe, &port->rport_q) {
793 rport = (struct bfa_fcs_rport_s *)qe;
794 if (wwn_is_equal(rport->nwwn, nwwn))
795 return rport;
796 }
797
798 bfa_trc(port->fcs, nwwn);
799 return (NULL);
800}
801
802/**
803 * Called by rport module when new rports are discovered.
804 */
805void
806bfa_fcs_port_add_rport(struct bfa_fcs_port_s *port,
807 struct bfa_fcs_rport_s *rport)
808{
809 list_add_tail(&rport->qe, &port->rport_q);
810 port->num_rports++;
811}
812
813/**
814 * Called by rport module to when rports are deleted.
815 */
816void
817bfa_fcs_port_del_rport(struct bfa_fcs_port_s *port,
818 struct bfa_fcs_rport_s *rport)
819{
820 bfa_assert(bfa_q_is_on_q(&port->rport_q, rport));
821 list_del(&rport->qe);
822 port->num_rports--;
823
824 bfa_sm_send_event(port, BFA_FCS_PORT_SM_DELRPORT);
825}
826
827/**
828 * Called by fabric for base port when fabric login is complete.
829 * Called by vport for virtual ports when FDISC is complete.
830 */
831void
832bfa_fcs_port_online(struct bfa_fcs_port_s *port)
833{
834 bfa_sm_send_event(port, BFA_FCS_PORT_SM_ONLINE);
835}
836
837/**
838 * Called by fabric for base port when fabric goes offline.
839 * Called by vport for virtual ports when virtual port becomes offline.
840 */
841void
842bfa_fcs_port_offline(struct bfa_fcs_port_s *port)
843{
844 bfa_sm_send_event(port, BFA_FCS_PORT_SM_OFFLINE);
845}
846
847/**
848 * Called by fabric to delete base lport and associated resources.
849 *
850 * Called by vport to delete lport and associated resources. Should call
851 * bfa_fcs_vport_delete_comp() for vports on completion.
852 */
853void
854bfa_fcs_port_delete(struct bfa_fcs_port_s *port)
855{
856 bfa_sm_send_event(port, BFA_FCS_PORT_SM_DELETE);
857}
858
859/**
860 * Called by fabric in private loop topology to process LIP event.
861 */
862void
863bfa_fcs_port_lip(struct bfa_fcs_port_s *port)
864{
865}
866
867/**
868 * Return TRUE if port is online, else return FALSE
869 */
870bfa_boolean_t
871bfa_fcs_port_is_online(struct bfa_fcs_port_s *port)
872{
873 return (bfa_sm_cmp_state(port, bfa_fcs_port_sm_online));
874}
875
876/**
877 * Logical port initialization of base or virtual port.
878 * Called by fabric for base port or by vport for virtual ports.
879 */
880void
881bfa_fcs_lport_init(struct bfa_fcs_port_s *lport, struct bfa_fcs_s *fcs,
882 u16 vf_id, struct bfa_port_cfg_s *port_cfg,
883 struct bfa_fcs_vport_s *vport)
884{
885 lport->fcs = fcs;
886 lport->fabric = bfa_fcs_vf_lookup(fcs, vf_id);
887 bfa_os_assign(lport->port_cfg, *port_cfg);
888 lport->vport = vport;
889 lport->lp_tag = (vport) ? bfa_lps_get_tag(vport->lps) :
890 bfa_lps_get_tag(lport->fabric->lps);
891
892 INIT_LIST_HEAD(&lport->rport_q);
893 lport->num_rports = 0;
894
895 lport->bfad_port =
896 bfa_fcb_port_new(fcs->bfad, lport, lport->port_cfg.roles,
897 lport->fabric->vf_drv,
898 vport ? vport->vport_drv : NULL);
899 bfa_fcs_port_aen_post(lport, BFA_LPORT_AEN_NEW);
900
901 bfa_sm_set_state(lport, bfa_fcs_port_sm_uninit);
902 bfa_sm_send_event(lport, BFA_FCS_PORT_SM_CREATE);
903}
904
905
906
907/**
908 * fcs_lport_api
909 */
910
911void
912bfa_fcs_port_get_attr(struct bfa_fcs_port_s *port,
913 struct bfa_port_attr_s *port_attr)
914{
915 if (bfa_sm_cmp_state(port, bfa_fcs_port_sm_online))
916 port_attr->pid = port->pid;
917 else
918 port_attr->pid = 0;
919
920 port_attr->port_cfg = port->port_cfg;
921
922 if (port->fabric) {
923 port_attr->port_type = bfa_fcs_fabric_port_type(port->fabric);
924 port_attr->loopback = bfa_fcs_fabric_is_loopback(port->fabric);
925 port_attr->fabric_name = bfa_fcs_port_get_fabric_name(port);
926 memcpy(port_attr->fabric_ip_addr,
927 bfa_fcs_port_get_fabric_ipaddr(port),
928 BFA_FCS_FABRIC_IPADDR_SZ);
929
930 if (port->vport != NULL)
931 port_attr->port_type = BFA_PPORT_TYPE_VPORT;
932
933 } else {
934 port_attr->port_type = BFA_PPORT_TYPE_UNKNOWN;
935 port_attr->state = BFA_PORT_UNINIT;
936 }
937
938}
939
940
diff --git a/drivers/scsi/bfa/bfa_fcs_port.c b/drivers/scsi/bfa/bfa_fcs_port.c
new file mode 100644
index 000000000000..9c4b24e62de1
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_fcs_port.c
@@ -0,0 +1,68 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * bfa_fcs_pport.c BFA FCS PPORT ( physical port)
20 */
21
22#include <fcs/bfa_fcs.h>
23#include <bfa_svc.h>
24#include <fcs/bfa_fcs_fabric.h>
25#include "fcs_trcmod.h"
26#include "fcs.h"
27#include "fcs_fabric.h"
28#include "fcs_port.h"
29
30BFA_TRC_FILE(FCS, PPORT);
31
32static void
33bfa_fcs_pport_event_handler(void *cbarg, bfa_pport_event_t event)
34{
35 struct bfa_fcs_s *fcs = cbarg;
36
37 bfa_trc(fcs, event);
38
39 switch (event) {
40 case BFA_PPORT_LINKUP:
41 bfa_fcs_fabric_link_up(&fcs->fabric);
42 break;
43
44 case BFA_PPORT_LINKDOWN:
45 bfa_fcs_fabric_link_down(&fcs->fabric);
46 break;
47
48 case BFA_PPORT_TRUNK_LINKDOWN:
49 bfa_assert(0);
50 break;
51
52 default:
53 bfa_assert(0);
54 }
55}
56
57void
58bfa_fcs_pport_modinit(struct bfa_fcs_s *fcs)
59{
60 bfa_pport_event_register(fcs->bfa, bfa_fcs_pport_event_handler,
61 fcs);
62}
63
64void
65bfa_fcs_pport_modexit(struct bfa_fcs_s *fcs)
66{
67 bfa_fcs_modexit_comp(fcs);
68}
diff --git a/drivers/scsi/bfa/bfa_fcs_uf.c b/drivers/scsi/bfa/bfa_fcs_uf.c
new file mode 100644
index 000000000000..ad01db6444b2
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_fcs_uf.c
@@ -0,0 +1,105 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * bfa_fcs_uf.c BFA FCS UF ( Unsolicited Frames)
20 */
21
22#include <fcs/bfa_fcs.h>
23#include <bfa_svc.h>
24#include <fcs/bfa_fcs_fabric.h>
25#include "fcs.h"
26#include "fcs_trcmod.h"
27#include "fcs_fabric.h"
28#include "fcs_uf.h"
29
30BFA_TRC_FILE(FCS, UF);
31
32/**
33 * BFA callback for unsolicited frame receive handler.
34 *
35 * @param[in] cbarg callback arg for receive handler
36 * @param[in] uf unsolicited frame descriptor
37 *
38 * @return None
39 */
40static void
41bfa_fcs_uf_recv(void *cbarg, struct bfa_uf_s *uf)
42{
43 struct bfa_fcs_s *fcs = (struct bfa_fcs_s *) cbarg;
44 struct fchs_s *fchs = bfa_uf_get_frmbuf(uf);
45 u16 len = bfa_uf_get_frmlen(uf);
46 struct fc_vft_s *vft;
47 struct bfa_fcs_fabric_s *fabric;
48
49 /**
50 * check for VFT header
51 */
52 if (fchs->routing == FC_RTG_EXT_HDR &&
53 fchs->cat_info == FC_CAT_VFT_HDR) {
54 bfa_stats(fcs, uf.tagged);
55 vft = bfa_uf_get_frmbuf(uf);
56 if (fcs->port_vfid == vft->vf_id)
57 fabric = &fcs->fabric;
58 else
59 fabric = bfa_fcs_vf_lookup(fcs, (u16) vft->vf_id);
60
61 /**
62 * drop frame if vfid is unknown
63 */
64 if (!fabric) {
65 bfa_assert(0);
66 bfa_stats(fcs, uf.vfid_unknown);
67 bfa_uf_free(uf);
68 return;
69 }
70
71 /**
72 * skip vft header
73 */
74 fchs = (struct fchs_s *) (vft + 1);
75 len -= sizeof(struct fc_vft_s);
76
77 bfa_trc(fcs, vft->vf_id);
78 } else {
79 bfa_stats(fcs, uf.untagged);
80 fabric = &fcs->fabric;
81 }
82
83 bfa_trc(fcs, ((u32 *) fchs)[0]);
84 bfa_trc(fcs, ((u32 *) fchs)[1]);
85 bfa_trc(fcs, ((u32 *) fchs)[2]);
86 bfa_trc(fcs, ((u32 *) fchs)[3]);
87 bfa_trc(fcs, ((u32 *) fchs)[4]);
88 bfa_trc(fcs, ((u32 *) fchs)[5]);
89 bfa_trc(fcs, len);
90
91 bfa_fcs_fabric_uf_recv(fabric, fchs, len);
92 bfa_uf_free(uf);
93}
94
95void
96bfa_fcs_uf_modinit(struct bfa_fcs_s *fcs)
97{
98 bfa_uf_recv_register(fcs->bfa, bfa_fcs_uf_recv, fcs);
99}
100
101void
102bfa_fcs_uf_modexit(struct bfa_fcs_s *fcs)
103{
104 bfa_fcs_modexit_comp(fcs);
105}
diff --git a/drivers/scsi/bfa/bfa_fcxp.c b/drivers/scsi/bfa/bfa_fcxp.c
new file mode 100644
index 000000000000..4754a0e9006a
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_fcxp.c
@@ -0,0 +1,782 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#include <bfa.h>
19#include <bfi/bfi_uf.h>
20#include <cs/bfa_debug.h>
21
22BFA_TRC_FILE(HAL, FCXP);
23BFA_MODULE(fcxp);
24
25/**
26 * forward declarations
27 */
28static void __bfa_fcxp_send_cbfn(void *cbarg, bfa_boolean_t complete);
29static void hal_fcxp_rx_plog(struct bfa_s *bfa, struct bfa_fcxp_s *fcxp,
30 struct bfi_fcxp_send_rsp_s *fcxp_rsp);
31static void hal_fcxp_tx_plog(struct bfa_s *bfa, u32 reqlen,
32 struct bfa_fcxp_s *fcxp, struct fchs_s *fchs);
33static void bfa_fcxp_qresume(void *cbarg);
34static void bfa_fcxp_queue(struct bfa_fcxp_s *fcxp,
35 struct bfi_fcxp_send_req_s *send_req);
36
37/**
38 * fcxp_pvt BFA FCXP private functions
39 */
40
41static void
42claim_fcxp_req_rsp_mem(struct bfa_fcxp_mod_s *mod, struct bfa_meminfo_s *mi)
43{
44 u8 *dm_kva = NULL;
45 u64 dm_pa;
46 u32 buf_pool_sz;
47
48 dm_kva = bfa_meminfo_dma_virt(mi);
49 dm_pa = bfa_meminfo_dma_phys(mi);
50
51 buf_pool_sz = mod->req_pld_sz * mod->num_fcxps;
52
53 /*
54 * Initialize the fcxp req payload list
55 */
56 mod->req_pld_list_kva = dm_kva;
57 mod->req_pld_list_pa = dm_pa;
58 dm_kva += buf_pool_sz;
59 dm_pa += buf_pool_sz;
60 bfa_os_memset(mod->req_pld_list_kva, 0, buf_pool_sz);
61
62 /*
63 * Initialize the fcxp rsp payload list
64 */
65 buf_pool_sz = mod->rsp_pld_sz * mod->num_fcxps;
66 mod->rsp_pld_list_kva = dm_kva;
67 mod->rsp_pld_list_pa = dm_pa;
68 dm_kva += buf_pool_sz;
69 dm_pa += buf_pool_sz;
70 bfa_os_memset(mod->rsp_pld_list_kva, 0, buf_pool_sz);
71
72 bfa_meminfo_dma_virt(mi) = dm_kva;
73 bfa_meminfo_dma_phys(mi) = dm_pa;
74}
75
76static void
77claim_fcxps_mem(struct bfa_fcxp_mod_s *mod, struct bfa_meminfo_s *mi)
78{
79 u16 i;
80 struct bfa_fcxp_s *fcxp;
81
82 fcxp = (struct bfa_fcxp_s *) bfa_meminfo_kva(mi);
83 bfa_os_memset(fcxp, 0, sizeof(struct bfa_fcxp_s) * mod->num_fcxps);
84
85 INIT_LIST_HEAD(&mod->fcxp_free_q);
86 INIT_LIST_HEAD(&mod->fcxp_active_q);
87
88 mod->fcxp_list = fcxp;
89
90 for (i = 0; i < mod->num_fcxps; i++) {
91 fcxp->fcxp_mod = mod;
92 fcxp->fcxp_tag = i;
93
94 list_add_tail(&fcxp->qe, &mod->fcxp_free_q);
95 bfa_reqq_winit(&fcxp->reqq_wqe, bfa_fcxp_qresume, fcxp);
96 fcxp->reqq_waiting = BFA_FALSE;
97
98 fcxp = fcxp + 1;
99 }
100
101 bfa_meminfo_kva(mi) = (void *)fcxp;
102}
103
104static void
105bfa_fcxp_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len,
106 u32 *dm_len)
107{
108 u16 num_fcxp_reqs = cfg->fwcfg.num_fcxp_reqs;
109
110 if (num_fcxp_reqs == 0)
111 return;
112
113 /*
114 * Account for req/rsp payload
115 */
116 *dm_len += BFA_FCXP_MAX_IBUF_SZ * num_fcxp_reqs;
117 if (cfg->drvcfg.min_cfg)
118 *dm_len += BFA_FCXP_MAX_IBUF_SZ * num_fcxp_reqs;
119 else
120 *dm_len += BFA_FCXP_MAX_LBUF_SZ * num_fcxp_reqs;
121
122 /*
123 * Account for fcxp structs
124 */
125 *ndm_len += sizeof(struct bfa_fcxp_s) * num_fcxp_reqs;
126}
127
128static void
129bfa_fcxp_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
130 struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev)
131{
132 struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
133
134 bfa_os_memset(mod, 0, sizeof(struct bfa_fcxp_mod_s));
135 mod->bfa = bfa;
136 mod->num_fcxps = cfg->fwcfg.num_fcxp_reqs;
137
138 /**
139 * Initialize FCXP request and response payload sizes.
140 */
141 mod->req_pld_sz = mod->rsp_pld_sz = BFA_FCXP_MAX_IBUF_SZ;
142 if (!cfg->drvcfg.min_cfg)
143 mod->rsp_pld_sz = BFA_FCXP_MAX_LBUF_SZ;
144
145 INIT_LIST_HEAD(&mod->wait_q);
146
147 claim_fcxp_req_rsp_mem(mod, meminfo);
148 claim_fcxps_mem(mod, meminfo);
149}
150
151static void
152bfa_fcxp_initdone(struct bfa_s *bfa)
153{
154}
155
156static void
157bfa_fcxp_detach(struct bfa_s *bfa)
158{
159}
160
161static void
162bfa_fcxp_start(struct bfa_s *bfa)
163{
164}
165
166static void
167bfa_fcxp_stop(struct bfa_s *bfa)
168{
169}
170
171static void
172bfa_fcxp_iocdisable(struct bfa_s *bfa)
173{
174 struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
175 struct bfa_fcxp_s *fcxp;
176 struct list_head *qe, *qen;
177
178 list_for_each_safe(qe, qen, &mod->fcxp_active_q) {
179 fcxp = (struct bfa_fcxp_s *) qe;
180 if (fcxp->caller == NULL) {
181 fcxp->send_cbfn(fcxp->caller, fcxp, fcxp->send_cbarg,
182 BFA_STATUS_IOC_FAILURE, 0, 0, NULL);
183 bfa_fcxp_free(fcxp);
184 } else {
185 fcxp->rsp_status = BFA_STATUS_IOC_FAILURE;
186 bfa_cb_queue(bfa, &fcxp->hcb_qe,
187 __bfa_fcxp_send_cbfn, fcxp);
188 }
189 }
190}
191
192static struct bfa_fcxp_s *
193bfa_fcxp_get(struct bfa_fcxp_mod_s *fm)
194{
195 struct bfa_fcxp_s *fcxp;
196
197 bfa_q_deq(&fm->fcxp_free_q, &fcxp);
198
199 if (fcxp)
200 list_add_tail(&fcxp->qe, &fm->fcxp_active_q);
201
202 return (fcxp);
203}
204
205static void
206bfa_fcxp_put(struct bfa_fcxp_s *fcxp)
207{
208 struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;
209 struct bfa_fcxp_wqe_s *wqe;
210
211 bfa_q_deq(&mod->wait_q, &wqe);
212 if (wqe) {
213 bfa_trc(mod->bfa, fcxp->fcxp_tag);
214 wqe->alloc_cbfn(wqe->alloc_cbarg, fcxp);
215 return;
216 }
217
218 bfa_assert(bfa_q_is_on_q(&mod->fcxp_active_q, fcxp));
219 list_del(&fcxp->qe);
220 list_add_tail(&fcxp->qe, &mod->fcxp_free_q);
221}
222
223static void
224bfa_fcxp_null_comp(void *bfad_fcxp, struct bfa_fcxp_s *fcxp, void *cbarg,
225 bfa_status_t req_status, u32 rsp_len,
226 u32 resid_len, struct fchs_s *rsp_fchs)
227{
228 /**discarded fcxp completion */
229}
230
231static void
232__bfa_fcxp_send_cbfn(void *cbarg, bfa_boolean_t complete)
233{
234 struct bfa_fcxp_s *fcxp = cbarg;
235
236 if (complete) {
237 fcxp->send_cbfn(fcxp->caller, fcxp, fcxp->send_cbarg,
238 fcxp->rsp_status, fcxp->rsp_len,
239 fcxp->residue_len, &fcxp->rsp_fchs);
240 } else {
241 bfa_fcxp_free(fcxp);
242 }
243}
244
245static void
246hal_fcxp_send_comp(struct bfa_s *bfa, struct bfi_fcxp_send_rsp_s *fcxp_rsp)
247{
248 struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
249 struct bfa_fcxp_s *fcxp;
250 u16 fcxp_tag = bfa_os_ntohs(fcxp_rsp->fcxp_tag);
251
252 bfa_trc(bfa, fcxp_tag);
253
254 fcxp_rsp->rsp_len = bfa_os_ntohl(fcxp_rsp->rsp_len);
255
256 /**
257 * @todo f/w should not set residue to non-0 when everything
258 * is received.
259 */
260 if (fcxp_rsp->req_status == BFA_STATUS_OK)
261 fcxp_rsp->residue_len = 0;
262 else
263 fcxp_rsp->residue_len = bfa_os_ntohl(fcxp_rsp->residue_len);
264
265 fcxp = BFA_FCXP_FROM_TAG(mod, fcxp_tag);
266
267 bfa_assert(fcxp->send_cbfn != NULL);
268
269 hal_fcxp_rx_plog(mod->bfa, fcxp, fcxp_rsp);
270
271 if (fcxp->send_cbfn != NULL) {
272 if (fcxp->caller == NULL) {
273 bfa_trc(mod->bfa, fcxp->fcxp_tag);
274
275 fcxp->send_cbfn(fcxp->caller, fcxp, fcxp->send_cbarg,
276 fcxp_rsp->req_status, fcxp_rsp->rsp_len,
277 fcxp_rsp->residue_len, &fcxp_rsp->fchs);
278 /*
279 * fcxp automatically freed on return from the callback
280 */
281 bfa_fcxp_free(fcxp);
282 } else {
283 bfa_trc(mod->bfa, fcxp->fcxp_tag);
284 fcxp->rsp_status = fcxp_rsp->req_status;
285 fcxp->rsp_len = fcxp_rsp->rsp_len;
286 fcxp->residue_len = fcxp_rsp->residue_len;
287 fcxp->rsp_fchs = fcxp_rsp->fchs;
288
289 bfa_cb_queue(bfa, &fcxp->hcb_qe,
290 __bfa_fcxp_send_cbfn, fcxp);
291 }
292 } else {
293 bfa_trc(bfa, fcxp_tag);
294 }
295}
296
297static void
298hal_fcxp_set_local_sges(struct bfi_sge_s *sge, u32 reqlen, u64 req_pa)
299{
300 union bfi_addr_u sga_zero = { {0} };
301
302 sge->sg_len = reqlen;
303 sge->flags = BFI_SGE_DATA_LAST;
304 bfa_dma_addr_set(sge[0].sga, req_pa);
305 bfa_sge_to_be(sge);
306 sge++;
307
308 sge->sga = sga_zero;
309 sge->sg_len = reqlen;
310 sge->flags = BFI_SGE_PGDLEN;
311 bfa_sge_to_be(sge);
312}
313
314static void
315hal_fcxp_tx_plog(struct bfa_s *bfa, u32 reqlen, struct bfa_fcxp_s *fcxp,
316 struct fchs_s *fchs)
317{
318 /*
319 * TODO: TX ox_id
320 */
321 if (reqlen > 0) {
322 if (fcxp->use_ireqbuf) {
323 u32 pld_w0 =
324 *((u32 *) BFA_FCXP_REQ_PLD(fcxp));
325
326 bfa_plog_fchdr_and_pl(bfa->plog, BFA_PL_MID_HAL_FCXP,
327 BFA_PL_EID_TX,
328 reqlen + sizeof(struct fchs_s), fchs, pld_w0);
329 } else {
330 bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP,
331 BFA_PL_EID_TX, reqlen + sizeof(struct fchs_s),
332 fchs);
333 }
334 } else {
335 bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP, BFA_PL_EID_TX,
336 reqlen + sizeof(struct fchs_s), fchs);
337 }
338}
339
340static void
341hal_fcxp_rx_plog(struct bfa_s *bfa, struct bfa_fcxp_s *fcxp,
342 struct bfi_fcxp_send_rsp_s *fcxp_rsp)
343{
344 if (fcxp_rsp->rsp_len > 0) {
345 if (fcxp->use_irspbuf) {
346 u32 pld_w0 =
347 *((u32 *) BFA_FCXP_RSP_PLD(fcxp));
348
349 bfa_plog_fchdr_and_pl(bfa->plog, BFA_PL_MID_HAL_FCXP,
350 BFA_PL_EID_RX,
351 (u16) fcxp_rsp->rsp_len,
352 &fcxp_rsp->fchs, pld_w0);
353 } else {
354 bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP,
355 BFA_PL_EID_RX,
356 (u16) fcxp_rsp->rsp_len,
357 &fcxp_rsp->fchs);
358 }
359 } else {
360 bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP, BFA_PL_EID_RX,
361 (u16) fcxp_rsp->rsp_len, &fcxp_rsp->fchs);
362 }
363}
364
365/**
366 * Handler to resume sending fcxp when space in available in cpe queue.
367 */
368static void
369bfa_fcxp_qresume(void *cbarg)
370{
371 struct bfa_fcxp_s *fcxp = cbarg;
372 struct bfa_s *bfa = fcxp->fcxp_mod->bfa;
373 struct bfi_fcxp_send_req_s *send_req;
374
375 fcxp->reqq_waiting = BFA_FALSE;
376 send_req = bfa_reqq_next(bfa, BFA_REQQ_FCXP);
377 bfa_fcxp_queue(fcxp, send_req);
378}
379
380/**
381 * Queue fcxp send request to foimrware.
382 */
383static void
384bfa_fcxp_queue(struct bfa_fcxp_s *fcxp, struct bfi_fcxp_send_req_s *send_req)
385{
386 struct bfa_s *bfa = fcxp->fcxp_mod->bfa;
387 struct bfa_fcxp_req_info_s *reqi = &fcxp->req_info;
388 struct bfa_fcxp_rsp_info_s *rspi = &fcxp->rsp_info;
389 struct bfa_rport_s *rport = reqi->bfa_rport;
390
391 bfi_h2i_set(send_req->mh, BFI_MC_FCXP, BFI_FCXP_H2I_SEND_REQ,
392 bfa_lpuid(bfa));
393
394 send_req->fcxp_tag = bfa_os_htons(fcxp->fcxp_tag);
395 if (rport) {
396 send_req->rport_fw_hndl = rport->fw_handle;
397 send_req->max_frmsz = bfa_os_htons(rport->rport_info.max_frmsz);
398 if (send_req->max_frmsz == 0)
399 send_req->max_frmsz = bfa_os_htons(FC_MAX_PDUSZ);
400 } else {
401 send_req->rport_fw_hndl = 0;
402 send_req->max_frmsz = bfa_os_htons(FC_MAX_PDUSZ);
403 }
404
405 send_req->vf_id = bfa_os_htons(reqi->vf_id);
406 send_req->lp_tag = reqi->lp_tag;
407 send_req->class = reqi->class;
408 send_req->rsp_timeout = rspi->rsp_timeout;
409 send_req->cts = reqi->cts;
410 send_req->fchs = reqi->fchs;
411
412 send_req->req_len = bfa_os_htonl(reqi->req_tot_len);
413 send_req->rsp_maxlen = bfa_os_htonl(rspi->rsp_maxlen);
414
415 /*
416 * setup req sgles
417 */
418 if (fcxp->use_ireqbuf == 1) {
419 hal_fcxp_set_local_sges(send_req->req_sge, reqi->req_tot_len,
420 BFA_FCXP_REQ_PLD_PA(fcxp));
421 } else {
422 if (fcxp->nreq_sgles > 0) {
423 bfa_assert(fcxp->nreq_sgles == 1);
424 hal_fcxp_set_local_sges(send_req->req_sge,
425 reqi->req_tot_len,
426 fcxp->req_sga_cbfn(fcxp->caller,
427 0));
428 } else {
429 bfa_assert(reqi->req_tot_len == 0);
430 hal_fcxp_set_local_sges(send_req->rsp_sge, 0, 0);
431 }
432 }
433
434 /*
435 * setup rsp sgles
436 */
437 if (fcxp->use_irspbuf == 1) {
438 bfa_assert(rspi->rsp_maxlen <= BFA_FCXP_MAX_LBUF_SZ);
439
440 hal_fcxp_set_local_sges(send_req->rsp_sge, rspi->rsp_maxlen,
441 BFA_FCXP_RSP_PLD_PA(fcxp));
442
443 } else {
444 if (fcxp->nrsp_sgles > 0) {
445 bfa_assert(fcxp->nrsp_sgles == 1);
446 hal_fcxp_set_local_sges(send_req->rsp_sge,
447 rspi->rsp_maxlen,
448 fcxp->rsp_sga_cbfn(fcxp->caller,
449 0));
450 } else {
451 bfa_assert(rspi->rsp_maxlen == 0);
452 hal_fcxp_set_local_sges(send_req->rsp_sge, 0, 0);
453 }
454 }
455
456 hal_fcxp_tx_plog(bfa, reqi->req_tot_len, fcxp, &reqi->fchs);
457
458 bfa_reqq_produce(bfa, BFA_REQQ_FCXP);
459
460 bfa_trc(bfa, bfa_reqq_pi(bfa, BFA_REQQ_FCXP));
461 bfa_trc(bfa, bfa_reqq_ci(bfa, BFA_REQQ_FCXP));
462}
463
464
465/**
466 * hal_fcxp_api BFA FCXP API
467 */
468
469/**
470 * Allocate an FCXP instance to send a response or to send a request
471 * that has a response. Request/response buffers are allocated by caller.
472 *
473 * @param[in] bfa BFA bfa instance
474 * @param[in] nreq_sgles Number of SG elements required for request
475 * buffer. 0, if fcxp internal buffers are used.
476 * Use bfa_fcxp_get_reqbuf() to get the
477 * internal req buffer.
478 * @param[in] req_sgles SG elements describing request buffer. Will be
479 * copied in by BFA and hence can be freed on
480 * return from this function.
481 * @param[in] get_req_sga function ptr to be called to get a request SG
482 * Address (given the sge index).
483 * @param[in] get_req_sglen function ptr to be called to get a request SG
484 * len (given the sge index).
485 * @param[in] get_rsp_sga function ptr to be called to get a response SG
486 * Address (given the sge index).
487 * @param[in] get_rsp_sglen function ptr to be called to get a response SG
488 * len (given the sge index).
489 *
490 * @return FCXP instance. NULL on failure.
491 */
492struct bfa_fcxp_s *
493bfa_fcxp_alloc(void *caller, struct bfa_s *bfa, int nreq_sgles,
494 int nrsp_sgles, bfa_fcxp_get_sgaddr_t req_sga_cbfn,
495 bfa_fcxp_get_sglen_t req_sglen_cbfn,
496 bfa_fcxp_get_sgaddr_t rsp_sga_cbfn,
497 bfa_fcxp_get_sglen_t rsp_sglen_cbfn)
498{
499 struct bfa_fcxp_s *fcxp = NULL;
500 u32 nreq_sgpg, nrsp_sgpg;
501
502 bfa_assert(bfa != NULL);
503
504 fcxp = bfa_fcxp_get(BFA_FCXP_MOD(bfa));
505 if (fcxp == NULL)
506 return (NULL);
507
508 bfa_trc(bfa, fcxp->fcxp_tag);
509
510 fcxp->caller = caller;
511
512 if (nreq_sgles == 0) {
513 fcxp->use_ireqbuf = 1;
514 } else {
515 bfa_assert(req_sga_cbfn != NULL);
516 bfa_assert(req_sglen_cbfn != NULL);
517
518 fcxp->use_ireqbuf = 0;
519 fcxp->req_sga_cbfn = req_sga_cbfn;
520 fcxp->req_sglen_cbfn = req_sglen_cbfn;
521
522 fcxp->nreq_sgles = nreq_sgles;
523
524 /*
525 * alloc required sgpgs
526 */
527 if (nreq_sgles > BFI_SGE_INLINE) {
528 nreq_sgpg = BFA_SGPG_NPAGE(nreq_sgles);
529
530 if (bfa_sgpg_malloc
531 (bfa, &fcxp->req_sgpg_q, nreq_sgpg)
532 != BFA_STATUS_OK) {
533 /* bfa_sgpg_wait(bfa, &fcxp->req_sgpg_wqe,
534 nreq_sgpg); */
535 /*
536 * TODO
537 */
538 }
539 }
540 }
541
542 if (nrsp_sgles == 0) {
543 fcxp->use_irspbuf = 1;
544 } else {
545 bfa_assert(rsp_sga_cbfn != NULL);
546 bfa_assert(rsp_sglen_cbfn != NULL);
547
548 fcxp->use_irspbuf = 0;
549 fcxp->rsp_sga_cbfn = rsp_sga_cbfn;
550 fcxp->rsp_sglen_cbfn = rsp_sglen_cbfn;
551
552 fcxp->nrsp_sgles = nrsp_sgles;
553 /*
554 * alloc required sgpgs
555 */
556 if (nrsp_sgles > BFI_SGE_INLINE) {
557 nrsp_sgpg = BFA_SGPG_NPAGE(nreq_sgles);
558
559 if (bfa_sgpg_malloc
560 (bfa, &fcxp->rsp_sgpg_q, nrsp_sgpg)
561 != BFA_STATUS_OK) {
562 /* bfa_sgpg_wait(bfa, &fcxp->rsp_sgpg_wqe,
563 nrsp_sgpg); */
564 /*
565 * TODO
566 */
567 }
568 }
569 }
570
571 return (fcxp);
572}
573
574/**
575 * Get the internal request buffer pointer
576 *
577 * @param[in] fcxp BFA fcxp pointer
578 *
579 * @return pointer to the internal request buffer
580 */
581void *
582bfa_fcxp_get_reqbuf(struct bfa_fcxp_s *fcxp)
583{
584 struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;
585 void *reqbuf;
586
587 bfa_assert(fcxp->use_ireqbuf == 1);
588 reqbuf = ((u8 *)mod->req_pld_list_kva) +
589 fcxp->fcxp_tag * mod->req_pld_sz;
590 return reqbuf;
591}
592
593u32
594bfa_fcxp_get_reqbufsz(struct bfa_fcxp_s *fcxp)
595{
596 struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;
597
598 return mod->req_pld_sz;
599}
600
601/**
602 * Get the internal response buffer pointer
603 *
604 * @param[in] fcxp BFA fcxp pointer
605 *
606 * @return pointer to the internal request buffer
607 */
608void *
609bfa_fcxp_get_rspbuf(struct bfa_fcxp_s *fcxp)
610{
611 struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;
612 void *rspbuf;
613
614 bfa_assert(fcxp->use_irspbuf == 1);
615
616 rspbuf = ((u8 *)mod->rsp_pld_list_kva) +
617 fcxp->fcxp_tag * mod->rsp_pld_sz;
618 return rspbuf;
619}
620
621/**
622 * Free the BFA FCXP
623 *
624 * @param[in] fcxp BFA fcxp pointer
625 *
626 * @return void
627 */
628void
629bfa_fcxp_free(struct bfa_fcxp_s *fcxp)
630{
631 struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;
632
633 bfa_assert(fcxp != NULL);
634 bfa_trc(mod->bfa, fcxp->fcxp_tag);
635 bfa_fcxp_put(fcxp);
636}
637
638/**
639 * Send a FCXP request
640 *
641 * @param[in] fcxp BFA fcxp pointer
642 * @param[in] rport BFA rport pointer. Could be left NULL for WKA rports
643 * @param[in] vf_id virtual Fabric ID
644 * @param[in] lp_tag lport tag
645 * @param[in] cts use Continous sequence
646 * @param[in] cos fc Class of Service
647 * @param[in] reqlen request length, does not include FCHS length
648 * @param[in] fchs fc Header Pointer. The header content will be copied
649 * in by BFA.
650 *
651 * @param[in] cbfn call back function to be called on receiving
652 * the response
653 * @param[in] cbarg arg for cbfn
654 * @param[in] rsp_timeout
655 * response timeout
656 *
657 * @return bfa_status_t
658 */
659void
660bfa_fcxp_send(struct bfa_fcxp_s *fcxp, struct bfa_rport_s *rport,
661 u16 vf_id, u8 lp_tag, bfa_boolean_t cts, enum fc_cos cos,
662 u32 reqlen, struct fchs_s *fchs, bfa_cb_fcxp_send_t cbfn,
663 void *cbarg, u32 rsp_maxlen, u8 rsp_timeout)
664{
665 struct bfa_s *bfa = fcxp->fcxp_mod->bfa;
666 struct bfa_fcxp_req_info_s *reqi = &fcxp->req_info;
667 struct bfa_fcxp_rsp_info_s *rspi = &fcxp->rsp_info;
668 struct bfi_fcxp_send_req_s *send_req;
669
670 bfa_trc(bfa, fcxp->fcxp_tag);
671
672 /**
673 * setup request/response info
674 */
675 reqi->bfa_rport = rport;
676 reqi->vf_id = vf_id;
677 reqi->lp_tag = lp_tag;
678 reqi->class = cos;
679 rspi->rsp_timeout = rsp_timeout;
680 reqi->cts = cts;
681 reqi->fchs = *fchs;
682 reqi->req_tot_len = reqlen;
683 rspi->rsp_maxlen = rsp_maxlen;
684 fcxp->send_cbfn = cbfn ? cbfn : bfa_fcxp_null_comp;
685 fcxp->send_cbarg = cbarg;
686
687 /**
688 * If no room in CPE queue, wait for
689 */
690 send_req = bfa_reqq_next(bfa, BFA_REQQ_FCXP);
691 if (!send_req) {
692 bfa_trc(bfa, fcxp->fcxp_tag);
693 fcxp->reqq_waiting = BFA_TRUE;
694 bfa_reqq_wait(bfa, BFA_REQQ_FCXP, &fcxp->reqq_wqe);
695 return;
696 }
697
698 bfa_fcxp_queue(fcxp, send_req);
699}
700
701/**
702 * Abort a BFA FCXP
703 *
704 * @param[in] fcxp BFA fcxp pointer
705 *
706 * @return void
707 */
708bfa_status_t
709bfa_fcxp_abort(struct bfa_fcxp_s *fcxp)
710{
711 bfa_assert(0);
712 return (BFA_STATUS_OK);
713}
714
715void
716bfa_fcxp_alloc_wait(struct bfa_s *bfa, struct bfa_fcxp_wqe_s *wqe,
717 bfa_fcxp_alloc_cbfn_t alloc_cbfn, void *alloc_cbarg)
718{
719 struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
720
721 bfa_assert(list_empty(&mod->fcxp_free_q));
722
723 wqe->alloc_cbfn = alloc_cbfn;
724 wqe->alloc_cbarg = alloc_cbarg;
725 list_add_tail(&wqe->qe, &mod->wait_q);
726}
727
728void
729bfa_fcxp_walloc_cancel(struct bfa_s *bfa, struct bfa_fcxp_wqe_s *wqe)
730{
731 struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
732
733 bfa_assert(bfa_q_is_on_q(&mod->wait_q, wqe));
734 list_del(&wqe->qe);
735}
736
737void
738bfa_fcxp_discard(struct bfa_fcxp_s *fcxp)
739{
740 /**
741 * If waiting for room in request queue, cancel reqq wait
742 * and free fcxp.
743 */
744 if (fcxp->reqq_waiting) {
745 fcxp->reqq_waiting = BFA_FALSE;
746 bfa_reqq_wcancel(&fcxp->reqq_wqe);
747 bfa_fcxp_free(fcxp);
748 return;
749 }
750
751 fcxp->send_cbfn = bfa_fcxp_null_comp;
752}
753
754
755
756/**
757 * hal_fcxp_public BFA FCXP public functions
758 */
759
760void
761bfa_fcxp_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
762{
763 switch (msg->mhdr.msg_id) {
764 case BFI_FCXP_I2H_SEND_RSP:
765 hal_fcxp_send_comp(bfa, (struct bfi_fcxp_send_rsp_s *) msg);
766 break;
767
768 default:
769 bfa_trc(bfa, msg->mhdr.msg_id);
770 bfa_assert(0);
771 }
772}
773
774u32
775bfa_fcxp_get_maxrsp(struct bfa_s *bfa)
776{
777 struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
778
779 return mod->rsp_pld_sz;
780}
781
782
diff --git a/drivers/scsi/bfa/bfa_fcxp_priv.h b/drivers/scsi/bfa/bfa_fcxp_priv.h
new file mode 100644
index 000000000000..4cda49397da0
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_fcxp_priv.h
@@ -0,0 +1,138 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFA_FCXP_PRIV_H__
19#define __BFA_FCXP_PRIV_H__
20
21#include <cs/bfa_sm.h>
22#include <protocol/fc.h>
23#include <bfa_svc.h>
24#include <bfi/bfi_fcxp.h>
25
26#define BFA_FCXP_MIN (1)
27#define BFA_FCXP_MAX_IBUF_SZ (2 * 1024 + 256)
28#define BFA_FCXP_MAX_LBUF_SZ (4 * 1024 + 256)
29
30struct bfa_fcxp_mod_s {
31 struct bfa_s *bfa; /* backpointer to BFA */
32 struct bfa_fcxp_s *fcxp_list; /* array of FCXPs */
33 u16 num_fcxps; /* max num FCXP requests */
34 struct list_head fcxp_free_q; /* free FCXPs */
35 struct list_head fcxp_active_q; /* active FCXPs */
36 void *req_pld_list_kva; /* list of FCXP req pld */
37 u64 req_pld_list_pa; /* list of FCXP req pld */
38 void *rsp_pld_list_kva; /* list of FCXP resp pld */
39 u64 rsp_pld_list_pa; /* list of FCXP resp pld */
40 struct list_head wait_q; /* wait queue for free fcxp */
41 u32 req_pld_sz;
42 u32 rsp_pld_sz;
43};
44
45#define BFA_FCXP_MOD(__bfa) (&(__bfa)->modules.fcxp_mod)
46#define BFA_FCXP_FROM_TAG(__mod, __tag) (&(__mod)->fcxp_list[__tag])
47
48typedef void (*fcxp_send_cb_t) (struct bfa_s *ioc, struct bfa_fcxp_s *fcxp,
49 void *cb_arg, bfa_status_t req_status,
50 u32 rsp_len, u32 resid_len,
51 struct fchs_s *rsp_fchs);
52
53/**
54 * Information needed for a FCXP request
55 */
56struct bfa_fcxp_req_info_s {
57 struct bfa_rport_s *bfa_rport; /* Pointer to the bfa rport that was
58 *returned from bfa_rport_create().
59 *This could be left NULL for WKA or for
60 *FCXP interactions before the rport
61 *nexus is established
62 */
63 struct fchs_s fchs; /* request FC header structure */
64 u8 cts; /* continous sequence */
65 u8 class; /* FC class for the request/response */
66 u16 max_frmsz; /* max send frame size */
67 u16 vf_id; /* vsan tag if applicable */
68 u8 lp_tag; /* lport tag */
69 u32 req_tot_len; /* request payload total length */
70};
71
72struct bfa_fcxp_rsp_info_s {
73 struct fchs_s rsp_fchs; /* Response frame's FC header will
74 * be *sent back in this field */
75 u8 rsp_timeout; /* timeout in seconds, 0-no response
76 */
77 u8 rsvd2[3];
78 u32 rsp_maxlen; /* max response length expected */
79};
80
81struct bfa_fcxp_s {
82 struct list_head qe; /* fcxp queue element */
83 bfa_sm_t sm; /* state machine */
84 void *caller; /* driver or fcs */
85 struct bfa_fcxp_mod_s *fcxp_mod;
86 /* back pointer to fcxp mod */
87 u16 fcxp_tag; /* internal tag */
88 struct bfa_fcxp_req_info_s req_info;
89 /* request info */
90 struct bfa_fcxp_rsp_info_s rsp_info;
91 /* response info */
92 u8 use_ireqbuf; /* use internal req buf */
93 u8 use_irspbuf; /* use internal rsp buf */
94 u32 nreq_sgles; /* num request SGLEs */
95 u32 nrsp_sgles; /* num response SGLEs */
96 struct list_head req_sgpg_q; /* SG pages for request buf */
97 struct list_head req_sgpg_wqe; /* wait queue for req SG page */
98 struct list_head rsp_sgpg_q; /* SG pages for response buf */
99 struct list_head rsp_sgpg_wqe; /* wait queue for rsp SG page */
100
101 bfa_fcxp_get_sgaddr_t req_sga_cbfn;
102 /* SG elem addr user function */
103 bfa_fcxp_get_sglen_t req_sglen_cbfn;
104 /* SG elem len user function */
105 bfa_fcxp_get_sgaddr_t rsp_sga_cbfn;
106 /* SG elem addr user function */
107 bfa_fcxp_get_sglen_t rsp_sglen_cbfn;
108 /* SG elem len user function */
109 bfa_cb_fcxp_send_t send_cbfn; /* send completion callback */
110 void *send_cbarg; /* callback arg */
111 struct bfa_sge_s req_sge[BFA_FCXP_MAX_SGES];
112 /* req SG elems */
113 struct bfa_sge_s rsp_sge[BFA_FCXP_MAX_SGES];
114 /* rsp SG elems */
115 u8 rsp_status; /* comp: rsp status */
116 u32 rsp_len; /* comp: actual response len */
117 u32 residue_len; /* comp: residual rsp length */
118 struct fchs_s rsp_fchs; /* comp: response fchs */
119 struct bfa_cb_qe_s hcb_qe; /* comp: callback qelem */
120 struct bfa_reqq_wait_s reqq_wqe;
121 bfa_boolean_t reqq_waiting;
122};
123
124#define BFA_FCXP_REQ_PLD(_fcxp) (bfa_fcxp_get_reqbuf(_fcxp))
125
126#define BFA_FCXP_RSP_FCHS(_fcxp) (&((_fcxp)->rsp_info.fchs))
127#define BFA_FCXP_RSP_PLD(_fcxp) (bfa_fcxp_get_rspbuf(_fcxp))
128
129#define BFA_FCXP_REQ_PLD_PA(_fcxp) \
130 ((_fcxp)->fcxp_mod->req_pld_list_pa + \
131 ((_fcxp)->fcxp_mod->req_pld_sz * (_fcxp)->fcxp_tag))
132
133#define BFA_FCXP_RSP_PLD_PA(_fcxp) \
134 ((_fcxp)->fcxp_mod->rsp_pld_list_pa + \
135 ((_fcxp)->fcxp_mod->rsp_pld_sz * (_fcxp)->fcxp_tag))
136
137void bfa_fcxp_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
138#endif /* __BFA_FCXP_PRIV_H__ */
diff --git a/drivers/scsi/bfa/bfa_fwimg_priv.h b/drivers/scsi/bfa/bfa_fwimg_priv.h
new file mode 100644
index 000000000000..1ec1355924d9
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_fwimg_priv.h
@@ -0,0 +1,31 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFA_FWIMG_PRIV_H__
19#define __BFA_FWIMG_PRIV_H__
20
21#define BFI_FLASH_CHUNK_SZ 256 /* Flash chunk size */
22#define BFI_FLASH_CHUNK_SZ_WORDS (BFI_FLASH_CHUNK_SZ/sizeof(u32))
23
24extern u32 *bfi_image_ct_get_chunk(u32 off);
25extern u32 bfi_image_ct_size;
26extern u32 *bfi_image_cb_get_chunk(u32 off);
27extern u32 bfi_image_cb_size;
28extern u32 *bfi_image_cb;
29extern u32 *bfi_image_ct;
30
31#endif /* __BFA_FWIMG_PRIV_H__ */
diff --git a/drivers/scsi/bfa/bfa_hw_cb.c b/drivers/scsi/bfa/bfa_hw_cb.c
new file mode 100644
index 000000000000..ede1438619e2
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_hw_cb.c
@@ -0,0 +1,142 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#include <bfa_priv.h>
19#include <bfi/bfi_cbreg.h>
20
21void
22bfa_hwcb_reginit(struct bfa_s *bfa)
23{
24 struct bfa_iocfc_regs_s *bfa_regs = &bfa->iocfc.bfa_regs;
25 bfa_os_addr_t kva = bfa_ioc_bar0(&bfa->ioc);
26 int i, q, fn = bfa_ioc_pcifn(&bfa->ioc);
27
28 if (fn == 0) {
29 bfa_regs->intr_status = (kva + HOSTFN0_INT_STATUS);
30 bfa_regs->intr_mask = (kva + HOSTFN0_INT_MSK);
31 } else {
32 bfa_regs->intr_status = (kva + HOSTFN1_INT_STATUS);
33 bfa_regs->intr_mask = (kva + HOSTFN1_INT_MSK);
34 }
35
36 for (i = 0; i < BFI_IOC_MAX_CQS; i++) {
37 /*
38 * CPE registers
39 */
40 q = CPE_Q_NUM(fn, i);
41 bfa_regs->cpe_q_pi[i] = (kva + CPE_Q_PI(q));
42 bfa_regs->cpe_q_ci[i] = (kva + CPE_Q_CI(q));
43 bfa_regs->cpe_q_depth[i] = (kva + CPE_Q_DEPTH(q));
44
45 /*
46 * RME registers
47 */
48 q = CPE_Q_NUM(fn, i);
49 bfa_regs->rme_q_pi[i] = (kva + RME_Q_PI(q));
50 bfa_regs->rme_q_ci[i] = (kva + RME_Q_CI(q));
51 bfa_regs->rme_q_depth[i] = (kva + RME_Q_DEPTH(q));
52 }
53}
54
55void
56bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq)
57{
58}
59
60static void
61bfa_hwcb_rspq_ack_msix(struct bfa_s *bfa, int rspq)
62{
63 bfa_reg_write(bfa->iocfc.bfa_regs.intr_status,
64 __HFN_INT_RME_Q0 << RME_Q_NUM(bfa_ioc_pcifn(&bfa->ioc), rspq));
65}
66
67void
68bfa_hwcb_msix_getvecs(struct bfa_s *bfa, u32 *msix_vecs_bmap,
69 u32 *num_vecs, u32 *max_vec_bit)
70{
71#define __HFN_NUMINTS 13
72 if (bfa_ioc_pcifn(&bfa->ioc) == 0) {
73 *msix_vecs_bmap = (__HFN_INT_CPE_Q0 | __HFN_INT_CPE_Q1 |
74 __HFN_INT_CPE_Q2 | __HFN_INT_CPE_Q3 |
75 __HFN_INT_RME_Q0 | __HFN_INT_RME_Q1 |
76 __HFN_INT_RME_Q2 | __HFN_INT_RME_Q3 |
77 __HFN_INT_MBOX_LPU0);
78 *max_vec_bit = __HFN_INT_MBOX_LPU0;
79 } else {
80 *msix_vecs_bmap = (__HFN_INT_CPE_Q4 | __HFN_INT_CPE_Q5 |
81 __HFN_INT_CPE_Q6 | __HFN_INT_CPE_Q7 |
82 __HFN_INT_RME_Q4 | __HFN_INT_RME_Q5 |
83 __HFN_INT_RME_Q6 | __HFN_INT_RME_Q7 |
84 __HFN_INT_MBOX_LPU1);
85 *max_vec_bit = __HFN_INT_MBOX_LPU1;
86 }
87
88 *msix_vecs_bmap |= (__HFN_INT_ERR_EMC | __HFN_INT_ERR_LPU0 |
89 __HFN_INT_ERR_LPU1 | __HFN_INT_ERR_PSS);
90 *num_vecs = __HFN_NUMINTS;
91}
92
93/**
94 * No special setup required for crossbow -- vector assignments are implicit.
95 */
96void
97bfa_hwcb_msix_init(struct bfa_s *bfa, int nvecs)
98{
99 int i;
100
101 bfa_assert((nvecs == 1) || (nvecs == __HFN_NUMINTS));
102
103 bfa->msix.nvecs = nvecs;
104 if (nvecs == 1) {
105 for (i = 0; i < BFA_MSIX_CB_MAX; i++)
106 bfa->msix.handler[i] = bfa_msix_all;
107 return;
108 }
109
110 for (i = BFA_MSIX_CPE_Q0; i <= BFA_MSIX_CPE_Q7; i++)
111 bfa->msix.handler[i] = bfa_msix_reqq;
112
113 for (i = BFA_MSIX_RME_Q0; i <= BFA_MSIX_RME_Q7; i++)
114 bfa->msix.handler[i] = bfa_msix_rspq;
115
116 for (; i < BFA_MSIX_CB_MAX; i++)
117 bfa->msix.handler[i] = bfa_msix_lpu_err;
118}
119
120/**
121 * Crossbow -- dummy, interrupts are masked
122 */
123void
124bfa_hwcb_msix_install(struct bfa_s *bfa)
125{
126}
127
128void
129bfa_hwcb_msix_uninstall(struct bfa_s *bfa)
130{
131}
132
133/**
134 * No special enable/disable -- vector assignments are implicit.
135 */
136void
137bfa_hwcb_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix)
138{
139 bfa->iocfc.hwif.hw_rspq_ack = bfa_hwcb_rspq_ack_msix;
140}
141
142
diff --git a/drivers/scsi/bfa/bfa_hw_ct.c b/drivers/scsi/bfa/bfa_hw_ct.c
new file mode 100644
index 000000000000..51ae5740e6e9
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_hw_ct.c
@@ -0,0 +1,162 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#include <bfa_priv.h>
19#include <bfi/bfi_ctreg.h>
20#include <bfa_ioc.h>
21
22BFA_TRC_FILE(HAL, IOCFC_CT);
23
24static u32 __ct_msix_err_vec_reg[] = {
25 HOST_MSIX_ERR_INDEX_FN0,
26 HOST_MSIX_ERR_INDEX_FN1,
27 HOST_MSIX_ERR_INDEX_FN2,
28 HOST_MSIX_ERR_INDEX_FN3,
29};
30
31static void
32bfa_hwct_msix_lpu_err_set(struct bfa_s *bfa, bfa_boolean_t msix, int vec)
33{
34 int fn = bfa_ioc_pcifn(&bfa->ioc);
35 bfa_os_addr_t kva = bfa_ioc_bar0(&bfa->ioc);
36
37 if (msix)
38 bfa_reg_write(kva + __ct_msix_err_vec_reg[fn], vec);
39 else
40 bfa_reg_write(kva + __ct_msix_err_vec_reg[fn], 0);
41}
42
43/**
44 * Dummy interrupt handler for handling spurious interrupt during chip-reinit.
45 */
46static void
47bfa_hwct_msix_dummy(struct bfa_s *bfa, int vec)
48{
49}
50
51void
52bfa_hwct_reginit(struct bfa_s *bfa)
53{
54 struct bfa_iocfc_regs_s *bfa_regs = &bfa->iocfc.bfa_regs;
55 bfa_os_addr_t kva = bfa_ioc_bar0(&bfa->ioc);
56 int i, q, fn = bfa_ioc_pcifn(&bfa->ioc);
57
58 if (fn == 0) {
59 bfa_regs->intr_status = (kva + HOSTFN0_INT_STATUS);
60 bfa_regs->intr_mask = (kva + HOSTFN0_INT_MSK);
61 } else {
62 bfa_regs->intr_status = (kva + HOSTFN1_INT_STATUS);
63 bfa_regs->intr_mask = (kva + HOSTFN1_INT_MSK);
64 }
65
66 for (i = 0; i < BFI_IOC_MAX_CQS; i++) {
67 /*
68 * CPE registers
69 */
70 q = CPE_Q_NUM(fn, i);
71 bfa_regs->cpe_q_pi[i] = (kva + CPE_PI_PTR_Q(q << 5));
72 bfa_regs->cpe_q_ci[i] = (kva + CPE_CI_PTR_Q(q << 5));
73 bfa_regs->cpe_q_depth[i] = (kva + CPE_DEPTH_Q(q << 5));
74 bfa_regs->cpe_q_ctrl[i] = (kva + CPE_QCTRL_Q(q << 5));
75
76 /*
77 * RME registers
78 */
79 q = CPE_Q_NUM(fn, i);
80 bfa_regs->rme_q_pi[i] = (kva + RME_PI_PTR_Q(q << 5));
81 bfa_regs->rme_q_ci[i] = (kva + RME_CI_PTR_Q(q << 5));
82 bfa_regs->rme_q_depth[i] = (kva + RME_DEPTH_Q(q << 5));
83 bfa_regs->rme_q_ctrl[i] = (kva + RME_QCTRL_Q(q << 5));
84 }
85}
86
87void
88bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq)
89{
90 u32 r32;
91
92 r32 = bfa_reg_read(bfa->iocfc.bfa_regs.rme_q_ctrl[rspq]);
93 bfa_reg_write(bfa->iocfc.bfa_regs.rme_q_ctrl[rspq], r32);
94}
95
96void
97bfa_hwct_msix_getvecs(struct bfa_s *bfa, u32 *msix_vecs_bmap,
98 u32 *num_vecs, u32 *max_vec_bit)
99{
100 *msix_vecs_bmap = (1 << BFA_MSIX_CT_MAX) - 1;
101 *max_vec_bit = (1 << (BFA_MSIX_CT_MAX - 1));
102 *num_vecs = BFA_MSIX_CT_MAX;
103}
104
105/**
106 * Setup MSI-X vector for catapult
107 */
108void
109bfa_hwct_msix_init(struct bfa_s *bfa, int nvecs)
110{
111 bfa_assert((nvecs == 1) || (nvecs == BFA_MSIX_CT_MAX));
112 bfa_trc(bfa, nvecs);
113
114 bfa->msix.nvecs = nvecs;
115 bfa_hwct_msix_uninstall(bfa);
116}
117
118void
119bfa_hwct_msix_install(struct bfa_s *bfa)
120{
121 int i;
122
123 if (bfa->msix.nvecs == 0)
124 return;
125
126 if (bfa->msix.nvecs == 1) {
127 for (i = 0; i < BFA_MSIX_CT_MAX; i++)
128 bfa->msix.handler[i] = bfa_msix_all;
129 return;
130 }
131
132 for (i = BFA_MSIX_CPE_Q0; i <= BFA_MSIX_CPE_Q3; i++)
133 bfa->msix.handler[i] = bfa_msix_reqq;
134
135 for (; i <= BFA_MSIX_RME_Q3; i++)
136 bfa->msix.handler[i] = bfa_msix_rspq;
137
138 bfa_assert(i == BFA_MSIX_LPU_ERR);
139 bfa->msix.handler[BFA_MSIX_LPU_ERR] = bfa_msix_lpu_err;
140}
141
142void
143bfa_hwct_msix_uninstall(struct bfa_s *bfa)
144{
145 int i;
146
147 for (i = 0; i < BFA_MSIX_CT_MAX; i++)
148 bfa->msix.handler[i] = bfa_hwct_msix_dummy;
149}
150
151/**
152 * Enable MSI-X vectors
153 */
154void
155bfa_hwct_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix)
156{
157 bfa_trc(bfa, 0);
158 bfa_hwct_msix_lpu_err_set(bfa, msix, BFA_MSIX_LPU_ERR);
159 bfa_ioc_isr_mode_set(&bfa->ioc, msix);
160}
161
162
diff --git a/drivers/scsi/bfa/bfa_intr.c b/drivers/scsi/bfa/bfa_intr.c
new file mode 100644
index 000000000000..0ca125712a04
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_intr.c
@@ -0,0 +1,218 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17#include <bfa.h>
18#include <bfi/bfi_cbreg.h>
19#include <bfa_port_priv.h>
20#include <bfa_intr_priv.h>
21#include <cs/bfa_debug.h>
22
23BFA_TRC_FILE(HAL, INTR);
24
25static void
26bfa_msix_errint(struct bfa_s *bfa, u32 intr)
27{
28 bfa_ioc_error_isr(&bfa->ioc);
29}
30
31static void
32bfa_msix_lpu(struct bfa_s *bfa)
33{
34 bfa_ioc_mbox_isr(&bfa->ioc);
35}
36
37void
38bfa_msix_all(struct bfa_s *bfa, int vec)
39{
40 bfa_intx(bfa);
41}
42
43/**
44 * hal_intr_api
45 */
46bfa_boolean_t
47bfa_intx(struct bfa_s *bfa)
48{
49 u32 intr, qintr;
50 int queue;
51
52 intr = bfa_reg_read(bfa->iocfc.bfa_regs.intr_status);
53 if (!intr)
54 return BFA_FALSE;
55
56 /**
57 * RME completion queue interrupt
58 */
59 qintr = intr & __HFN_INT_RME_MASK;
60 bfa_reg_write(bfa->iocfc.bfa_regs.intr_status, qintr);
61
62 for (queue = 0; queue < BFI_IOC_MAX_CQS_ASIC; queue ++) {
63 if (intr & (__HFN_INT_RME_Q0 << queue))
64 bfa_msix_rspq(bfa, queue & (BFI_IOC_MAX_CQS - 1));
65 }
66 intr &= ~qintr;
67 if (!intr)
68 return BFA_TRUE;
69
70 /**
71 * CPE completion queue interrupt
72 */
73 qintr = intr & __HFN_INT_CPE_MASK;
74 bfa_reg_write(bfa->iocfc.bfa_regs.intr_status, qintr);
75
76 for (queue = 0; queue < BFI_IOC_MAX_CQS_ASIC; queue++) {
77 if (intr & (__HFN_INT_CPE_Q0 << queue))
78 bfa_msix_reqq(bfa, queue & (BFI_IOC_MAX_CQS - 1));
79 }
80 intr &= ~qintr;
81 if (!intr)
82 return BFA_TRUE;
83
84 bfa_msix_lpu_err(bfa, intr);
85
86 return BFA_TRUE;
87}
88
89void
90bfa_isr_enable(struct bfa_s *bfa)
91{
92 u32 intr_unmask;
93 int pci_func = bfa_ioc_pcifn(&bfa->ioc);
94
95 bfa_trc(bfa, pci_func);
96
97 bfa_msix_install(bfa);
98 intr_unmask = (__HFN_INT_ERR_EMC | __HFN_INT_ERR_LPU0 |
99 __HFN_INT_ERR_LPU1 | __HFN_INT_ERR_PSS);
100
101 if (pci_func == 0)
102 intr_unmask |= (__HFN_INT_CPE_Q0 | __HFN_INT_CPE_Q1 |
103 __HFN_INT_CPE_Q2 | __HFN_INT_CPE_Q3 |
104 __HFN_INT_RME_Q0 | __HFN_INT_RME_Q1 |
105 __HFN_INT_RME_Q2 | __HFN_INT_RME_Q3 |
106 __HFN_INT_MBOX_LPU0);
107 else
108 intr_unmask |= (__HFN_INT_CPE_Q4 | __HFN_INT_CPE_Q5 |
109 __HFN_INT_CPE_Q6 | __HFN_INT_CPE_Q7 |
110 __HFN_INT_RME_Q4 | __HFN_INT_RME_Q5 |
111 __HFN_INT_RME_Q6 | __HFN_INT_RME_Q7 |
112 __HFN_INT_MBOX_LPU1);
113
114 bfa_reg_write(bfa->iocfc.bfa_regs.intr_status, intr_unmask);
115 bfa_reg_write(bfa->iocfc.bfa_regs.intr_mask, ~intr_unmask);
116 bfa_isr_mode_set(bfa, bfa->msix.nvecs != 0);
117}
118
119void
120bfa_isr_disable(struct bfa_s *bfa)
121{
122 bfa_isr_mode_set(bfa, BFA_FALSE);
123 bfa_reg_write(bfa->iocfc.bfa_regs.intr_mask, -1L);
124 bfa_msix_uninstall(bfa);
125}
126
127void
128bfa_msix_reqq(struct bfa_s *bfa, int qid)
129{
130 struct list_head *waitq, *qe, *qen;
131 struct bfa_reqq_wait_s *wqe;
132
133 qid &= (BFI_IOC_MAX_CQS - 1);
134
135 waitq = bfa_reqq(bfa, qid);
136 list_for_each_safe(qe, qen, waitq) {
137 /**
138 * Callback only as long as there is room in request queue
139 */
140 if (bfa_reqq_full(bfa, qid))
141 break;
142
143 list_del(qe);
144 wqe = (struct bfa_reqq_wait_s *) qe;
145 wqe->qresume(wqe->cbarg);
146 }
147}
148
149void
150bfa_isr_unhandled(struct bfa_s *bfa, struct bfi_msg_s *m)
151{
152 bfa_trc(bfa, m->mhdr.msg_class);
153 bfa_trc(bfa, m->mhdr.msg_id);
154 bfa_trc(bfa, m->mhdr.mtag.i2htok);
155 bfa_assert(0);
156 bfa_trc_stop(bfa->trcmod);
157}
158
159void
160bfa_msix_rspq(struct bfa_s *bfa, int rsp_qid)
161{
162 struct bfi_msg_s *m;
163 u32 pi, ci;
164
165 bfa_trc_fp(bfa, rsp_qid);
166
167 rsp_qid &= (BFI_IOC_MAX_CQS - 1);
168
169 bfa->iocfc.hwif.hw_rspq_ack(bfa, rsp_qid);
170
171 ci = bfa_rspq_ci(bfa, rsp_qid);
172 pi = bfa_rspq_pi(bfa, rsp_qid);
173
174 bfa_trc_fp(bfa, ci);
175 bfa_trc_fp(bfa, pi);
176
177 if (bfa->rme_process) {
178 while (ci != pi) {
179 m = bfa_rspq_elem(bfa, rsp_qid, ci);
180 bfa_assert_fp(m->mhdr.msg_class < BFI_MC_MAX);
181
182 bfa_isrs[m->mhdr.msg_class] (bfa, m);
183
184 CQ_INCR(ci, bfa->iocfc.cfg.drvcfg.num_rspq_elems);
185 }
186 }
187
188 /**
189 * update CI
190 */
191 bfa_rspq_ci(bfa, rsp_qid) = pi;
192 bfa_reg_write(bfa->iocfc.bfa_regs.rme_q_ci[rsp_qid], pi);
193 bfa_os_mmiowb();
194}
195
196void
197bfa_msix_lpu_err(struct bfa_s *bfa, int vec)
198{
199 u32 intr;
200
201 intr = bfa_reg_read(bfa->iocfc.bfa_regs.intr_status);
202
203 if (intr & (__HFN_INT_MBOX_LPU0 | __HFN_INT_MBOX_LPU1))
204 bfa_msix_lpu(bfa);
205
206 if (intr & (__HFN_INT_ERR_EMC |
207 __HFN_INT_ERR_LPU0 | __HFN_INT_ERR_LPU1 |
208 __HFN_INT_ERR_PSS))
209 bfa_msix_errint(bfa, intr);
210}
211
212void
213bfa_isr_bind(enum bfi_mclass mc, bfa_isr_func_t isr_func)
214{
215 bfa_isrs[mc] = isr_func;
216}
217
218
diff --git a/drivers/scsi/bfa/bfa_intr_priv.h b/drivers/scsi/bfa/bfa_intr_priv.h
new file mode 100644
index 000000000000..8ce6e6b105c8
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_intr_priv.h
@@ -0,0 +1,115 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFA_INTR_PRIV_H__
19#define __BFA_INTR_PRIV_H__
20
21/**
22 * Message handler
23 */
24typedef void (*bfa_isr_func_t) (struct bfa_s *bfa, struct bfi_msg_s *m);
25void bfa_isr_unhandled(struct bfa_s *bfa, struct bfi_msg_s *m);
26void bfa_isr_bind(enum bfi_mclass mc, bfa_isr_func_t isr_func);
27
28
29#define bfa_reqq_pi(__bfa, __reqq) (__bfa)->iocfc.req_cq_pi[__reqq]
30#define bfa_reqq_ci(__bfa, __reqq) \
31 *(u32 *)((__bfa)->iocfc.req_cq_shadow_ci[__reqq].kva)
32
33#define bfa_reqq_full(__bfa, __reqq) \
34 (((bfa_reqq_pi(__bfa, __reqq) + 1) & \
35 ((__bfa)->iocfc.cfg.drvcfg.num_reqq_elems - 1)) == \
36 bfa_reqq_ci(__bfa, __reqq))
37
38#define bfa_reqq_next(__bfa, __reqq) \
39 (bfa_reqq_full(__bfa, __reqq) ? NULL : \
40 ((void *)((struct bfi_msg_s *)((__bfa)->iocfc.req_cq_ba[__reqq].kva) \
41 + bfa_reqq_pi((__bfa), (__reqq)))))
42
43#define bfa_reqq_produce(__bfa, __reqq) do { \
44 (__bfa)->iocfc.req_cq_pi[__reqq]++; \
45 (__bfa)->iocfc.req_cq_pi[__reqq] &= \
46 ((__bfa)->iocfc.cfg.drvcfg.num_reqq_elems - 1); \
47 bfa_reg_write((__bfa)->iocfc.bfa_regs.cpe_q_pi[__reqq], \
48 (__bfa)->iocfc.req_cq_pi[__reqq]); \
49 bfa_os_mmiowb(); \
50} while (0)
51
52#define bfa_rspq_pi(__bfa, __rspq) \
53 *(u32 *)((__bfa)->iocfc.rsp_cq_shadow_pi[__rspq].kva)
54
55#define bfa_rspq_ci(__bfa, __rspq) (__bfa)->iocfc.rsp_cq_ci[__rspq]
56#define bfa_rspq_elem(__bfa, __rspq, __ci) \
57 &((struct bfi_msg_s *)((__bfa)->iocfc.rsp_cq_ba[__rspq].kva))[__ci]
58
59#define CQ_INCR(__index, __size) \
60 (__index)++; (__index) &= ((__size) - 1)
61
62/**
63 * Queue element to wait for room in request queue. FIFO order is
64 * maintained when fullfilling requests.
65 */
66struct bfa_reqq_wait_s {
67 struct list_head qe;
68 void (*qresume) (void *cbarg);
69 void *cbarg;
70};
71
72/**
73 * Circular queue usage assignments
74 */
75enum {
76 BFA_REQQ_IOC = 0, /* all low-priority IOC msgs */
77 BFA_REQQ_FCXP = 0, /* all FCXP messages */
78 BFA_REQQ_LPS = 0, /* all lport service msgs */
79 BFA_REQQ_PORT = 0, /* all port messages */
80 BFA_REQQ_FLASH = 0, /* for flash module */
81 BFA_REQQ_DIAG = 0, /* for diag module */
82 BFA_REQQ_RPORT = 0, /* all port messages */
83 BFA_REQQ_SBOOT = 0, /* all san boot messages */
84 BFA_REQQ_QOS_LO = 1, /* all low priority IO */
85 BFA_REQQ_QOS_MD = 2, /* all medium priority IO */
86 BFA_REQQ_QOS_HI = 3, /* all high priority IO */
87};
88
89static inline void
90bfa_reqq_winit(struct bfa_reqq_wait_s *wqe, void (*qresume) (void *cbarg),
91 void *cbarg)
92{
93 wqe->qresume = qresume;
94 wqe->cbarg = cbarg;
95}
96
97#define bfa_reqq(__bfa, __reqq) &(__bfa)->reqq_waitq[__reqq]
98
99/**
100 * static inline void
101 * bfa_reqq_wait(struct bfa_s *bfa, int reqq, struct bfa_reqq_wait_s *wqe)
102 */
103#define bfa_reqq_wait(__bfa, __reqq, __wqe) do { \
104 \
105 struct list_head *waitq = bfa_reqq(__bfa, __reqq); \
106 \
107 bfa_assert(((__reqq) < BFI_IOC_MAX_CQS)); \
108 bfa_assert((__wqe)->qresume && (__wqe)->cbarg); \
109 \
110 list_add_tail(&(__wqe)->qe, waitq); \
111} while (0)
112
113#define bfa_reqq_wcancel(__wqe) list_del(&(__wqe)->qe)
114
115#endif /* __BFA_INTR_PRIV_H__ */
diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c
new file mode 100644
index 000000000000..149348934ce3
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_ioc.c
@@ -0,0 +1,2382 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#include <bfa.h>
19#include <bfa_ioc.h>
20#include <bfa_fwimg_priv.h>
21#include <bfa_trcmod_priv.h>
22#include <cs/bfa_debug.h>
23#include <bfi/bfi_ioc.h>
24#include <bfi/bfi_ctreg.h>
25#include <aen/bfa_aen_ioc.h>
26#include <aen/bfa_aen.h>
27#include <log/bfa_log_hal.h>
28#include <defs/bfa_defs_pci.h>
29
30BFA_TRC_FILE(HAL, IOC);
31
32/**
33 * IOC local definitions
34 */
35#define BFA_IOC_TOV 2000 /* msecs */
36#define BFA_IOC_HB_TOV 1000 /* msecs */
37#define BFA_IOC_HB_FAIL_MAX 4
38#define BFA_IOC_HWINIT_MAX 2
39#define BFA_IOC_FWIMG_MINSZ (16 * 1024)
40#define BFA_IOC_TOV_RECOVER (BFA_IOC_HB_FAIL_MAX * BFA_IOC_HB_TOV \
41 + BFA_IOC_TOV)
42
43#define bfa_ioc_timer_start(__ioc) \
44 bfa_timer_begin((__ioc)->timer_mod, &(__ioc)->ioc_timer, \
45 bfa_ioc_timeout, (__ioc), BFA_IOC_TOV)
46#define bfa_ioc_timer_stop(__ioc) bfa_timer_stop(&(__ioc)->ioc_timer)
47
48#define BFA_DBG_FWTRC_ENTS (BFI_IOC_TRC_ENTS)
49#define BFA_DBG_FWTRC_LEN \
50 (BFA_DBG_FWTRC_ENTS * sizeof(struct bfa_trc_s) + \
51 (sizeof(struct bfa_trc_mod_s) - \
52 BFA_TRC_MAX * sizeof(struct bfa_trc_s)))
53#define BFA_DBG_FWTRC_OFF(_fn) (BFI_IOC_TRC_OFF + BFA_DBG_FWTRC_LEN * (_fn))
54#define bfa_ioc_stats(_ioc, _stats) (_ioc)->stats._stats ++
55
56#define BFA_FLASH_CHUNK_NO(off) (off / BFI_FLASH_CHUNK_SZ_WORDS)
57#define BFA_FLASH_OFFSET_IN_CHUNK(off) (off % BFI_FLASH_CHUNK_SZ_WORDS)
58#define BFA_FLASH_CHUNK_ADDR(chunkno) (chunkno * BFI_FLASH_CHUNK_SZ_WORDS)
59bfa_boolean_t bfa_auto_recover = BFA_FALSE;
60
61/*
62 * forward declarations
63 */
64static void bfa_ioc_aen_post(struct bfa_ioc_s *bfa,
65 enum bfa_ioc_aen_event event);
66static void bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc);
67static void bfa_ioc_hw_sem_release(struct bfa_ioc_s *ioc);
68static void bfa_ioc_hw_sem_get_cancel(struct bfa_ioc_s *ioc);
69static void bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force);
70static void bfa_ioc_timeout(void *ioc);
71static void bfa_ioc_send_enable(struct bfa_ioc_s *ioc);
72static void bfa_ioc_send_disable(struct bfa_ioc_s *ioc);
73static void bfa_ioc_send_getattr(struct bfa_ioc_s *ioc);
74static void bfa_ioc_hb_monitor(struct bfa_ioc_s *ioc);
75static void bfa_ioc_hb_stop(struct bfa_ioc_s *ioc);
76static void bfa_ioc_reset(struct bfa_ioc_s *ioc, bfa_boolean_t force);
77static void bfa_ioc_mbox_poll(struct bfa_ioc_s *ioc);
78static void bfa_ioc_mbox_hbfail(struct bfa_ioc_s *ioc);
79static void bfa_ioc_recover(struct bfa_ioc_s *ioc);
80static bfa_boolean_t bfa_ioc_firmware_lock(struct bfa_ioc_s *ioc);
81static void bfa_ioc_firmware_unlock(struct bfa_ioc_s *ioc);
82static void bfa_ioc_disable_comp(struct bfa_ioc_s *ioc);
83static void bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc);
84
85/**
86 * bfa_ioc_sm
87 */
88
89/**
90 * IOC state machine events
91 */
92enum ioc_event {
93 IOC_E_ENABLE = 1, /* IOC enable request */
94 IOC_E_DISABLE = 2, /* IOC disable request */
95 IOC_E_TIMEOUT = 3, /* f/w response timeout */
96 IOC_E_FWREADY = 4, /* f/w initialization done */
97 IOC_E_FWRSP_GETATTR = 5, /* IOC get attribute response */
98 IOC_E_FWRSP_ENABLE = 6, /* enable f/w response */
99 IOC_E_FWRSP_DISABLE = 7, /* disable f/w response */
100 IOC_E_HBFAIL = 8, /* heartbeat failure */
101 IOC_E_HWERROR = 9, /* hardware error interrupt */
102 IOC_E_SEMLOCKED = 10, /* h/w semaphore is locked */
103 IOC_E_DETACH = 11, /* driver detach cleanup */
104};
105
106bfa_fsm_state_decl(bfa_ioc, reset, struct bfa_ioc_s, enum ioc_event);
107bfa_fsm_state_decl(bfa_ioc, fwcheck, struct bfa_ioc_s, enum ioc_event);
108bfa_fsm_state_decl(bfa_ioc, mismatch, struct bfa_ioc_s, enum ioc_event);
109bfa_fsm_state_decl(bfa_ioc, semwait, struct bfa_ioc_s, enum ioc_event);
110bfa_fsm_state_decl(bfa_ioc, hwinit, struct bfa_ioc_s, enum ioc_event);
111bfa_fsm_state_decl(bfa_ioc, enabling, struct bfa_ioc_s, enum ioc_event);
112bfa_fsm_state_decl(bfa_ioc, getattr, struct bfa_ioc_s, enum ioc_event);
113bfa_fsm_state_decl(bfa_ioc, op, struct bfa_ioc_s, enum ioc_event);
114bfa_fsm_state_decl(bfa_ioc, initfail, struct bfa_ioc_s, enum ioc_event);
115bfa_fsm_state_decl(bfa_ioc, hbfail, struct bfa_ioc_s, enum ioc_event);
116bfa_fsm_state_decl(bfa_ioc, disabling, struct bfa_ioc_s, enum ioc_event);
117bfa_fsm_state_decl(bfa_ioc, disabled, struct bfa_ioc_s, enum ioc_event);
118
119static struct bfa_sm_table_s ioc_sm_table[] = {
120 {BFA_SM(bfa_ioc_sm_reset), BFA_IOC_RESET},
121 {BFA_SM(bfa_ioc_sm_fwcheck), BFA_IOC_FWMISMATCH},
122 {BFA_SM(bfa_ioc_sm_mismatch), BFA_IOC_FWMISMATCH},
123 {BFA_SM(bfa_ioc_sm_semwait), BFA_IOC_SEMWAIT},
124 {BFA_SM(bfa_ioc_sm_hwinit), BFA_IOC_HWINIT},
125 {BFA_SM(bfa_ioc_sm_enabling), BFA_IOC_HWINIT},
126 {BFA_SM(bfa_ioc_sm_getattr), BFA_IOC_GETATTR},
127 {BFA_SM(bfa_ioc_sm_op), BFA_IOC_OPERATIONAL},
128 {BFA_SM(bfa_ioc_sm_initfail), BFA_IOC_INITFAIL},
129 {BFA_SM(bfa_ioc_sm_hbfail), BFA_IOC_HBFAIL},
130 {BFA_SM(bfa_ioc_sm_disabling), BFA_IOC_DISABLING},
131 {BFA_SM(bfa_ioc_sm_disabled), BFA_IOC_DISABLED},
132};
133
134/**
135 * Reset entry actions -- initialize state machine
136 */
137static void
138bfa_ioc_sm_reset_entry(struct bfa_ioc_s *ioc)
139{
140 ioc->retry_count = 0;
141 ioc->auto_recover = bfa_auto_recover;
142}
143
144/**
145 * Beginning state. IOC is in reset state.
146 */
147static void
148bfa_ioc_sm_reset(struct bfa_ioc_s *ioc, enum ioc_event event)
149{
150 bfa_trc(ioc, event);
151
152 switch (event) {
153 case IOC_E_ENABLE:
154 bfa_fsm_set_state(ioc, bfa_ioc_sm_fwcheck);
155 break;
156
157 case IOC_E_DISABLE:
158 bfa_ioc_disable_comp(ioc);
159 break;
160
161 case IOC_E_DETACH:
162 break;
163
164 default:
165 bfa_sm_fault(ioc, event);
166 }
167}
168
169/**
170 * Semaphore should be acquired for version check.
171 */
172static void
173bfa_ioc_sm_fwcheck_entry(struct bfa_ioc_s *ioc)
174{
175 bfa_ioc_hw_sem_get(ioc);
176}
177
178/**
179 * Awaiting h/w semaphore to continue with version check.
180 */
181static void
182bfa_ioc_sm_fwcheck(struct bfa_ioc_s *ioc, enum ioc_event event)
183{
184 bfa_trc(ioc, event);
185
186 switch (event) {
187 case IOC_E_SEMLOCKED:
188 if (bfa_ioc_firmware_lock(ioc)) {
189 ioc->retry_count = 0;
190 bfa_fsm_set_state(ioc, bfa_ioc_sm_hwinit);
191 } else {
192 bfa_ioc_hw_sem_release(ioc);
193 bfa_fsm_set_state(ioc, bfa_ioc_sm_mismatch);
194 }
195 break;
196
197 case IOC_E_DISABLE:
198 bfa_ioc_disable_comp(ioc);
199 /*
200 * fall through
201 */
202
203 case IOC_E_DETACH:
204 bfa_ioc_hw_sem_get_cancel(ioc);
205 bfa_fsm_set_state(ioc, bfa_ioc_sm_reset);
206 break;
207
208 case IOC_E_FWREADY:
209 break;
210
211 default:
212 bfa_sm_fault(ioc, event);
213 }
214}
215
216/**
217 * Notify enable completion callback and generate mismatch AEN.
218 */
219static void
220bfa_ioc_sm_mismatch_entry(struct bfa_ioc_s *ioc)
221{
222 /**
223 * Provide enable completion callback and AEN notification only once.
224 */
225 if (ioc->retry_count == 0) {
226 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
227 bfa_ioc_aen_post(ioc, BFA_IOC_AEN_FWMISMATCH);
228 }
229 ioc->retry_count++;
230 bfa_ioc_timer_start(ioc);
231}
232
233/**
234 * Awaiting firmware version match.
235 */
236static void
237bfa_ioc_sm_mismatch(struct bfa_ioc_s *ioc, enum ioc_event event)
238{
239 bfa_trc(ioc, event);
240
241 switch (event) {
242 case IOC_E_TIMEOUT:
243 bfa_fsm_set_state(ioc, bfa_ioc_sm_fwcheck);
244 break;
245
246 case IOC_E_DISABLE:
247 bfa_ioc_disable_comp(ioc);
248 /*
249 * fall through
250 */
251
252 case IOC_E_DETACH:
253 bfa_ioc_timer_stop(ioc);
254 bfa_fsm_set_state(ioc, bfa_ioc_sm_reset);
255 break;
256
257 case IOC_E_FWREADY:
258 break;
259
260 default:
261 bfa_sm_fault(ioc, event);
262 }
263}
264
265/**
266 * Request for semaphore.
267 */
268static void
269bfa_ioc_sm_semwait_entry(struct bfa_ioc_s *ioc)
270{
271 bfa_ioc_hw_sem_get(ioc);
272}
273
274/**
275 * Awaiting semaphore for h/w initialzation.
276 */
277static void
278bfa_ioc_sm_semwait(struct bfa_ioc_s *ioc, enum ioc_event event)
279{
280 bfa_trc(ioc, event);
281
282 switch (event) {
283 case IOC_E_SEMLOCKED:
284 ioc->retry_count = 0;
285 bfa_fsm_set_state(ioc, bfa_ioc_sm_hwinit);
286 break;
287
288 case IOC_E_DISABLE:
289 bfa_ioc_hw_sem_get_cancel(ioc);
290 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
291 break;
292
293 default:
294 bfa_sm_fault(ioc, event);
295 }
296}
297
298
299static void
300bfa_ioc_sm_hwinit_entry(struct bfa_ioc_s *ioc)
301{
302 bfa_ioc_timer_start(ioc);
303 bfa_ioc_reset(ioc, BFA_FALSE);
304}
305
306/**
307 * Hardware is being initialized. Interrupts are enabled.
308 * Holding hardware semaphore lock.
309 */
310static void
311bfa_ioc_sm_hwinit(struct bfa_ioc_s *ioc, enum ioc_event event)
312{
313 bfa_trc(ioc, event);
314
315 switch (event) {
316 case IOC_E_FWREADY:
317 bfa_ioc_timer_stop(ioc);
318 bfa_fsm_set_state(ioc, bfa_ioc_sm_enabling);
319 break;
320
321 case IOC_E_HWERROR:
322 bfa_ioc_timer_stop(ioc);
323 /*
324 * fall through
325 */
326
327 case IOC_E_TIMEOUT:
328 ioc->retry_count++;
329 if (ioc->retry_count < BFA_IOC_HWINIT_MAX) {
330 bfa_ioc_timer_start(ioc);
331 bfa_ioc_reset(ioc, BFA_TRUE);
332 break;
333 }
334
335 bfa_ioc_hw_sem_release(ioc);
336 bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail);
337 break;
338
339 case IOC_E_DISABLE:
340 bfa_ioc_hw_sem_release(ioc);
341 bfa_ioc_timer_stop(ioc);
342 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
343 break;
344
345 default:
346 bfa_sm_fault(ioc, event);
347 }
348}
349
350
351static void
352bfa_ioc_sm_enabling_entry(struct bfa_ioc_s *ioc)
353{
354 bfa_ioc_timer_start(ioc);
355 bfa_ioc_send_enable(ioc);
356}
357
358/**
359 * Host IOC function is being enabled, awaiting response from firmware.
360 * Semaphore is acquired.
361 */
362static void
363bfa_ioc_sm_enabling(struct bfa_ioc_s *ioc, enum ioc_event event)
364{
365 bfa_trc(ioc, event);
366
367 switch (event) {
368 case IOC_E_FWRSP_ENABLE:
369 bfa_ioc_timer_stop(ioc);
370 bfa_ioc_hw_sem_release(ioc);
371 bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr);
372 break;
373
374 case IOC_E_HWERROR:
375 bfa_ioc_timer_stop(ioc);
376 /*
377 * fall through
378 */
379
380 case IOC_E_TIMEOUT:
381 ioc->retry_count++;
382 if (ioc->retry_count < BFA_IOC_HWINIT_MAX) {
383 bfa_reg_write(ioc->ioc_regs.ioc_fwstate,
384 BFI_IOC_UNINIT);
385 bfa_fsm_set_state(ioc, bfa_ioc_sm_hwinit);
386 break;
387 }
388
389 bfa_ioc_hw_sem_release(ioc);
390 bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail);
391 break;
392
393 case IOC_E_DISABLE:
394 bfa_ioc_timer_stop(ioc);
395 bfa_ioc_hw_sem_release(ioc);
396 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
397 break;
398
399 case IOC_E_FWREADY:
400 bfa_ioc_send_enable(ioc);
401 break;
402
403 default:
404 bfa_sm_fault(ioc, event);
405 }
406}
407
408
409static void
410bfa_ioc_sm_getattr_entry(struct bfa_ioc_s *ioc)
411{
412 bfa_ioc_timer_start(ioc);
413 bfa_ioc_send_getattr(ioc);
414}
415
416/**
417 * IOC configuration in progress. Timer is active.
418 */
419static void
420bfa_ioc_sm_getattr(struct bfa_ioc_s *ioc, enum ioc_event event)
421{
422 bfa_trc(ioc, event);
423
424 switch (event) {
425 case IOC_E_FWRSP_GETATTR:
426 bfa_ioc_timer_stop(ioc);
427 bfa_fsm_set_state(ioc, bfa_ioc_sm_op);
428 break;
429
430 case IOC_E_HWERROR:
431 bfa_ioc_timer_stop(ioc);
432 /*
433 * fall through
434 */
435
436 case IOC_E_TIMEOUT:
437 bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail);
438 break;
439
440 case IOC_E_DISABLE:
441 bfa_ioc_timer_stop(ioc);
442 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
443 break;
444
445 default:
446 bfa_sm_fault(ioc, event);
447 }
448}
449
450
451static void
452bfa_ioc_sm_op_entry(struct bfa_ioc_s *ioc)
453{
454 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_OK);
455 bfa_ioc_hb_monitor(ioc);
456 bfa_ioc_aen_post(ioc, BFA_IOC_AEN_ENABLE);
457}
458
459static void
460bfa_ioc_sm_op(struct bfa_ioc_s *ioc, enum ioc_event event)
461{
462 bfa_trc(ioc, event);
463
464 switch (event) {
465 case IOC_E_ENABLE:
466 break;
467
468 case IOC_E_DISABLE:
469 bfa_ioc_hb_stop(ioc);
470 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
471 break;
472
473 case IOC_E_HWERROR:
474 case IOC_E_FWREADY:
475 /**
476 * Hard error or IOC recovery by other function.
477 * Treat it same as heartbeat failure.
478 */
479 bfa_ioc_hb_stop(ioc);
480 /*
481 * !!! fall through !!!
482 */
483
484 case IOC_E_HBFAIL:
485 bfa_fsm_set_state(ioc, bfa_ioc_sm_hbfail);
486 break;
487
488 default:
489 bfa_sm_fault(ioc, event);
490 }
491}
492
493
494static void
495bfa_ioc_sm_disabling_entry(struct bfa_ioc_s *ioc)
496{
497 bfa_ioc_aen_post(ioc, BFA_IOC_AEN_DISABLE);
498 bfa_ioc_timer_start(ioc);
499 bfa_ioc_send_disable(ioc);
500}
501
502/**
503 * IOC is being disabled
504 */
505static void
506bfa_ioc_sm_disabling(struct bfa_ioc_s *ioc, enum ioc_event event)
507{
508 bfa_trc(ioc, event);
509
510 switch (event) {
511 case IOC_E_HWERROR:
512 case IOC_E_FWRSP_DISABLE:
513 bfa_ioc_timer_stop(ioc);
514 /*
515 * !!! fall through !!!
516 */
517
518 case IOC_E_TIMEOUT:
519 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
520 break;
521
522 default:
523 bfa_sm_fault(ioc, event);
524 }
525}
526
527/**
528 * IOC disable completion entry.
529 */
530static void
531bfa_ioc_sm_disabled_entry(struct bfa_ioc_s *ioc)
532{
533 bfa_ioc_disable_comp(ioc);
534}
535
536static void
537bfa_ioc_sm_disabled(struct bfa_ioc_s *ioc, enum ioc_event event)
538{
539 bfa_trc(ioc, event);
540
541 switch (event) {
542 case IOC_E_ENABLE:
543 bfa_fsm_set_state(ioc, bfa_ioc_sm_semwait);
544 break;
545
546 case IOC_E_DISABLE:
547 ioc->cbfn->disable_cbfn(ioc->bfa);
548 break;
549
550 case IOC_E_FWREADY:
551 break;
552
553 case IOC_E_DETACH:
554 bfa_ioc_firmware_unlock(ioc);
555 bfa_fsm_set_state(ioc, bfa_ioc_sm_reset);
556 break;
557
558 default:
559 bfa_sm_fault(ioc, event);
560 }
561}
562
563
564static void
565bfa_ioc_sm_initfail_entry(struct bfa_ioc_s *ioc)
566{
567 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
568 bfa_ioc_timer_start(ioc);
569}
570
571/**
572 * Hardware initialization failed.
573 */
574static void
575bfa_ioc_sm_initfail(struct bfa_ioc_s *ioc, enum ioc_event event)
576{
577 bfa_trc(ioc, event);
578
579 switch (event) {
580 case IOC_E_DISABLE:
581 bfa_ioc_timer_stop(ioc);
582 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
583 break;
584
585 case IOC_E_DETACH:
586 bfa_ioc_timer_stop(ioc);
587 bfa_ioc_firmware_unlock(ioc);
588 bfa_fsm_set_state(ioc, bfa_ioc_sm_reset);
589 break;
590
591 case IOC_E_TIMEOUT:
592 bfa_fsm_set_state(ioc, bfa_ioc_sm_semwait);
593 break;
594
595 default:
596 bfa_sm_fault(ioc, event);
597 }
598}
599
600
601static void
602bfa_ioc_sm_hbfail_entry(struct bfa_ioc_s *ioc)
603{
604 struct list_head *qe;
605 struct bfa_ioc_hbfail_notify_s *notify;
606
607 /**
608 * Mark IOC as failed in hardware and stop firmware.
609 */
610 bfa_ioc_lpu_stop(ioc);
611 bfa_reg_write(ioc->ioc_regs.ioc_fwstate, BFI_IOC_HBFAIL);
612
613 if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT) {
614 bfa_reg_write(ioc->ioc_regs.ll_halt, __FW_INIT_HALT_P);
615 /*
616 * Wait for halt to take effect
617 */
618 bfa_reg_read(ioc->ioc_regs.ll_halt);
619 }
620
621 /**
622 * Notify driver and common modules registered for notification.
623 */
624 ioc->cbfn->hbfail_cbfn(ioc->bfa);
625 list_for_each(qe, &ioc->hb_notify_q) {
626 notify = (struct bfa_ioc_hbfail_notify_s *)qe;
627 notify->cbfn(notify->cbarg);
628 }
629
630 /**
631 * Flush any queued up mailbox requests.
632 */
633 bfa_ioc_mbox_hbfail(ioc);
634 bfa_ioc_aen_post(ioc, BFA_IOC_AEN_HBFAIL);
635
636 /**
637 * Trigger auto-recovery after a delay.
638 */
639 if (ioc->auto_recover) {
640 bfa_timer_begin(ioc->timer_mod, &ioc->ioc_timer,
641 bfa_ioc_timeout, ioc, BFA_IOC_TOV_RECOVER);
642 }
643}
644
645/**
646 * IOC heartbeat failure.
647 */
648static void
649bfa_ioc_sm_hbfail(struct bfa_ioc_s *ioc, enum ioc_event event)
650{
651 bfa_trc(ioc, event);
652
653 switch (event) {
654
655 case IOC_E_ENABLE:
656 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
657 break;
658
659 case IOC_E_DISABLE:
660 if (ioc->auto_recover)
661 bfa_ioc_timer_stop(ioc);
662 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled);
663 break;
664
665 case IOC_E_TIMEOUT:
666 bfa_fsm_set_state(ioc, bfa_ioc_sm_semwait);
667 break;
668
669 case IOC_E_FWREADY:
670 /**
671 * Recovery is already initiated by other function.
672 */
673 break;
674
675 default:
676 bfa_sm_fault(ioc, event);
677 }
678}
679
680
681
682/**
683 * bfa_ioc_pvt BFA IOC private functions
684 */
685
686static void
687bfa_ioc_disable_comp(struct bfa_ioc_s *ioc)
688{
689 struct list_head *qe;
690 struct bfa_ioc_hbfail_notify_s *notify;
691
692 ioc->cbfn->disable_cbfn(ioc->bfa);
693
694 /**
695 * Notify common modules registered for notification.
696 */
697 list_for_each(qe, &ioc->hb_notify_q) {
698 notify = (struct bfa_ioc_hbfail_notify_s *)qe;
699 notify->cbfn(notify->cbarg);
700 }
701}
702
703static void
704bfa_ioc_sem_timeout(void *ioc_arg)
705{
706 struct bfa_ioc_s *ioc = (struct bfa_ioc_s *)ioc_arg;
707
708 bfa_ioc_hw_sem_get(ioc);
709}
710
711static void
712bfa_ioc_usage_sem_get(struct bfa_ioc_s *ioc)
713{
714 u32 r32;
715 int cnt = 0;
716#define BFA_SEM_SPINCNT 1000
717
718 do {
719 r32 = bfa_reg_read(ioc->ioc_regs.ioc_usage_sem_reg);
720 cnt++;
721 if (cnt > BFA_SEM_SPINCNT)
722 break;
723 } while (r32 != 0);
724 bfa_assert(cnt < BFA_SEM_SPINCNT);
725}
726
727static void
728bfa_ioc_usage_sem_release(struct bfa_ioc_s *ioc)
729{
730 bfa_reg_write(ioc->ioc_regs.ioc_usage_sem_reg, 1);
731}
732
733static void
734bfa_ioc_hw_sem_get(struct bfa_ioc_s *ioc)
735{
736 u32 r32;
737
738 /**
739 * First read to the semaphore register will return 0, subsequent reads
740 * will return 1. Semaphore is released by writing 0 to the register
741 */
742 r32 = bfa_reg_read(ioc->ioc_regs.ioc_sem_reg);
743 if (r32 == 0) {
744 bfa_fsm_send_event(ioc, IOC_E_SEMLOCKED);
745 return;
746 }
747
748 bfa_timer_begin(ioc->timer_mod, &ioc->sem_timer, bfa_ioc_sem_timeout,
749 ioc, BFA_IOC_TOV);
750}
751
752static void
753bfa_ioc_hw_sem_release(struct bfa_ioc_s *ioc)
754{
755 bfa_reg_write(ioc->ioc_regs.ioc_sem_reg, 1);
756}
757
758static void
759bfa_ioc_hw_sem_get_cancel(struct bfa_ioc_s *ioc)
760{
761 bfa_timer_stop(&ioc->sem_timer);
762}
763
764/**
765 * Initialize LPU local memory (aka secondary memory / SRAM)
766 */
767static void
768bfa_ioc_lmem_init(struct bfa_ioc_s *ioc)
769{
770 u32 pss_ctl;
771 int i;
772#define PSS_LMEM_INIT_TIME 10000
773
774 pss_ctl = bfa_reg_read(ioc->ioc_regs.pss_ctl_reg);
775 pss_ctl &= ~__PSS_LMEM_RESET;
776 pss_ctl |= __PSS_LMEM_INIT_EN;
777 pss_ctl |= __PSS_I2C_CLK_DIV(3UL); /* i2c workaround 12.5khz clock */
778 bfa_reg_write(ioc->ioc_regs.pss_ctl_reg, pss_ctl);
779
780 /**
781 * wait for memory initialization to be complete
782 */
783 i = 0;
784 do {
785 pss_ctl = bfa_reg_read(ioc->ioc_regs.pss_ctl_reg);
786 i++;
787 } while (!(pss_ctl & __PSS_LMEM_INIT_DONE) && (i < PSS_LMEM_INIT_TIME));
788
789 /**
790 * If memory initialization is not successful, IOC timeout will catch
791 * such failures.
792 */
793 bfa_assert(pss_ctl & __PSS_LMEM_INIT_DONE);
794 bfa_trc(ioc, pss_ctl);
795
796 pss_ctl &= ~(__PSS_LMEM_INIT_DONE | __PSS_LMEM_INIT_EN);
797 bfa_reg_write(ioc->ioc_regs.pss_ctl_reg, pss_ctl);
798}
799
800static void
801bfa_ioc_lpu_start(struct bfa_ioc_s *ioc)
802{
803 u32 pss_ctl;
804
805 /**
806 * Take processor out of reset.
807 */
808 pss_ctl = bfa_reg_read(ioc->ioc_regs.pss_ctl_reg);
809 pss_ctl &= ~__PSS_LPU0_RESET;
810
811 bfa_reg_write(ioc->ioc_regs.pss_ctl_reg, pss_ctl);
812}
813
814static void
815bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc)
816{
817 u32 pss_ctl;
818
819 /**
820 * Put processors in reset.
821 */
822 pss_ctl = bfa_reg_read(ioc->ioc_regs.pss_ctl_reg);
823 pss_ctl |= (__PSS_LPU0_RESET | __PSS_LPU1_RESET);
824
825 bfa_reg_write(ioc->ioc_regs.pss_ctl_reg, pss_ctl);
826}
827
828/**
829 * Get driver and firmware versions.
830 */
831static void
832bfa_ioc_fwver_get(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr)
833{
834 u32 pgnum, pgoff;
835 u32 loff = 0;
836 int i;
837 u32 *fwsig = (u32 *) fwhdr;
838
839 pgnum = bfa_ioc_smem_pgnum(ioc, loff);
840 pgoff = bfa_ioc_smem_pgoff(ioc, loff);
841 bfa_reg_write(ioc->ioc_regs.host_page_num_fn, pgnum);
842
843 for (i = 0; i < (sizeof(struct bfi_ioc_image_hdr_s) / sizeof(u32));
844 i++) {
845 fwsig[i] = bfa_mem_read(ioc->ioc_regs.smem_page_start, loff);
846 loff += sizeof(u32);
847 }
848}
849
850static u32 *
851bfa_ioc_fwimg_get_chunk(struct bfa_ioc_s *ioc, u32 off)
852{
853 if (ioc->ctdev)
854 return bfi_image_ct_get_chunk(off);
855 return bfi_image_cb_get_chunk(off);
856}
857
858static u32
859bfa_ioc_fwimg_get_size(struct bfa_ioc_s *ioc)
860{
861return (ioc->ctdev) ? bfi_image_ct_size : bfi_image_cb_size;
862}
863
864/**
865 * Returns TRUE if same.
866 */
867static bfa_boolean_t
868bfa_ioc_fwver_cmp(struct bfa_ioc_s *ioc, struct bfi_ioc_image_hdr_s *fwhdr)
869{
870 struct bfi_ioc_image_hdr_s *drv_fwhdr;
871 int i;
872
873 drv_fwhdr =
874 (struct bfi_ioc_image_hdr_s *)bfa_ioc_fwimg_get_chunk(ioc, 0);
875
876 for (i = 0; i < BFI_IOC_MD5SUM_SZ; i++) {
877 if (fwhdr->md5sum[i] != drv_fwhdr->md5sum[i]) {
878 bfa_trc(ioc, i);
879 bfa_trc(ioc, fwhdr->md5sum[i]);
880 bfa_trc(ioc, drv_fwhdr->md5sum[i]);
881 return BFA_FALSE;
882 }
883 }
884
885 bfa_trc(ioc, fwhdr->md5sum[0]);
886 return BFA_TRUE;
887}
888
889/**
890 * Return true if current running version is valid. Firmware signature and
891 * execution context (driver/bios) must match.
892 */
893static bfa_boolean_t
894bfa_ioc_fwver_valid(struct bfa_ioc_s *ioc)
895{
896 struct bfi_ioc_image_hdr_s fwhdr, *drv_fwhdr;
897
898 /**
899 * If bios/efi boot (flash based) -- return true
900 */
901 if (bfa_ioc_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)
902 return BFA_TRUE;
903
904 bfa_ioc_fwver_get(ioc, &fwhdr);
905 drv_fwhdr =
906 (struct bfi_ioc_image_hdr_s *)bfa_ioc_fwimg_get_chunk(ioc, 0);
907
908 if (fwhdr.signature != drv_fwhdr->signature) {
909 bfa_trc(ioc, fwhdr.signature);
910 bfa_trc(ioc, drv_fwhdr->signature);
911 return BFA_FALSE;
912 }
913
914 if (fwhdr.exec != drv_fwhdr->exec) {
915 bfa_trc(ioc, fwhdr.exec);
916 bfa_trc(ioc, drv_fwhdr->exec);
917 return BFA_FALSE;
918 }
919
920 return bfa_ioc_fwver_cmp(ioc, &fwhdr);
921}
922
923/**
924 * Return true if firmware of current driver matches the running firmware.
925 */
926static bfa_boolean_t
927bfa_ioc_firmware_lock(struct bfa_ioc_s *ioc)
928{
929 enum bfi_ioc_state ioc_fwstate;
930 u32 usecnt;
931 struct bfi_ioc_image_hdr_s fwhdr;
932
933 /**
934 * Firmware match check is relevant only for CNA.
935 */
936 if (!ioc->cna)
937 return BFA_TRUE;
938
939 /**
940 * If bios boot (flash based) -- do not increment usage count
941 */
942 if (bfa_ioc_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)
943 return BFA_TRUE;
944
945 bfa_ioc_usage_sem_get(ioc);
946 usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg);
947
948 /**
949 * If usage count is 0, always return TRUE.
950 */
951 if (usecnt == 0) {
952 bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, 1);
953 bfa_ioc_usage_sem_release(ioc);
954 bfa_trc(ioc, usecnt);
955 return BFA_TRUE;
956 }
957
958 ioc_fwstate = bfa_reg_read(ioc->ioc_regs.ioc_fwstate);
959 bfa_trc(ioc, ioc_fwstate);
960
961 /**
962 * Use count cannot be non-zero and chip in uninitialized state.
963 */
964 bfa_assert(ioc_fwstate != BFI_IOC_UNINIT);
965
966 /**
967 * Check if another driver with a different firmware is active
968 */
969 bfa_ioc_fwver_get(ioc, &fwhdr);
970 if (!bfa_ioc_fwver_cmp(ioc, &fwhdr)) {
971 bfa_ioc_usage_sem_release(ioc);
972 bfa_trc(ioc, usecnt);
973 return BFA_FALSE;
974 }
975
976 /**
977 * Same firmware version. Increment the reference count.
978 */
979 usecnt++;
980 bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt);
981 bfa_ioc_usage_sem_release(ioc);
982 bfa_trc(ioc, usecnt);
983 return BFA_TRUE;
984}
985
986static void
987bfa_ioc_firmware_unlock(struct bfa_ioc_s *ioc)
988{
989 u32 usecnt;
990
991 /**
992 * Firmware lock is relevant only for CNA.
993 * If bios boot (flash based) -- do not decrement usage count
994 */
995 if (!ioc->cna || (bfa_ioc_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ))
996 return;
997
998 /**
999 * decrement usage count
1000 */
1001 bfa_ioc_usage_sem_get(ioc);
1002 usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg);
1003 bfa_assert(usecnt > 0);
1004
1005 usecnt--;
1006 bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt);
1007 bfa_trc(ioc, usecnt);
1008
1009 bfa_ioc_usage_sem_release(ioc);
1010}
1011
1012/**
1013 * Conditionally flush any pending message from firmware at start.
1014 */
1015static void
1016bfa_ioc_msgflush(struct bfa_ioc_s *ioc)
1017{
1018 u32 r32;
1019
1020 r32 = bfa_reg_read(ioc->ioc_regs.lpu_mbox_cmd);
1021 if (r32)
1022 bfa_reg_write(ioc->ioc_regs.lpu_mbox_cmd, 1);
1023}
1024
1025
1026static void
1027bfa_ioc_hwinit(struct bfa_ioc_s *ioc, bfa_boolean_t force)
1028{
1029 enum bfi_ioc_state ioc_fwstate;
1030 bfa_boolean_t fwvalid;
1031
1032 ioc_fwstate = bfa_reg_read(ioc->ioc_regs.ioc_fwstate);
1033
1034 if (force)
1035 ioc_fwstate = BFI_IOC_UNINIT;
1036
1037 bfa_trc(ioc, ioc_fwstate);
1038
1039 /**
1040 * check if firmware is valid
1041 */
1042 fwvalid = (ioc_fwstate == BFI_IOC_UNINIT) ?
1043 BFA_FALSE : bfa_ioc_fwver_valid(ioc);
1044
1045 if (!fwvalid) {
1046 bfa_ioc_boot(ioc, BFI_BOOT_TYPE_NORMAL, ioc->pcidev.device_id);
1047 return;
1048 }
1049
1050 /**
1051 * If hardware initialization is in progress (initialized by other IOC),
1052 * just wait for an initialization completion interrupt.
1053 */
1054 if (ioc_fwstate == BFI_IOC_INITING) {
1055 bfa_trc(ioc, ioc_fwstate);
1056 ioc->cbfn->reset_cbfn(ioc->bfa);
1057 return;
1058 }
1059
1060 /**
1061 * If IOC function is disabled and firmware version is same,
1062 * just re-enable IOC.
1063 */
1064 if (ioc_fwstate == BFI_IOC_DISABLED || ioc_fwstate == BFI_IOC_OP) {
1065 bfa_trc(ioc, ioc_fwstate);
1066
1067 /**
1068 * When using MSI-X any pending firmware ready event should
1069 * be flushed. Otherwise MSI-X interrupts are not delivered.
1070 */
1071 bfa_ioc_msgflush(ioc);
1072 ioc->cbfn->reset_cbfn(ioc->bfa);
1073 bfa_fsm_send_event(ioc, IOC_E_FWREADY);
1074 return;
1075 }
1076
1077 /**
1078 * Initialize the h/w for any other states.
1079 */
1080 bfa_ioc_boot(ioc, BFI_BOOT_TYPE_NORMAL, ioc->pcidev.device_id);
1081}
1082
1083static void
1084bfa_ioc_timeout(void *ioc_arg)
1085{
1086 struct bfa_ioc_s *ioc = (struct bfa_ioc_s *)ioc_arg;
1087
1088 bfa_trc(ioc, 0);
1089 bfa_fsm_send_event(ioc, IOC_E_TIMEOUT);
1090}
1091
1092void
1093bfa_ioc_mbox_send(struct bfa_ioc_s *ioc, void *ioc_msg, int len)
1094{
1095 u32 *msgp = (u32 *) ioc_msg;
1096 u32 i;
1097
1098 bfa_trc(ioc, msgp[0]);
1099 bfa_trc(ioc, len);
1100
1101 bfa_assert(len <= BFI_IOC_MSGLEN_MAX);
1102
1103 /*
1104 * first write msg to mailbox registers
1105 */
1106 for (i = 0; i < len / sizeof(u32); i++)
1107 bfa_reg_write(ioc->ioc_regs.hfn_mbox + i * sizeof(u32),
1108 bfa_os_wtole(msgp[i]));
1109
1110 for (; i < BFI_IOC_MSGLEN_MAX / sizeof(u32); i++)
1111 bfa_reg_write(ioc->ioc_regs.hfn_mbox + i * sizeof(u32), 0);
1112
1113 /*
1114 * write 1 to mailbox CMD to trigger LPU event
1115 */
1116 bfa_reg_write(ioc->ioc_regs.hfn_mbox_cmd, 1);
1117 (void)bfa_reg_read(ioc->ioc_regs.hfn_mbox_cmd);
1118}
1119
1120static void
1121bfa_ioc_send_enable(struct bfa_ioc_s *ioc)
1122{
1123 struct bfi_ioc_ctrl_req_s enable_req;
1124
1125 bfi_h2i_set(enable_req.mh, BFI_MC_IOC, BFI_IOC_H2I_ENABLE_REQ,
1126 bfa_ioc_portid(ioc));
1127 enable_req.ioc_class = ioc->ioc_mc;
1128 bfa_ioc_mbox_send(ioc, &enable_req, sizeof(struct bfi_ioc_ctrl_req_s));
1129}
1130
1131static void
1132bfa_ioc_send_disable(struct bfa_ioc_s *ioc)
1133{
1134 struct bfi_ioc_ctrl_req_s disable_req;
1135
1136 bfi_h2i_set(disable_req.mh, BFI_MC_IOC, BFI_IOC_H2I_DISABLE_REQ,
1137 bfa_ioc_portid(ioc));
1138 bfa_ioc_mbox_send(ioc, &disable_req, sizeof(struct bfi_ioc_ctrl_req_s));
1139}
1140
1141static void
1142bfa_ioc_send_getattr(struct bfa_ioc_s *ioc)
1143{
1144 struct bfi_ioc_getattr_req_s attr_req;
1145
1146 bfi_h2i_set(attr_req.mh, BFI_MC_IOC, BFI_IOC_H2I_GETATTR_REQ,
1147 bfa_ioc_portid(ioc));
1148 bfa_dma_be_addr_set(attr_req.attr_addr, ioc->attr_dma.pa);
1149 bfa_ioc_mbox_send(ioc, &attr_req, sizeof(attr_req));
1150}
1151
1152static void
1153bfa_ioc_hb_check(void *cbarg)
1154{
1155 struct bfa_ioc_s *ioc = cbarg;
1156 u32 hb_count;
1157
1158 hb_count = bfa_reg_read(ioc->ioc_regs.heartbeat);
1159 if (ioc->hb_count == hb_count) {
1160 ioc->hb_fail++;
1161 } else {
1162 ioc->hb_count = hb_count;
1163 ioc->hb_fail = 0;
1164 }
1165
1166 if (ioc->hb_fail >= BFA_IOC_HB_FAIL_MAX) {
1167 bfa_log(ioc->logm, BFA_LOG_HAL_HEARTBEAT_FAILURE, hb_count);
1168 ioc->hb_fail = 0;
1169 bfa_ioc_recover(ioc);
1170 return;
1171 }
1172
1173 bfa_ioc_mbox_poll(ioc);
1174 bfa_timer_begin(ioc->timer_mod, &ioc->ioc_timer, bfa_ioc_hb_check, ioc,
1175 BFA_IOC_HB_TOV);
1176}
1177
1178static void
1179bfa_ioc_hb_monitor(struct bfa_ioc_s *ioc)
1180{
1181 ioc->hb_fail = 0;
1182 ioc->hb_count = bfa_reg_read(ioc->ioc_regs.heartbeat);
1183 bfa_timer_begin(ioc->timer_mod, &ioc->ioc_timer, bfa_ioc_hb_check, ioc,
1184 BFA_IOC_HB_TOV);
1185}
1186
1187static void
1188bfa_ioc_hb_stop(struct bfa_ioc_s *ioc)
1189{
1190 bfa_timer_stop(&ioc->ioc_timer);
1191}
1192
1193/**
1194 * Host to LPU mailbox message addresses
1195 */
1196static struct {
1197 u32 hfn_mbox, lpu_mbox, hfn_pgn;
1198} iocreg_fnreg[] = {
1199 {
1200 HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0}, {
1201 HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1}, {
1202 HOSTFN2_LPU_MBOX0_0, LPU_HOSTFN2_MBOX0_0, HOST_PAGE_NUM_FN2}, {
1203 HOSTFN3_LPU_MBOX0_8, LPU_HOSTFN3_MBOX0_8, HOST_PAGE_NUM_FN3}
1204};
1205
1206/**
1207 * Host <-> LPU mailbox command/status registers - port 0
1208 */
1209static struct {
1210 u32 hfn, lpu;
1211} iocreg_mbcmd_p0[] = {
1212 {
1213 HOSTFN0_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN0_MBOX0_CMD_STAT}, {
1214 HOSTFN1_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN1_MBOX0_CMD_STAT}, {
1215 HOSTFN2_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN2_MBOX0_CMD_STAT}, {
1216 HOSTFN3_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN3_MBOX0_CMD_STAT}
1217};
1218
1219/**
1220 * Host <-> LPU mailbox command/status registers - port 1
1221 */
1222static struct {
1223 u32 hfn, lpu;
1224} iocreg_mbcmd_p1[] = {
1225 {
1226 HOSTFN0_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN0_MBOX0_CMD_STAT}, {
1227 HOSTFN1_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN1_MBOX0_CMD_STAT}, {
1228 HOSTFN2_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN2_MBOX0_CMD_STAT}, {
1229 HOSTFN3_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN3_MBOX0_CMD_STAT}
1230};
1231
1232/**
1233 * Shared IRQ handling in INTX mode
1234 */
1235static struct {
1236 u32 isr, msk;
1237} iocreg_shirq_next[] = {
1238 {
1239 HOSTFN1_INT_STATUS, HOSTFN1_INT_MSK}, {
1240 HOSTFN2_INT_STATUS, HOSTFN2_INT_MSK}, {
1241 HOSTFN3_INT_STATUS, HOSTFN3_INT_MSK}, {
1242HOSTFN0_INT_STATUS, HOSTFN0_INT_MSK},};
1243
1244static void
1245bfa_ioc_reg_init(struct bfa_ioc_s *ioc)
1246{
1247 bfa_os_addr_t rb;
1248 int pcifn = bfa_ioc_pcifn(ioc);
1249
1250 rb = bfa_ioc_bar0(ioc);
1251
1252 ioc->ioc_regs.hfn_mbox = rb + iocreg_fnreg[pcifn].hfn_mbox;
1253 ioc->ioc_regs.lpu_mbox = rb + iocreg_fnreg[pcifn].lpu_mbox;
1254 ioc->ioc_regs.host_page_num_fn = rb + iocreg_fnreg[pcifn].hfn_pgn;
1255
1256 if (ioc->port_id == 0) {
1257 ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG;
1258 ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG;
1259 ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].hfn;
1260 ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].lpu;
1261 ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P0;
1262 } else {
1263 ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG);
1264 ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG);
1265 ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].hfn;
1266 ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].lpu;
1267 ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P1;
1268 }
1269
1270 /**
1271 * Shared IRQ handling in INTX mode
1272 */
1273 ioc->ioc_regs.shirq_isr_next = rb + iocreg_shirq_next[pcifn].isr;
1274 ioc->ioc_regs.shirq_msk_next = rb + iocreg_shirq_next[pcifn].msk;
1275
1276 /*
1277 * PSS control registers
1278 */
1279 ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG);
1280 ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_425_CTL_REG);
1281 ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_312_CTL_REG);
1282
1283 /*
1284 * IOC semaphore registers and serialization
1285 */
1286 ioc->ioc_regs.ioc_sem_reg = (rb + HOST_SEM0_REG);
1287 ioc->ioc_regs.ioc_usage_sem_reg = (rb + HOST_SEM1_REG);
1288 ioc->ioc_regs.ioc_usage_reg = (rb + BFA_FW_USE_COUNT);
1289
1290 /**
1291 * sram memory access
1292 */
1293 ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START);
1294 ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CB;
1295 if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT)
1296 ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CT;
1297}
1298
1299/**
1300 * Initiate a full firmware download.
1301 */
1302static void
1303bfa_ioc_download_fw(struct bfa_ioc_s *ioc, u32 boot_type,
1304 u32 boot_param)
1305{
1306 u32 *fwimg;
1307 u32 pgnum, pgoff;
1308 u32 loff = 0;
1309 u32 chunkno = 0;
1310 u32 i;
1311
1312 /**
1313 * Initialize LMEM first before code download
1314 */
1315 bfa_ioc_lmem_init(ioc);
1316
1317 /**
1318 * Flash based firmware boot
1319 */
1320 bfa_trc(ioc, bfa_ioc_fwimg_get_size(ioc));
1321 if (bfa_ioc_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)
1322 boot_type = BFI_BOOT_TYPE_FLASH;
1323 fwimg = bfa_ioc_fwimg_get_chunk(ioc, chunkno);
1324 fwimg[BFI_BOOT_TYPE_OFF / sizeof(u32)] = bfa_os_swap32(boot_type);
1325 fwimg[BFI_BOOT_PARAM_OFF / sizeof(u32)] =
1326 bfa_os_swap32(boot_param);
1327
1328 pgnum = bfa_ioc_smem_pgnum(ioc, loff);
1329 pgoff = bfa_ioc_smem_pgoff(ioc, loff);
1330
1331 bfa_reg_write(ioc->ioc_regs.host_page_num_fn, pgnum);
1332
1333 for (i = 0; i < bfa_ioc_fwimg_get_size(ioc); i++) {
1334
1335 if (BFA_FLASH_CHUNK_NO(i) != chunkno) {
1336 chunkno = BFA_FLASH_CHUNK_NO(i);
1337 fwimg = bfa_ioc_fwimg_get_chunk(ioc,
1338 BFA_FLASH_CHUNK_ADDR(chunkno));
1339 }
1340
1341 /**
1342 * write smem
1343 */
1344 bfa_mem_write(ioc->ioc_regs.smem_page_start, loff,
1345 fwimg[BFA_FLASH_OFFSET_IN_CHUNK(i)]);
1346
1347 loff += sizeof(u32);
1348
1349 /**
1350 * handle page offset wrap around
1351 */
1352 loff = PSS_SMEM_PGOFF(loff);
1353 if (loff == 0) {
1354 pgnum++;
1355 bfa_reg_write(ioc->ioc_regs.host_page_num_fn, pgnum);
1356 }
1357 }
1358
1359 bfa_reg_write(ioc->ioc_regs.host_page_num_fn,
1360 bfa_ioc_smem_pgnum(ioc, 0));
1361}
1362
1363static void
1364bfa_ioc_reset(struct bfa_ioc_s *ioc, bfa_boolean_t force)
1365{
1366 bfa_ioc_hwinit(ioc, force);
1367}
1368
1369/**
1370 * Update BFA configuration from firmware configuration.
1371 */
1372static void
1373bfa_ioc_getattr_reply(struct bfa_ioc_s *ioc)
1374{
1375 struct bfi_ioc_attr_s *attr = ioc->attr;
1376
1377 attr->adapter_prop = bfa_os_ntohl(attr->adapter_prop);
1378 attr->maxfrsize = bfa_os_ntohs(attr->maxfrsize);
1379
1380 bfa_fsm_send_event(ioc, IOC_E_FWRSP_GETATTR);
1381}
1382
1383/**
1384 * Attach time initialization of mbox logic.
1385 */
1386static void
1387bfa_ioc_mbox_attach(struct bfa_ioc_s *ioc)
1388{
1389 struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod;
1390 int mc;
1391
1392 INIT_LIST_HEAD(&mod->cmd_q);
1393 for (mc = 0; mc < BFI_MC_MAX; mc++) {
1394 mod->mbhdlr[mc].cbfn = NULL;
1395 mod->mbhdlr[mc].cbarg = ioc->bfa;
1396 }
1397}
1398
1399/**
1400 * Mbox poll timer -- restarts any pending mailbox requests.
1401 */
1402static void
1403bfa_ioc_mbox_poll(struct bfa_ioc_s *ioc)
1404{
1405 struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod;
1406 struct bfa_mbox_cmd_s *cmd;
1407 u32 stat;
1408
1409 /**
1410 * If no command pending, do nothing
1411 */
1412 if (list_empty(&mod->cmd_q))
1413 return;
1414
1415 /**
1416 * If previous command is not yet fetched by firmware, do nothing
1417 */
1418 stat = bfa_reg_read(ioc->ioc_regs.hfn_mbox_cmd);
1419 if (stat)
1420 return;
1421
1422 /**
1423 * Enqueue command to firmware.
1424 */
1425 bfa_q_deq(&mod->cmd_q, &cmd);
1426 bfa_ioc_mbox_send(ioc, cmd->msg, sizeof(cmd->msg));
1427}
1428
1429/**
1430 * Cleanup any pending requests.
1431 */
1432static void
1433bfa_ioc_mbox_hbfail(struct bfa_ioc_s *ioc)
1434{
1435 struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod;
1436 struct bfa_mbox_cmd_s *cmd;
1437
1438 while (!list_empty(&mod->cmd_q))
1439 bfa_q_deq(&mod->cmd_q, &cmd);
1440}
1441
1442/**
1443 * Initialize IOC to port mapping.
1444 */
1445
1446#define FNC_PERS_FN_SHIFT(__fn) ((__fn) * 8)
1447static void
1448bfa_ioc_map_port(struct bfa_ioc_s *ioc)
1449{
1450 bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva;
1451 u32 r32;
1452
1453 /**
1454 * For crossbow, port id is same as pci function.
1455 */
1456 if (ioc->pcidev.device_id != BFA_PCI_DEVICE_ID_CT) {
1457 ioc->port_id = bfa_ioc_pcifn(ioc);
1458 return;
1459 }
1460
1461 /**
1462 * For catapult, base port id on personality register and IOC type
1463 */
1464 r32 = bfa_reg_read(rb + FNC_PERS_REG);
1465 r32 >>= FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc));
1466 ioc->port_id = (r32 & __F0_PORT_MAP_MK) >> __F0_PORT_MAP_SH;
1467
1468 bfa_trc(ioc, bfa_ioc_pcifn(ioc));
1469 bfa_trc(ioc, ioc->port_id);
1470}
1471
1472
1473
1474/**
1475 * bfa_ioc_public
1476 */
1477
1478/**
1479* Set interrupt mode for a function: INTX or MSIX
1480 */
1481void
1482bfa_ioc_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix)
1483{
1484 bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva;
1485 u32 r32, mode;
1486
1487 r32 = bfa_reg_read(rb + FNC_PERS_REG);
1488 bfa_trc(ioc, r32);
1489
1490 mode = (r32 >> FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))) &
1491 __F0_INTX_STATUS;
1492
1493 /**
1494 * If already in desired mode, do not change anything
1495 */
1496 if (!msix && mode)
1497 return;
1498
1499 if (msix)
1500 mode = __F0_INTX_STATUS_MSIX;
1501 else
1502 mode = __F0_INTX_STATUS_INTA;
1503
1504 r32 &= ~(__F0_INTX_STATUS << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)));
1505 r32 |= (mode << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)));
1506 bfa_trc(ioc, r32);
1507
1508 bfa_reg_write(rb + FNC_PERS_REG, r32);
1509}
1510
1511bfa_status_t
1512bfa_ioc_pll_init(struct bfa_ioc_s *ioc)
1513{
1514 bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva;
1515 u32 pll_sclk, pll_fclk, r32;
1516
1517 if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT) {
1518 pll_sclk =
1519 __APP_PLL_312_ENABLE | __APP_PLL_312_LRESETN |
1520 __APP_PLL_312_RSEL200500 | __APP_PLL_312_P0_1(0U) |
1521 __APP_PLL_312_JITLMT0_1(3U) |
1522 __APP_PLL_312_CNTLMT0_1(1U);
1523 pll_fclk =
1524 __APP_PLL_425_ENABLE | __APP_PLL_425_LRESETN |
1525 __APP_PLL_425_RSEL200500 | __APP_PLL_425_P0_1(0U) |
1526 __APP_PLL_425_JITLMT0_1(3U) |
1527 __APP_PLL_425_CNTLMT0_1(1U);
1528
1529 /**
1530 * For catapult, choose operational mode FC/FCoE
1531 */
1532 if (ioc->fcmode) {
1533 bfa_reg_write((rb + OP_MODE), 0);
1534 bfa_reg_write((rb + ETH_MAC_SER_REG),
1535 __APP_EMS_CMLCKSEL | __APP_EMS_REFCKBUFEN2
1536 | __APP_EMS_CHANNEL_SEL);
1537 } else {
1538 ioc->pllinit = BFA_TRUE;
1539 bfa_reg_write((rb + OP_MODE), __GLOBAL_FCOE_MODE);
1540 bfa_reg_write((rb + ETH_MAC_SER_REG),
1541 __APP_EMS_REFCKBUFEN1);
1542 }
1543 } else {
1544 pll_sclk =
1545 __APP_PLL_312_ENABLE | __APP_PLL_312_LRESETN |
1546 __APP_PLL_312_P0_1(3U) | __APP_PLL_312_JITLMT0_1(3U) |
1547 __APP_PLL_312_CNTLMT0_1(3U);
1548 pll_fclk =
1549 __APP_PLL_425_ENABLE | __APP_PLL_425_LRESETN |
1550 __APP_PLL_425_RSEL200500 | __APP_PLL_425_P0_1(3U) |
1551 __APP_PLL_425_JITLMT0_1(3U) |
1552 __APP_PLL_425_CNTLMT0_1(3U);
1553 }
1554
1555 bfa_reg_write((rb + BFA_IOC0_STATE_REG), BFI_IOC_UNINIT);
1556 bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_UNINIT);
1557
1558 bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
1559 bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
1560 bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
1561 bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
1562 bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
1563 bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
1564
1565 bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
1566 __APP_PLL_312_LOGIC_SOFT_RESET);
1567 bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
1568 __APP_PLL_312_BYPASS | __APP_PLL_312_LOGIC_SOFT_RESET);
1569 bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
1570 __APP_PLL_425_LOGIC_SOFT_RESET);
1571 bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
1572 __APP_PLL_425_BYPASS | __APP_PLL_425_LOGIC_SOFT_RESET);
1573 bfa_os_udelay(2);
1574 bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
1575 __APP_PLL_312_LOGIC_SOFT_RESET);
1576 bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
1577 __APP_PLL_425_LOGIC_SOFT_RESET);
1578
1579 bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
1580 pll_sclk | __APP_PLL_312_LOGIC_SOFT_RESET);
1581 bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
1582 pll_fclk | __APP_PLL_425_LOGIC_SOFT_RESET);
1583
1584 /**
1585 * Wait for PLLs to lock.
1586 */
1587 bfa_os_udelay(2000);
1588 bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
1589 bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
1590
1591 bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk);
1592 bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk);
1593
1594 if (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT) {
1595 bfa_reg_write((rb + MBIST_CTL_REG), __EDRAM_BISTR_START);
1596 bfa_os_udelay(1000);
1597 r32 = bfa_reg_read((rb + MBIST_STAT_REG));
1598 bfa_trc(ioc, r32);
1599 }
1600
1601 return BFA_STATUS_OK;
1602}
1603
1604/**
1605 * Interface used by diag module to do firmware boot with memory test
1606 * as the entry vector.
1607 */
1608void
1609bfa_ioc_boot(struct bfa_ioc_s *ioc, u32 boot_type, u32 boot_param)
1610{
1611 bfa_os_addr_t rb;
1612
1613 bfa_ioc_stats(ioc, ioc_boots);
1614
1615 if (bfa_ioc_pll_init(ioc) != BFA_STATUS_OK)
1616 return;
1617
1618 /**
1619 * Initialize IOC state of all functions on a chip reset.
1620 */
1621 rb = ioc->pcidev.pci_bar_kva;
1622 if (boot_param == BFI_BOOT_TYPE_MEMTEST) {
1623 bfa_reg_write((rb + BFA_IOC0_STATE_REG), BFI_IOC_MEMTEST);
1624 bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_MEMTEST);
1625 } else {
1626 bfa_reg_write((rb + BFA_IOC0_STATE_REG), BFI_IOC_INITING);
1627 bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_INITING);
1628 }
1629
1630 bfa_ioc_download_fw(ioc, boot_type, boot_param);
1631
1632 /**
1633 * Enable interrupts just before starting LPU
1634 */
1635 ioc->cbfn->reset_cbfn(ioc->bfa);
1636 bfa_ioc_lpu_start(ioc);
1637}
1638
1639/**
1640 * Enable/disable IOC failure auto recovery.
1641 */
1642void
1643bfa_ioc_auto_recover(bfa_boolean_t auto_recover)
1644{
1645 bfa_auto_recover = BFA_FALSE;
1646}
1647
1648
1649bfa_boolean_t
1650bfa_ioc_is_operational(struct bfa_ioc_s *ioc)
1651{
1652 return bfa_fsm_cmp_state(ioc, bfa_ioc_sm_op);
1653}
1654
1655void
1656bfa_ioc_msgget(struct bfa_ioc_s *ioc, void *mbmsg)
1657{
1658 u32 *msgp = mbmsg;
1659 u32 r32;
1660 int i;
1661
1662 /**
1663 * read the MBOX msg
1664 */
1665 for (i = 0; i < (sizeof(union bfi_ioc_i2h_msg_u) / sizeof(u32));
1666 i++) {
1667 r32 = bfa_reg_read(ioc->ioc_regs.lpu_mbox +
1668 i * sizeof(u32));
1669 msgp[i] = bfa_os_htonl(r32);
1670 }
1671
1672 /**
1673 * turn off mailbox interrupt by clearing mailbox status
1674 */
1675 bfa_reg_write(ioc->ioc_regs.lpu_mbox_cmd, 1);
1676 bfa_reg_read(ioc->ioc_regs.lpu_mbox_cmd);
1677}
1678
1679void
1680bfa_ioc_isr(struct bfa_ioc_s *ioc, struct bfi_mbmsg_s *m)
1681{
1682 union bfi_ioc_i2h_msg_u *msg;
1683
1684 msg = (union bfi_ioc_i2h_msg_u *)m;
1685
1686 bfa_ioc_stats(ioc, ioc_isrs);
1687
1688 switch (msg->mh.msg_id) {
1689 case BFI_IOC_I2H_HBEAT:
1690 break;
1691
1692 case BFI_IOC_I2H_READY_EVENT:
1693 bfa_fsm_send_event(ioc, IOC_E_FWREADY);
1694 break;
1695
1696 case BFI_IOC_I2H_ENABLE_REPLY:
1697 bfa_fsm_send_event(ioc, IOC_E_FWRSP_ENABLE);
1698 break;
1699
1700 case BFI_IOC_I2H_DISABLE_REPLY:
1701 bfa_fsm_send_event(ioc, IOC_E_FWRSP_DISABLE);
1702 break;
1703
1704 case BFI_IOC_I2H_GETATTR_REPLY:
1705 bfa_ioc_getattr_reply(ioc);
1706 break;
1707
1708 default:
1709 bfa_trc(ioc, msg->mh.msg_id);
1710 bfa_assert(0);
1711 }
1712}
1713
1714/**
1715 * IOC attach time initialization and setup.
1716 *
1717 * @param[in] ioc memory for IOC
1718 * @param[in] bfa driver instance structure
1719 * @param[in] trcmod kernel trace module
1720 * @param[in] aen kernel aen event module
1721 * @param[in] logm kernel logging module
1722 */
1723void
1724bfa_ioc_attach(struct bfa_ioc_s *ioc, void *bfa, struct bfa_ioc_cbfn_s *cbfn,
1725 struct bfa_timer_mod_s *timer_mod, struct bfa_trc_mod_s *trcmod,
1726 struct bfa_aen_s *aen, struct bfa_log_mod_s *logm)
1727{
1728 ioc->bfa = bfa;
1729 ioc->cbfn = cbfn;
1730 ioc->timer_mod = timer_mod;
1731 ioc->trcmod = trcmod;
1732 ioc->aen = aen;
1733 ioc->logm = logm;
1734 ioc->fcmode = BFA_FALSE;
1735 ioc->pllinit = BFA_FALSE;
1736 ioc->dbg_fwsave_once = BFA_TRUE;
1737
1738 bfa_ioc_mbox_attach(ioc);
1739 INIT_LIST_HEAD(&ioc->hb_notify_q);
1740
1741 bfa_fsm_set_state(ioc, bfa_ioc_sm_reset);
1742}
1743
1744/**
1745 * Driver detach time IOC cleanup.
1746 */
1747void
1748bfa_ioc_detach(struct bfa_ioc_s *ioc)
1749{
1750 bfa_fsm_send_event(ioc, IOC_E_DETACH);
1751}
1752
1753/**
1754 * Setup IOC PCI properties.
1755 *
1756 * @param[in] pcidev PCI device information for this IOC
1757 */
1758void
1759bfa_ioc_pci_init(struct bfa_ioc_s *ioc, struct bfa_pcidev_s *pcidev,
1760 enum bfi_mclass mc)
1761{
1762 ioc->ioc_mc = mc;
1763 ioc->pcidev = *pcidev;
1764 ioc->ctdev = (ioc->pcidev.device_id == BFA_PCI_DEVICE_ID_CT);
1765 ioc->cna = ioc->ctdev && !ioc->fcmode;
1766
1767 bfa_ioc_map_port(ioc);
1768 bfa_ioc_reg_init(ioc);
1769}
1770
1771/**
1772 * Initialize IOC dma memory
1773 *
1774 * @param[in] dm_kva kernel virtual address of IOC dma memory
1775 * @param[in] dm_pa physical address of IOC dma memory
1776 */
1777void
1778bfa_ioc_mem_claim(struct bfa_ioc_s *ioc, u8 *dm_kva, u64 dm_pa)
1779{
1780 /**
1781 * dma memory for firmware attribute
1782 */
1783 ioc->attr_dma.kva = dm_kva;
1784 ioc->attr_dma.pa = dm_pa;
1785 ioc->attr = (struct bfi_ioc_attr_s *)dm_kva;
1786}
1787
1788/**
1789 * Return size of dma memory required.
1790 */
1791u32
1792bfa_ioc_meminfo(void)
1793{
1794 return BFA_ROUNDUP(sizeof(struct bfi_ioc_attr_s), BFA_DMA_ALIGN_SZ);
1795}
1796
1797void
1798bfa_ioc_enable(struct bfa_ioc_s *ioc)
1799{
1800 bfa_ioc_stats(ioc, ioc_enables);
1801 ioc->dbg_fwsave_once = BFA_TRUE;
1802
1803 bfa_fsm_send_event(ioc, IOC_E_ENABLE);
1804}
1805
1806void
1807bfa_ioc_disable(struct bfa_ioc_s *ioc)
1808{
1809 bfa_ioc_stats(ioc, ioc_disables);
1810 bfa_fsm_send_event(ioc, IOC_E_DISABLE);
1811}
1812
1813/**
1814 * Returns memory required for saving firmware trace in case of crash.
1815 * Driver must call this interface to allocate memory required for
1816 * automatic saving of firmware trace. Driver should call
1817 * bfa_ioc_debug_memclaim() right after bfa_ioc_attach() to setup this
1818 * trace memory.
1819 */
1820int
1821bfa_ioc_debug_trcsz(bfa_boolean_t auto_recover)
1822{
1823return (auto_recover) ? BFA_DBG_FWTRC_LEN : 0;
1824}
1825
1826/**
1827 * Initialize memory for saving firmware trace. Driver must initialize
1828 * trace memory before call bfa_ioc_enable().
1829 */
1830void
1831bfa_ioc_debug_memclaim(struct bfa_ioc_s *ioc, void *dbg_fwsave)
1832{
1833 bfa_assert(ioc->auto_recover);
1834 ioc->dbg_fwsave = dbg_fwsave;
1835 ioc->dbg_fwsave_len = bfa_ioc_debug_trcsz(ioc->auto_recover);
1836}
1837
1838u32
1839bfa_ioc_smem_pgnum(struct bfa_ioc_s *ioc, u32 fmaddr)
1840{
1841 return PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, fmaddr);
1842}
1843
1844u32
1845bfa_ioc_smem_pgoff(struct bfa_ioc_s *ioc, u32 fmaddr)
1846{
1847 return PSS_SMEM_PGOFF(fmaddr);
1848}
1849
1850/**
1851 * Register mailbox message handler functions
1852 *
1853 * @param[in] ioc IOC instance
1854 * @param[in] mcfuncs message class handler functions
1855 */
1856void
1857bfa_ioc_mbox_register(struct bfa_ioc_s *ioc, bfa_ioc_mbox_mcfunc_t *mcfuncs)
1858{
1859 struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod;
1860 int mc;
1861
1862 for (mc = 0; mc < BFI_MC_MAX; mc++)
1863 mod->mbhdlr[mc].cbfn = mcfuncs[mc];
1864}
1865
1866/**
1867 * Register mailbox message handler function, to be called by common modules
1868 */
1869void
1870bfa_ioc_mbox_regisr(struct bfa_ioc_s *ioc, enum bfi_mclass mc,
1871 bfa_ioc_mbox_mcfunc_t cbfn, void *cbarg)
1872{
1873 struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod;
1874
1875 mod->mbhdlr[mc].cbfn = cbfn;
1876 mod->mbhdlr[mc].cbarg = cbarg;
1877}
1878
1879/**
1880 * Queue a mailbox command request to firmware. Waits if mailbox is busy.
1881 * Responsibility of caller to serialize
1882 *
1883 * @param[in] ioc IOC instance
1884 * @param[i] cmd Mailbox command
1885 */
1886void
1887bfa_ioc_mbox_queue(struct bfa_ioc_s *ioc, struct bfa_mbox_cmd_s *cmd)
1888{
1889 struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod;
1890 u32 stat;
1891
1892 /**
1893 * If a previous command is pending, queue new command
1894 */
1895 if (!list_empty(&mod->cmd_q)) {
1896 list_add_tail(&cmd->qe, &mod->cmd_q);
1897 return;
1898 }
1899
1900 /**
1901 * If mailbox is busy, queue command for poll timer
1902 */
1903 stat = bfa_reg_read(ioc->ioc_regs.hfn_mbox_cmd);
1904 if (stat) {
1905 list_add_tail(&cmd->qe, &mod->cmd_q);
1906 return;
1907 }
1908
1909 /**
1910 * mailbox is free -- queue command to firmware
1911 */
1912 bfa_ioc_mbox_send(ioc, cmd->msg, sizeof(cmd->msg));
1913}
1914
1915/**
1916 * Handle mailbox interrupts
1917 */
1918void
1919bfa_ioc_mbox_isr(struct bfa_ioc_s *ioc)
1920{
1921 struct bfa_ioc_mbox_mod_s *mod = &ioc->mbox_mod;
1922 struct bfi_mbmsg_s m;
1923 int mc;
1924
1925 bfa_ioc_msgget(ioc, &m);
1926
1927 /**
1928 * Treat IOC message class as special.
1929 */
1930 mc = m.mh.msg_class;
1931 if (mc == BFI_MC_IOC) {
1932 bfa_ioc_isr(ioc, &m);
1933 return;
1934 }
1935
1936 if ((mc > BFI_MC_MAX) || (mod->mbhdlr[mc].cbfn == NULL))
1937 return;
1938
1939 mod->mbhdlr[mc].cbfn(mod->mbhdlr[mc].cbarg, &m);
1940}
1941
1942void
1943bfa_ioc_error_isr(struct bfa_ioc_s *ioc)
1944{
1945 bfa_fsm_send_event(ioc, IOC_E_HWERROR);
1946}
1947
1948#ifndef BFA_BIOS_BUILD
1949
1950/**
1951 * return true if IOC is disabled
1952 */
1953bfa_boolean_t
1954bfa_ioc_is_disabled(struct bfa_ioc_s *ioc)
1955{
1956 return (bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabling)
1957 || bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabled));
1958}
1959
1960/**
1961 * return true if IOC firmware is different.
1962 */
1963bfa_boolean_t
1964bfa_ioc_fw_mismatch(struct bfa_ioc_s *ioc)
1965{
1966 return (bfa_fsm_cmp_state(ioc, bfa_ioc_sm_reset)
1967 || bfa_fsm_cmp_state(ioc, bfa_ioc_sm_fwcheck)
1968 || bfa_fsm_cmp_state(ioc, bfa_ioc_sm_mismatch));
1969}
1970
1971#define bfa_ioc_state_disabled(__sm) \
1972 (((__sm) == BFI_IOC_UNINIT) || \
1973 ((__sm) == BFI_IOC_INITING) || \
1974 ((__sm) == BFI_IOC_HWINIT) || \
1975 ((__sm) == BFI_IOC_DISABLED) || \
1976 ((__sm) == BFI_IOC_HBFAIL) || \
1977 ((__sm) == BFI_IOC_CFG_DISABLED))
1978
1979/**
1980 * Check if adapter is disabled -- both IOCs should be in a disabled
1981 * state.
1982 */
1983bfa_boolean_t
1984bfa_ioc_adapter_is_disabled(struct bfa_ioc_s *ioc)
1985{
1986 u32 ioc_state;
1987 bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva;
1988
1989 if (!bfa_fsm_cmp_state(ioc, bfa_ioc_sm_disabled))
1990 return BFA_FALSE;
1991
1992 ioc_state = bfa_reg_read(rb + BFA_IOC0_STATE_REG);
1993 if (!bfa_ioc_state_disabled(ioc_state))
1994 return BFA_FALSE;
1995
1996 ioc_state = bfa_reg_read(rb + BFA_IOC1_STATE_REG);
1997 if (!bfa_ioc_state_disabled(ioc_state))
1998 return BFA_FALSE;
1999
2000 return BFA_TRUE;
2001}
2002
2003/**
2004 * Add to IOC heartbeat failure notification queue. To be used by common
2005 * modules such as
2006 */
2007void
2008bfa_ioc_hbfail_register(struct bfa_ioc_s *ioc,
2009 struct bfa_ioc_hbfail_notify_s *notify)
2010{
2011 list_add_tail(&notify->qe, &ioc->hb_notify_q);
2012}
2013
2014#define BFA_MFG_NAME "Brocade"
2015void
2016bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc,
2017 struct bfa_adapter_attr_s *ad_attr)
2018{
2019 struct bfi_ioc_attr_s *ioc_attr;
2020 char model[BFA_ADAPTER_MODEL_NAME_LEN];
2021
2022 ioc_attr = ioc->attr;
2023 bfa_os_memcpy((void *)&ad_attr->serial_num,
2024 (void *)ioc_attr->brcd_serialnum,
2025 BFA_ADAPTER_SERIAL_NUM_LEN);
2026
2027 bfa_os_memcpy(&ad_attr->fw_ver, ioc_attr->fw_version, BFA_VERSION_LEN);
2028 bfa_os_memcpy(&ad_attr->optrom_ver, ioc_attr->optrom_version,
2029 BFA_VERSION_LEN);
2030 bfa_os_memcpy(&ad_attr->manufacturer, BFA_MFG_NAME,
2031 BFA_ADAPTER_MFG_NAME_LEN);
2032 bfa_os_memcpy(&ad_attr->vpd, &ioc_attr->vpd,
2033 sizeof(struct bfa_mfg_vpd_s));
2034
2035 ad_attr->nports = BFI_ADAPTER_GETP(NPORTS, ioc_attr->adapter_prop);
2036 ad_attr->max_speed = BFI_ADAPTER_GETP(SPEED, ioc_attr->adapter_prop);
2037
2038 /**
2039 * model name
2040 */
2041 if (BFI_ADAPTER_GETP(SPEED, ioc_attr->adapter_prop) == 10) {
2042 strcpy(model, "BR-10?0");
2043 model[5] = '0' + ad_attr->nports;
2044 } else {
2045 strcpy(model, "Brocade-??5");
2046 model[8] =
2047 '0' + BFI_ADAPTER_GETP(SPEED, ioc_attr->adapter_prop);
2048 model[9] = '0' + ad_attr->nports;
2049 }
2050
2051 if (BFI_ADAPTER_IS_SPECIAL(ioc_attr->adapter_prop))
2052 ad_attr->prototype = 1;
2053 else
2054 ad_attr->prototype = 0;
2055
2056 bfa_os_memcpy(&ad_attr->model, model, BFA_ADAPTER_MODEL_NAME_LEN);
2057 bfa_os_memcpy(&ad_attr->model_descr, &ad_attr->model,
2058 BFA_ADAPTER_MODEL_NAME_LEN);
2059
2060 ad_attr->pwwn = bfa_ioc_get_pwwn(ioc);
2061 ad_attr->mac = bfa_ioc_get_mac(ioc);
2062
2063 ad_attr->pcie_gen = ioc_attr->pcie_gen;
2064 ad_attr->pcie_lanes = ioc_attr->pcie_lanes;
2065 ad_attr->pcie_lanes_orig = ioc_attr->pcie_lanes_orig;
2066 ad_attr->asic_rev = ioc_attr->asic_rev;
2067 ad_attr->hw_ver[0] = 'R';
2068 ad_attr->hw_ver[1] = 'e';
2069 ad_attr->hw_ver[2] = 'v';
2070 ad_attr->hw_ver[3] = '-';
2071 ad_attr->hw_ver[4] = ioc_attr->asic_rev;
2072 ad_attr->hw_ver[5] = '\0';
2073
2074 ad_attr->cna_capable = ioc->cna;
2075}
2076
2077void
2078bfa_ioc_get_attr(struct bfa_ioc_s *ioc, struct bfa_ioc_attr_s *ioc_attr)
2079{
2080 bfa_os_memset((void *)ioc_attr, 0, sizeof(struct bfa_ioc_attr_s));
2081
2082 ioc_attr->state = bfa_sm_to_state(ioc_sm_table, ioc->fsm);
2083 ioc_attr->port_id = ioc->port_id;
2084
2085 if (!ioc->ctdev)
2086 ioc_attr->ioc_type = BFA_IOC_TYPE_FC;
2087 else if (ioc->ioc_mc == BFI_MC_IOCFC)
2088 ioc_attr->ioc_type = BFA_IOC_TYPE_FCoE;
2089 else if (ioc->ioc_mc == BFI_MC_LL)
2090 ioc_attr->ioc_type = BFA_IOC_TYPE_LL;
2091
2092 bfa_ioc_get_adapter_attr(ioc, &ioc_attr->adapter_attr);
2093
2094 ioc_attr->pci_attr.device_id = ioc->pcidev.device_id;
2095 ioc_attr->pci_attr.pcifn = ioc->pcidev.pci_func;
2096 ioc_attr->pci_attr.chip_rev[0] = 'R';
2097 ioc_attr->pci_attr.chip_rev[1] = 'e';
2098 ioc_attr->pci_attr.chip_rev[2] = 'v';
2099 ioc_attr->pci_attr.chip_rev[3] = '-';
2100 ioc_attr->pci_attr.chip_rev[4] = ioc_attr->adapter_attr.asic_rev;
2101 ioc_attr->pci_attr.chip_rev[5] = '\0';
2102}
2103
2104/**
2105 * hal_wwn_public
2106 */
2107wwn_t
2108bfa_ioc_get_pwwn(struct bfa_ioc_s *ioc)
2109{
2110 union {
2111 wwn_t wwn;
2112 u8 byte[sizeof(wwn_t)];
2113 }
2114 w;
2115
2116 w.wwn = ioc->attr->mfg_wwn;
2117
2118 if (bfa_ioc_portid(ioc) == 1)
2119 w.byte[7]++;
2120
2121 return w.wwn;
2122}
2123
2124wwn_t
2125bfa_ioc_get_nwwn(struct bfa_ioc_s *ioc)
2126{
2127 union {
2128 wwn_t wwn;
2129 u8 byte[sizeof(wwn_t)];
2130 }
2131 w;
2132
2133 w.wwn = ioc->attr->mfg_wwn;
2134
2135 if (bfa_ioc_portid(ioc) == 1)
2136 w.byte[7]++;
2137
2138 w.byte[0] = 0x20;
2139
2140 return w.wwn;
2141}
2142
2143wwn_t
2144bfa_ioc_get_wwn_naa5(struct bfa_ioc_s *ioc, u16 inst)
2145{
2146 union {
2147 wwn_t wwn;
2148 u8 byte[sizeof(wwn_t)];
2149 }
2150 w , w5;
2151
2152 bfa_trc(ioc, inst);
2153
2154 w.wwn = ioc->attr->mfg_wwn;
2155 w5.byte[0] = 0x50 | w.byte[2] >> 4;
2156 w5.byte[1] = w.byte[2] << 4 | w.byte[3] >> 4;
2157 w5.byte[2] = w.byte[3] << 4 | w.byte[4] >> 4;
2158 w5.byte[3] = w.byte[4] << 4 | w.byte[5] >> 4;
2159 w5.byte[4] = w.byte[5] << 4 | w.byte[6] >> 4;
2160 w5.byte[5] = w.byte[6] << 4 | w.byte[7] >> 4;
2161 w5.byte[6] = w.byte[7] << 4 | (inst & 0x0f00) >> 8;
2162 w5.byte[7] = (inst & 0xff);
2163
2164 return w5.wwn;
2165}
2166
2167u64
2168bfa_ioc_get_adid(struct bfa_ioc_s *ioc)
2169{
2170 return ioc->attr->mfg_wwn;
2171}
2172
2173mac_t
2174bfa_ioc_get_mac(struct bfa_ioc_s *ioc)
2175{
2176 mac_t mac;
2177
2178 mac = ioc->attr->mfg_mac;
2179 mac.mac[MAC_ADDRLEN - 1] += bfa_ioc_pcifn(ioc);
2180
2181 return mac;
2182}
2183
2184void
2185bfa_ioc_set_fcmode(struct bfa_ioc_s *ioc)
2186{
2187 ioc->fcmode = BFA_TRUE;
2188 ioc->port_id = bfa_ioc_pcifn(ioc);
2189}
2190
2191bfa_boolean_t
2192bfa_ioc_get_fcmode(struct bfa_ioc_s *ioc)
2193{
2194 return ioc->fcmode || (ioc->pcidev.device_id != BFA_PCI_DEVICE_ID_CT);
2195}
2196
2197/**
2198 * Return true if interrupt should be claimed.
2199 */
2200bfa_boolean_t
2201bfa_ioc_intx_claim(struct bfa_ioc_s *ioc)
2202{
2203 u32 isr, msk;
2204
2205 /**
2206 * Always claim if not catapult.
2207 */
2208 if (!ioc->ctdev)
2209 return BFA_TRUE;
2210
2211 /**
2212 * FALSE if next device is claiming interrupt.
2213 * TRUE if next device is not interrupting or not present.
2214 */
2215 msk = bfa_reg_read(ioc->ioc_regs.shirq_msk_next);
2216 isr = bfa_reg_read(ioc->ioc_regs.shirq_isr_next);
2217 return !(isr & ~msk);
2218}
2219
2220/**
2221 * Send AEN notification
2222 */
2223static void
2224bfa_ioc_aen_post(struct bfa_ioc_s *ioc, enum bfa_ioc_aen_event event)
2225{
2226 union bfa_aen_data_u aen_data;
2227 struct bfa_log_mod_s *logmod = ioc->logm;
2228 s32 inst_num = 0;
2229 struct bfa_ioc_attr_s ioc_attr;
2230
2231 switch (event) {
2232 case BFA_IOC_AEN_HBGOOD:
2233 bfa_log(logmod, BFA_AEN_IOC_HBGOOD, inst_num);
2234 break;
2235 case BFA_IOC_AEN_HBFAIL:
2236 bfa_log(logmod, BFA_AEN_IOC_HBFAIL, inst_num);
2237 break;
2238 case BFA_IOC_AEN_ENABLE:
2239 bfa_log(logmod, BFA_AEN_IOC_ENABLE, inst_num);
2240 break;
2241 case BFA_IOC_AEN_DISABLE:
2242 bfa_log(logmod, BFA_AEN_IOC_DISABLE, inst_num);
2243 break;
2244 case BFA_IOC_AEN_FWMISMATCH:
2245 bfa_log(logmod, BFA_AEN_IOC_FWMISMATCH, inst_num);
2246 break;
2247 default:
2248 break;
2249 }
2250
2251 memset(&aen_data.ioc.pwwn, 0, sizeof(aen_data.ioc.pwwn));
2252 memset(&aen_data.ioc.mac, 0, sizeof(aen_data.ioc.mac));
2253 bfa_ioc_get_attr(ioc, &ioc_attr);
2254 switch (ioc_attr.ioc_type) {
2255 case BFA_IOC_TYPE_FC:
2256 aen_data.ioc.pwwn = bfa_ioc_get_pwwn(ioc);
2257 break;
2258 case BFA_IOC_TYPE_FCoE:
2259 aen_data.ioc.pwwn = bfa_ioc_get_pwwn(ioc);
2260 aen_data.ioc.mac = bfa_ioc_get_mac(ioc);
2261 break;
2262 case BFA_IOC_TYPE_LL:
2263 aen_data.ioc.mac = bfa_ioc_get_mac(ioc);
2264 break;
2265 default:
2266 bfa_assert(ioc_attr.ioc_type == BFA_IOC_TYPE_FC);
2267 break;
2268 }
2269 aen_data.ioc.ioc_type = ioc_attr.ioc_type;
2270}
2271
2272/**
2273 * Retrieve saved firmware trace from a prior IOC failure.
2274 */
2275bfa_status_t
2276bfa_ioc_debug_fwsave(struct bfa_ioc_s *ioc, void *trcdata, int *trclen)
2277{
2278 int tlen;
2279
2280 if (ioc->dbg_fwsave_len == 0)
2281 return BFA_STATUS_ENOFSAVE;
2282
2283 tlen = *trclen;
2284 if (tlen > ioc->dbg_fwsave_len)
2285 tlen = ioc->dbg_fwsave_len;
2286
2287 bfa_os_memcpy(trcdata, ioc->dbg_fwsave, tlen);
2288 *trclen = tlen;
2289 return BFA_STATUS_OK;
2290}
2291
2292/**
2293 * Retrieve saved firmware trace from a prior IOC failure.
2294 */
2295bfa_status_t
2296bfa_ioc_debug_fwtrc(struct bfa_ioc_s *ioc, void *trcdata, int *trclen)
2297{
2298 u32 pgnum;
2299 u32 loff = BFA_DBG_FWTRC_OFF(bfa_ioc_portid(ioc));
2300 int i, tlen;
2301 u32 *tbuf = trcdata, r32;
2302
2303 bfa_trc(ioc, *trclen);
2304
2305 pgnum = bfa_ioc_smem_pgnum(ioc, loff);
2306 loff = bfa_ioc_smem_pgoff(ioc, loff);
2307 bfa_reg_write(ioc->ioc_regs.host_page_num_fn, pgnum);
2308
2309 tlen = *trclen;
2310 if (tlen > BFA_DBG_FWTRC_LEN)
2311 tlen = BFA_DBG_FWTRC_LEN;
2312 tlen /= sizeof(u32);
2313
2314 bfa_trc(ioc, tlen);
2315
2316 for (i = 0; i < tlen; i++) {
2317 r32 = bfa_mem_read(ioc->ioc_regs.smem_page_start, loff);
2318 tbuf[i] = bfa_os_ntohl(r32);
2319 loff += sizeof(u32);
2320
2321 /**
2322 * handle page offset wrap around
2323 */
2324 loff = PSS_SMEM_PGOFF(loff);
2325 if (loff == 0) {
2326 pgnum++;
2327 bfa_reg_write(ioc->ioc_regs.host_page_num_fn, pgnum);
2328 }
2329 }
2330 bfa_reg_write(ioc->ioc_regs.host_page_num_fn,
2331 bfa_ioc_smem_pgnum(ioc, 0));
2332 bfa_trc(ioc, pgnum);
2333
2334 *trclen = tlen * sizeof(u32);
2335 return BFA_STATUS_OK;
2336}
2337
2338/**
2339 * Save firmware trace if configured.
2340 */
2341static void
2342bfa_ioc_debug_save(struct bfa_ioc_s *ioc)
2343{
2344 int tlen;
2345
2346 if (ioc->dbg_fwsave_len) {
2347 tlen = ioc->dbg_fwsave_len;
2348 bfa_ioc_debug_fwtrc(ioc, ioc->dbg_fwsave, &tlen);
2349 }
2350}
2351
2352/**
2353 * Firmware failure detected. Start recovery actions.
2354 */
2355static void
2356bfa_ioc_recover(struct bfa_ioc_s *ioc)
2357{
2358 if (ioc->dbg_fwsave_once) {
2359 ioc->dbg_fwsave_once = BFA_FALSE;
2360 bfa_ioc_debug_save(ioc);
2361 }
2362
2363 bfa_ioc_stats(ioc, ioc_hbfails);
2364 bfa_fsm_send_event(ioc, IOC_E_HBFAIL);
2365}
2366
2367#else
2368
2369static void
2370bfa_ioc_aen_post(struct bfa_ioc_s *ioc, enum bfa_ioc_aen_event event)
2371{
2372}
2373
2374static void
2375bfa_ioc_recover(struct bfa_ioc_s *ioc)
2376{
2377 bfa_assert(0);
2378}
2379
2380#endif
2381
2382
diff --git a/drivers/scsi/bfa/bfa_ioc.h b/drivers/scsi/bfa/bfa_ioc.h
new file mode 100644
index 000000000000..58efd4b13143
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_ioc.h
@@ -0,0 +1,259 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFA_IOC_H__
19#define __BFA_IOC_H__
20
21#include <cs/bfa_sm.h>
22#include <bfi/bfi.h>
23#include <bfi/bfi_ioc.h>
24#include <bfi/bfi_boot.h>
25#include <bfa_timer.h>
26
27/**
28 * PCI device information required by IOC
29 */
30struct bfa_pcidev_s {
31 int pci_slot;
32 u8 pci_func;
33 u16 device_id;
34 bfa_os_addr_t pci_bar_kva;
35};
36
37/**
38 * Structure used to remember the DMA-able memory block's KVA and Physical
39 * Address
40 */
41struct bfa_dma_s {
42 void *kva; /*! Kernel virtual address */
43 u64 pa; /*! Physical address */
44};
45
46#define BFA_DMA_ALIGN_SZ 256
47#define BFA_ROUNDUP(_l, _s) (((_l) + ((_s) - 1)) & ~((_s) - 1))
48
49
50
51#define bfa_dma_addr_set(dma_addr, pa) \
52 __bfa_dma_addr_set(&dma_addr, (u64)pa)
53
54static inline void
55__bfa_dma_addr_set(union bfi_addr_u *dma_addr, u64 pa)
56{
57 dma_addr->a32.addr_lo = (u32) pa;
58 dma_addr->a32.addr_hi = (u32) (bfa_os_u32(pa));
59}
60
61
62#define bfa_dma_be_addr_set(dma_addr, pa) \
63 __bfa_dma_be_addr_set(&dma_addr, (u64)pa)
64static inline void
65__bfa_dma_be_addr_set(union bfi_addr_u *dma_addr, u64 pa)
66{
67 dma_addr->a32.addr_lo = (u32) bfa_os_htonl(pa);
68 dma_addr->a32.addr_hi = (u32) bfa_os_htonl(bfa_os_u32(pa));
69}
70
71struct bfa_ioc_regs_s {
72 bfa_os_addr_t hfn_mbox_cmd;
73 bfa_os_addr_t hfn_mbox;
74 bfa_os_addr_t lpu_mbox_cmd;
75 bfa_os_addr_t lpu_mbox;
76 bfa_os_addr_t pss_ctl_reg;
77 bfa_os_addr_t app_pll_fast_ctl_reg;
78 bfa_os_addr_t app_pll_slow_ctl_reg;
79 bfa_os_addr_t ioc_sem_reg;
80 bfa_os_addr_t ioc_usage_sem_reg;
81 bfa_os_addr_t ioc_usage_reg;
82 bfa_os_addr_t host_page_num_fn;
83 bfa_os_addr_t heartbeat;
84 bfa_os_addr_t ioc_fwstate;
85 bfa_os_addr_t ll_halt;
86 bfa_os_addr_t shirq_isr_next;
87 bfa_os_addr_t shirq_msk_next;
88 bfa_os_addr_t smem_page_start;
89 u32 smem_pg0;
90};
91
92#define bfa_reg_read(_raddr) bfa_os_reg_read(_raddr)
93#define bfa_reg_write(_raddr, _val) bfa_os_reg_write(_raddr, _val)
94#define bfa_mem_read(_raddr, _off) bfa_os_mem_read(_raddr, _off)
95#define bfa_mem_write(_raddr, _off, _val) \
96 bfa_os_mem_write(_raddr, _off, _val)
97/**
98 * IOC Mailbox structures
99 */
100struct bfa_mbox_cmd_s {
101 struct list_head qe;
102 u32 msg[BFI_IOC_MSGSZ];
103};
104
105/**
106 * IOC mailbox module
107 */
108typedef void (*bfa_ioc_mbox_mcfunc_t)(void *cbarg, struct bfi_mbmsg_s *m);
109struct bfa_ioc_mbox_mod_s {
110 struct list_head cmd_q; /* pending mbox queue */
111 int nmclass; /* number of handlers */
112 struct {
113 bfa_ioc_mbox_mcfunc_t cbfn; /* message handlers */
114 void *cbarg;
115 } mbhdlr[BFI_MC_MAX];
116};
117
118/**
119 * IOC callback function interfaces
120 */
121typedef void (*bfa_ioc_enable_cbfn_t)(void *bfa, enum bfa_status status);
122typedef void (*bfa_ioc_disable_cbfn_t)(void *bfa);
123typedef void (*bfa_ioc_hbfail_cbfn_t)(void *bfa);
124typedef void (*bfa_ioc_reset_cbfn_t)(void *bfa);
125struct bfa_ioc_cbfn_s {
126 bfa_ioc_enable_cbfn_t enable_cbfn;
127 bfa_ioc_disable_cbfn_t disable_cbfn;
128 bfa_ioc_hbfail_cbfn_t hbfail_cbfn;
129 bfa_ioc_reset_cbfn_t reset_cbfn;
130};
131
132/**
133 * Heartbeat failure notification queue element.
134 */
135struct bfa_ioc_hbfail_notify_s {
136 struct list_head qe;
137 bfa_ioc_hbfail_cbfn_t cbfn;
138 void *cbarg;
139};
140
141/**
142 * Initialize a heartbeat failure notification structure
143 */
144#define bfa_ioc_hbfail_init(__notify, __cbfn, __cbarg) do { \
145 (__notify)->cbfn = (__cbfn); \
146 (__notify)->cbarg = (__cbarg); \
147} while (0)
148
149struct bfa_ioc_s {
150 bfa_fsm_t fsm;
151 struct bfa_s *bfa;
152 struct bfa_pcidev_s pcidev;
153 struct bfa_timer_mod_s *timer_mod;
154 struct bfa_timer_s ioc_timer;
155 struct bfa_timer_s sem_timer;
156 u32 hb_count;
157 u32 hb_fail;
158 u32 retry_count;
159 struct list_head hb_notify_q;
160 void *dbg_fwsave;
161 int dbg_fwsave_len;
162 bfa_boolean_t dbg_fwsave_once;
163 enum bfi_mclass ioc_mc;
164 struct bfa_ioc_regs_s ioc_regs;
165 struct bfa_trc_mod_s *trcmod;
166 struct bfa_aen_s *aen;
167 struct bfa_log_mod_s *logm;
168 struct bfa_ioc_drv_stats_s stats;
169 bfa_boolean_t auto_recover;
170 bfa_boolean_t fcmode;
171 bfa_boolean_t ctdev;
172 bfa_boolean_t cna;
173 bfa_boolean_t pllinit;
174 u8 port_id;
175
176 struct bfa_dma_s attr_dma;
177 struct bfi_ioc_attr_s *attr;
178 struct bfa_ioc_cbfn_s *cbfn;
179 struct bfa_ioc_mbox_mod_s mbox_mod;
180};
181
182#define bfa_ioc_pcifn(__ioc) (__ioc)->pcidev.pci_func
183#define bfa_ioc_devid(__ioc) (__ioc)->pcidev.device_id
184#define bfa_ioc_bar0(__ioc) (__ioc)->pcidev.pci_bar_kva
185#define bfa_ioc_portid(__ioc) ((__ioc)->port_id)
186#define bfa_ioc_fetch_stats(__ioc, __stats) \
187 ((__stats)->drv_stats) = (__ioc)->stats
188#define bfa_ioc_clr_stats(__ioc) \
189 bfa_os_memset(&(__ioc)->stats, 0, sizeof((__ioc)->stats))
190#define bfa_ioc_maxfrsize(__ioc) (__ioc)->attr->maxfrsize
191#define bfa_ioc_rx_bbcredit(__ioc) (__ioc)->attr->rx_bbcredit
192#define bfa_ioc_speed_sup(__ioc) \
193 BFI_ADAPTER_GETP(SPEED, (__ioc)->attr->adapter_prop)
194
195/**
196 * IOC mailbox interface
197 */
198void bfa_ioc_mbox_queue(struct bfa_ioc_s *ioc, struct bfa_mbox_cmd_s *cmd);
199void bfa_ioc_mbox_register(struct bfa_ioc_s *ioc,
200 bfa_ioc_mbox_mcfunc_t *mcfuncs);
201void bfa_ioc_mbox_isr(struct bfa_ioc_s *ioc);
202void bfa_ioc_mbox_send(struct bfa_ioc_s *ioc, void *ioc_msg, int len);
203void bfa_ioc_msgget(struct bfa_ioc_s *ioc, void *mbmsg);
204void bfa_ioc_mbox_regisr(struct bfa_ioc_s *ioc, enum bfi_mclass mc,
205 bfa_ioc_mbox_mcfunc_t cbfn, void *cbarg);
206
207/**
208 * IOC interfaces
209 */
210void bfa_ioc_attach(struct bfa_ioc_s *ioc, void *bfa,
211 struct bfa_ioc_cbfn_s *cbfn, struct bfa_timer_mod_s *timer_mod,
212 struct bfa_trc_mod_s *trcmod,
213 struct bfa_aen_s *aen, struct bfa_log_mod_s *logm);
214void bfa_ioc_detach(struct bfa_ioc_s *ioc);
215void bfa_ioc_pci_init(struct bfa_ioc_s *ioc, struct bfa_pcidev_s *pcidev,
216 enum bfi_mclass mc);
217u32 bfa_ioc_meminfo(void);
218void bfa_ioc_mem_claim(struct bfa_ioc_s *ioc, u8 *dm_kva, u64 dm_pa);
219void bfa_ioc_enable(struct bfa_ioc_s *ioc);
220void bfa_ioc_disable(struct bfa_ioc_s *ioc);
221bfa_boolean_t bfa_ioc_intx_claim(struct bfa_ioc_s *ioc);
222
223void bfa_ioc_boot(struct bfa_ioc_s *ioc, u32 boot_type, u32 boot_param);
224void bfa_ioc_isr(struct bfa_ioc_s *ioc, struct bfi_mbmsg_s *msg);
225void bfa_ioc_error_isr(struct bfa_ioc_s *ioc);
226void bfa_ioc_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t intx);
227bfa_status_t bfa_ioc_pll_init(struct bfa_ioc_s *ioc);
228bfa_boolean_t bfa_ioc_is_operational(struct bfa_ioc_s *ioc);
229bfa_boolean_t bfa_ioc_is_disabled(struct bfa_ioc_s *ioc);
230bfa_boolean_t bfa_ioc_fw_mismatch(struct bfa_ioc_s *ioc);
231bfa_boolean_t bfa_ioc_adapter_is_disabled(struct bfa_ioc_s *ioc);
232void bfa_ioc_cfg_complete(struct bfa_ioc_s *ioc);
233void bfa_ioc_get_attr(struct bfa_ioc_s *ioc, struct bfa_ioc_attr_s *ioc_attr);
234void bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc,
235 struct bfa_adapter_attr_s *ad_attr);
236int bfa_ioc_debug_trcsz(bfa_boolean_t auto_recover);
237void bfa_ioc_debug_memclaim(struct bfa_ioc_s *ioc, void *dbg_fwsave);
238bfa_status_t bfa_ioc_debug_fwsave(struct bfa_ioc_s *ioc, void *trcdata,
239 int *trclen);
240bfa_status_t bfa_ioc_debug_fwtrc(struct bfa_ioc_s *ioc, void *trcdata,
241 int *trclen);
242u32 bfa_ioc_smem_pgnum(struct bfa_ioc_s *ioc, u32 fmaddr);
243u32 bfa_ioc_smem_pgoff(struct bfa_ioc_s *ioc, u32 fmaddr);
244void bfa_ioc_set_fcmode(struct bfa_ioc_s *ioc);
245bfa_boolean_t bfa_ioc_get_fcmode(struct bfa_ioc_s *ioc);
246void bfa_ioc_hbfail_register(struct bfa_ioc_s *ioc,
247 struct bfa_ioc_hbfail_notify_s *notify);
248
249/*
250 * bfa mfg wwn API functions
251 */
252wwn_t bfa_ioc_get_pwwn(struct bfa_ioc_s *ioc);
253wwn_t bfa_ioc_get_nwwn(struct bfa_ioc_s *ioc);
254wwn_t bfa_ioc_get_wwn_naa5(struct bfa_ioc_s *ioc, u16 inst);
255mac_t bfa_ioc_get_mac(struct bfa_ioc_s *ioc);
256u64 bfa_ioc_get_adid(struct bfa_ioc_s *ioc);
257
258#endif /* __BFA_IOC_H__ */
259
diff --git a/drivers/scsi/bfa/bfa_iocfc.c b/drivers/scsi/bfa/bfa_iocfc.c
new file mode 100644
index 000000000000..12350b022d63
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_iocfc.c
@@ -0,0 +1,872 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#include <cs/bfa_debug.h>
19#include <bfa_priv.h>
20#include <log/bfa_log_hal.h>
21#include <bfi/bfi_boot.h>
22#include <bfi/bfi_cbreg.h>
23#include <aen/bfa_aen_ioc.h>
24#include <defs/bfa_defs_iocfc.h>
25#include <defs/bfa_defs_pci.h>
26#include "bfa_callback_priv.h"
27#include "bfad_drv.h"
28
29BFA_TRC_FILE(HAL, IOCFC);
30
31/**
32 * IOC local definitions
33 */
34#define BFA_IOCFC_TOV 5000 /* msecs */
35
36enum {
37 BFA_IOCFC_ACT_NONE = 0,
38 BFA_IOCFC_ACT_INIT = 1,
39 BFA_IOCFC_ACT_STOP = 2,
40 BFA_IOCFC_ACT_DISABLE = 3,
41};
42
43/*
44 * forward declarations
45 */
46static void bfa_iocfc_enable_cbfn(void *bfa_arg, enum bfa_status status);
47static void bfa_iocfc_disable_cbfn(void *bfa_arg);
48static void bfa_iocfc_hbfail_cbfn(void *bfa_arg);
49static void bfa_iocfc_reset_cbfn(void *bfa_arg);
50static void bfa_iocfc_stats_clear(void *bfa_arg);
51static void bfa_iocfc_stats_swap(struct bfa_fw_stats_s *d,
52 struct bfa_fw_stats_s *s);
53static void bfa_iocfc_stats_clr_cb(void *bfa_arg, bfa_boolean_t complete);
54static void bfa_iocfc_stats_clr_timeout(void *bfa_arg);
55static void bfa_iocfc_stats_cb(void *bfa_arg, bfa_boolean_t complete);
56static void bfa_iocfc_stats_timeout(void *bfa_arg);
57
58static struct bfa_ioc_cbfn_s bfa_iocfc_cbfn;
59
60/**
61 * bfa_ioc_pvt BFA IOC private functions
62 */
63
64static void
65bfa_iocfc_cqs_sz(struct bfa_iocfc_cfg_s *cfg, u32 *dm_len)
66{
67 int i, per_reqq_sz, per_rspq_sz;
68
69 per_reqq_sz = BFA_ROUNDUP((cfg->drvcfg.num_reqq_elems * BFI_LMSG_SZ),
70 BFA_DMA_ALIGN_SZ);
71 per_rspq_sz = BFA_ROUNDUP((cfg->drvcfg.num_rspq_elems * BFI_LMSG_SZ),
72 BFA_DMA_ALIGN_SZ);
73
74 /*
75 * Calculate CQ size
76 */
77 for (i = 0; i < cfg->fwcfg.num_cqs; i++) {
78 *dm_len = *dm_len + per_reqq_sz;
79 *dm_len = *dm_len + per_rspq_sz;
80 }
81
82 /*
83 * Calculate Shadow CI/PI size
84 */
85 for (i = 0; i < cfg->fwcfg.num_cqs; i++)
86 *dm_len += (2 * BFA_CACHELINE_SZ);
87}
88
89static void
90bfa_iocfc_fw_cfg_sz(struct bfa_iocfc_cfg_s *cfg, u32 *dm_len)
91{
92 *dm_len +=
93 BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfg_s), BFA_CACHELINE_SZ);
94 *dm_len +=
95 BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfgrsp_s),
96 BFA_CACHELINE_SZ);
97 *dm_len += BFA_ROUNDUP(sizeof(struct bfa_fw_stats_s), BFA_CACHELINE_SZ);
98}
99
100/**
101 * Use the Mailbox interface to send BFI_IOCFC_H2I_CFG_REQ
102 */
103static void
104bfa_iocfc_send_cfg(void *bfa_arg)
105{
106 struct bfa_s *bfa = bfa_arg;
107 struct bfa_iocfc_s *iocfc = &bfa->iocfc;
108 struct bfi_iocfc_cfg_req_s cfg_req;
109 struct bfi_iocfc_cfg_s *cfg_info = iocfc->cfginfo;
110 struct bfa_iocfc_cfg_s *cfg = &iocfc->cfg;
111 int i;
112
113 bfa_assert(cfg->fwcfg.num_cqs <= BFI_IOC_MAX_CQS);
114 bfa_trc(bfa, cfg->fwcfg.num_cqs);
115
116 iocfc->cfgdone = BFA_FALSE;
117 bfa_iocfc_reset_queues(bfa);
118
119 /**
120 * initialize IOC configuration info
121 */
122 cfg_info->endian_sig = BFI_IOC_ENDIAN_SIG;
123 cfg_info->num_cqs = cfg->fwcfg.num_cqs;
124
125 bfa_dma_be_addr_set(cfg_info->cfgrsp_addr, iocfc->cfgrsp_dma.pa);
126 bfa_dma_be_addr_set(cfg_info->stats_addr, iocfc->stats_pa);
127
128 /**
129 * dma map REQ and RSP circular queues and shadow pointers
130 */
131 for (i = 0; i < cfg->fwcfg.num_cqs; i++) {
132 bfa_dma_be_addr_set(cfg_info->req_cq_ba[i],
133 iocfc->req_cq_ba[i].pa);
134 bfa_dma_be_addr_set(cfg_info->req_shadow_ci[i],
135 iocfc->req_cq_shadow_ci[i].pa);
136 cfg_info->req_cq_elems[i] =
137 bfa_os_htons(cfg->drvcfg.num_reqq_elems);
138
139 bfa_dma_be_addr_set(cfg_info->rsp_cq_ba[i],
140 iocfc->rsp_cq_ba[i].pa);
141 bfa_dma_be_addr_set(cfg_info->rsp_shadow_pi[i],
142 iocfc->rsp_cq_shadow_pi[i].pa);
143 cfg_info->rsp_cq_elems[i] =
144 bfa_os_htons(cfg->drvcfg.num_rspq_elems);
145 }
146
147 /**
148 * dma map IOC configuration itself
149 */
150 bfi_h2i_set(cfg_req.mh, BFI_MC_IOCFC, BFI_IOCFC_H2I_CFG_REQ,
151 bfa_lpuid(bfa));
152 bfa_dma_be_addr_set(cfg_req.ioc_cfg_dma_addr, iocfc->cfg_info.pa);
153
154 bfa_ioc_mbox_send(&bfa->ioc, &cfg_req,
155 sizeof(struct bfi_iocfc_cfg_req_s));
156}
157
158static void
159bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
160 struct bfa_pcidev_s *pcidev)
161{
162 struct bfa_iocfc_s *iocfc = &bfa->iocfc;
163
164 bfa->bfad = bfad;
165 iocfc->bfa = bfa;
166 iocfc->action = BFA_IOCFC_ACT_NONE;
167
168 bfa_os_assign(iocfc->cfg, *cfg);
169
170 /**
171 * Initialize chip specific handlers.
172 */
173 if (bfa_ioc_devid(&bfa->ioc) == BFA_PCI_DEVICE_ID_CT) {
174 iocfc->hwif.hw_reginit = bfa_hwct_reginit;
175 iocfc->hwif.hw_rspq_ack = bfa_hwct_rspq_ack;
176 iocfc->hwif.hw_msix_init = bfa_hwct_msix_init;
177 iocfc->hwif.hw_msix_install = bfa_hwct_msix_install;
178 iocfc->hwif.hw_msix_uninstall = bfa_hwct_msix_uninstall;
179 iocfc->hwif.hw_isr_mode_set = bfa_hwct_isr_mode_set;
180 iocfc->hwif.hw_msix_getvecs = bfa_hwct_msix_getvecs;
181 } else {
182 iocfc->hwif.hw_reginit = bfa_hwcb_reginit;
183 iocfc->hwif.hw_rspq_ack = bfa_hwcb_rspq_ack;
184 iocfc->hwif.hw_msix_init = bfa_hwcb_msix_init;
185 iocfc->hwif.hw_msix_install = bfa_hwcb_msix_install;
186 iocfc->hwif.hw_msix_uninstall = bfa_hwcb_msix_uninstall;
187 iocfc->hwif.hw_isr_mode_set = bfa_hwcb_isr_mode_set;
188 iocfc->hwif.hw_msix_getvecs = bfa_hwcb_msix_getvecs;
189 }
190
191 iocfc->hwif.hw_reginit(bfa);
192 bfa->msix.nvecs = 0;
193}
194
195static void
196bfa_iocfc_mem_claim(struct bfa_s *bfa, struct bfa_iocfc_cfg_s *cfg,
197 struct bfa_meminfo_s *meminfo)
198{
199 u8 *dm_kva;
200 u64 dm_pa;
201 int i, per_reqq_sz, per_rspq_sz;
202 struct bfa_iocfc_s *iocfc = &bfa->iocfc;
203 int dbgsz;
204
205 dm_kva = bfa_meminfo_dma_virt(meminfo);
206 dm_pa = bfa_meminfo_dma_phys(meminfo);
207
208 /*
209 * First allocate dma memory for IOC.
210 */
211 bfa_ioc_mem_claim(&bfa->ioc, dm_kva, dm_pa);
212 dm_kva += bfa_ioc_meminfo();
213 dm_pa += bfa_ioc_meminfo();
214
215 /*
216 * Claim DMA-able memory for the request/response queues and for shadow
217 * ci/pi registers
218 */
219 per_reqq_sz = BFA_ROUNDUP((cfg->drvcfg.num_reqq_elems * BFI_LMSG_SZ),
220 BFA_DMA_ALIGN_SZ);
221 per_rspq_sz = BFA_ROUNDUP((cfg->drvcfg.num_rspq_elems * BFI_LMSG_SZ),
222 BFA_DMA_ALIGN_SZ);
223
224 for (i = 0; i < cfg->fwcfg.num_cqs; i++) {
225 iocfc->req_cq_ba[i].kva = dm_kva;
226 iocfc->req_cq_ba[i].pa = dm_pa;
227 bfa_os_memset(dm_kva, 0, per_reqq_sz);
228 dm_kva += per_reqq_sz;
229 dm_pa += per_reqq_sz;
230
231 iocfc->rsp_cq_ba[i].kva = dm_kva;
232 iocfc->rsp_cq_ba[i].pa = dm_pa;
233 bfa_os_memset(dm_kva, 0, per_rspq_sz);
234 dm_kva += per_rspq_sz;
235 dm_pa += per_rspq_sz;
236 }
237
238 for (i = 0; i < cfg->fwcfg.num_cqs; i++) {
239 iocfc->req_cq_shadow_ci[i].kva = dm_kva;
240 iocfc->req_cq_shadow_ci[i].pa = dm_pa;
241 dm_kva += BFA_CACHELINE_SZ;
242 dm_pa += BFA_CACHELINE_SZ;
243
244 iocfc->rsp_cq_shadow_pi[i].kva = dm_kva;
245 iocfc->rsp_cq_shadow_pi[i].pa = dm_pa;
246 dm_kva += BFA_CACHELINE_SZ;
247 dm_pa += BFA_CACHELINE_SZ;
248 }
249
250 /*
251 * Claim DMA-able memory for the config info page
252 */
253 bfa->iocfc.cfg_info.kva = dm_kva;
254 bfa->iocfc.cfg_info.pa = dm_pa;
255 bfa->iocfc.cfginfo = (struct bfi_iocfc_cfg_s *) dm_kva;
256 dm_kva += BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfg_s), BFA_CACHELINE_SZ);
257 dm_pa += BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfg_s), BFA_CACHELINE_SZ);
258
259 /*
260 * Claim DMA-able memory for the config response
261 */
262 bfa->iocfc.cfgrsp_dma.kva = dm_kva;
263 bfa->iocfc.cfgrsp_dma.pa = dm_pa;
264 bfa->iocfc.cfgrsp = (struct bfi_iocfc_cfgrsp_s *) dm_kva;
265
266 dm_kva +=
267 BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfgrsp_s),
268 BFA_CACHELINE_SZ);
269 dm_pa += BFA_ROUNDUP(sizeof(struct bfi_iocfc_cfgrsp_s),
270 BFA_CACHELINE_SZ);
271
272 /*
273 * Claim DMA-able memory for iocfc stats
274 */
275 bfa->iocfc.stats_kva = dm_kva;
276 bfa->iocfc.stats_pa = dm_pa;
277 bfa->iocfc.fw_stats = (struct bfa_fw_stats_s *) dm_kva;
278 dm_kva += BFA_ROUNDUP(sizeof(struct bfa_fw_stats_s), BFA_CACHELINE_SZ);
279 dm_pa += BFA_ROUNDUP(sizeof(struct bfa_fw_stats_s), BFA_CACHELINE_SZ);
280
281 bfa_meminfo_dma_virt(meminfo) = dm_kva;
282 bfa_meminfo_dma_phys(meminfo) = dm_pa;
283
284 dbgsz = bfa_ioc_debug_trcsz(bfa_auto_recover);
285 if (dbgsz > 0) {
286 bfa_ioc_debug_memclaim(&bfa->ioc, bfa_meminfo_kva(meminfo));
287 bfa_meminfo_kva(meminfo) += dbgsz;
288 }
289}
290
291/**
292 * BFA submodules initialization completion notification.
293 */
294static void
295bfa_iocfc_initdone_submod(struct bfa_s *bfa)
296{
297 int i;
298
299 for (i = 0; hal_mods[i]; i++)
300 hal_mods[i]->initdone(bfa);
301}
302
303/**
304 * Start BFA submodules.
305 */
306static void
307bfa_iocfc_start_submod(struct bfa_s *bfa)
308{
309 int i;
310
311 bfa->rme_process = BFA_TRUE;
312
313 for (i = 0; hal_mods[i]; i++)
314 hal_mods[i]->start(bfa);
315}
316
317/**
318 * Disable BFA submodules.
319 */
320static void
321bfa_iocfc_disable_submod(struct bfa_s *bfa)
322{
323 int i;
324
325 for (i = 0; hal_mods[i]; i++)
326 hal_mods[i]->iocdisable(bfa);
327}
328
329static void
330bfa_iocfc_init_cb(void *bfa_arg, bfa_boolean_t complete)
331{
332 struct bfa_s *bfa = bfa_arg;
333
334 if (complete) {
335 if (bfa->iocfc.cfgdone)
336 bfa_cb_init(bfa->bfad, BFA_STATUS_OK);
337 else
338 bfa_cb_init(bfa->bfad, BFA_STATUS_FAILED);
339 } else
340 bfa->iocfc.action = BFA_IOCFC_ACT_NONE;
341}
342
343static void
344bfa_iocfc_stop_cb(void *bfa_arg, bfa_boolean_t compl)
345{
346 struct bfa_s *bfa = bfa_arg;
347 struct bfad_s *bfad = bfa->bfad;
348
349 if (compl)
350 complete(&bfad->comp);
351
352 else
353 bfa->iocfc.action = BFA_IOCFC_ACT_NONE;
354}
355
356static void
357bfa_iocfc_disable_cb(void *bfa_arg, bfa_boolean_t compl)
358{
359 struct bfa_s *bfa = bfa_arg;
360 struct bfad_s *bfad = bfa->bfad;
361
362 if (compl)
363 complete(&bfad->disable_comp);
364}
365
366/**
367 * Update BFA configuration from firmware configuration.
368 */
369static void
370bfa_iocfc_cfgrsp(struct bfa_s *bfa)
371{
372 struct bfa_iocfc_s *iocfc = &bfa->iocfc;
373 struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp;
374 struct bfa_iocfc_fwcfg_s *fwcfg = &cfgrsp->fwcfg;
375 struct bfi_iocfc_cfg_s *cfginfo = iocfc->cfginfo;
376
377 fwcfg->num_cqs = fwcfg->num_cqs;
378 fwcfg->num_ioim_reqs = bfa_os_ntohs(fwcfg->num_ioim_reqs);
379 fwcfg->num_tskim_reqs = bfa_os_ntohs(fwcfg->num_tskim_reqs);
380 fwcfg->num_fcxp_reqs = bfa_os_ntohs(fwcfg->num_fcxp_reqs);
381 fwcfg->num_uf_bufs = bfa_os_ntohs(fwcfg->num_uf_bufs);
382 fwcfg->num_rports = bfa_os_ntohs(fwcfg->num_rports);
383
384 cfginfo->intr_attr.coalesce = cfgrsp->intr_attr.coalesce;
385 cfginfo->intr_attr.delay = bfa_os_ntohs(cfgrsp->intr_attr.delay);
386 cfginfo->intr_attr.latency = bfa_os_ntohs(cfgrsp->intr_attr.latency);
387
388 iocfc->cfgdone = BFA_TRUE;
389
390 /**
391 * Configuration is complete - initialize/start submodules
392 */
393 if (iocfc->action == BFA_IOCFC_ACT_INIT)
394 bfa_cb_queue(bfa, &iocfc->init_hcb_qe, bfa_iocfc_init_cb, bfa);
395 else
396 bfa_iocfc_start_submod(bfa);
397}
398
399static void
400bfa_iocfc_stats_clear(void *bfa_arg)
401{
402 struct bfa_s *bfa = bfa_arg;
403 struct bfa_iocfc_s *iocfc = &bfa->iocfc;
404 struct bfi_iocfc_stats_req_s stats_req;
405
406 bfa_timer_start(bfa, &iocfc->stats_timer,
407 bfa_iocfc_stats_clr_timeout, bfa,
408 BFA_IOCFC_TOV);
409
410 bfi_h2i_set(stats_req.mh, BFI_MC_IOCFC, BFI_IOCFC_H2I_CLEAR_STATS_REQ,
411 bfa_lpuid(bfa));
412 bfa_ioc_mbox_send(&bfa->ioc, &stats_req,
413 sizeof(struct bfi_iocfc_stats_req_s));
414}
415
416static void
417bfa_iocfc_stats_swap(struct bfa_fw_stats_s *d, struct bfa_fw_stats_s *s)
418{
419 u32 *dip = (u32 *) d;
420 u32 *sip = (u32 *) s;
421 int i;
422
423 for (i = 0; i < (sizeof(struct bfa_fw_stats_s) / sizeof(u32)); i++)
424 dip[i] = bfa_os_ntohl(sip[i]);
425}
426
427static void
428bfa_iocfc_stats_clr_cb(void *bfa_arg, bfa_boolean_t complete)
429{
430 struct bfa_s *bfa = bfa_arg;
431 struct bfa_iocfc_s *iocfc = &bfa->iocfc;
432
433 if (complete) {
434 bfa_ioc_clr_stats(&bfa->ioc);
435 iocfc->stats_cbfn(iocfc->stats_cbarg, iocfc->stats_status);
436 } else {
437 iocfc->stats_busy = BFA_FALSE;
438 iocfc->stats_status = BFA_STATUS_OK;
439 }
440}
441
442static void
443bfa_iocfc_stats_clr_timeout(void *bfa_arg)
444{
445 struct bfa_s *bfa = bfa_arg;
446 struct bfa_iocfc_s *iocfc = &bfa->iocfc;
447
448 bfa_trc(bfa, 0);
449
450 iocfc->stats_status = BFA_STATUS_ETIMER;
451 bfa_cb_queue(bfa, &iocfc->stats_hcb_qe, bfa_iocfc_stats_clr_cb, bfa);
452}
453
454static void
455bfa_iocfc_stats_cb(void *bfa_arg, bfa_boolean_t complete)
456{
457 struct bfa_s *bfa = bfa_arg;
458 struct bfa_iocfc_s *iocfc = &bfa->iocfc;
459
460 if (complete) {
461 if (iocfc->stats_status == BFA_STATUS_OK) {
462 bfa_os_memset(iocfc->stats_ret, 0,
463 sizeof(*iocfc->stats_ret));
464 bfa_iocfc_stats_swap(&iocfc->stats_ret->fw_stats,
465 iocfc->fw_stats);
466 }
467 iocfc->stats_cbfn(iocfc->stats_cbarg, iocfc->stats_status);
468 } else {
469 iocfc->stats_busy = BFA_FALSE;
470 iocfc->stats_status = BFA_STATUS_OK;
471 }
472}
473
474static void
475bfa_iocfc_stats_timeout(void *bfa_arg)
476{
477 struct bfa_s *bfa = bfa_arg;
478 struct bfa_iocfc_s *iocfc = &bfa->iocfc;
479
480 bfa_trc(bfa, 0);
481
482 iocfc->stats_status = BFA_STATUS_ETIMER;
483 bfa_cb_queue(bfa, &iocfc->stats_hcb_qe, bfa_iocfc_stats_cb, bfa);
484}
485
486static void
487bfa_iocfc_stats_query(struct bfa_s *bfa)
488{
489 struct bfa_iocfc_s *iocfc = &bfa->iocfc;
490 struct bfi_iocfc_stats_req_s stats_req;
491
492 bfa_timer_start(bfa, &iocfc->stats_timer,
493 bfa_iocfc_stats_timeout, bfa, BFA_IOCFC_TOV);
494
495 bfi_h2i_set(stats_req.mh, BFI_MC_IOCFC, BFI_IOCFC_H2I_GET_STATS_REQ,
496 bfa_lpuid(bfa));
497 bfa_ioc_mbox_send(&bfa->ioc, &stats_req,
498 sizeof(struct bfi_iocfc_stats_req_s));
499}
500
501void
502bfa_iocfc_reset_queues(struct bfa_s *bfa)
503{
504 int q;
505
506 for (q = 0; q < BFI_IOC_MAX_CQS; q++) {
507 bfa_reqq_ci(bfa, q) = 0;
508 bfa_reqq_pi(bfa, q) = 0;
509 bfa_rspq_ci(bfa, q) = 0;
510 bfa_rspq_pi(bfa, q) = 0;
511 }
512}
513
514/**
515 * IOC enable request is complete
516 */
517static void
518bfa_iocfc_enable_cbfn(void *bfa_arg, enum bfa_status status)
519{
520 struct bfa_s *bfa = bfa_arg;
521
522 if (status != BFA_STATUS_OK) {
523 bfa_isr_disable(bfa);
524 if (bfa->iocfc.action == BFA_IOCFC_ACT_INIT)
525 bfa_cb_queue(bfa, &bfa->iocfc.init_hcb_qe,
526 bfa_iocfc_init_cb, bfa);
527 return;
528 }
529
530 bfa_iocfc_initdone_submod(bfa);
531 bfa_iocfc_send_cfg(bfa);
532}
533
534/**
535 * IOC disable request is complete
536 */
537static void
538bfa_iocfc_disable_cbfn(void *bfa_arg)
539{
540 struct bfa_s *bfa = bfa_arg;
541
542 bfa_isr_disable(bfa);
543 bfa_iocfc_disable_submod(bfa);
544
545 if (bfa->iocfc.action == BFA_IOCFC_ACT_STOP)
546 bfa_cb_queue(bfa, &bfa->iocfc.stop_hcb_qe, bfa_iocfc_stop_cb,
547 bfa);
548 else {
549 bfa_assert(bfa->iocfc.action == BFA_IOCFC_ACT_DISABLE);
550 bfa_cb_queue(bfa, &bfa->iocfc.dis_hcb_qe, bfa_iocfc_disable_cb,
551 bfa);
552 }
553}
554
555/**
556 * Notify sub-modules of hardware failure.
557 */
558static void
559bfa_iocfc_hbfail_cbfn(void *bfa_arg)
560{
561 struct bfa_s *bfa = bfa_arg;
562
563 bfa->rme_process = BFA_FALSE;
564
565 bfa_isr_disable(bfa);
566 bfa_iocfc_disable_submod(bfa);
567
568 if (bfa->iocfc.action == BFA_IOCFC_ACT_INIT)
569 bfa_cb_queue(bfa, &bfa->iocfc.init_hcb_qe, bfa_iocfc_init_cb,
570 bfa);
571}
572
573/**
574 * Actions on chip-reset completion.
575 */
576static void
577bfa_iocfc_reset_cbfn(void *bfa_arg)
578{
579 struct bfa_s *bfa = bfa_arg;
580
581 bfa_iocfc_reset_queues(bfa);
582 bfa_isr_enable(bfa);
583}
584
585
586
587/**
588 * bfa_ioc_public
589 */
590
591/**
592 * Query IOC memory requirement information.
593 */
594void
595bfa_iocfc_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len,
596 u32 *dm_len)
597{
598 /* dma memory for IOC */
599 *dm_len += bfa_ioc_meminfo();
600
601 bfa_iocfc_fw_cfg_sz(cfg, dm_len);
602 bfa_iocfc_cqs_sz(cfg, dm_len);
603 *km_len += bfa_ioc_debug_trcsz(bfa_auto_recover);
604}
605
606/**
607 * Query IOC memory requirement information.
608 */
609void
610bfa_iocfc_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
611 struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev)
612{
613 int i;
614
615 bfa_iocfc_cbfn.enable_cbfn = bfa_iocfc_enable_cbfn;
616 bfa_iocfc_cbfn.disable_cbfn = bfa_iocfc_disable_cbfn;
617 bfa_iocfc_cbfn.hbfail_cbfn = bfa_iocfc_hbfail_cbfn;
618 bfa_iocfc_cbfn.reset_cbfn = bfa_iocfc_reset_cbfn;
619
620 bfa_ioc_attach(&bfa->ioc, bfa, &bfa_iocfc_cbfn, &bfa->timer_mod,
621 bfa->trcmod, bfa->aen, bfa->logm);
622 bfa_ioc_pci_init(&bfa->ioc, pcidev, BFI_MC_IOCFC);
623 bfa_ioc_mbox_register(&bfa->ioc, bfa_mbox_isrs);
624
625 /**
626 * Choose FC (ssid: 0x1C) v/s FCoE (ssid: 0x14) mode.
627 */
628 if (0)
629 bfa_ioc_set_fcmode(&bfa->ioc);
630
631 bfa_iocfc_init_mem(bfa, bfad, cfg, pcidev);
632 bfa_iocfc_mem_claim(bfa, cfg, meminfo);
633 bfa_timer_init(&bfa->timer_mod);
634
635 INIT_LIST_HEAD(&bfa->comp_q);
636 for (i = 0; i < BFI_IOC_MAX_CQS; i++)
637 INIT_LIST_HEAD(&bfa->reqq_waitq[i]);
638}
639
640/**
641 * Query IOC memory requirement information.
642 */
643void
644bfa_iocfc_detach(struct bfa_s *bfa)
645{
646 bfa_ioc_detach(&bfa->ioc);
647}
648
649/**
650 * Query IOC memory requirement information.
651 */
652void
653bfa_iocfc_init(struct bfa_s *bfa)
654{
655 bfa->iocfc.action = BFA_IOCFC_ACT_INIT;
656 bfa_ioc_enable(&bfa->ioc);
657 bfa_msix_install(bfa);
658}
659
660/**
661 * IOC start called from bfa_start(). Called to start IOC operations
662 * at driver instantiation for this instance.
663 */
664void
665bfa_iocfc_start(struct bfa_s *bfa)
666{
667 if (bfa->iocfc.cfgdone)
668 bfa_iocfc_start_submod(bfa);
669}
670
671/**
672 * IOC stop called from bfa_stop(). Called only when driver is unloaded
673 * for this instance.
674 */
675void
676bfa_iocfc_stop(struct bfa_s *bfa)
677{
678 bfa->iocfc.action = BFA_IOCFC_ACT_STOP;
679
680 bfa->rme_process = BFA_FALSE;
681 bfa_ioc_disable(&bfa->ioc);
682}
683
684void
685bfa_iocfc_isr(void *bfaarg, struct bfi_mbmsg_s *m)
686{
687 struct bfa_s *bfa = bfaarg;
688 struct bfa_iocfc_s *iocfc = &bfa->iocfc;
689 union bfi_iocfc_i2h_msg_u *msg;
690
691 msg = (union bfi_iocfc_i2h_msg_u *) m;
692 bfa_trc(bfa, msg->mh.msg_id);
693
694 switch (msg->mh.msg_id) {
695 case BFI_IOCFC_I2H_CFG_REPLY:
696 iocfc->cfg_reply = &msg->cfg_reply;
697 bfa_iocfc_cfgrsp(bfa);
698 break;
699
700 case BFI_IOCFC_I2H_GET_STATS_RSP:
701 if (iocfc->stats_busy == BFA_FALSE
702 || iocfc->stats_status == BFA_STATUS_ETIMER)
703 break;
704
705 bfa_timer_stop(&iocfc->stats_timer);
706 iocfc->stats_status = BFA_STATUS_OK;
707 bfa_cb_queue(bfa, &iocfc->stats_hcb_qe, bfa_iocfc_stats_cb,
708 bfa);
709 break;
710 case BFI_IOCFC_I2H_CLEAR_STATS_RSP:
711 /*
712 * check for timer pop before processing the rsp
713 */
714 if (iocfc->stats_busy == BFA_FALSE
715 || iocfc->stats_status == BFA_STATUS_ETIMER)
716 break;
717
718 bfa_timer_stop(&iocfc->stats_timer);
719 iocfc->stats_status = BFA_STATUS_OK;
720 bfa_cb_queue(bfa, &iocfc->stats_hcb_qe,
721 bfa_iocfc_stats_clr_cb, bfa);
722 break;
723 case BFI_IOCFC_I2H_UPDATEQ_RSP:
724 iocfc->updateq_cbfn(iocfc->updateq_cbarg, BFA_STATUS_OK);
725 break;
726 default:
727 bfa_assert(0);
728 }
729}
730
731#ifndef BFA_BIOS_BUILD
732void
733bfa_adapter_get_attr(struct bfa_s *bfa, struct bfa_adapter_attr_s *ad_attr)
734{
735 bfa_ioc_get_adapter_attr(&bfa->ioc, ad_attr);
736}
737
738u64
739bfa_adapter_get_id(struct bfa_s *bfa)
740{
741 return bfa_ioc_get_adid(&bfa->ioc);
742}
743
744void
745bfa_iocfc_get_attr(struct bfa_s *bfa, struct bfa_iocfc_attr_s *attr)
746{
747 struct bfa_iocfc_s *iocfc = &bfa->iocfc;
748
749 attr->intr_attr = iocfc->cfginfo->intr_attr;
750 attr->config = iocfc->cfg;
751}
752
753bfa_status_t
754bfa_iocfc_israttr_set(struct bfa_s *bfa, struct bfa_iocfc_intr_attr_s *attr)
755{
756 struct bfa_iocfc_s *iocfc = &bfa->iocfc;
757 struct bfi_iocfc_set_intr_req_s *m;
758
759 iocfc->cfginfo->intr_attr = *attr;
760 if (!bfa_iocfc_is_operational(bfa))
761 return BFA_STATUS_OK;
762
763 m = bfa_reqq_next(bfa, BFA_REQQ_IOC);
764 if (!m)
765 return BFA_STATUS_DEVBUSY;
766
767 bfi_h2i_set(m->mh, BFI_MC_IOCFC, BFI_IOCFC_H2I_SET_INTR_REQ,
768 bfa_lpuid(bfa));
769 m->coalesce = attr->coalesce;
770 m->delay = bfa_os_htons(attr->delay);
771 m->latency = bfa_os_htons(attr->latency);
772
773 bfa_trc(bfa, attr->delay);
774 bfa_trc(bfa, attr->latency);
775
776 bfa_reqq_produce(bfa, BFA_REQQ_IOC);
777 return BFA_STATUS_OK;
778}
779
780void
781bfa_iocfc_set_snsbase(struct bfa_s *bfa, u64 snsbase_pa)
782{
783 struct bfa_iocfc_s *iocfc = &bfa->iocfc;
784
785 iocfc->cfginfo->sense_buf_len = (BFI_IOIM_SNSLEN - 1);
786 bfa_dma_be_addr_set(iocfc->cfginfo->ioim_snsbase, snsbase_pa);
787}
788
789bfa_status_t
790bfa_iocfc_get_stats(struct bfa_s *bfa, struct bfa_iocfc_stats_s *stats,
791 bfa_cb_ioc_t cbfn, void *cbarg)
792{
793 struct bfa_iocfc_s *iocfc = &bfa->iocfc;
794
795 if (iocfc->stats_busy) {
796 bfa_trc(bfa, iocfc->stats_busy);
797 return (BFA_STATUS_DEVBUSY);
798 }
799
800 iocfc->stats_busy = BFA_TRUE;
801 iocfc->stats_ret = stats;
802 iocfc->stats_cbfn = cbfn;
803 iocfc->stats_cbarg = cbarg;
804
805 bfa_iocfc_stats_query(bfa);
806
807 return (BFA_STATUS_OK);
808}
809
810bfa_status_t
811bfa_iocfc_clear_stats(struct bfa_s *bfa, bfa_cb_ioc_t cbfn, void *cbarg)
812{
813 struct bfa_iocfc_s *iocfc = &bfa->iocfc;
814
815 if (iocfc->stats_busy) {
816 bfa_trc(bfa, iocfc->stats_busy);
817 return (BFA_STATUS_DEVBUSY);
818 }
819
820 iocfc->stats_busy = BFA_TRUE;
821 iocfc->stats_cbfn = cbfn;
822 iocfc->stats_cbarg = cbarg;
823
824 bfa_iocfc_stats_clear(bfa);
825 return (BFA_STATUS_OK);
826}
827
828/**
829 * Enable IOC after it is disabled.
830 */
831void
832bfa_iocfc_enable(struct bfa_s *bfa)
833{
834 bfa_plog_str(bfa->plog, BFA_PL_MID_HAL, BFA_PL_EID_MISC, 0,
835 "IOC Enable");
836 bfa_ioc_enable(&bfa->ioc);
837}
838
839void
840bfa_iocfc_disable(struct bfa_s *bfa)
841{
842 bfa_plog_str(bfa->plog, BFA_PL_MID_HAL, BFA_PL_EID_MISC, 0,
843 "IOC Disable");
844 bfa->iocfc.action = BFA_IOCFC_ACT_DISABLE;
845
846 bfa->rme_process = BFA_FALSE;
847 bfa_ioc_disable(&bfa->ioc);
848}
849
850
851bfa_boolean_t
852bfa_iocfc_is_operational(struct bfa_s *bfa)
853{
854 return bfa_ioc_is_operational(&bfa->ioc) && bfa->iocfc.cfgdone;
855}
856
857/**
858 * Return boot target port wwns -- read from boot information in flash.
859 */
860void
861bfa_iocfc_get_bootwwns(struct bfa_s *bfa, u8 *nwwns, wwn_t **wwns)
862{
863 struct bfa_iocfc_s *iocfc = &bfa->iocfc;
864 struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp;
865
866 *nwwns = cfgrsp->bootwwns.nwwns;
867 *wwns = cfgrsp->bootwwns.wwn;
868}
869
870#endif
871
872
diff --git a/drivers/scsi/bfa/bfa_iocfc.h b/drivers/scsi/bfa/bfa_iocfc.h
new file mode 100644
index 000000000000..7ad177ed4cfc
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_iocfc.h
@@ -0,0 +1,168 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFA_IOCFC_H__
19#define __BFA_IOCFC_H__
20
21#include <bfa_ioc.h>
22#include <bfa.h>
23#include <bfi/bfi_iocfc.h>
24#include <bfa_callback_priv.h>
25
26#define BFA_REQQ_NELEMS_MIN (4)
27#define BFA_RSPQ_NELEMS_MIN (4)
28
29struct bfa_iocfc_regs_s {
30 bfa_os_addr_t intr_status;
31 bfa_os_addr_t intr_mask;
32 bfa_os_addr_t cpe_q_pi[BFI_IOC_MAX_CQS];
33 bfa_os_addr_t cpe_q_ci[BFI_IOC_MAX_CQS];
34 bfa_os_addr_t cpe_q_depth[BFI_IOC_MAX_CQS];
35 bfa_os_addr_t cpe_q_ctrl[BFI_IOC_MAX_CQS];
36 bfa_os_addr_t rme_q_ci[BFI_IOC_MAX_CQS];
37 bfa_os_addr_t rme_q_pi[BFI_IOC_MAX_CQS];
38 bfa_os_addr_t rme_q_depth[BFI_IOC_MAX_CQS];
39 bfa_os_addr_t rme_q_ctrl[BFI_IOC_MAX_CQS];
40};
41
42/**
43 * MSIX vector handlers
44 */
45#define BFA_MSIX_MAX_VECTORS 22
46typedef void (*bfa_msix_handler_t)(struct bfa_s *bfa, int vec);
47struct bfa_msix_s {
48 int nvecs;
49 bfa_msix_handler_t handler[BFA_MSIX_MAX_VECTORS];
50};
51
52/**
53 * Chip specific interfaces
54 */
55struct bfa_hwif_s {
56 void (*hw_reginit)(struct bfa_s *bfa);
57 void (*hw_rspq_ack)(struct bfa_s *bfa, int rspq);
58 void (*hw_msix_init)(struct bfa_s *bfa, int nvecs);
59 void (*hw_msix_install)(struct bfa_s *bfa);
60 void (*hw_msix_uninstall)(struct bfa_s *bfa);
61 void (*hw_isr_mode_set)(struct bfa_s *bfa, bfa_boolean_t msix);
62 void (*hw_msix_getvecs)(struct bfa_s *bfa, u32 *vecmap,
63 u32 *nvecs, u32 *maxvec);
64};
65typedef void (*bfa_cb_iocfc_t) (void *cbarg, enum bfa_status status);
66
67struct bfa_iocfc_s {
68 struct bfa_s *bfa;
69 struct bfa_iocfc_cfg_s cfg;
70 int action;
71
72 u32 req_cq_pi[BFI_IOC_MAX_CQS];
73 u32 rsp_cq_ci[BFI_IOC_MAX_CQS];
74
75 struct bfa_cb_qe_s init_hcb_qe;
76 struct bfa_cb_qe_s stop_hcb_qe;
77 struct bfa_cb_qe_s dis_hcb_qe;
78 struct bfa_cb_qe_s stats_hcb_qe;
79 bfa_boolean_t cfgdone;
80
81 struct bfa_dma_s cfg_info;
82 struct bfi_iocfc_cfg_s *cfginfo;
83 struct bfa_dma_s cfgrsp_dma;
84 struct bfi_iocfc_cfgrsp_s *cfgrsp;
85 struct bfi_iocfc_cfg_reply_s *cfg_reply;
86
87 u8 *stats_kva;
88 u64 stats_pa;
89 struct bfa_fw_stats_s *fw_stats;
90 struct bfa_timer_s stats_timer; /* timer */
91 struct bfa_iocfc_stats_s *stats_ret; /* driver stats location */
92 bfa_status_t stats_status; /* stats/statsclr status */
93 bfa_boolean_t stats_busy; /* outstanding stats */
94 bfa_cb_ioc_t stats_cbfn; /* driver callback function */
95 void *stats_cbarg; /* user callback arg */
96
97 struct bfa_dma_s req_cq_ba[BFI_IOC_MAX_CQS];
98 struct bfa_dma_s req_cq_shadow_ci[BFI_IOC_MAX_CQS];
99 struct bfa_dma_s rsp_cq_ba[BFI_IOC_MAX_CQS];
100 struct bfa_dma_s rsp_cq_shadow_pi[BFI_IOC_MAX_CQS];
101 struct bfa_iocfc_regs_s bfa_regs; /* BFA device registers */
102 struct bfa_hwif_s hwif;
103
104 bfa_cb_iocfc_t updateq_cbfn; /* bios callback function */
105 void *updateq_cbarg; /* bios callback arg */
106};
107
108#define bfa_lpuid(__bfa) bfa_ioc_portid(&(__bfa)->ioc)
109#define bfa_msix_init(__bfa, __nvecs) \
110 (__bfa)->iocfc.hwif.hw_msix_init(__bfa, __nvecs)
111#define bfa_msix_install(__bfa) \
112 (__bfa)->iocfc.hwif.hw_msix_install(__bfa)
113#define bfa_msix_uninstall(__bfa) \
114 (__bfa)->iocfc.hwif.hw_msix_uninstall(__bfa)
115#define bfa_isr_mode_set(__bfa, __msix) \
116 (__bfa)->iocfc.hwif.hw_isr_mode_set(__bfa, __msix)
117#define bfa_msix_getvecs(__bfa, __vecmap, __nvecs, __maxvec) \
118 (__bfa)->iocfc.hwif.hw_msix_getvecs(__bfa, __vecmap, __nvecs, __maxvec)
119
120/*
121 * FC specific IOC functions.
122 */
123void bfa_iocfc_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len,
124 u32 *dm_len);
125void bfa_iocfc_attach(struct bfa_s *bfa, void *bfad,
126 struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo,
127 struct bfa_pcidev_s *pcidev);
128void bfa_iocfc_detach(struct bfa_s *bfa);
129void bfa_iocfc_init(struct bfa_s *bfa);
130void bfa_iocfc_start(struct bfa_s *bfa);
131void bfa_iocfc_stop(struct bfa_s *bfa);
132void bfa_iocfc_isr(void *bfa, struct bfi_mbmsg_s *msg);
133void bfa_iocfc_set_snsbase(struct bfa_s *bfa, u64 snsbase_pa);
134bfa_boolean_t bfa_iocfc_is_operational(struct bfa_s *bfa);
135void bfa_iocfc_reset_queues(struct bfa_s *bfa);
136void bfa_iocfc_updateq(struct bfa_s *bfa, u32 reqq_ba, u32 rspq_ba,
137 u32 reqq_sci, u32 rspq_spi,
138 bfa_cb_iocfc_t cbfn, void *cbarg);
139
140void bfa_msix_all(struct bfa_s *bfa, int vec);
141void bfa_msix_reqq(struct bfa_s *bfa, int vec);
142void bfa_msix_rspq(struct bfa_s *bfa, int vec);
143void bfa_msix_lpu_err(struct bfa_s *bfa, int vec);
144
145void bfa_hwcb_reginit(struct bfa_s *bfa);
146void bfa_hwcb_rspq_ack(struct bfa_s *bfa, int rspq);
147void bfa_hwcb_msix_init(struct bfa_s *bfa, int nvecs);
148void bfa_hwcb_msix_install(struct bfa_s *bfa);
149void bfa_hwcb_msix_uninstall(struct bfa_s *bfa);
150void bfa_hwcb_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix);
151void bfa_hwcb_msix_getvecs(struct bfa_s *bfa, u32 *vecmap,
152 u32 *nvecs, u32 *maxvec);
153void bfa_hwct_reginit(struct bfa_s *bfa);
154void bfa_hwct_rspq_ack(struct bfa_s *bfa, int rspq);
155void bfa_hwct_msix_init(struct bfa_s *bfa, int nvecs);
156void bfa_hwct_msix_install(struct bfa_s *bfa);
157void bfa_hwct_msix_uninstall(struct bfa_s *bfa);
158void bfa_hwct_isr_mode_set(struct bfa_s *bfa, bfa_boolean_t msix);
159void bfa_hwct_msix_getvecs(struct bfa_s *bfa, u32 *vecmap,
160 u32 *nvecs, u32 *maxvec);
161
162void bfa_com_meminfo(bfa_boolean_t mincfg, u32 *dm_len);
163void bfa_com_attach(struct bfa_s *bfa, struct bfa_meminfo_s *mi,
164 bfa_boolean_t mincfg);
165void bfa_iocfc_get_bootwwns(struct bfa_s *bfa, u8 *nwwns, wwn_t **wwns);
166
167#endif /* __BFA_IOCFC_H__ */
168
diff --git a/drivers/scsi/bfa/bfa_iocfc_q.c b/drivers/scsi/bfa/bfa_iocfc_q.c
new file mode 100644
index 000000000000..500a17df40b2
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_iocfc_q.c
@@ -0,0 +1,44 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#include <bfa.h>
19#include "bfa_intr_priv.h"
20
21BFA_TRC_FILE(HAL, IOCFC_Q);
22
23void
24bfa_iocfc_updateq(struct bfa_s *bfa, u32 reqq_ba, u32 rspq_ba,
25 u32 reqq_sci, u32 rspq_spi, bfa_cb_iocfc_t cbfn,
26 void *cbarg)
27{
28 struct bfa_iocfc_s *iocfc = &bfa->iocfc;
29 struct bfi_iocfc_updateq_req_s updateq_req;
30
31 iocfc->updateq_cbfn = cbfn;
32 iocfc->updateq_cbarg = cbarg;
33
34 bfi_h2i_set(updateq_req.mh, BFI_MC_IOCFC, BFI_IOCFC_H2I_UPDATEQ_REQ,
35 bfa_lpuid(bfa));
36
37 updateq_req.reqq_ba = bfa_os_htonl(reqq_ba);
38 updateq_req.rspq_ba = bfa_os_htonl(rspq_ba);
39 updateq_req.reqq_sci = bfa_os_htonl(reqq_sci);
40 updateq_req.rspq_spi = bfa_os_htonl(rspq_spi);
41
42 bfa_ioc_mbox_send(&bfa->ioc, &updateq_req,
43 sizeof(struct bfi_iocfc_updateq_req_s));
44}
diff --git a/drivers/scsi/bfa/bfa_ioim.c b/drivers/scsi/bfa/bfa_ioim.c
new file mode 100644
index 000000000000..7ae2552e1e14
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_ioim.c
@@ -0,0 +1,1311 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#include <bfa.h>
19#include <cs/bfa_debug.h>
20#include <bfa_cb_ioim_macros.h>
21
22BFA_TRC_FILE(HAL, IOIM);
23
24/*
25 * forward declarations.
26 */
27static bfa_boolean_t bfa_ioim_send_ioreq(struct bfa_ioim_s *ioim);
28static bfa_boolean_t bfa_ioim_sge_setup(struct bfa_ioim_s *ioim);
29static void bfa_ioim_sgpg_setup(struct bfa_ioim_s *ioim);
30static bfa_boolean_t bfa_ioim_send_abort(struct bfa_ioim_s *ioim);
31static void bfa_ioim_notify_cleanup(struct bfa_ioim_s *ioim);
32static void __bfa_cb_ioim_good_comp(void *cbarg, bfa_boolean_t complete);
33static void __bfa_cb_ioim_comp(void *cbarg, bfa_boolean_t complete);
34static void __bfa_cb_ioim_abort(void *cbarg, bfa_boolean_t complete);
35static void __bfa_cb_ioim_failed(void *cbarg, bfa_boolean_t complete);
36static void __bfa_cb_ioim_pathtov(void *cbarg, bfa_boolean_t complete);
37
38/**
39 * bfa_ioim_sm
40 */
41
42/**
43 * IO state machine events
44 */
45enum bfa_ioim_event {
46 BFA_IOIM_SM_START = 1, /* io start request from host */
47 BFA_IOIM_SM_COMP_GOOD = 2, /* io good comp, resource free */
48 BFA_IOIM_SM_COMP = 3, /* io comp, resource is free */
49 BFA_IOIM_SM_COMP_UTAG = 4, /* io comp, resource is free */
50 BFA_IOIM_SM_DONE = 5, /* io comp, resource not free */
51 BFA_IOIM_SM_FREE = 6, /* io resource is freed */
52 BFA_IOIM_SM_ABORT = 7, /* abort request from scsi stack */
53 BFA_IOIM_SM_ABORT_COMP = 8, /* abort from f/w */
54 BFA_IOIM_SM_ABORT_DONE = 9, /* abort completion from f/w */
55 BFA_IOIM_SM_QRESUME = 10, /* CQ space available to queue IO */
56 BFA_IOIM_SM_SGALLOCED = 11, /* SG page allocation successful */
57 BFA_IOIM_SM_SQRETRY = 12, /* sequence recovery retry */
58 BFA_IOIM_SM_HCB = 13, /* bfa callback complete */
59 BFA_IOIM_SM_CLEANUP = 14, /* IO cleanup from itnim */
60 BFA_IOIM_SM_TMSTART = 15, /* IO cleanup from tskim */
61 BFA_IOIM_SM_TMDONE = 16, /* IO cleanup from tskim */
62 BFA_IOIM_SM_HWFAIL = 17, /* IOC h/w failure event */
63 BFA_IOIM_SM_IOTOV = 18, /* ITN offline TOV */
64};
65
66/*
67 * forward declaration of IO state machine
68 */
69static void bfa_ioim_sm_uninit(struct bfa_ioim_s *ioim,
70 enum bfa_ioim_event event);
71static void bfa_ioim_sm_sgalloc(struct bfa_ioim_s *ioim,
72 enum bfa_ioim_event event);
73static void bfa_ioim_sm_active(struct bfa_ioim_s *ioim,
74 enum bfa_ioim_event event);
75static void bfa_ioim_sm_abort(struct bfa_ioim_s *ioim,
76 enum bfa_ioim_event event);
77static void bfa_ioim_sm_cleanup(struct bfa_ioim_s *ioim,
78 enum bfa_ioim_event event);
79static void bfa_ioim_sm_qfull(struct bfa_ioim_s *ioim,
80 enum bfa_ioim_event event);
81static void bfa_ioim_sm_abort_qfull(struct bfa_ioim_s *ioim,
82 enum bfa_ioim_event event);
83static void bfa_ioim_sm_cleanup_qfull(struct bfa_ioim_s *ioim,
84 enum bfa_ioim_event event);
85static void bfa_ioim_sm_hcb(struct bfa_ioim_s *ioim,
86 enum bfa_ioim_event event);
87static void bfa_ioim_sm_hcb_free(struct bfa_ioim_s *ioim,
88 enum bfa_ioim_event event);
89static void bfa_ioim_sm_resfree(struct bfa_ioim_s *ioim,
90 enum bfa_ioim_event event);
91
92/**
93 * IO is not started (unallocated).
94 */
95static void
96bfa_ioim_sm_uninit(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
97{
98 bfa_trc_fp(ioim->bfa, ioim->iotag);
99 bfa_trc_fp(ioim->bfa, event);
100
101 switch (event) {
102 case BFA_IOIM_SM_START:
103 if (!bfa_itnim_is_online(ioim->itnim)) {
104 if (!bfa_itnim_hold_io(ioim->itnim)) {
105 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
106 list_del(&ioim->qe);
107 list_add_tail(&ioim->qe,
108 &ioim->fcpim->ioim_comp_q);
109 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe,
110 __bfa_cb_ioim_pathtov, ioim);
111 } else {
112 list_del(&ioim->qe);
113 list_add_tail(&ioim->qe,
114 &ioim->itnim->pending_q);
115 }
116 break;
117 }
118
119 if (ioim->nsges > BFI_SGE_INLINE) {
120 if (!bfa_ioim_sge_setup(ioim)) {
121 bfa_sm_set_state(ioim, bfa_ioim_sm_sgalloc);
122 return;
123 }
124 }
125
126 if (!bfa_ioim_send_ioreq(ioim)) {
127 bfa_sm_set_state(ioim, bfa_ioim_sm_qfull);
128 break;
129 }
130
131 bfa_sm_set_state(ioim, bfa_ioim_sm_active);
132 break;
133
134 case BFA_IOIM_SM_IOTOV:
135 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
136 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe,
137 __bfa_cb_ioim_pathtov, ioim);
138 break;
139
140 case BFA_IOIM_SM_ABORT:
141 /**
142 * IO in pending queue can get abort requests. Complete abort
143 * requests immediately.
144 */
145 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
146 bfa_assert(bfa_q_is_on_q(&ioim->itnim->pending_q, ioim));
147 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
148 ioim);
149 break;
150
151 default:
152 bfa_assert(0);
153 }
154}
155
156/**
157 * IO is waiting for SG pages.
158 */
159static void
160bfa_ioim_sm_sgalloc(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
161{
162 bfa_trc(ioim->bfa, ioim->iotag);
163 bfa_trc(ioim->bfa, event);
164
165 switch (event) {
166 case BFA_IOIM_SM_SGALLOCED:
167 if (!bfa_ioim_send_ioreq(ioim)) {
168 bfa_sm_set_state(ioim, bfa_ioim_sm_qfull);
169 break;
170 }
171 bfa_sm_set_state(ioim, bfa_ioim_sm_active);
172 break;
173
174 case BFA_IOIM_SM_CLEANUP:
175 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
176 bfa_sgpg_wcancel(ioim->bfa, &ioim->iosp->sgpg_wqe);
177 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
178 ioim);
179 bfa_ioim_notify_cleanup(ioim);
180 break;
181
182 case BFA_IOIM_SM_ABORT:
183 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
184 bfa_sgpg_wcancel(ioim->bfa, &ioim->iosp->sgpg_wqe);
185 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
186 ioim);
187 break;
188
189 case BFA_IOIM_SM_HWFAIL:
190 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
191 bfa_sgpg_wcancel(ioim->bfa, &ioim->iosp->sgpg_wqe);
192 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
193 ioim);
194 break;
195
196 default:
197 bfa_assert(0);
198 }
199}
200
201/**
202 * IO is active.
203 */
204static void
205bfa_ioim_sm_active(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
206{
207 bfa_trc_fp(ioim->bfa, ioim->iotag);
208 bfa_trc_fp(ioim->bfa, event);
209
210 switch (event) {
211 case BFA_IOIM_SM_COMP_GOOD:
212 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
213 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe,
214 __bfa_cb_ioim_good_comp, ioim);
215 break;
216
217 case BFA_IOIM_SM_COMP:
218 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
219 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_comp,
220 ioim);
221 break;
222
223 case BFA_IOIM_SM_DONE:
224 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free);
225 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_comp,
226 ioim);
227 break;
228
229 case BFA_IOIM_SM_ABORT:
230 ioim->iosp->abort_explicit = BFA_TRUE;
231 ioim->io_cbfn = __bfa_cb_ioim_abort;
232
233 if (bfa_ioim_send_abort(ioim))
234 bfa_sm_set_state(ioim, bfa_ioim_sm_abort);
235 else {
236 bfa_sm_set_state(ioim, bfa_ioim_sm_abort_qfull);
237 bfa_reqq_wait(ioim->bfa, ioim->itnim->reqq,
238 &ioim->iosp->reqq_wait);
239 }
240 break;
241
242 case BFA_IOIM_SM_CLEANUP:
243 ioim->iosp->abort_explicit = BFA_FALSE;
244 ioim->io_cbfn = __bfa_cb_ioim_failed;
245
246 if (bfa_ioim_send_abort(ioim))
247 bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup);
248 else {
249 bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup_qfull);
250 bfa_reqq_wait(ioim->bfa, ioim->itnim->reqq,
251 &ioim->iosp->reqq_wait);
252 }
253 break;
254
255 case BFA_IOIM_SM_HWFAIL:
256 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
257 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
258 ioim);
259 break;
260
261 default:
262 bfa_assert(0);
263 }
264}
265
266/**
267 * IO is being aborted, waiting for completion from firmware.
268 */
269static void
270bfa_ioim_sm_abort(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
271{
272 bfa_trc(ioim->bfa, ioim->iotag);
273 bfa_trc(ioim->bfa, event);
274
275 switch (event) {
276 case BFA_IOIM_SM_COMP_GOOD:
277 case BFA_IOIM_SM_COMP:
278 case BFA_IOIM_SM_DONE:
279 case BFA_IOIM_SM_FREE:
280 break;
281
282 case BFA_IOIM_SM_ABORT_DONE:
283 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free);
284 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
285 ioim);
286 break;
287
288 case BFA_IOIM_SM_ABORT_COMP:
289 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
290 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
291 ioim);
292 break;
293
294 case BFA_IOIM_SM_COMP_UTAG:
295 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
296 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
297 ioim);
298 break;
299
300 case BFA_IOIM_SM_CLEANUP:
301 bfa_assert(ioim->iosp->abort_explicit == BFA_TRUE);
302 ioim->iosp->abort_explicit = BFA_FALSE;
303
304 if (bfa_ioim_send_abort(ioim))
305 bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup);
306 else {
307 bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup_qfull);
308 bfa_reqq_wait(ioim->bfa, ioim->itnim->reqq,
309 &ioim->iosp->reqq_wait);
310 }
311 break;
312
313 case BFA_IOIM_SM_HWFAIL:
314 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
315 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
316 ioim);
317 break;
318
319 default:
320 bfa_assert(0);
321 }
322}
323
324/**
325 * IO is being cleaned up (implicit abort), waiting for completion from
326 * firmware.
327 */
328static void
329bfa_ioim_sm_cleanup(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
330{
331 bfa_trc(ioim->bfa, ioim->iotag);
332 bfa_trc(ioim->bfa, event);
333
334 switch (event) {
335 case BFA_IOIM_SM_COMP_GOOD:
336 case BFA_IOIM_SM_COMP:
337 case BFA_IOIM_SM_DONE:
338 case BFA_IOIM_SM_FREE:
339 break;
340
341 case BFA_IOIM_SM_ABORT:
342 /**
343 * IO is already being aborted implicitly
344 */
345 ioim->io_cbfn = __bfa_cb_ioim_abort;
346 break;
347
348 case BFA_IOIM_SM_ABORT_DONE:
349 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free);
350 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, ioim->io_cbfn, ioim);
351 bfa_ioim_notify_cleanup(ioim);
352 break;
353
354 case BFA_IOIM_SM_ABORT_COMP:
355 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
356 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, ioim->io_cbfn, ioim);
357 bfa_ioim_notify_cleanup(ioim);
358 break;
359
360 case BFA_IOIM_SM_COMP_UTAG:
361 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
362 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, ioim->io_cbfn, ioim);
363 bfa_ioim_notify_cleanup(ioim);
364 break;
365
366 case BFA_IOIM_SM_HWFAIL:
367 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
368 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
369 ioim);
370 break;
371
372 case BFA_IOIM_SM_CLEANUP:
373 /**
374 * IO can be in cleanup state already due to TM command. 2nd cleanup
375 * request comes from ITN offline event.
376 */
377 break;
378
379 default:
380 bfa_assert(0);
381 }
382}
383
384/**
385 * IO is waiting for room in request CQ
386 */
387static void
388bfa_ioim_sm_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
389{
390 bfa_trc(ioim->bfa, ioim->iotag);
391 bfa_trc(ioim->bfa, event);
392
393 switch (event) {
394 case BFA_IOIM_SM_QRESUME:
395 bfa_sm_set_state(ioim, bfa_ioim_sm_active);
396 bfa_ioim_send_ioreq(ioim);
397 break;
398
399 case BFA_IOIM_SM_ABORT:
400 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
401 bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
402 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
403 ioim);
404 break;
405
406 case BFA_IOIM_SM_CLEANUP:
407 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
408 bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
409 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
410 ioim);
411 bfa_ioim_notify_cleanup(ioim);
412 break;
413
414 case BFA_IOIM_SM_HWFAIL:
415 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
416 bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
417 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
418 ioim);
419 break;
420
421 default:
422 bfa_assert(0);
423 }
424}
425
426/**
427 * Active IO is being aborted, waiting for room in request CQ.
428 */
429static void
430bfa_ioim_sm_abort_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
431{
432 bfa_trc(ioim->bfa, ioim->iotag);
433 bfa_trc(ioim->bfa, event);
434
435 switch (event) {
436 case BFA_IOIM_SM_QRESUME:
437 bfa_sm_set_state(ioim, bfa_ioim_sm_abort);
438 bfa_ioim_send_abort(ioim);
439 break;
440
441 case BFA_IOIM_SM_CLEANUP:
442 bfa_assert(ioim->iosp->abort_explicit == BFA_TRUE);
443 ioim->iosp->abort_explicit = BFA_FALSE;
444 bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup_qfull);
445 break;
446
447 case BFA_IOIM_SM_COMP_GOOD:
448 case BFA_IOIM_SM_COMP:
449 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
450 bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
451 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
452 ioim);
453 break;
454
455 case BFA_IOIM_SM_DONE:
456 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free);
457 bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
458 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort,
459 ioim);
460 break;
461
462 case BFA_IOIM_SM_HWFAIL:
463 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
464 bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
465 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
466 ioim);
467 break;
468
469 default:
470 bfa_assert(0);
471 }
472}
473
474/**
475 * Active IO is being cleaned up, waiting for room in request CQ.
476 */
477static void
478bfa_ioim_sm_cleanup_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
479{
480 bfa_trc(ioim->bfa, ioim->iotag);
481 bfa_trc(ioim->bfa, event);
482
483 switch (event) {
484 case BFA_IOIM_SM_QRESUME:
485 bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup);
486 bfa_ioim_send_abort(ioim);
487 break;
488
489 case BFA_IOIM_SM_ABORT:
490 /**
491 * IO is alraedy being cleaned up implicitly
492 */
493 ioim->io_cbfn = __bfa_cb_ioim_abort;
494 break;
495
496 case BFA_IOIM_SM_COMP_GOOD:
497 case BFA_IOIM_SM_COMP:
498 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
499 bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
500 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, ioim->io_cbfn, ioim);
501 bfa_ioim_notify_cleanup(ioim);
502 break;
503
504 case BFA_IOIM_SM_DONE:
505 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free);
506 bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
507 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, ioim->io_cbfn, ioim);
508 bfa_ioim_notify_cleanup(ioim);
509 break;
510
511 case BFA_IOIM_SM_HWFAIL:
512 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
513 bfa_reqq_wcancel(&ioim->iosp->reqq_wait);
514 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed,
515 ioim);
516 break;
517
518 default:
519 bfa_assert(0);
520 }
521}
522
523/**
524 * IO bfa callback is pending.
525 */
526static void
527bfa_ioim_sm_hcb(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
528{
529 bfa_trc_fp(ioim->bfa, ioim->iotag);
530 bfa_trc_fp(ioim->bfa, event);
531
532 switch (event) {
533 case BFA_IOIM_SM_HCB:
534 bfa_sm_set_state(ioim, bfa_ioim_sm_uninit);
535 bfa_ioim_free(ioim);
536 bfa_cb_ioim_resfree(ioim->bfa->bfad);
537 break;
538
539 case BFA_IOIM_SM_CLEANUP:
540 bfa_ioim_notify_cleanup(ioim);
541 break;
542
543 case BFA_IOIM_SM_HWFAIL:
544 break;
545
546 default:
547 bfa_assert(0);
548 }
549}
550
551/**
552 * IO bfa callback is pending. IO resource cannot be freed.
553 */
554static void
555bfa_ioim_sm_hcb_free(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
556{
557 bfa_trc(ioim->bfa, ioim->iotag);
558 bfa_trc(ioim->bfa, event);
559
560 switch (event) {
561 case BFA_IOIM_SM_HCB:
562 bfa_sm_set_state(ioim, bfa_ioim_sm_resfree);
563 list_del(&ioim->qe);
564 list_add_tail(&ioim->qe, &ioim->fcpim->ioim_resfree_q);
565 break;
566
567 case BFA_IOIM_SM_FREE:
568 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
569 break;
570
571 case BFA_IOIM_SM_CLEANUP:
572 bfa_ioim_notify_cleanup(ioim);
573 break;
574
575 case BFA_IOIM_SM_HWFAIL:
576 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb);
577 break;
578
579 default:
580 bfa_assert(0);
581 }
582}
583
584/**
585 * IO is completed, waiting resource free from firmware.
586 */
587static void
588bfa_ioim_sm_resfree(struct bfa_ioim_s *ioim, enum bfa_ioim_event event)
589{
590 bfa_trc(ioim->bfa, ioim->iotag);
591 bfa_trc(ioim->bfa, event);
592
593 switch (event) {
594 case BFA_IOIM_SM_FREE:
595 bfa_sm_set_state(ioim, bfa_ioim_sm_uninit);
596 bfa_ioim_free(ioim);
597 bfa_cb_ioim_resfree(ioim->bfa->bfad);
598 break;
599
600 case BFA_IOIM_SM_CLEANUP:
601 bfa_ioim_notify_cleanup(ioim);
602 break;
603
604 case BFA_IOIM_SM_HWFAIL:
605 break;
606
607 default:
608 bfa_assert(0);
609 }
610}
611
612
613
614/**
615 * bfa_ioim_private
616 */
617
618static void
619__bfa_cb_ioim_good_comp(void *cbarg, bfa_boolean_t complete)
620{
621 struct bfa_ioim_s *ioim = cbarg;
622
623 if (!complete) {
624 bfa_sm_send_event(ioim, BFA_IOIM_SM_HCB);
625 return;
626 }
627
628 bfa_cb_ioim_good_comp(ioim->bfa->bfad, ioim->dio);
629}
630
631static void
632__bfa_cb_ioim_comp(void *cbarg, bfa_boolean_t complete)
633{
634 struct bfa_ioim_s *ioim = cbarg;
635 struct bfi_ioim_rsp_s *m;
636 u8 *snsinfo = NULL;
637 u8 sns_len = 0;
638 s32 residue = 0;
639
640 if (!complete) {
641 bfa_sm_send_event(ioim, BFA_IOIM_SM_HCB);
642 return;
643 }
644
645 m = (struct bfi_ioim_rsp_s *) &ioim->iosp->comp_rspmsg;
646 if (m->io_status == BFI_IOIM_STS_OK) {
647 /**
648 * setup sense information, if present
649 */
650 if (m->scsi_status == SCSI_STATUS_CHECK_CONDITION
651 && m->sns_len) {
652 sns_len = m->sns_len;
653 snsinfo = ioim->iosp->snsinfo;
654 }
655
656 /**
657 * setup residue value correctly for normal completions
658 */
659 if (m->resid_flags == FCP_RESID_UNDER)
660 residue = bfa_os_ntohl(m->residue);
661 if (m->resid_flags == FCP_RESID_OVER) {
662 residue = bfa_os_ntohl(m->residue);
663 residue = -residue;
664 }
665 }
666
667 bfa_cb_ioim_done(ioim->bfa->bfad, ioim->dio, m->io_status,
668 m->scsi_status, sns_len, snsinfo, residue);
669}
670
671static void
672__bfa_cb_ioim_failed(void *cbarg, bfa_boolean_t complete)
673{
674 struct bfa_ioim_s *ioim = cbarg;
675
676 if (!complete) {
677 bfa_sm_send_event(ioim, BFA_IOIM_SM_HCB);
678 return;
679 }
680
681 bfa_cb_ioim_done(ioim->bfa->bfad, ioim->dio, BFI_IOIM_STS_ABORTED,
682 0, 0, NULL, 0);
683}
684
685static void
686__bfa_cb_ioim_pathtov(void *cbarg, bfa_boolean_t complete)
687{
688 struct bfa_ioim_s *ioim = cbarg;
689
690 if (!complete) {
691 bfa_sm_send_event(ioim, BFA_IOIM_SM_HCB);
692 return;
693 }
694
695 bfa_cb_ioim_done(ioim->bfa->bfad, ioim->dio, BFI_IOIM_STS_PATHTOV,
696 0, 0, NULL, 0);
697}
698
699static void
700__bfa_cb_ioim_abort(void *cbarg, bfa_boolean_t complete)
701{
702 struct bfa_ioim_s *ioim = cbarg;
703
704 if (!complete) {
705 bfa_sm_send_event(ioim, BFA_IOIM_SM_HCB);
706 return;
707 }
708
709 bfa_cb_ioim_abort(ioim->bfa->bfad, ioim->dio);
710}
711
712static void
713bfa_ioim_sgpg_alloced(void *cbarg)
714{
715 struct bfa_ioim_s *ioim = cbarg;
716
717 ioim->nsgpgs = BFA_SGPG_NPAGE(ioim->nsges);
718 list_splice_tail_init(&ioim->iosp->sgpg_wqe.sgpg_q, &ioim->sgpg_q);
719 bfa_ioim_sgpg_setup(ioim);
720 bfa_sm_send_event(ioim, BFA_IOIM_SM_SGALLOCED);
721}
722
723/**
724 * Send I/O request to firmware.
725 */
726static bfa_boolean_t
727bfa_ioim_send_ioreq(struct bfa_ioim_s *ioim)
728{
729 struct bfa_itnim_s *itnim = ioim->itnim;
730 struct bfi_ioim_req_s *m;
731 static struct fcp_cmnd_s cmnd_z0 = { 0 };
732 struct bfi_sge_s *sge;
733 u32 pgdlen = 0;
734
735 /**
736 * check for room in queue to send request now
737 */
738 m = bfa_reqq_next(ioim->bfa, itnim->reqq);
739 if (!m) {
740 bfa_reqq_wait(ioim->bfa, ioim->itnim->reqq,
741 &ioim->iosp->reqq_wait);
742 return BFA_FALSE;
743 }
744
745 /**
746 * build i/o request message next
747 */
748 m->io_tag = bfa_os_htons(ioim->iotag);
749 m->rport_hdl = ioim->itnim->rport->fw_handle;
750 m->io_timeout = bfa_cb_ioim_get_timeout(ioim->dio);
751
752 /**
753 * build inline IO SG element here
754 */
755 sge = &m->sges[0];
756 if (ioim->nsges) {
757 sge->sga = bfa_cb_ioim_get_sgaddr(ioim->dio, 0);
758 pgdlen = bfa_cb_ioim_get_sglen(ioim->dio, 0);
759 sge->sg_len = pgdlen;
760 sge->flags = (ioim->nsges > BFI_SGE_INLINE) ?
761 BFI_SGE_DATA_CPL : BFI_SGE_DATA_LAST;
762 bfa_sge_to_be(sge);
763 sge++;
764 }
765
766 if (ioim->nsges > BFI_SGE_INLINE) {
767 sge->sga = ioim->sgpg->sgpg_pa;
768 } else {
769 sge->sga.a32.addr_lo = 0;
770 sge->sga.a32.addr_hi = 0;
771 }
772 sge->sg_len = pgdlen;
773 sge->flags = BFI_SGE_PGDLEN;
774 bfa_sge_to_be(sge);
775
776 /**
777 * set up I/O command parameters
778 */
779 bfa_os_assign(m->cmnd, cmnd_z0);
780 m->cmnd.lun = bfa_cb_ioim_get_lun(ioim->dio);
781 m->cmnd.iodir = bfa_cb_ioim_get_iodir(ioim->dio);
782 bfa_os_assign(m->cmnd.cdb,
783 *(struct scsi_cdb_s *)bfa_cb_ioim_get_cdb(ioim->dio));
784 m->cmnd.fcp_dl = bfa_os_htonl(bfa_cb_ioim_get_size(ioim->dio));
785
786 /**
787 * set up I/O message header
788 */
789 switch (m->cmnd.iodir) {
790 case FCP_IODIR_READ:
791 bfi_h2i_set(m->mh, BFI_MC_IOIM_READ, 0, bfa_lpuid(ioim->bfa));
792 bfa_stats(itnim, input_reqs);
793 break;
794 case FCP_IODIR_WRITE:
795 bfi_h2i_set(m->mh, BFI_MC_IOIM_WRITE, 0, bfa_lpuid(ioim->bfa));
796 bfa_stats(itnim, output_reqs);
797 break;
798 case FCP_IODIR_RW:
799 bfa_stats(itnim, input_reqs);
800 bfa_stats(itnim, output_reqs);
801 default:
802 bfi_h2i_set(m->mh, BFI_MC_IOIM_IO, 0, bfa_lpuid(ioim->bfa));
803 }
804 if (itnim->seq_rec ||
805 (bfa_cb_ioim_get_size(ioim->dio) & (sizeof(u32) - 1)))
806 bfi_h2i_set(m->mh, BFI_MC_IOIM_IO, 0, bfa_lpuid(ioim->bfa));
807
808#ifdef IOIM_ADVANCED
809 m->cmnd.crn = bfa_cb_ioim_get_crn(ioim->dio);
810 m->cmnd.priority = bfa_cb_ioim_get_priority(ioim->dio);
811 m->cmnd.taskattr = bfa_cb_ioim_get_taskattr(ioim->dio);
812
813 /**
814 * Handle large CDB (>16 bytes).
815 */
816 m->cmnd.addl_cdb_len = (bfa_cb_ioim_get_cdblen(ioim->dio) -
817 FCP_CMND_CDB_LEN) / sizeof(u32);
818 if (m->cmnd.addl_cdb_len) {
819 bfa_os_memcpy(&m->cmnd.cdb + 1, (struct scsi_cdb_s *)
820 bfa_cb_ioim_get_cdb(ioim->dio) + 1,
821 m->cmnd.addl_cdb_len * sizeof(u32));
822 fcp_cmnd_fcpdl(&m->cmnd) =
823 bfa_os_htonl(bfa_cb_ioim_get_size(ioim->dio));
824 }
825#endif
826
827 /**
828 * queue I/O message to firmware
829 */
830 bfa_reqq_produce(ioim->bfa, itnim->reqq);
831 return BFA_TRUE;
832}
833
834/**
835 * Setup any additional SG pages needed.Inline SG element is setup
836 * at queuing time.
837 */
838static bfa_boolean_t
839bfa_ioim_sge_setup(struct bfa_ioim_s *ioim)
840{
841 u16 nsgpgs;
842
843 bfa_assert(ioim->nsges > BFI_SGE_INLINE);
844
845 /**
846 * allocate SG pages needed
847 */
848 nsgpgs = BFA_SGPG_NPAGE(ioim->nsges);
849 if (!nsgpgs)
850 return BFA_TRUE;
851
852 if (bfa_sgpg_malloc(ioim->bfa, &ioim->sgpg_q, nsgpgs)
853 != BFA_STATUS_OK) {
854 bfa_sgpg_wait(ioim->bfa, &ioim->iosp->sgpg_wqe, nsgpgs);
855 return BFA_FALSE;
856 }
857
858 ioim->nsgpgs = nsgpgs;
859 bfa_ioim_sgpg_setup(ioim);
860
861 return BFA_TRUE;
862}
863
864static void
865bfa_ioim_sgpg_setup(struct bfa_ioim_s *ioim)
866{
867 int sgeid, nsges, i;
868 struct bfi_sge_s *sge;
869 struct bfa_sgpg_s *sgpg;
870 u32 pgcumsz;
871
872 sgeid = BFI_SGE_INLINE;
873 ioim->sgpg = sgpg = bfa_q_first(&ioim->sgpg_q);
874
875 do {
876 sge = sgpg->sgpg->sges;
877 nsges = ioim->nsges - sgeid;
878 if (nsges > BFI_SGPG_DATA_SGES)
879 nsges = BFI_SGPG_DATA_SGES;
880
881 pgcumsz = 0;
882 for (i = 0; i < nsges; i++, sge++, sgeid++) {
883 sge->sga = bfa_cb_ioim_get_sgaddr(ioim->dio, sgeid);
884 sge->sg_len = bfa_cb_ioim_get_sglen(ioim->dio, sgeid);
885 pgcumsz += sge->sg_len;
886
887 /**
888 * set flags
889 */
890 if (i < (nsges - 1))
891 sge->flags = BFI_SGE_DATA;
892 else if (sgeid < (ioim->nsges - 1))
893 sge->flags = BFI_SGE_DATA_CPL;
894 else
895 sge->flags = BFI_SGE_DATA_LAST;
896 }
897
898 sgpg = (struct bfa_sgpg_s *) bfa_q_next(sgpg);
899
900 /**
901 * set the link element of each page
902 */
903 if (sgeid == ioim->nsges) {
904 sge->flags = BFI_SGE_PGDLEN;
905 sge->sga.a32.addr_lo = 0;
906 sge->sga.a32.addr_hi = 0;
907 } else {
908 sge->flags = BFI_SGE_LINK;
909 sge->sga = sgpg->sgpg_pa;
910 }
911 sge->sg_len = pgcumsz;
912 } while (sgeid < ioim->nsges);
913}
914
915/**
916 * Send I/O abort request to firmware.
917 */
918static bfa_boolean_t
919bfa_ioim_send_abort(struct bfa_ioim_s *ioim)
920{
921 struct bfa_itnim_s *itnim = ioim->itnim;
922 struct bfi_ioim_abort_req_s *m;
923 enum bfi_ioim_h2i msgop;
924
925 /**
926 * check for room in queue to send request now
927 */
928 m = bfa_reqq_next(ioim->bfa, itnim->reqq);
929 if (!m)
930 return BFA_FALSE;
931
932 /**
933 * build i/o request message next
934 */
935 if (ioim->iosp->abort_explicit)
936 msgop = BFI_IOIM_H2I_IOABORT_REQ;
937 else
938 msgop = BFI_IOIM_H2I_IOCLEANUP_REQ;
939
940 bfi_h2i_set(m->mh, BFI_MC_IOIM, msgop, bfa_lpuid(ioim->bfa));
941 m->io_tag = bfa_os_htons(ioim->iotag);
942 m->abort_tag = ++ioim->abort_tag;
943
944 /**
945 * queue I/O message to firmware
946 */
947 bfa_reqq_produce(ioim->bfa, itnim->reqq);
948 return BFA_TRUE;
949}
950
951/**
952 * Call to resume any I/O requests waiting for room in request queue.
953 */
954static void
955bfa_ioim_qresume(void *cbarg)
956{
957 struct bfa_ioim_s *ioim = cbarg;
958
959 bfa_fcpim_stats(ioim->fcpim, qresumes);
960 bfa_sm_send_event(ioim, BFA_IOIM_SM_QRESUME);
961}
962
963
964static void
965bfa_ioim_notify_cleanup(struct bfa_ioim_s *ioim)
966{
967 /**
968 * Move IO from itnim queue to fcpim global queue since itnim will be
969 * freed.
970 */
971 list_del(&ioim->qe);
972 list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
973
974 if (!ioim->iosp->tskim) {
975 if (ioim->fcpim->delay_comp && ioim->itnim->iotov_active) {
976 bfa_cb_dequeue(&ioim->hcb_qe);
977 list_del(&ioim->qe);
978 list_add_tail(&ioim->qe, &ioim->itnim->delay_comp_q);
979 }
980 bfa_itnim_iodone(ioim->itnim);
981 } else
982 bfa_tskim_iodone(ioim->iosp->tskim);
983}
984
985/**
986 * or after the link comes back.
987 */
988void
989bfa_ioim_delayed_comp(struct bfa_ioim_s *ioim, bfa_boolean_t iotov)
990{
991 /**
992 * If path tov timer expired, failback with PATHTOV status - these
993 * IO requests are not normally retried by IO stack.
994 *
995 * Otherwise device cameback online and fail it with normal failed
996 * status so that IO stack retries these failed IO requests.
997 */
998 if (iotov)
999 ioim->io_cbfn = __bfa_cb_ioim_pathtov;
1000 else
1001 ioim->io_cbfn = __bfa_cb_ioim_failed;
1002
1003 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, ioim->io_cbfn, ioim);
1004
1005 /**
1006 * Move IO to fcpim global queue since itnim will be
1007 * freed.
1008 */
1009 list_del(&ioim->qe);
1010 list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
1011}
1012
1013
1014
1015/**
1016 * bfa_ioim_friend
1017 */
1018
1019/**
1020 * Memory allocation and initialization.
1021 */
1022void
1023bfa_ioim_attach(struct bfa_fcpim_mod_s *fcpim, struct bfa_meminfo_s *minfo)
1024{
1025 struct bfa_ioim_s *ioim;
1026 struct bfa_ioim_sp_s *iosp;
1027 u16 i;
1028 u8 *snsinfo;
1029 u32 snsbufsz;
1030
1031 /**
1032 * claim memory first
1033 */
1034 ioim = (struct bfa_ioim_s *) bfa_meminfo_kva(minfo);
1035 fcpim->ioim_arr = ioim;
1036 bfa_meminfo_kva(minfo) = (u8 *) (ioim + fcpim->num_ioim_reqs);
1037
1038 iosp = (struct bfa_ioim_sp_s *) bfa_meminfo_kva(minfo);
1039 fcpim->ioim_sp_arr = iosp;
1040 bfa_meminfo_kva(minfo) = (u8 *) (iosp + fcpim->num_ioim_reqs);
1041
1042 /**
1043 * Claim DMA memory for per IO sense data.
1044 */
1045 snsbufsz = fcpim->num_ioim_reqs * BFI_IOIM_SNSLEN;
1046 fcpim->snsbase.pa = bfa_meminfo_dma_phys(minfo);
1047 bfa_meminfo_dma_phys(minfo) += snsbufsz;
1048
1049 fcpim->snsbase.kva = bfa_meminfo_dma_virt(minfo);
1050 bfa_meminfo_dma_virt(minfo) += snsbufsz;
1051 snsinfo = fcpim->snsbase.kva;
1052 bfa_iocfc_set_snsbase(fcpim->bfa, fcpim->snsbase.pa);
1053
1054 /**
1055 * Initialize ioim free queues
1056 */
1057 INIT_LIST_HEAD(&fcpim->ioim_free_q);
1058 INIT_LIST_HEAD(&fcpim->ioim_resfree_q);
1059 INIT_LIST_HEAD(&fcpim->ioim_comp_q);
1060
1061 for (i = 0; i < fcpim->num_ioim_reqs;
1062 i++, ioim++, iosp++, snsinfo += BFI_IOIM_SNSLEN) {
1063 /*
1064 * initialize IOIM
1065 */
1066 bfa_os_memset(ioim, 0, sizeof(struct bfa_ioim_s));
1067 ioim->iotag = i;
1068 ioim->bfa = fcpim->bfa;
1069 ioim->fcpim = fcpim;
1070 ioim->iosp = iosp;
1071 iosp->snsinfo = snsinfo;
1072 INIT_LIST_HEAD(&ioim->sgpg_q);
1073 bfa_reqq_winit(&ioim->iosp->reqq_wait,
1074 bfa_ioim_qresume, ioim);
1075 bfa_sgpg_winit(&ioim->iosp->sgpg_wqe,
1076 bfa_ioim_sgpg_alloced, ioim);
1077 bfa_sm_set_state(ioim, bfa_ioim_sm_uninit);
1078
1079 list_add_tail(&ioim->qe, &fcpim->ioim_free_q);
1080 }
1081}
1082
1083/**
1084 * Driver detach time call.
1085 */
1086void
1087bfa_ioim_detach(struct bfa_fcpim_mod_s *fcpim)
1088{
1089}
1090
1091void
1092bfa_ioim_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
1093{
1094 struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
1095 struct bfi_ioim_rsp_s *rsp = (struct bfi_ioim_rsp_s *) m;
1096 struct bfa_ioim_s *ioim;
1097 u16 iotag;
1098 enum bfa_ioim_event evt = BFA_IOIM_SM_COMP;
1099
1100 iotag = bfa_os_ntohs(rsp->io_tag);
1101
1102 ioim = BFA_IOIM_FROM_TAG(fcpim, iotag);
1103 bfa_assert(ioim->iotag == iotag);
1104
1105 bfa_trc(ioim->bfa, ioim->iotag);
1106 bfa_trc(ioim->bfa, rsp->io_status);
1107 bfa_trc(ioim->bfa, rsp->reuse_io_tag);
1108
1109 if (bfa_sm_cmp_state(ioim, bfa_ioim_sm_active))
1110 bfa_os_assign(ioim->iosp->comp_rspmsg, *m);
1111
1112 switch (rsp->io_status) {
1113 case BFI_IOIM_STS_OK:
1114 bfa_fcpim_stats(fcpim, iocomp_ok);
1115 if (rsp->reuse_io_tag == 0)
1116 evt = BFA_IOIM_SM_DONE;
1117 else
1118 evt = BFA_IOIM_SM_COMP;
1119 break;
1120
1121 case BFI_IOIM_STS_TIMEDOUT:
1122 case BFI_IOIM_STS_ABORTED:
1123 rsp->io_status = BFI_IOIM_STS_ABORTED;
1124 bfa_fcpim_stats(fcpim, iocomp_aborted);
1125 if (rsp->reuse_io_tag == 0)
1126 evt = BFA_IOIM_SM_DONE;
1127 else
1128 evt = BFA_IOIM_SM_COMP;
1129 break;
1130
1131 case BFI_IOIM_STS_PROTO_ERR:
1132 bfa_fcpim_stats(fcpim, iocom_proto_err);
1133 bfa_assert(rsp->reuse_io_tag);
1134 evt = BFA_IOIM_SM_COMP;
1135 break;
1136
1137 case BFI_IOIM_STS_SQER_NEEDED:
1138 bfa_fcpim_stats(fcpim, iocom_sqer_needed);
1139 bfa_assert(rsp->reuse_io_tag == 0);
1140 evt = BFA_IOIM_SM_SQRETRY;
1141 break;
1142
1143 case BFI_IOIM_STS_RES_FREE:
1144 bfa_fcpim_stats(fcpim, iocom_res_free);
1145 evt = BFA_IOIM_SM_FREE;
1146 break;
1147
1148 case BFI_IOIM_STS_HOST_ABORTED:
1149 bfa_fcpim_stats(fcpim, iocom_hostabrts);
1150 if (rsp->abort_tag != ioim->abort_tag) {
1151 bfa_trc(ioim->bfa, rsp->abort_tag);
1152 bfa_trc(ioim->bfa, ioim->abort_tag);
1153 return;
1154 }
1155
1156 if (rsp->reuse_io_tag)
1157 evt = BFA_IOIM_SM_ABORT_COMP;
1158 else
1159 evt = BFA_IOIM_SM_ABORT_DONE;
1160 break;
1161
1162 case BFI_IOIM_STS_UTAG:
1163 bfa_fcpim_stats(fcpim, iocom_utags);
1164 evt = BFA_IOIM_SM_COMP_UTAG;
1165 break;
1166
1167 default:
1168 bfa_assert(0);
1169 }
1170
1171 bfa_sm_send_event(ioim, evt);
1172}
1173
1174void
1175bfa_ioim_good_comp_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
1176{
1177 struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
1178 struct bfi_ioim_rsp_s *rsp = (struct bfi_ioim_rsp_s *) m;
1179 struct bfa_ioim_s *ioim;
1180 u16 iotag;
1181
1182 iotag = bfa_os_ntohs(rsp->io_tag);
1183
1184 ioim = BFA_IOIM_FROM_TAG(fcpim, iotag);
1185 bfa_assert(ioim->iotag == iotag);
1186
1187 bfa_trc_fp(ioim->bfa, ioim->iotag);
1188 bfa_sm_send_event(ioim, BFA_IOIM_SM_COMP_GOOD);
1189}
1190
1191/**
1192 * Called by itnim to clean up IO while going offline.
1193 */
1194void
1195bfa_ioim_cleanup(struct bfa_ioim_s *ioim)
1196{
1197 bfa_trc(ioim->bfa, ioim->iotag);
1198 bfa_fcpim_stats(ioim->fcpim, io_cleanups);
1199
1200 ioim->iosp->tskim = NULL;
1201 bfa_sm_send_event(ioim, BFA_IOIM_SM_CLEANUP);
1202}
1203
1204void
1205bfa_ioim_cleanup_tm(struct bfa_ioim_s *ioim, struct bfa_tskim_s *tskim)
1206{
1207 bfa_trc(ioim->bfa, ioim->iotag);
1208 bfa_fcpim_stats(ioim->fcpim, io_tmaborts);
1209
1210 ioim->iosp->tskim = tskim;
1211 bfa_sm_send_event(ioim, BFA_IOIM_SM_CLEANUP);
1212}
1213
1214/**
1215 * IOC failure handling.
1216 */
1217void
1218bfa_ioim_iocdisable(struct bfa_ioim_s *ioim)
1219{
1220 bfa_sm_send_event(ioim, BFA_IOIM_SM_HWFAIL);
1221}
1222
1223/**
1224 * IO offline TOV popped. Fail the pending IO.
1225 */
1226void
1227bfa_ioim_tov(struct bfa_ioim_s *ioim)
1228{
1229 bfa_sm_send_event(ioim, BFA_IOIM_SM_IOTOV);
1230}
1231
1232
1233
1234/**
1235 * bfa_ioim_api
1236 */
1237
1238/**
1239 * Allocate IOIM resource for initiator mode I/O request.
1240 */
1241struct bfa_ioim_s *
1242bfa_ioim_alloc(struct bfa_s *bfa, struct bfad_ioim_s *dio,
1243 struct bfa_itnim_s *itnim, u16 nsges)
1244{
1245 struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
1246 struct bfa_ioim_s *ioim;
1247
1248 /**
1249 * alocate IOIM resource
1250 */
1251 bfa_q_deq(&fcpim->ioim_free_q, &ioim);
1252 if (!ioim) {
1253 bfa_fcpim_stats(fcpim, no_iotags);
1254 return NULL;
1255 }
1256
1257 ioim->dio = dio;
1258 ioim->itnim = itnim;
1259 ioim->nsges = nsges;
1260 ioim->nsgpgs = 0;
1261
1262 bfa_stats(fcpim, total_ios);
1263 bfa_stats(itnim, ios);
1264 fcpim->ios_active++;
1265
1266 list_add_tail(&ioim->qe, &itnim->io_q);
1267 bfa_trc_fp(ioim->bfa, ioim->iotag);
1268
1269 return ioim;
1270}
1271
1272void
1273bfa_ioim_free(struct bfa_ioim_s *ioim)
1274{
1275 struct bfa_fcpim_mod_s *fcpim = ioim->fcpim;
1276
1277 bfa_trc_fp(ioim->bfa, ioim->iotag);
1278 bfa_assert_fp(bfa_sm_cmp_state(ioim, bfa_ioim_sm_uninit));
1279
1280 bfa_assert_fp(list_empty(&ioim->sgpg_q)
1281 || (ioim->nsges > BFI_SGE_INLINE));
1282
1283 if (ioim->nsgpgs > 0)
1284 bfa_sgpg_mfree(ioim->bfa, &ioim->sgpg_q, ioim->nsgpgs);
1285
1286 bfa_stats(ioim->itnim, io_comps);
1287 fcpim->ios_active--;
1288
1289 list_del(&ioim->qe);
1290 list_add_tail(&ioim->qe, &fcpim->ioim_free_q);
1291}
1292
1293void
1294bfa_ioim_start(struct bfa_ioim_s *ioim)
1295{
1296 bfa_trc_fp(ioim->bfa, ioim->iotag);
1297 bfa_sm_send_event(ioim, BFA_IOIM_SM_START);
1298}
1299
1300/**
1301 * Driver I/O abort request.
1302 */
1303void
1304bfa_ioim_abort(struct bfa_ioim_s *ioim)
1305{
1306 bfa_trc(ioim->bfa, ioim->iotag);
1307 bfa_fcpim_stats(ioim->fcpim, io_aborts);
1308 bfa_sm_send_event(ioim, BFA_IOIM_SM_ABORT);
1309}
1310
1311
diff --git a/drivers/scsi/bfa/bfa_itnim.c b/drivers/scsi/bfa/bfa_itnim.c
new file mode 100644
index 000000000000..4d5c61a4f85c
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_itnim.c
@@ -0,0 +1,1088 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#include <bfa.h>
19#include <bfa_fcpim.h>
20#include "bfa_fcpim_priv.h"
21
22BFA_TRC_FILE(HAL, ITNIM);
23
24#define BFA_ITNIM_FROM_TAG(_fcpim, _tag) \
25 ((_fcpim)->itnim_arr + ((_tag) & ((_fcpim)->num_itnims - 1)))
26
27#define bfa_fcpim_additn(__itnim) \
28 list_add_tail(&(__itnim)->qe, &(__itnim)->fcpim->itnim_q)
29#define bfa_fcpim_delitn(__itnim) do { \
30 bfa_assert(bfa_q_is_on_q(&(__itnim)->fcpim->itnim_q, __itnim)); \
31 list_del(&(__itnim)->qe); \
32 bfa_assert(list_empty(&(__itnim)->io_q)); \
33 bfa_assert(list_empty(&(__itnim)->io_cleanup_q)); \
34 bfa_assert(list_empty(&(__itnim)->pending_q)); \
35} while (0)
36
37#define bfa_itnim_online_cb(__itnim) do { \
38 if ((__itnim)->bfa->fcs) \
39 bfa_cb_itnim_online((__itnim)->ditn); \
40 else { \
41 bfa_cb_queue((__itnim)->bfa, &(__itnim)->hcb_qe, \
42 __bfa_cb_itnim_online, (__itnim)); \
43 } \
44} while (0)
45
46#define bfa_itnim_offline_cb(__itnim) do { \
47 if ((__itnim)->bfa->fcs) \
48 bfa_cb_itnim_offline((__itnim)->ditn); \
49 else { \
50 bfa_cb_queue((__itnim)->bfa, &(__itnim)->hcb_qe, \
51 __bfa_cb_itnim_offline, (__itnim)); \
52 } \
53} while (0)
54
55#define bfa_itnim_sler_cb(__itnim) do { \
56 if ((__itnim)->bfa->fcs) \
57 bfa_cb_itnim_sler((__itnim)->ditn); \
58 else { \
59 bfa_cb_queue((__itnim)->bfa, &(__itnim)->hcb_qe, \
60 __bfa_cb_itnim_sler, (__itnim)); \
61 } \
62} while (0)
63
64/*
65 * forward declarations
66 */
67static void bfa_itnim_iocdisable_cleanup(struct bfa_itnim_s *itnim);
68static bfa_boolean_t bfa_itnim_send_fwcreate(struct bfa_itnim_s *itnim);
69static bfa_boolean_t bfa_itnim_send_fwdelete(struct bfa_itnim_s *itnim);
70static void bfa_itnim_cleanp_comp(void *itnim_cbarg);
71static void bfa_itnim_cleanup(struct bfa_itnim_s *itnim);
72static void __bfa_cb_itnim_online(void *cbarg, bfa_boolean_t complete);
73static void __bfa_cb_itnim_offline(void *cbarg, bfa_boolean_t complete);
74static void __bfa_cb_itnim_sler(void *cbarg, bfa_boolean_t complete);
75static void bfa_itnim_iotov_online(struct bfa_itnim_s *itnim);
76static void bfa_itnim_iotov_cleanup(struct bfa_itnim_s *itnim);
77static void bfa_itnim_iotov(void *itnim_arg);
78static void bfa_itnim_iotov_start(struct bfa_itnim_s *itnim);
79static void bfa_itnim_iotov_stop(struct bfa_itnim_s *itnim);
80static void bfa_itnim_iotov_delete(struct bfa_itnim_s *itnim);
81
82/**
83 * bfa_itnim_sm BFA itnim state machine
84 */
85
86
87enum bfa_itnim_event {
88 BFA_ITNIM_SM_CREATE = 1, /* itnim is created */
89 BFA_ITNIM_SM_ONLINE = 2, /* itnim is online */
90 BFA_ITNIM_SM_OFFLINE = 3, /* itnim is offline */
91 BFA_ITNIM_SM_FWRSP = 4, /* firmware response */
92 BFA_ITNIM_SM_DELETE = 5, /* deleting an existing itnim */
93 BFA_ITNIM_SM_CLEANUP = 6, /* IO cleanup completion */
94 BFA_ITNIM_SM_SLER = 7, /* second level error recovery */
95 BFA_ITNIM_SM_HWFAIL = 8, /* IOC h/w failure event */
96 BFA_ITNIM_SM_QRESUME = 9, /* queue space available */
97};
98
99static void bfa_itnim_sm_uninit(struct bfa_itnim_s *itnim,
100 enum bfa_itnim_event event);
101static void bfa_itnim_sm_created(struct bfa_itnim_s *itnim,
102 enum bfa_itnim_event event);
103static void bfa_itnim_sm_fwcreate(struct bfa_itnim_s *itnim,
104 enum bfa_itnim_event event);
105static void bfa_itnim_sm_delete_pending(struct bfa_itnim_s *itnim,
106 enum bfa_itnim_event event);
107static void bfa_itnim_sm_online(struct bfa_itnim_s *itnim,
108 enum bfa_itnim_event event);
109static void bfa_itnim_sm_sler(struct bfa_itnim_s *itnim,
110 enum bfa_itnim_event event);
111static void bfa_itnim_sm_cleanup_offline(struct bfa_itnim_s *itnim,
112 enum bfa_itnim_event event);
113static void bfa_itnim_sm_cleanup_delete(struct bfa_itnim_s *itnim,
114 enum bfa_itnim_event event);
115static void bfa_itnim_sm_fwdelete(struct bfa_itnim_s *itnim,
116 enum bfa_itnim_event event);
117static void bfa_itnim_sm_offline(struct bfa_itnim_s *itnim,
118 enum bfa_itnim_event event);
119static void bfa_itnim_sm_iocdisable(struct bfa_itnim_s *itnim,
120 enum bfa_itnim_event event);
121static void bfa_itnim_sm_deleting(struct bfa_itnim_s *itnim,
122 enum bfa_itnim_event event);
123static void bfa_itnim_sm_fwcreate_qfull(struct bfa_itnim_s *itnim,
124 enum bfa_itnim_event event);
125static void bfa_itnim_sm_fwdelete_qfull(struct bfa_itnim_s *itnim,
126 enum bfa_itnim_event event);
127static void bfa_itnim_sm_deleting_qfull(struct bfa_itnim_s *itnim,
128 enum bfa_itnim_event event);
129
130/**
131 * Beginning/unallocated state - no events expected.
132 */
133static void
134bfa_itnim_sm_uninit(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
135{
136 bfa_trc(itnim->bfa, itnim->rport->rport_tag);
137 bfa_trc(itnim->bfa, event);
138
139 switch (event) {
140 case BFA_ITNIM_SM_CREATE:
141 bfa_sm_set_state(itnim, bfa_itnim_sm_created);
142 itnim->is_online = BFA_FALSE;
143 bfa_fcpim_additn(itnim);
144 break;
145
146 default:
147 bfa_assert(0);
148 }
149}
150
151/**
152 * Beginning state, only online event expected.
153 */
154static void
155bfa_itnim_sm_created(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
156{
157 bfa_trc(itnim->bfa, itnim->rport->rport_tag);
158 bfa_trc(itnim->bfa, event);
159
160 switch (event) {
161 case BFA_ITNIM_SM_ONLINE:
162 if (bfa_itnim_send_fwcreate(itnim))
163 bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate);
164 else
165 bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate_qfull);
166 break;
167
168 case BFA_ITNIM_SM_DELETE:
169 bfa_sm_set_state(itnim, bfa_itnim_sm_uninit);
170 bfa_fcpim_delitn(itnim);
171 break;
172
173 case BFA_ITNIM_SM_HWFAIL:
174 bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
175 break;
176
177 default:
178 bfa_assert(0);
179 }
180}
181
182/**
183 * Waiting for itnim create response from firmware.
184 */
185static void
186bfa_itnim_sm_fwcreate(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
187{
188 bfa_trc(itnim->bfa, itnim->rport->rport_tag);
189 bfa_trc(itnim->bfa, event);
190
191 switch (event) {
192 case BFA_ITNIM_SM_FWRSP:
193 bfa_sm_set_state(itnim, bfa_itnim_sm_online);
194 itnim->is_online = BFA_TRUE;
195 bfa_itnim_iotov_online(itnim);
196 bfa_itnim_online_cb(itnim);
197 break;
198
199 case BFA_ITNIM_SM_DELETE:
200 bfa_sm_set_state(itnim, bfa_itnim_sm_delete_pending);
201 break;
202
203 case BFA_ITNIM_SM_OFFLINE:
204 if (bfa_itnim_send_fwdelete(itnim))
205 bfa_sm_set_state(itnim, bfa_itnim_sm_fwdelete);
206 else
207 bfa_sm_set_state(itnim, bfa_itnim_sm_fwdelete_qfull);
208 break;
209
210 case BFA_ITNIM_SM_HWFAIL:
211 bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
212 break;
213
214 default:
215 bfa_assert(0);
216 }
217}
218
219static void
220bfa_itnim_sm_fwcreate_qfull(struct bfa_itnim_s *itnim,
221 enum bfa_itnim_event event)
222{
223 bfa_trc(itnim->bfa, itnim->rport->rport_tag);
224 bfa_trc(itnim->bfa, event);
225
226 switch (event) {
227 case BFA_ITNIM_SM_QRESUME:
228 bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate);
229 bfa_itnim_send_fwcreate(itnim);
230 break;
231
232 case BFA_ITNIM_SM_DELETE:
233 bfa_sm_set_state(itnim, bfa_itnim_sm_uninit);
234 bfa_reqq_wcancel(&itnim->reqq_wait);
235 bfa_fcpim_delitn(itnim);
236 break;
237
238 case BFA_ITNIM_SM_OFFLINE:
239 bfa_sm_set_state(itnim, bfa_itnim_sm_offline);
240 bfa_reqq_wcancel(&itnim->reqq_wait);
241 bfa_itnim_offline_cb(itnim);
242 break;
243
244 case BFA_ITNIM_SM_HWFAIL:
245 bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
246 bfa_reqq_wcancel(&itnim->reqq_wait);
247 break;
248
249 default:
250 bfa_assert(0);
251 }
252}
253
254/**
255 * Waiting for itnim create response from firmware, a delete is pending.
256 */
257static void
258bfa_itnim_sm_delete_pending(struct bfa_itnim_s *itnim,
259 enum bfa_itnim_event event)
260{
261 bfa_trc(itnim->bfa, itnim->rport->rport_tag);
262 bfa_trc(itnim->bfa, event);
263
264 switch (event) {
265 case BFA_ITNIM_SM_FWRSP:
266 if (bfa_itnim_send_fwdelete(itnim))
267 bfa_sm_set_state(itnim, bfa_itnim_sm_deleting);
268 else
269 bfa_sm_set_state(itnim, bfa_itnim_sm_deleting_qfull);
270 break;
271
272 case BFA_ITNIM_SM_HWFAIL:
273 bfa_sm_set_state(itnim, bfa_itnim_sm_uninit);
274 bfa_fcpim_delitn(itnim);
275 break;
276
277 default:
278 bfa_assert(0);
279 }
280}
281
282/**
283 * Online state - normal parking state.
284 */
285static void
286bfa_itnim_sm_online(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
287{
288 bfa_trc(itnim->bfa, itnim->rport->rport_tag);
289 bfa_trc(itnim->bfa, event);
290
291 switch (event) {
292 case BFA_ITNIM_SM_OFFLINE:
293 bfa_sm_set_state(itnim, bfa_itnim_sm_cleanup_offline);
294 itnim->is_online = BFA_FALSE;
295 bfa_itnim_iotov_start(itnim);
296 bfa_itnim_cleanup(itnim);
297 break;
298
299 case BFA_ITNIM_SM_DELETE:
300 bfa_sm_set_state(itnim, bfa_itnim_sm_cleanup_delete);
301 itnim->is_online = BFA_FALSE;
302 bfa_itnim_cleanup(itnim);
303 break;
304
305 case BFA_ITNIM_SM_SLER:
306 bfa_sm_set_state(itnim, bfa_itnim_sm_sler);
307 itnim->is_online = BFA_FALSE;
308 bfa_itnim_iotov_start(itnim);
309 bfa_itnim_sler_cb(itnim);
310 break;
311
312 case BFA_ITNIM_SM_HWFAIL:
313 bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
314 itnim->is_online = BFA_FALSE;
315 bfa_itnim_iotov_start(itnim);
316 bfa_itnim_iocdisable_cleanup(itnim);
317 break;
318
319 default:
320 bfa_assert(0);
321 }
322}
323
324/**
325 * Second level error recovery need.
326 */
327static void
328bfa_itnim_sm_sler(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
329{
330 bfa_trc(itnim->bfa, itnim->rport->rport_tag);
331 bfa_trc(itnim->bfa, event);
332
333 switch (event) {
334 case BFA_ITNIM_SM_OFFLINE:
335 bfa_sm_set_state(itnim, bfa_itnim_sm_cleanup_offline);
336 bfa_itnim_cleanup(itnim);
337 break;
338
339 case BFA_ITNIM_SM_DELETE:
340 bfa_sm_set_state(itnim, bfa_itnim_sm_cleanup_delete);
341 bfa_itnim_cleanup(itnim);
342 bfa_itnim_iotov_delete(itnim);
343 break;
344
345 case BFA_ITNIM_SM_HWFAIL:
346 bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
347 bfa_itnim_iocdisable_cleanup(itnim);
348 break;
349
350 default:
351 bfa_assert(0);
352 }
353}
354
355/**
356 * Going offline. Waiting for active IO cleanup.
357 */
358static void
359bfa_itnim_sm_cleanup_offline(struct bfa_itnim_s *itnim,
360 enum bfa_itnim_event event)
361{
362 bfa_trc(itnim->bfa, itnim->rport->rport_tag);
363 bfa_trc(itnim->bfa, event);
364
365 switch (event) {
366 case BFA_ITNIM_SM_CLEANUP:
367 if (bfa_itnim_send_fwdelete(itnim))
368 bfa_sm_set_state(itnim, bfa_itnim_sm_fwdelete);
369 else
370 bfa_sm_set_state(itnim, bfa_itnim_sm_fwdelete_qfull);
371 break;
372
373 case BFA_ITNIM_SM_DELETE:
374 bfa_sm_set_state(itnim, bfa_itnim_sm_cleanup_delete);
375 bfa_itnim_iotov_delete(itnim);
376 break;
377
378 case BFA_ITNIM_SM_HWFAIL:
379 bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
380 bfa_itnim_iocdisable_cleanup(itnim);
381 bfa_itnim_offline_cb(itnim);
382 break;
383
384 case BFA_ITNIM_SM_SLER:
385 break;
386
387 default:
388 bfa_assert(0);
389 }
390}
391
392/**
393 * Deleting itnim. Waiting for active IO cleanup.
394 */
395static void
396bfa_itnim_sm_cleanup_delete(struct bfa_itnim_s *itnim,
397 enum bfa_itnim_event event)
398{
399 bfa_trc(itnim->bfa, itnim->rport->rport_tag);
400 bfa_trc(itnim->bfa, event);
401
402 switch (event) {
403 case BFA_ITNIM_SM_CLEANUP:
404 if (bfa_itnim_send_fwdelete(itnim))
405 bfa_sm_set_state(itnim, bfa_itnim_sm_deleting);
406 else
407 bfa_sm_set_state(itnim, bfa_itnim_sm_deleting_qfull);
408 break;
409
410 case BFA_ITNIM_SM_HWFAIL:
411 bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
412 bfa_itnim_iocdisable_cleanup(itnim);
413 break;
414
415 default:
416 bfa_assert(0);
417 }
418}
419
420/**
421 * Rport offline. Fimrware itnim is being deleted - awaiting f/w response.
422 */
423static void
424bfa_itnim_sm_fwdelete(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
425{
426 bfa_trc(itnim->bfa, itnim->rport->rport_tag);
427 bfa_trc(itnim->bfa, event);
428
429 switch (event) {
430 case BFA_ITNIM_SM_FWRSP:
431 bfa_sm_set_state(itnim, bfa_itnim_sm_offline);
432 bfa_itnim_offline_cb(itnim);
433 break;
434
435 case BFA_ITNIM_SM_DELETE:
436 bfa_sm_set_state(itnim, bfa_itnim_sm_deleting);
437 break;
438
439 case BFA_ITNIM_SM_HWFAIL:
440 bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
441 bfa_itnim_offline_cb(itnim);
442 break;
443
444 default:
445 bfa_assert(0);
446 }
447}
448
449static void
450bfa_itnim_sm_fwdelete_qfull(struct bfa_itnim_s *itnim,
451 enum bfa_itnim_event event)
452{
453 bfa_trc(itnim->bfa, itnim->rport->rport_tag);
454 bfa_trc(itnim->bfa, event);
455
456 switch (event) {
457 case BFA_ITNIM_SM_QRESUME:
458 bfa_sm_set_state(itnim, bfa_itnim_sm_fwdelete);
459 bfa_itnim_send_fwdelete(itnim);
460 break;
461
462 case BFA_ITNIM_SM_DELETE:
463 bfa_sm_set_state(itnim, bfa_itnim_sm_deleting_qfull);
464 break;
465
466 case BFA_ITNIM_SM_HWFAIL:
467 bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
468 bfa_reqq_wcancel(&itnim->reqq_wait);
469 bfa_itnim_offline_cb(itnim);
470 break;
471
472 default:
473 bfa_assert(0);
474 }
475}
476
477/**
478 * Offline state.
479 */
480static void
481bfa_itnim_sm_offline(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
482{
483 bfa_trc(itnim->bfa, itnim->rport->rport_tag);
484 bfa_trc(itnim->bfa, event);
485
486 switch (event) {
487 case BFA_ITNIM_SM_DELETE:
488 bfa_sm_set_state(itnim, bfa_itnim_sm_uninit);
489 bfa_itnim_iotov_delete(itnim);
490 bfa_fcpim_delitn(itnim);
491 break;
492
493 case BFA_ITNIM_SM_ONLINE:
494 if (bfa_itnim_send_fwcreate(itnim))
495 bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate);
496 else
497 bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate_qfull);
498 break;
499
500 case BFA_ITNIM_SM_HWFAIL:
501 bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable);
502 break;
503
504 default:
505 bfa_assert(0);
506 }
507}
508
509/**
510 * IOC h/w failed state.
511 */
512static void
513bfa_itnim_sm_iocdisable(struct bfa_itnim_s *itnim,
514 enum bfa_itnim_event event)
515{
516 bfa_trc(itnim->bfa, itnim->rport->rport_tag);
517 bfa_trc(itnim->bfa, event);
518
519 switch (event) {
520 case BFA_ITNIM_SM_DELETE:
521 bfa_sm_set_state(itnim, bfa_itnim_sm_uninit);
522 bfa_itnim_iotov_delete(itnim);
523 bfa_fcpim_delitn(itnim);
524 break;
525
526 case BFA_ITNIM_SM_OFFLINE:
527 bfa_itnim_offline_cb(itnim);
528 break;
529
530 case BFA_ITNIM_SM_ONLINE:
531 if (bfa_itnim_send_fwcreate(itnim))
532 bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate);
533 else
534 bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate_qfull);
535 break;
536
537 case BFA_ITNIM_SM_HWFAIL:
538 break;
539
540 default:
541 bfa_assert(0);
542 }
543}
544
545/**
546 * Itnim is deleted, waiting for firmware response to delete.
547 */
548static void
549bfa_itnim_sm_deleting(struct bfa_itnim_s *itnim, enum bfa_itnim_event event)
550{
551 bfa_trc(itnim->bfa, itnim->rport->rport_tag);
552 bfa_trc(itnim->bfa, event);
553
554 switch (event) {
555 case BFA_ITNIM_SM_FWRSP:
556 case BFA_ITNIM_SM_HWFAIL:
557 bfa_sm_set_state(itnim, bfa_itnim_sm_uninit);
558 bfa_fcpim_delitn(itnim);
559 break;
560
561 default:
562 bfa_assert(0);
563 }
564}
565
566static void
567bfa_itnim_sm_deleting_qfull(struct bfa_itnim_s *itnim,
568 enum bfa_itnim_event event)
569{
570 bfa_trc(itnim->bfa, itnim->rport->rport_tag);
571 bfa_trc(itnim->bfa, event);
572
573 switch (event) {
574 case BFA_ITNIM_SM_QRESUME:
575 bfa_sm_set_state(itnim, bfa_itnim_sm_deleting);
576 bfa_itnim_send_fwdelete(itnim);
577 break;
578
579 case BFA_ITNIM_SM_HWFAIL:
580 bfa_sm_set_state(itnim, bfa_itnim_sm_uninit);
581 bfa_reqq_wcancel(&itnim->reqq_wait);
582 bfa_fcpim_delitn(itnim);
583 break;
584
585 default:
586 bfa_assert(0);
587 }
588}
589
590
591
592/**
593 * bfa_itnim_private
594 */
595
596/**
597 * Initiate cleanup of all IOs on an IOC failure.
598 */
599static void
600bfa_itnim_iocdisable_cleanup(struct bfa_itnim_s *itnim)
601{
602 struct bfa_tskim_s *tskim;
603 struct bfa_ioim_s *ioim;
604 struct list_head *qe, *qen;
605
606 list_for_each_safe(qe, qen, &itnim->tsk_q) {
607 tskim = (struct bfa_tskim_s *) qe;
608 bfa_tskim_iocdisable(tskim);
609 }
610
611 list_for_each_safe(qe, qen, &itnim->io_q) {
612 ioim = (struct bfa_ioim_s *) qe;
613 bfa_ioim_iocdisable(ioim);
614 }
615
616 /**
617 * For IO request in pending queue, we pretend an early timeout.
618 */
619 list_for_each_safe(qe, qen, &itnim->pending_q) {
620 ioim = (struct bfa_ioim_s *) qe;
621 bfa_ioim_tov(ioim);
622 }
623
624 list_for_each_safe(qe, qen, &itnim->io_cleanup_q) {
625 ioim = (struct bfa_ioim_s *) qe;
626 bfa_ioim_iocdisable(ioim);
627 }
628}
629
630/**
631 * IO cleanup completion
632 */
633static void
634bfa_itnim_cleanp_comp(void *itnim_cbarg)
635{
636 struct bfa_itnim_s *itnim = itnim_cbarg;
637
638 bfa_stats(itnim, cleanup_comps);
639 bfa_sm_send_event(itnim, BFA_ITNIM_SM_CLEANUP);
640}
641
642/**
643 * Initiate cleanup of all IOs.
644 */
645static void
646bfa_itnim_cleanup(struct bfa_itnim_s *itnim)
647{
648 struct bfa_ioim_s *ioim;
649 struct bfa_tskim_s *tskim;
650 struct list_head *qe, *qen;
651
652 bfa_wc_init(&itnim->wc, bfa_itnim_cleanp_comp, itnim);
653
654 list_for_each_safe(qe, qen, &itnim->io_q) {
655 ioim = (struct bfa_ioim_s *) qe;
656
657 /**
658 * Move IO to a cleanup queue from active queue so that a later
659 * TM will not pickup this IO.
660 */
661 list_del(&ioim->qe);
662 list_add_tail(&ioim->qe, &itnim->io_cleanup_q);
663
664 bfa_wc_up(&itnim->wc);
665 bfa_ioim_cleanup(ioim);
666 }
667
668 list_for_each_safe(qe, qen, &itnim->tsk_q) {
669 tskim = (struct bfa_tskim_s *) qe;
670 bfa_wc_up(&itnim->wc);
671 bfa_tskim_cleanup(tskim);
672 }
673
674 bfa_wc_wait(&itnim->wc);
675}
676
677static void
678__bfa_cb_itnim_online(void *cbarg, bfa_boolean_t complete)
679{
680 struct bfa_itnim_s *itnim = cbarg;
681
682 if (complete)
683 bfa_cb_itnim_online(itnim->ditn);
684}
685
686static void
687__bfa_cb_itnim_offline(void *cbarg, bfa_boolean_t complete)
688{
689 struct bfa_itnim_s *itnim = cbarg;
690
691 if (complete)
692 bfa_cb_itnim_offline(itnim->ditn);
693}
694
695static void
696__bfa_cb_itnim_sler(void *cbarg, bfa_boolean_t complete)
697{
698 struct bfa_itnim_s *itnim = cbarg;
699
700 if (complete)
701 bfa_cb_itnim_sler(itnim->ditn);
702}
703
704/**
705 * Call to resume any I/O requests waiting for room in request queue.
706 */
707static void
708bfa_itnim_qresume(void *cbarg)
709{
710 struct bfa_itnim_s *itnim = cbarg;
711
712 bfa_sm_send_event(itnim, BFA_ITNIM_SM_QRESUME);
713}
714
715
716
717
718/**
719 * bfa_itnim_public
720 */
721
722void
723bfa_itnim_iodone(struct bfa_itnim_s *itnim)
724{
725 bfa_wc_down(&itnim->wc);
726}
727
728void
729bfa_itnim_tskdone(struct bfa_itnim_s *itnim)
730{
731 bfa_wc_down(&itnim->wc);
732}
733
734void
735bfa_itnim_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len,
736 u32 *dm_len)
737{
738 /**
739 * ITN memory
740 */
741 *km_len += cfg->fwcfg.num_rports * sizeof(struct bfa_itnim_s);
742}
743
744void
745bfa_itnim_attach(struct bfa_fcpim_mod_s *fcpim, struct bfa_meminfo_s *minfo)
746{
747 struct bfa_s *bfa = fcpim->bfa;
748 struct bfa_itnim_s *itnim;
749 int i;
750
751 INIT_LIST_HEAD(&fcpim->itnim_q);
752
753 itnim = (struct bfa_itnim_s *) bfa_meminfo_kva(minfo);
754 fcpim->itnim_arr = itnim;
755
756 for (i = 0; i < fcpim->num_itnims; i++, itnim++) {
757 bfa_os_memset(itnim, 0, sizeof(struct bfa_itnim_s));
758 itnim->bfa = bfa;
759 itnim->fcpim = fcpim;
760 itnim->reqq = BFA_REQQ_QOS_LO;
761 itnim->rport = BFA_RPORT_FROM_TAG(bfa, i);
762 itnim->iotov_active = BFA_FALSE;
763 bfa_reqq_winit(&itnim->reqq_wait, bfa_itnim_qresume, itnim);
764
765 INIT_LIST_HEAD(&itnim->io_q);
766 INIT_LIST_HEAD(&itnim->io_cleanup_q);
767 INIT_LIST_HEAD(&itnim->pending_q);
768 INIT_LIST_HEAD(&itnim->tsk_q);
769 INIT_LIST_HEAD(&itnim->delay_comp_q);
770 bfa_sm_set_state(itnim, bfa_itnim_sm_uninit);
771 }
772
773 bfa_meminfo_kva(minfo) = (u8 *) itnim;
774}
775
776void
777bfa_itnim_iocdisable(struct bfa_itnim_s *itnim)
778{
779 bfa_stats(itnim, ioc_disabled);
780 bfa_sm_send_event(itnim, BFA_ITNIM_SM_HWFAIL);
781}
782
783static bfa_boolean_t
784bfa_itnim_send_fwcreate(struct bfa_itnim_s *itnim)
785{
786 struct bfi_itnim_create_req_s *m;
787
788 itnim->msg_no++;
789
790 /**
791 * check for room in queue to send request now
792 */
793 m = bfa_reqq_next(itnim->bfa, itnim->reqq);
794 if (!m) {
795 bfa_reqq_wait(itnim->bfa, itnim->reqq, &itnim->reqq_wait);
796 return BFA_FALSE;
797 }
798
799 bfi_h2i_set(m->mh, BFI_MC_ITNIM, BFI_ITNIM_H2I_CREATE_REQ,
800 bfa_lpuid(itnim->bfa));
801 m->fw_handle = itnim->rport->fw_handle;
802 m->class = FC_CLASS_3;
803 m->seq_rec = itnim->seq_rec;
804 m->msg_no = itnim->msg_no;
805
806 /**
807 * queue I/O message to firmware
808 */
809 bfa_reqq_produce(itnim->bfa, itnim->reqq);
810 return BFA_TRUE;
811}
812
813static bfa_boolean_t
814bfa_itnim_send_fwdelete(struct bfa_itnim_s *itnim)
815{
816 struct bfi_itnim_delete_req_s *m;
817
818 /**
819 * check for room in queue to send request now
820 */
821 m = bfa_reqq_next(itnim->bfa, itnim->reqq);
822 if (!m) {
823 bfa_reqq_wait(itnim->bfa, itnim->reqq, &itnim->reqq_wait);
824 return BFA_FALSE;
825 }
826
827 bfi_h2i_set(m->mh, BFI_MC_ITNIM, BFI_ITNIM_H2I_DELETE_REQ,
828 bfa_lpuid(itnim->bfa));
829 m->fw_handle = itnim->rport->fw_handle;
830
831 /**
832 * queue I/O message to firmware
833 */
834 bfa_reqq_produce(itnim->bfa, itnim->reqq);
835 return BFA_TRUE;
836}
837
838/**
839 * Cleanup all pending failed inflight requests.
840 */
841static void
842bfa_itnim_delayed_comp(struct bfa_itnim_s *itnim, bfa_boolean_t iotov)
843{
844 struct bfa_ioim_s *ioim;
845 struct list_head *qe, *qen;
846
847 list_for_each_safe(qe, qen, &itnim->delay_comp_q) {
848 ioim = (struct bfa_ioim_s *)qe;
849 bfa_ioim_delayed_comp(ioim, iotov);
850 }
851}
852
853/**
854 * Start all pending IO requests.
855 */
856static void
857bfa_itnim_iotov_online(struct bfa_itnim_s *itnim)
858{
859 struct bfa_ioim_s *ioim;
860
861 bfa_itnim_iotov_stop(itnim);
862
863 /**
864 * Abort all inflight IO requests in the queue
865 */
866 bfa_itnim_delayed_comp(itnim, BFA_FALSE);
867
868 /**
869 * Start all pending IO requests.
870 */
871 while (!list_empty(&itnim->pending_q)) {
872 bfa_q_deq(&itnim->pending_q, &ioim);
873 list_add_tail(&ioim->qe, &itnim->io_q);
874 bfa_ioim_start(ioim);
875 }
876}
877
878/**
879 * Fail all pending IO requests
880 */
881static void
882bfa_itnim_iotov_cleanup(struct bfa_itnim_s *itnim)
883{
884 struct bfa_ioim_s *ioim;
885
886 /**
887 * Fail all inflight IO requests in the queue
888 */
889 bfa_itnim_delayed_comp(itnim, BFA_TRUE);
890
891 /**
892 * Fail any pending IO requests.
893 */
894 while (!list_empty(&itnim->pending_q)) {
895 bfa_q_deq(&itnim->pending_q, &ioim);
896 list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
897 bfa_ioim_tov(ioim);
898 }
899}
900
901/**
902 * IO TOV timer callback. Fail any pending IO requests.
903 */
904static void
905bfa_itnim_iotov(void *itnim_arg)
906{
907 struct bfa_itnim_s *itnim = itnim_arg;
908
909 itnim->iotov_active = BFA_FALSE;
910
911 bfa_cb_itnim_tov_begin(itnim->ditn);
912 bfa_itnim_iotov_cleanup(itnim);
913 bfa_cb_itnim_tov(itnim->ditn);
914}
915
916/**
917 * Start IO TOV timer for failing back pending IO requests in offline state.
918 */
919static void
920bfa_itnim_iotov_start(struct bfa_itnim_s *itnim)
921{
922 if (itnim->fcpim->path_tov > 0) {
923
924 itnim->iotov_active = BFA_TRUE;
925 bfa_assert(bfa_itnim_hold_io(itnim));
926 bfa_timer_start(itnim->bfa, &itnim->timer,
927 bfa_itnim_iotov, itnim, itnim->fcpim->path_tov);
928 }
929}
930
931/**
932 * Stop IO TOV timer.
933 */
934static void
935bfa_itnim_iotov_stop(struct bfa_itnim_s *itnim)
936{
937 if (itnim->iotov_active) {
938 itnim->iotov_active = BFA_FALSE;
939 bfa_timer_stop(&itnim->timer);
940 }
941}
942
943/**
944 * Stop IO TOV timer.
945 */
946static void
947bfa_itnim_iotov_delete(struct bfa_itnim_s *itnim)
948{
949 bfa_boolean_t pathtov_active = BFA_FALSE;
950
951 if (itnim->iotov_active)
952 pathtov_active = BFA_TRUE;
953
954 bfa_itnim_iotov_stop(itnim);
955 if (pathtov_active)
956 bfa_cb_itnim_tov_begin(itnim->ditn);
957 bfa_itnim_iotov_cleanup(itnim);
958 if (pathtov_active)
959 bfa_cb_itnim_tov(itnim->ditn);
960}
961
962
963
964/**
965 * bfa_itnim_public
966 */
967
968/**
969 * Itnim interrupt processing.
970 */
971void
972bfa_itnim_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
973{
974 struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
975 union bfi_itnim_i2h_msg_u msg;
976 struct bfa_itnim_s *itnim;
977
978 bfa_trc(bfa, m->mhdr.msg_id);
979
980 msg.msg = m;
981
982 switch (m->mhdr.msg_id) {
983 case BFI_ITNIM_I2H_CREATE_RSP:
984 itnim = BFA_ITNIM_FROM_TAG(fcpim,
985 msg.create_rsp->bfa_handle);
986 bfa_assert(msg.create_rsp->status == BFA_STATUS_OK);
987 bfa_stats(itnim, create_comps);
988 bfa_sm_send_event(itnim, BFA_ITNIM_SM_FWRSP);
989 break;
990
991 case BFI_ITNIM_I2H_DELETE_RSP:
992 itnim = BFA_ITNIM_FROM_TAG(fcpim,
993 msg.delete_rsp->bfa_handle);
994 bfa_assert(msg.delete_rsp->status == BFA_STATUS_OK);
995 bfa_stats(itnim, delete_comps);
996 bfa_sm_send_event(itnim, BFA_ITNIM_SM_FWRSP);
997 break;
998
999 case BFI_ITNIM_I2H_SLER_EVENT:
1000 itnim = BFA_ITNIM_FROM_TAG(fcpim,
1001 msg.sler_event->bfa_handle);
1002 bfa_stats(itnim, sler_events);
1003 bfa_sm_send_event(itnim, BFA_ITNIM_SM_SLER);
1004 break;
1005
1006 default:
1007 bfa_trc(bfa, m->mhdr.msg_id);
1008 bfa_assert(0);
1009 }
1010}
1011
1012
1013
1014/**
1015 * bfa_itnim_api
1016 */
1017
1018struct bfa_itnim_s *
1019bfa_itnim_create(struct bfa_s *bfa, struct bfa_rport_s *rport, void *ditn)
1020{
1021 struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
1022 struct bfa_itnim_s *itnim;
1023
1024 itnim = BFA_ITNIM_FROM_TAG(fcpim, rport->rport_tag);
1025 bfa_assert(itnim->rport == rport);
1026
1027 itnim->ditn = ditn;
1028
1029 bfa_stats(itnim, creates);
1030 bfa_sm_send_event(itnim, BFA_ITNIM_SM_CREATE);
1031
1032 return (itnim);
1033}
1034
1035void
1036bfa_itnim_delete(struct bfa_itnim_s *itnim)
1037{
1038 bfa_stats(itnim, deletes);
1039 bfa_sm_send_event(itnim, BFA_ITNIM_SM_DELETE);
1040}
1041
1042void
1043bfa_itnim_online(struct bfa_itnim_s *itnim, bfa_boolean_t seq_rec)
1044{
1045 itnim->seq_rec = seq_rec;
1046 bfa_stats(itnim, onlines);
1047 bfa_sm_send_event(itnim, BFA_ITNIM_SM_ONLINE);
1048}
1049
1050void
1051bfa_itnim_offline(struct bfa_itnim_s *itnim)
1052{
1053 bfa_stats(itnim, offlines);
1054 bfa_sm_send_event(itnim, BFA_ITNIM_SM_OFFLINE);
1055}
1056
1057/**
1058 * Return true if itnim is considered offline for holding off IO request.
1059 * IO is not held if itnim is being deleted.
1060 */
1061bfa_boolean_t
1062bfa_itnim_hold_io(struct bfa_itnim_s *itnim)
1063{
1064 return (
1065 itnim->fcpim->path_tov && itnim->iotov_active &&
1066 (bfa_sm_cmp_state(itnim, bfa_itnim_sm_fwcreate) ||
1067 bfa_sm_cmp_state(itnim, bfa_itnim_sm_sler) ||
1068 bfa_sm_cmp_state(itnim, bfa_itnim_sm_cleanup_offline) ||
1069 bfa_sm_cmp_state(itnim, bfa_itnim_sm_fwdelete) ||
1070 bfa_sm_cmp_state(itnim, bfa_itnim_sm_offline) ||
1071 bfa_sm_cmp_state(itnim, bfa_itnim_sm_iocdisable))
1072);
1073}
1074
1075void
1076bfa_itnim_get_stats(struct bfa_itnim_s *itnim,
1077 struct bfa_itnim_hal_stats_s *stats)
1078{
1079 *stats = itnim->stats;
1080}
1081
1082void
1083bfa_itnim_clear_stats(struct bfa_itnim_s *itnim)
1084{
1085 bfa_os_memset(&itnim->stats, 0, sizeof(itnim->stats));
1086}
1087
1088
diff --git a/drivers/scsi/bfa/bfa_log.c b/drivers/scsi/bfa/bfa_log.c
new file mode 100644
index 000000000000..c2735e55cf03
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_log.c
@@ -0,0 +1,346 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * bfa_log.c BFA log library
20 */
21
22#include <bfa_os_inc.h>
23#include <cs/bfa_log.h>
24
25/*
26 * global log info structure
27 */
28struct bfa_log_info_s {
29 u32 start_idx; /* start index for a module */
30 u32 total_count; /* total count for a module */
31 enum bfa_log_severity level; /* global log level */
32 bfa_log_cb_t cbfn; /* callback function */
33};
34
35static struct bfa_log_info_s bfa_log_info[BFA_LOG_MODULE_ID_MAX + 1];
36static u32 bfa_log_msg_total_count;
37static int bfa_log_initialized;
38
39static char *bfa_log_severity[] =
40 { "[none]", "[critical]", "[error]", "[warn]", "[info]", "" };
41
42/**
43 * BFA log library initialization
44 *
45 * The log library initialization includes the following,
46 * - set log instance name and callback function
47 * - read the message array generated from xml files
48 * - calculate start index for each module
49 * - calculate message count for each module
50 * - perform error checking
51 *
52 * @param[in] log_mod - log module info
53 * @param[in] instance_name - instance name
54 * @param[in] cbfn - callback function
55 *
56 * It return 0 on success, or -1 on failure
57 */
58int
59bfa_log_init(struct bfa_log_mod_s *log_mod, char *instance_name,
60 bfa_log_cb_t cbfn)
61{
62 struct bfa_log_msgdef_s *msg;
63 u32 pre_mod_id = 0;
64 u32 cur_mod_id = 0;
65 u32 i, pre_idx, idx, msg_id;
66
67 /*
68 * set instance name
69 */
70 if (log_mod) {
71 strncpy(log_mod->instance_info, instance_name,
72 sizeof(log_mod->instance_info));
73 log_mod->cbfn = cbfn;
74 for (i = 0; i <= BFA_LOG_MODULE_ID_MAX; i++)
75 log_mod->log_level[i] = BFA_LOG_WARNING;
76 }
77
78 if (bfa_log_initialized)
79 return 0;
80
81 for (i = 0; i <= BFA_LOG_MODULE_ID_MAX; i++) {
82 bfa_log_info[i].start_idx = 0;
83 bfa_log_info[i].total_count = 0;
84 bfa_log_info[i].level = BFA_LOG_WARNING;
85 bfa_log_info[i].cbfn = cbfn;
86 }
87
88 pre_idx = 0;
89 idx = 0;
90 msg = bfa_log_msg_array;
91 msg_id = BFA_LOG_GET_MSG_ID(msg);
92 pre_mod_id = BFA_LOG_GET_MOD_ID(msg_id);
93 while (msg_id != 0) {
94 cur_mod_id = BFA_LOG_GET_MOD_ID(msg_id);
95
96 if (cur_mod_id > BFA_LOG_MODULE_ID_MAX) {
97 cbfn(log_mod, msg_id,
98 "%s%s log: module id %u out of range\n",
99 BFA_LOG_CAT_NAME,
100 bfa_log_severity[BFA_LOG_ERROR],
101 cur_mod_id);
102 return -1;
103 }
104
105 if (pre_mod_id > BFA_LOG_MODULE_ID_MAX) {
106 cbfn(log_mod, msg_id,
107 "%s%s log: module id %u out of range\n",
108 BFA_LOG_CAT_NAME,
109 bfa_log_severity[BFA_LOG_ERROR],
110 pre_mod_id);
111 return -1;
112 }
113
114 if (cur_mod_id != pre_mod_id) {
115 bfa_log_info[pre_mod_id].start_idx = pre_idx;
116 bfa_log_info[pre_mod_id].total_count = idx - pre_idx;
117 pre_mod_id = cur_mod_id;
118 pre_idx = idx;
119 }
120
121 idx++;
122 msg++;
123 msg_id = BFA_LOG_GET_MSG_ID(msg);
124 }
125
126 bfa_log_info[cur_mod_id].start_idx = pre_idx;
127 bfa_log_info[cur_mod_id].total_count = idx - pre_idx;
128 bfa_log_msg_total_count = idx;
129
130 cbfn(log_mod, msg_id, "%s%s log: init OK, msg total count %u\n",
131 BFA_LOG_CAT_NAME,
132 bfa_log_severity[BFA_LOG_INFO], bfa_log_msg_total_count);
133
134 bfa_log_initialized = 1;
135
136 return 0;
137}
138
139/**
140 * BFA log set log level for a module
141 *
142 * @param[in] log_mod - log module info
143 * @param[in] mod_id - module id
144 * @param[in] log_level - log severity level
145 *
146 * It return BFA_STATUS_OK on success, or > 0 on failure
147 */
148bfa_status_t
149bfa_log_set_level(struct bfa_log_mod_s *log_mod, int mod_id,
150 enum bfa_log_severity log_level)
151{
152 if (mod_id <= BFA_LOG_UNUSED_ID || mod_id > BFA_LOG_MODULE_ID_MAX)
153 return BFA_STATUS_EINVAL;
154
155 if (log_level <= BFA_LOG_INVALID || log_level > BFA_LOG_LEVEL_MAX)
156 return BFA_STATUS_EINVAL;
157
158 if (log_mod)
159 log_mod->log_level[mod_id] = log_level;
160 else
161 bfa_log_info[mod_id].level = log_level;
162
163 return BFA_STATUS_OK;
164}
165
166/**
167 * BFA log set log level for all modules
168 *
169 * @param[in] log_mod - log module info
170 * @param[in] log_level - log severity level
171 *
172 * It return BFA_STATUS_OK on success, or > 0 on failure
173 */
174bfa_status_t
175bfa_log_set_level_all(struct bfa_log_mod_s *log_mod,
176 enum bfa_log_severity log_level)
177{
178 int mod_id = BFA_LOG_UNUSED_ID + 1;
179
180 if (log_level <= BFA_LOG_INVALID || log_level > BFA_LOG_LEVEL_MAX)
181 return BFA_STATUS_EINVAL;
182
183 if (log_mod) {
184 for (; mod_id <= BFA_LOG_MODULE_ID_MAX; mod_id++)
185 log_mod->log_level[mod_id] = log_level;
186 } else {
187 for (; mod_id <= BFA_LOG_MODULE_ID_MAX; mod_id++)
188 bfa_log_info[mod_id].level = log_level;
189 }
190
191 return BFA_STATUS_OK;
192}
193
194/**
195 * BFA log set log level for all aen sub-modules
196 *
197 * @param[in] log_mod - log module info
198 * @param[in] log_level - log severity level
199 *
200 * It return BFA_STATUS_OK on success, or > 0 on failure
201 */
202bfa_status_t
203bfa_log_set_level_aen(struct bfa_log_mod_s *log_mod,
204 enum bfa_log_severity log_level)
205{
206 int mod_id = BFA_LOG_AEN_MIN + 1;
207
208 if (log_mod) {
209 for (; mod_id <= BFA_LOG_AEN_MAX; mod_id++)
210 log_mod->log_level[mod_id] = log_level;
211 } else {
212 for (; mod_id <= BFA_LOG_AEN_MAX; mod_id++)
213 bfa_log_info[mod_id].level = log_level;
214 }
215
216 return BFA_STATUS_OK;
217}
218
219/**
220 * BFA log get log level for a module
221 *
222 * @param[in] log_mod - log module info
223 * @param[in] mod_id - module id
224 *
225 * It returns log level or -1 on error
226 */
227enum bfa_log_severity
228bfa_log_get_level(struct bfa_log_mod_s *log_mod, int mod_id)
229{
230 if (mod_id <= BFA_LOG_UNUSED_ID || mod_id > BFA_LOG_MODULE_ID_MAX)
231 return BFA_LOG_INVALID;
232
233 if (log_mod)
234 return (log_mod->log_level[mod_id]);
235 else
236 return (bfa_log_info[mod_id].level);
237}
238
239enum bfa_log_severity
240bfa_log_get_msg_level(struct bfa_log_mod_s *log_mod, u32 msg_id)
241{
242 struct bfa_log_msgdef_s *msg;
243 u32 mod = BFA_LOG_GET_MOD_ID(msg_id);
244 u32 idx = BFA_LOG_GET_MSG_IDX(msg_id) - 1;
245
246 if (!bfa_log_initialized)
247 return BFA_LOG_INVALID;
248
249 if (mod > BFA_LOG_MODULE_ID_MAX)
250 return BFA_LOG_INVALID;
251
252 if (idx >= bfa_log_info[mod].total_count) {
253 bfa_log_info[mod].cbfn(log_mod, msg_id,
254 "%s%s log: inconsistent idx %u vs. total count %u\n",
255 BFA_LOG_CAT_NAME, bfa_log_severity[BFA_LOG_ERROR], idx,
256 bfa_log_info[mod].total_count);
257 return BFA_LOG_INVALID;
258 }
259
260 msg = bfa_log_msg_array + bfa_log_info[mod].start_idx + idx;
261 if (msg_id != BFA_LOG_GET_MSG_ID(msg)) {
262 bfa_log_info[mod].cbfn(log_mod, msg_id,
263 "%s%s log: inconsistent msg id %u array msg id %u\n",
264 BFA_LOG_CAT_NAME, bfa_log_severity[BFA_LOG_ERROR],
265 msg_id, BFA_LOG_GET_MSG_ID(msg));
266 return BFA_LOG_INVALID;
267 }
268
269 return BFA_LOG_GET_SEVERITY(msg);
270}
271
272/**
273 * BFA log message handling
274 *
275 * BFA log message handling finds the message based on message id and prints
276 * out the message based on its format and arguments. It also does prefix
277 * the severity etc.
278 *
279 * @param[in] log_mod - log module info
280 * @param[in] msg_id - message id
281 * @param[in] ... - message arguments
282 *
283 * It return 0 on success, or -1 on errors
284 */
285int
286bfa_log(struct bfa_log_mod_s *log_mod, u32 msg_id, ...)
287{
288 va_list ap;
289 char buf[256];
290 struct bfa_log_msgdef_s *msg;
291 int log_level;
292 u32 mod = BFA_LOG_GET_MOD_ID(msg_id);
293 u32 idx = BFA_LOG_GET_MSG_IDX(msg_id) - 1;
294
295 if (!bfa_log_initialized)
296 return -1;
297
298 if (mod > BFA_LOG_MODULE_ID_MAX)
299 return -1;
300
301 if (idx >= bfa_log_info[mod].total_count) {
302 bfa_log_info[mod].
303 cbfn
304 (log_mod, msg_id,
305 "%s%s log: inconsistent idx %u vs. total count %u\n",
306 BFA_LOG_CAT_NAME, bfa_log_severity[BFA_LOG_ERROR], idx,
307 bfa_log_info[mod].total_count);
308 return -1;
309 }
310
311 msg = bfa_log_msg_array + bfa_log_info[mod].start_idx + idx;
312 if (msg_id != BFA_LOG_GET_MSG_ID(msg)) {
313 bfa_log_info[mod].
314 cbfn
315 (log_mod, msg_id,
316 "%s%s log: inconsistent msg id %u array msg id %u\n",
317 BFA_LOG_CAT_NAME, bfa_log_severity[BFA_LOG_ERROR],
318 msg_id, BFA_LOG_GET_MSG_ID(msg));
319 return -1;
320 }
321
322 log_level = log_mod ? log_mod->log_level[mod] : bfa_log_info[mod].level;
323 if ((BFA_LOG_GET_SEVERITY(msg) > log_level) &&
324 (msg->attributes != BFA_LOG_ATTR_NONE))
325 return 0;
326
327 va_start(ap, msg_id);
328 bfa_os_vsprintf(buf, BFA_LOG_GET_MSG_FMT_STRING(msg), ap);
329 va_end(ap);
330
331 if (log_mod)
332 log_mod->cbfn(log_mod, msg_id, "%s[%s]%s%s %s: %s\n",
333 BFA_LOG_CAT_NAME, log_mod->instance_info,
334 bfa_log_severity[BFA_LOG_GET_SEVERITY(msg)],
335 (msg->attributes & BFA_LOG_ATTR_AUDIT)
336 ? " (audit) " : "", msg->msg_value, buf);
337 else
338 bfa_log_info[mod].cbfn(log_mod, msg_id, "%s%s%s %s: %s\n",
339 BFA_LOG_CAT_NAME,
340 bfa_log_severity[BFA_LOG_GET_SEVERITY(msg)],
341 (msg->attributes & BFA_LOG_ATTR_AUDIT) ?
342 " (audit) " : "", msg->msg_value, buf);
343
344 return 0;
345}
346
diff --git a/drivers/scsi/bfa/bfa_log_module.c b/drivers/scsi/bfa/bfa_log_module.c
new file mode 100644
index 000000000000..5c154d341d69
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_log_module.c
@@ -0,0 +1,451 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#include <cs/bfa_log.h>
19#include <aen/bfa_aen_adapter.h>
20#include <aen/bfa_aen_audit.h>
21#include <aen/bfa_aen_ethport.h>
22#include <aen/bfa_aen_ioc.h>
23#include <aen/bfa_aen_itnim.h>
24#include <aen/bfa_aen_lport.h>
25#include <aen/bfa_aen_port.h>
26#include <aen/bfa_aen_rport.h>
27#include <log/bfa_log_fcs.h>
28#include <log/bfa_log_hal.h>
29#include <log/bfa_log_linux.h>
30#include <log/bfa_log_wdrv.h>
31
32struct bfa_log_msgdef_s bfa_log_msg_array[] = {
33
34
35/* messages define for BFA_AEN_CAT_ADAPTER Module */
36{BFA_AEN_ADAPTER_ADD, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
37 "BFA_AEN_ADAPTER_ADD",
38 "New adapter found: SN = %s, base port WWN = %s.",
39 ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2},
40
41{BFA_AEN_ADAPTER_REMOVE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
42 BFA_LOG_WARNING, "BFA_AEN_ADAPTER_REMOVE",
43 "Adapter removed: SN = %s.",
44 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
45
46
47
48
49/* messages define for BFA_AEN_CAT_AUDIT Module */
50{BFA_AEN_AUDIT_AUTH_ENABLE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
51 BFA_LOG_INFO, "BFA_AEN_AUDIT_AUTH_ENABLE",
52 "Authentication enabled for base port: WWN = %s.",
53 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
54
55{BFA_AEN_AUDIT_AUTH_DISABLE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
56 BFA_LOG_INFO, "BFA_AEN_AUDIT_AUTH_DISABLE",
57 "Authentication disabled for base port: WWN = %s.",
58 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
59
60
61
62
63/* messages define for BFA_AEN_CAT_ETHPORT Module */
64{BFA_AEN_ETHPORT_LINKUP, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
65 "BFA_AEN_ETHPORT_LINKUP",
66 "Base port ethernet linkup: mac = %s.",
67 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
68
69{BFA_AEN_ETHPORT_LINKDOWN, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
70 "BFA_AEN_ETHPORT_LINKDOWN",
71 "Base port ethernet linkdown: mac = %s.",
72 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
73
74{BFA_AEN_ETHPORT_ENABLE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
75 "BFA_AEN_ETHPORT_ENABLE",
76 "Base port ethernet interface enabled: mac = %s.",
77 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
78
79{BFA_AEN_ETHPORT_DISABLE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
80 "BFA_AEN_ETHPORT_DISABLE",
81 "Base port ethernet interface disabled: mac = %s.",
82 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
83
84
85
86
87/* messages define for BFA_AEN_CAT_IOC Module */
88{BFA_AEN_IOC_HBGOOD, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
89 "BFA_AEN_IOC_HBGOOD",
90 "Heart Beat of IOC %d is good.",
91 ((BFA_LOG_D << BFA_LOG_ARG0) | 0), 1},
92
93{BFA_AEN_IOC_HBFAIL, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_CRITICAL,
94 "BFA_AEN_IOC_HBFAIL",
95 "Heart Beat of IOC %d has failed.",
96 ((BFA_LOG_D << BFA_LOG_ARG0) | 0), 1},
97
98{BFA_AEN_IOC_ENABLE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
99 "BFA_AEN_IOC_ENABLE",
100 "IOC %d is enabled.",
101 ((BFA_LOG_D << BFA_LOG_ARG0) | 0), 1},
102
103{BFA_AEN_IOC_DISABLE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
104 "BFA_AEN_IOC_DISABLE",
105 "IOC %d is disabled.",
106 ((BFA_LOG_D << BFA_LOG_ARG0) | 0), 1},
107
108{BFA_AEN_IOC_FWMISMATCH, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
109 BFA_LOG_CRITICAL, "BFA_AEN_IOC_FWMISMATCH",
110 "Running firmware version is incompatible with the driver version.",
111 (0), 0},
112
113
114
115
116/* messages define for BFA_AEN_CAT_ITNIM Module */
117{BFA_AEN_ITNIM_ONLINE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
118 "BFA_AEN_ITNIM_ONLINE",
119 "Target (WWN = %s) is online for initiator (WWN = %s).",
120 ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2},
121
122{BFA_AEN_ITNIM_OFFLINE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
123 "BFA_AEN_ITNIM_OFFLINE",
124 "Target (WWN = %s) offlined by initiator (WWN = %s).",
125 ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2},
126
127{BFA_AEN_ITNIM_DISCONNECT, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
128 BFA_LOG_ERROR, "BFA_AEN_ITNIM_DISCONNECT",
129 "Target (WWN = %s) connectivity lost for initiator (WWN = %s).",
130 ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2},
131
132
133
134
135/* messages define for BFA_AEN_CAT_LPORT Module */
136{BFA_AEN_LPORT_NEW, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
137 "BFA_AEN_LPORT_NEW",
138 "New logical port created: WWN = %s, Role = %s.",
139 ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2},
140
141{BFA_AEN_LPORT_DELETE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
142 "BFA_AEN_LPORT_DELETE",
143 "Logical port deleted: WWN = %s, Role = %s.",
144 ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2},
145
146{BFA_AEN_LPORT_ONLINE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
147 "BFA_AEN_LPORT_ONLINE",
148 "Logical port online: WWN = %s, Role = %s.",
149 ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2},
150
151{BFA_AEN_LPORT_OFFLINE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
152 "BFA_AEN_LPORT_OFFLINE",
153 "Logical port taken offline: WWN = %s, Role = %s.",
154 ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2},
155
156{BFA_AEN_LPORT_DISCONNECT, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
157 BFA_LOG_ERROR, "BFA_AEN_LPORT_DISCONNECT",
158 "Logical port lost fabric connectivity: WWN = %s, Role = %s.",
159 ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2},
160
161{BFA_AEN_LPORT_NEW_PROP, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
162 "BFA_AEN_LPORT_NEW_PROP",
163 "New virtual port created using proprietary interface: WWN = %s, Role = %s.",
164 ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2},
165
166{BFA_AEN_LPORT_DELETE_PROP, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
167 BFA_LOG_INFO, "BFA_AEN_LPORT_DELETE_PROP",
168 "Virtual port deleted using proprietary interface: WWN = %s, Role = %s.",
169 ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2},
170
171{BFA_AEN_LPORT_NEW_STANDARD, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
172 BFA_LOG_INFO, "BFA_AEN_LPORT_NEW_STANDARD",
173 "New virtual port created using standard interface: WWN = %s, Role = %s.",
174 ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2},
175
176{BFA_AEN_LPORT_DELETE_STANDARD, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
177 BFA_LOG_INFO, "BFA_AEN_LPORT_DELETE_STANDARD",
178 "Virtual port deleted using standard interface: WWN = %s, Role = %s.",
179 ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2},
180
181{BFA_AEN_LPORT_NPIV_DUP_WWN, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
182 BFA_LOG_WARNING, "BFA_AEN_LPORT_NPIV_DUP_WWN",
183 "Virtual port login failed. Duplicate WWN = %s reported by fabric.",
184 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
185
186{BFA_AEN_LPORT_NPIV_FABRIC_MAX, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
187 BFA_LOG_WARNING, "BFA_AEN_LPORT_NPIV_FABRIC_MAX",
188 "Virtual port (WWN = %s) login failed. Max NPIV ports already exist in"
189 " fabric/fport.",
190 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
191
192{BFA_AEN_LPORT_NPIV_UNKNOWN, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
193 BFA_LOG_WARNING, "BFA_AEN_LPORT_NPIV_UNKNOWN",
194 "Virtual port (WWN = %s) login failed.",
195 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
196
197
198
199
200/* messages define for BFA_AEN_CAT_PORT Module */
201{BFA_AEN_PORT_ONLINE, BFA_LOG_ATTR_NONE, BFA_LOG_INFO, "BFA_AEN_PORT_ONLINE",
202 "Base port online: WWN = %s.",
203 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
204
205{BFA_AEN_PORT_OFFLINE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_WARNING,
206 "BFA_AEN_PORT_OFFLINE",
207 "Base port offline: WWN = %s.",
208 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
209
210{BFA_AEN_PORT_RLIR, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
211 "BFA_AEN_PORT_RLIR",
212 "RLIR event not supported.",
213 (0), 0},
214
215{BFA_AEN_PORT_SFP_INSERT, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
216 "BFA_AEN_PORT_SFP_INSERT",
217 "New SFP found: WWN/MAC = %s.",
218 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
219
220{BFA_AEN_PORT_SFP_REMOVE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
221 BFA_LOG_WARNING, "BFA_AEN_PORT_SFP_REMOVE",
222 "SFP removed: WWN/MAC = %s.",
223 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
224
225{BFA_AEN_PORT_SFP_POM, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_WARNING,
226 "BFA_AEN_PORT_SFP_POM",
227 "SFP POM level to %s: WWN/MAC = %s.",
228 ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2},
229
230{BFA_AEN_PORT_ENABLE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
231 "BFA_AEN_PORT_ENABLE",
232 "Base port enabled: WWN = %s.",
233 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
234
235{BFA_AEN_PORT_DISABLE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
236 "BFA_AEN_PORT_DISABLE",
237 "Base port disabled: WWN = %s.",
238 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
239
240{BFA_AEN_PORT_AUTH_ON, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
241 "BFA_AEN_PORT_AUTH_ON",
242 "Authentication successful for base port: WWN = %s.",
243 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
244
245{BFA_AEN_PORT_AUTH_OFF, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_ERROR,
246 "BFA_AEN_PORT_AUTH_OFF",
247 "Authentication unsuccessful for base port: WWN = %s.",
248 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
249
250{BFA_AEN_PORT_DISCONNECT, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_ERROR,
251 "BFA_AEN_PORT_DISCONNECT",
252 "Base port (WWN = %s) lost fabric connectivity.",
253 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
254
255{BFA_AEN_PORT_QOS_NEG, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_WARNING,
256 "BFA_AEN_PORT_QOS_NEG",
257 "QOS negotiation failed for base port: WWN = %s.",
258 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
259
260{BFA_AEN_PORT_FABRIC_NAME_CHANGE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
261 BFA_LOG_WARNING, "BFA_AEN_PORT_FABRIC_NAME_CHANGE",
262 "Base port WWN = %s, Fabric WWN = %s.",
263 ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2},
264
265{BFA_AEN_PORT_SFP_ACCESS_ERROR, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
266 BFA_LOG_WARNING, "BFA_AEN_PORT_SFP_ACCESS_ERROR",
267 "SFP access error: WWN/MAC = %s.",
268 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
269
270{BFA_AEN_PORT_SFP_UNSUPPORT, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
271 BFA_LOG_WARNING, "BFA_AEN_PORT_SFP_UNSUPPORT",
272 "Unsupported SFP found: WWN/MAC = %s.",
273 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
274
275
276
277
278/* messages define for BFA_AEN_CAT_RPORT Module */
279{BFA_AEN_RPORT_ONLINE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
280 "BFA_AEN_RPORT_ONLINE",
281 "Remote port (WWN = %s) online for logical port (WWN = %s).",
282 ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2},
283
284{BFA_AEN_RPORT_OFFLINE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
285 "BFA_AEN_RPORT_OFFLINE",
286 "Remote port (WWN = %s) offlined by logical port (WWN = %s).",
287 ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2},
288
289{BFA_AEN_RPORT_DISCONNECT, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
290 BFA_LOG_ERROR, "BFA_AEN_RPORT_DISCONNECT",
291 "Remote port (WWN = %s) connectivity lost for logical port (WWN = %s).",
292 ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) | 0), 2},
293
294{BFA_AEN_RPORT_QOS_PRIO, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
295 "BFA_AEN_RPORT_QOS_PRIO",
296 "QOS priority changed to %s: RPWWN = %s and LPWWN = %s.",
297 ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) |
298 (BFA_LOG_S << BFA_LOG_ARG2) | 0), 3},
299
300{BFA_AEN_RPORT_QOS_FLOWID, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
301 "BFA_AEN_RPORT_QOS_FLOWID",
302 "QOS flow ID changed to %d: RPWWN = %s and LPWWN = %s.",
303 ((BFA_LOG_D << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) |
304 (BFA_LOG_S << BFA_LOG_ARG2) | 0), 3},
305
306
307
308
309/* messages define for FCS Module */
310{BFA_LOG_FCS_FABRIC_NOSWITCH, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
311 BFA_LOG_INFO, "FCS_FABRIC_NOSWITCH",
312 "No switched fabric presence is detected.",
313 (0), 0},
314
315{BFA_LOG_FCS_FABRIC_ISOLATED, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
316 BFA_LOG_INFO, "FCS_FABRIC_ISOLATED",
317 "Port is isolated due to VF_ID mismatch. PWWN: %s, Port VF_ID: %04x and"
318 " switch port VF_ID: %04x.",
319 ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_X << BFA_LOG_ARG1) |
320 (BFA_LOG_X << BFA_LOG_ARG2) | 0), 3},
321
322
323
324
325/* messages define for HAL Module */
326{BFA_LOG_HAL_ASSERT, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_ERROR,
327 "HAL_ASSERT",
328 "Assertion failure: %s:%d: %s",
329 ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_D << BFA_LOG_ARG1) |
330 (BFA_LOG_S << BFA_LOG_ARG2) | 0), 3},
331
332{BFA_LOG_HAL_HEARTBEAT_FAILURE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
333 BFA_LOG_CRITICAL, "HAL_HEARTBEAT_FAILURE",
334 "Firmware heartbeat failure at %d",
335 ((BFA_LOG_D << BFA_LOG_ARG0) | 0), 1},
336
337{BFA_LOG_HAL_FCPIM_PARM_INVALID, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
338 BFA_LOG_INFO, "HAL_FCPIM_PARM_INVALID",
339 "Driver configuration %s value %d is invalid. Value should be within"
340 " %d and %d.",
341 ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_D << BFA_LOG_ARG1) |
342 (BFA_LOG_D << BFA_LOG_ARG2) | (BFA_LOG_D << BFA_LOG_ARG3) | 0), 4},
343
344{BFA_LOG_HAL_SM_ASSERT, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_ERROR,
345 "HAL_SM_ASSERT",
346 "SM Assertion failure: %s:%d: event = %d",
347 ((BFA_LOG_S << BFA_LOG_ARG0) | (BFA_LOG_D << BFA_LOG_ARG1) |
348 (BFA_LOG_D << BFA_LOG_ARG2) | 0), 3},
349
350
351
352
353/* messages define for LINUX Module */
354{BFA_LOG_LINUX_DEVICE_CLAIMED, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
355 BFA_LOG_INFO, "LINUX_DEVICE_CLAIMED",
356 "bfa device at %s claimed.",
357 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
358
359{BFA_LOG_LINUX_HASH_INIT_FAILED, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
360 BFA_LOG_INFO, "LINUX_HASH_INIT_FAILED",
361 "Hash table initialization failure for the port %s.",
362 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
363
364{BFA_LOG_LINUX_SYSFS_FAILED, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
365 BFA_LOG_INFO, "LINUX_SYSFS_FAILED",
366 "sysfs file creation failure for the port %s.",
367 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
368
369{BFA_LOG_LINUX_MEM_ALLOC_FAILED, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
370 BFA_LOG_INFO, "LINUX_MEM_ALLOC_FAILED",
371 "Memory allocation failed: %s. ",
372 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
373
374{BFA_LOG_LINUX_DRIVER_REGISTRATION_FAILED,
375 BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
376 "LINUX_DRIVER_REGISTRATION_FAILED",
377 "%s. ",
378 ((BFA_LOG_S << BFA_LOG_ARG0) | 0), 1},
379
380{BFA_LOG_LINUX_ITNIM_FREE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
381 "LINUX_ITNIM_FREE",
382 "scsi%d: FCID: %s WWPN: %s",
383 ((BFA_LOG_D << BFA_LOG_ARG0) | (BFA_LOG_S << BFA_LOG_ARG1) |
384 (BFA_LOG_S << BFA_LOG_ARG2) | 0), 3},
385
386{BFA_LOG_LINUX_ITNIM_ONLINE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
387 BFA_LOG_INFO, "LINUX_ITNIM_ONLINE",
388 "Target: %d:0:%d FCID: %s WWPN: %s",
389 ((BFA_LOG_D << BFA_LOG_ARG0) | (BFA_LOG_D << BFA_LOG_ARG1) |
390 (BFA_LOG_S << BFA_LOG_ARG2) | (BFA_LOG_S << BFA_LOG_ARG3) | 0), 4},
391
392{BFA_LOG_LINUX_ITNIM_OFFLINE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
393 BFA_LOG_INFO, "LINUX_ITNIM_OFFLINE",
394 "Target: %d:0:%d FCID: %s WWPN: %s",
395 ((BFA_LOG_D << BFA_LOG_ARG0) | (BFA_LOG_D << BFA_LOG_ARG1) |
396 (BFA_LOG_S << BFA_LOG_ARG2) | (BFA_LOG_S << BFA_LOG_ARG3) | 0), 4},
397
398{BFA_LOG_LINUX_SCSI_HOST_FREE, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
399 BFA_LOG_INFO, "LINUX_SCSI_HOST_FREE",
400 "Free scsi%d",
401 ((BFA_LOG_D << BFA_LOG_ARG0) | 0), 1},
402
403{BFA_LOG_LINUX_SCSI_ABORT, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG, BFA_LOG_INFO,
404 "LINUX_SCSI_ABORT",
405 "scsi%d: abort cmnd %p, iotag %x",
406 ((BFA_LOG_D << BFA_LOG_ARG0) | (BFA_LOG_P << BFA_LOG_ARG1) |
407 (BFA_LOG_X << BFA_LOG_ARG2) | 0), 3},
408
409{BFA_LOG_LINUX_SCSI_ABORT_COMP, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
410 BFA_LOG_INFO, "LINUX_SCSI_ABORT_COMP",
411 "scsi%d: complete abort 0x%p, iotag 0x%x",
412 ((BFA_LOG_D << BFA_LOG_ARG0) | (BFA_LOG_P << BFA_LOG_ARG1) |
413 (BFA_LOG_X << BFA_LOG_ARG2) | 0), 3},
414
415
416
417
418/* messages define for WDRV Module */
419{BFA_LOG_WDRV_IOC_INIT_ERROR, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
420 BFA_LOG_INFO, "WDRV_IOC_INIT_ERROR",
421 "IOC initialization has failed.",
422 (0), 0},
423
424{BFA_LOG_WDRV_IOC_INTERNAL_ERROR, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
425 BFA_LOG_INFO, "WDRV_IOC_INTERNAL_ERROR",
426 "IOC internal error. ",
427 (0), 0},
428
429{BFA_LOG_WDRV_IOC_START_ERROR, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
430 BFA_LOG_INFO, "WDRV_IOC_START_ERROR",
431 "IOC could not be started. ",
432 (0), 0},
433
434{BFA_LOG_WDRV_IOC_STOP_ERROR, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
435 BFA_LOG_INFO, "WDRV_IOC_STOP_ERROR",
436 "IOC could not be stopped. ",
437 (0), 0},
438
439{BFA_LOG_WDRV_INSUFFICIENT_RESOURCES, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
440 BFA_LOG_INFO, "WDRV_INSUFFICIENT_RESOURCES",
441 "Insufficient memory. ",
442 (0), 0},
443
444{BFA_LOG_WDRV_BASE_ADDRESS_MAP_ERROR, BFA_LOG_ATTR_NONE | BFA_LOG_ATTR_LOG,
445 BFA_LOG_INFO, "WDRV_BASE_ADDRESS_MAP_ERROR",
446 "Unable to map the IOC onto the system address space. ",
447 (0), 0},
448
449
450{0, 0, 0, "", "", 0, 0},
451};
diff --git a/drivers/scsi/bfa/bfa_lps.c b/drivers/scsi/bfa/bfa_lps.c
new file mode 100644
index 000000000000..9844b45412b6
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_lps.c
@@ -0,0 +1,782 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#include <bfa.h>
19#include <bfi/bfi_lps.h>
20#include <cs/bfa_debug.h>
21
22BFA_TRC_FILE(HAL, LPS);
23BFA_MODULE(lps);
24
25#define BFA_LPS_MIN_LPORTS (1)
26#define BFA_LPS_MAX_LPORTS (256)
27
28/**
29 * forward declarations
30 */
31static void bfa_lps_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len,
32 u32 *dm_len);
33static void bfa_lps_attach(struct bfa_s *bfa, void *bfad,
34 struct bfa_iocfc_cfg_s *cfg,
35 struct bfa_meminfo_s *meminfo,
36 struct bfa_pcidev_s *pcidev);
37static void bfa_lps_initdone(struct bfa_s *bfa);
38static void bfa_lps_detach(struct bfa_s *bfa);
39static void bfa_lps_start(struct bfa_s *bfa);
40static void bfa_lps_stop(struct bfa_s *bfa);
41static void bfa_lps_iocdisable(struct bfa_s *bfa);
42static void bfa_lps_login_rsp(struct bfa_s *bfa,
43 struct bfi_lps_login_rsp_s *rsp);
44static void bfa_lps_logout_rsp(struct bfa_s *bfa,
45 struct bfi_lps_logout_rsp_s *rsp);
46static void bfa_lps_reqq_resume(void *lps_arg);
47static void bfa_lps_free(struct bfa_lps_s *lps);
48static void bfa_lps_send_login(struct bfa_lps_s *lps);
49static void bfa_lps_send_logout(struct bfa_lps_s *lps);
50static void bfa_lps_login_comp(struct bfa_lps_s *lps);
51static void bfa_lps_logout_comp(struct bfa_lps_s *lps);
52
53
54/**
55 * lps_pvt BFA LPS private functions
56 */
57
58enum bfa_lps_event {
59 BFA_LPS_SM_LOGIN = 1, /* login request from user */
60 BFA_LPS_SM_LOGOUT = 2, /* logout request from user */
61 BFA_LPS_SM_FWRSP = 3, /* f/w response to login/logout */
62 BFA_LPS_SM_RESUME = 4, /* space present in reqq queue */
63 BFA_LPS_SM_DELETE = 5, /* lps delete from user */
64 BFA_LPS_SM_OFFLINE = 6, /* Link is offline */
65};
66
67static void bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event);
68static void bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event);
69static void bfa_lps_sm_loginwait(struct bfa_lps_s *lps,
70 enum bfa_lps_event event);
71static void bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event);
72static void bfa_lps_sm_logout(struct bfa_lps_s *lps, enum bfa_lps_event event);
73static void bfa_lps_sm_logowait(struct bfa_lps_s *lps,
74 enum bfa_lps_event event);
75
76/**
77 * Init state -- no login
78 */
79static void
80bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event)
81{
82 bfa_trc(lps->bfa, lps->lp_tag);
83 bfa_trc(lps->bfa, event);
84
85 switch (event) {
86 case BFA_LPS_SM_LOGIN:
87 if (bfa_reqq_full(lps->bfa, lps->reqq)) {
88 bfa_sm_set_state(lps, bfa_lps_sm_loginwait);
89 bfa_reqq_wait(lps->bfa, lps->reqq, &lps->wqe);
90 } else {
91 bfa_sm_set_state(lps, bfa_lps_sm_login);
92 bfa_lps_send_login(lps);
93 }
94 break;
95
96 case BFA_LPS_SM_LOGOUT:
97 bfa_lps_logout_comp(lps);
98 break;
99
100 case BFA_LPS_SM_DELETE:
101 bfa_lps_free(lps);
102 break;
103
104 case BFA_LPS_SM_OFFLINE:
105 break;
106
107 case BFA_LPS_SM_FWRSP:
108 /* Could happen when fabric detects loopback and discards
109 * the lps request. Fw will eventually sent out the timeout
110 * Just ignore
111 */
112 break;
113
114 default:
115 bfa_assert(0);
116 }
117}
118
119/**
120 * login is in progress -- awaiting response from firmware
121 */
122static void
123bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event)
124{
125 bfa_trc(lps->bfa, lps->lp_tag);
126 bfa_trc(lps->bfa, event);
127
128 switch (event) {
129 case BFA_LPS_SM_FWRSP:
130 if (lps->status == BFA_STATUS_OK)
131 bfa_sm_set_state(lps, bfa_lps_sm_online);
132 else
133 bfa_sm_set_state(lps, bfa_lps_sm_init);
134 bfa_lps_login_comp(lps);
135 break;
136
137 case BFA_LPS_SM_OFFLINE:
138 bfa_sm_set_state(lps, bfa_lps_sm_init);
139 break;
140
141 default:
142 bfa_assert(0);
143 }
144}
145
146/**
147 * login pending - awaiting space in request queue
148 */
149static void
150bfa_lps_sm_loginwait(struct bfa_lps_s *lps, enum bfa_lps_event event)
151{
152 bfa_trc(lps->bfa, lps->lp_tag);
153 bfa_trc(lps->bfa, event);
154
155 switch (event) {
156 case BFA_LPS_SM_RESUME:
157 bfa_sm_set_state(lps, bfa_lps_sm_login);
158 break;
159
160 case BFA_LPS_SM_OFFLINE:
161 bfa_sm_set_state(lps, bfa_lps_sm_init);
162 bfa_reqq_wcancel(&lps->wqe);
163 break;
164
165 default:
166 bfa_assert(0);
167 }
168}
169
170/**
171 * login complete
172 */
173static void
174bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event)
175{
176 bfa_trc(lps->bfa, lps->lp_tag);
177 bfa_trc(lps->bfa, event);
178
179 switch (event) {
180 case BFA_LPS_SM_LOGOUT:
181 if (bfa_reqq_full(lps->bfa, lps->reqq)) {
182 bfa_sm_set_state(lps, bfa_lps_sm_logowait);
183 bfa_reqq_wait(lps->bfa, lps->reqq, &lps->wqe);
184 } else {
185 bfa_sm_set_state(lps, bfa_lps_sm_logout);
186 bfa_lps_send_logout(lps);
187 }
188 break;
189
190 case BFA_LPS_SM_OFFLINE:
191 case BFA_LPS_SM_DELETE:
192 bfa_sm_set_state(lps, bfa_lps_sm_init);
193 break;
194
195 default:
196 bfa_assert(0);
197 }
198}
199
200/**
201 * logout in progress - awaiting firmware response
202 */
203static void
204bfa_lps_sm_logout(struct bfa_lps_s *lps, enum bfa_lps_event event)
205{
206 bfa_trc(lps->bfa, lps->lp_tag);
207 bfa_trc(lps->bfa, event);
208
209 switch (event) {
210 case BFA_LPS_SM_FWRSP:
211 bfa_sm_set_state(lps, bfa_lps_sm_init);
212 bfa_lps_logout_comp(lps);
213 break;
214
215 case BFA_LPS_SM_OFFLINE:
216 bfa_sm_set_state(lps, bfa_lps_sm_init);
217 break;
218
219 default:
220 bfa_assert(0);
221 }
222}
223
224/**
225 * logout pending -- awaiting space in request queue
226 */
227static void
228bfa_lps_sm_logowait(struct bfa_lps_s *lps, enum bfa_lps_event event)
229{
230 bfa_trc(lps->bfa, lps->lp_tag);
231 bfa_trc(lps->bfa, event);
232
233 switch (event) {
234 case BFA_LPS_SM_RESUME:
235 bfa_sm_set_state(lps, bfa_lps_sm_logout);
236 bfa_lps_send_logout(lps);
237 break;
238
239 case BFA_LPS_SM_OFFLINE:
240 bfa_sm_set_state(lps, bfa_lps_sm_init);
241 bfa_reqq_wcancel(&lps->wqe);
242 break;
243
244 default:
245 bfa_assert(0);
246 }
247}
248
249
250
251/**
252 * lps_pvt BFA LPS private functions
253 */
254
255/**
256 * return memory requirement
257 */
258static void
259bfa_lps_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len, u32 *dm_len)
260{
261 if (cfg->drvcfg.min_cfg)
262 *ndm_len += sizeof(struct bfa_lps_s) * BFA_LPS_MIN_LPORTS;
263 else
264 *ndm_len += sizeof(struct bfa_lps_s) * BFA_LPS_MAX_LPORTS;
265}
266
267/**
268 * bfa module attach at initialization time
269 */
270static void
271bfa_lps_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
272 struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev)
273{
274 struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa);
275 struct bfa_lps_s *lps;
276 int i;
277
278 bfa_os_memset(mod, 0, sizeof(struct bfa_lps_mod_s));
279 mod->num_lps = BFA_LPS_MAX_LPORTS;
280 if (cfg->drvcfg.min_cfg)
281 mod->num_lps = BFA_LPS_MIN_LPORTS;
282 else
283 mod->num_lps = BFA_LPS_MAX_LPORTS;
284 mod->lps_arr = lps = (struct bfa_lps_s *) bfa_meminfo_kva(meminfo);
285
286 bfa_meminfo_kva(meminfo) += mod->num_lps * sizeof(struct bfa_lps_s);
287
288 INIT_LIST_HEAD(&mod->lps_free_q);
289 INIT_LIST_HEAD(&mod->lps_active_q);
290
291 for (i = 0; i < mod->num_lps; i++, lps++) {
292 lps->bfa = bfa;
293 lps->lp_tag = (u8) i;
294 lps->reqq = BFA_REQQ_LPS;
295 bfa_reqq_winit(&lps->wqe, bfa_lps_reqq_resume, lps);
296 list_add_tail(&lps->qe, &mod->lps_free_q);
297 }
298}
299
300static void
301bfa_lps_initdone(struct bfa_s *bfa)
302{
303}
304
305static void
306bfa_lps_detach(struct bfa_s *bfa)
307{
308}
309
310static void
311bfa_lps_start(struct bfa_s *bfa)
312{
313}
314
315static void
316bfa_lps_stop(struct bfa_s *bfa)
317{
318}
319
320/**
321 * IOC in disabled state -- consider all lps offline
322 */
323static void
324bfa_lps_iocdisable(struct bfa_s *bfa)
325{
326 struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa);
327 struct bfa_lps_s *lps;
328 struct list_head *qe, *qen;
329
330 list_for_each_safe(qe, qen, &mod->lps_active_q) {
331 lps = (struct bfa_lps_s *) qe;
332 bfa_sm_send_event(lps, BFA_LPS_SM_OFFLINE);
333 }
334}
335
336/**
337 * Firmware login response
338 */
339static void
340bfa_lps_login_rsp(struct bfa_s *bfa, struct bfi_lps_login_rsp_s *rsp)
341{
342 struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa);
343 struct bfa_lps_s *lps;
344
345 bfa_assert(rsp->lp_tag < mod->num_lps);
346 lps = BFA_LPS_FROM_TAG(mod, rsp->lp_tag);
347
348 lps->status = rsp->status;
349 switch (rsp->status) {
350 case BFA_STATUS_OK:
351 lps->fport = rsp->f_port;
352 lps->npiv_en = rsp->npiv_en;
353 lps->lp_pid = rsp->lp_pid;
354 lps->pr_bbcred = bfa_os_ntohs(rsp->bb_credit);
355 lps->pr_pwwn = rsp->port_name;
356 lps->pr_nwwn = rsp->node_name;
357 lps->auth_req = rsp->auth_req;
358 lps->lp_mac = rsp->lp_mac;
359 lps->brcd_switch = rsp->brcd_switch;
360 lps->fcf_mac = rsp->fcf_mac;
361
362 break;
363
364 case BFA_STATUS_FABRIC_RJT:
365 lps->lsrjt_rsn = rsp->lsrjt_rsn;
366 lps->lsrjt_expl = rsp->lsrjt_expl;
367
368 break;
369
370 case BFA_STATUS_EPROTOCOL:
371 lps->ext_status = rsp->ext_status;
372
373 break;
374
375 default:
376 /* Nothing to do with other status */
377 break;
378 }
379
380 bfa_sm_send_event(lps, BFA_LPS_SM_FWRSP);
381}
382
383/**
384 * Firmware logout response
385 */
386static void
387bfa_lps_logout_rsp(struct bfa_s *bfa, struct bfi_lps_logout_rsp_s *rsp)
388{
389 struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa);
390 struct bfa_lps_s *lps;
391
392 bfa_assert(rsp->lp_tag < mod->num_lps);
393 lps = BFA_LPS_FROM_TAG(mod, rsp->lp_tag);
394
395 bfa_sm_send_event(lps, BFA_LPS_SM_FWRSP);
396}
397
398/**
399 * Space is available in request queue, resume queueing request to firmware.
400 */
401static void
402bfa_lps_reqq_resume(void *lps_arg)
403{
404 struct bfa_lps_s *lps = lps_arg;
405
406 bfa_sm_send_event(lps, BFA_LPS_SM_RESUME);
407}
408
409/**
410 * lps is freed -- triggered by vport delete
411 */
412static void
413bfa_lps_free(struct bfa_lps_s *lps)
414{
415 struct bfa_lps_mod_s *mod = BFA_LPS_MOD(lps->bfa);
416
417 list_del(&lps->qe);
418 list_add_tail(&lps->qe, &mod->lps_free_q);
419}
420
421/**
422 * send login request to firmware
423 */
424static void
425bfa_lps_send_login(struct bfa_lps_s *lps)
426{
427 struct bfi_lps_login_req_s *m;
428
429 m = bfa_reqq_next(lps->bfa, lps->reqq);
430 bfa_assert(m);
431
432 bfi_h2i_set(m->mh, BFI_MC_LPS, BFI_LPS_H2I_LOGIN_REQ,
433 bfa_lpuid(lps->bfa));
434
435 m->lp_tag = lps->lp_tag;
436 m->alpa = lps->alpa;
437 m->pdu_size = bfa_os_htons(lps->pdusz);
438 m->pwwn = lps->pwwn;
439 m->nwwn = lps->nwwn;
440 m->fdisc = lps->fdisc;
441 m->auth_en = lps->auth_en;
442
443 bfa_reqq_produce(lps->bfa, lps->reqq);
444}
445
446/**
447 * send logout request to firmware
448 */
449static void
450bfa_lps_send_logout(struct bfa_lps_s *lps)
451{
452 struct bfi_lps_logout_req_s *m;
453
454 m = bfa_reqq_next(lps->bfa, lps->reqq);
455 bfa_assert(m);
456
457 bfi_h2i_set(m->mh, BFI_MC_LPS, BFI_LPS_H2I_LOGOUT_REQ,
458 bfa_lpuid(lps->bfa));
459
460 m->lp_tag = lps->lp_tag;
461 m->port_name = lps->pwwn;
462 bfa_reqq_produce(lps->bfa, lps->reqq);
463}
464
465/**
466 * Indirect login completion handler for non-fcs
467 */
468static void
469bfa_lps_login_comp_cb(void *arg, bfa_boolean_t complete)
470{
471 struct bfa_lps_s *lps = arg;
472
473 if (!complete)
474 return;
475
476 if (lps->fdisc)
477 bfa_cb_lps_fdisc_comp(lps->bfa->bfad, lps->uarg, lps->status);
478 else
479 bfa_cb_lps_flogi_comp(lps->bfa->bfad, lps->uarg, lps->status);
480}
481
482/**
483 * Login completion handler -- direct call for fcs, queue for others
484 */
485static void
486bfa_lps_login_comp(struct bfa_lps_s *lps)
487{
488 if (!lps->bfa->fcs) {
489 bfa_cb_queue(lps->bfa, &lps->hcb_qe,
490 bfa_lps_login_comp_cb, lps);
491 return;
492 }
493
494 if (lps->fdisc)
495 bfa_cb_lps_fdisc_comp(lps->bfa->bfad, lps->uarg, lps->status);
496 else
497 bfa_cb_lps_flogi_comp(lps->bfa->bfad, lps->uarg, lps->status);
498}
499
500/**
501 * Indirect logout completion handler for non-fcs
502 */
503static void
504bfa_lps_logout_comp_cb(void *arg, bfa_boolean_t complete)
505{
506 struct bfa_lps_s *lps = arg;
507
508 if (!complete)
509 return;
510
511 if (lps->fdisc)
512 bfa_cb_lps_fdisclogo_comp(lps->bfa->bfad, lps->uarg);
513 else
514 bfa_cb_lps_flogo_comp(lps->bfa->bfad, lps->uarg);
515}
516
517/**
518 * Logout completion handler -- direct call for fcs, queue for others
519 */
520static void
521bfa_lps_logout_comp(struct bfa_lps_s *lps)
522{
523 if (!lps->bfa->fcs) {
524 bfa_cb_queue(lps->bfa, &lps->hcb_qe,
525 bfa_lps_logout_comp_cb, lps);
526 return;
527 }
528 if (lps->fdisc)
529 bfa_cb_lps_fdisclogo_comp(lps->bfa->bfad, lps->uarg);
530 else
531 bfa_cb_lps_flogo_comp(lps->bfa->bfad, lps->uarg);
532}
533
534
535
536/**
537 * lps_public BFA LPS public functions
538 */
539
540/**
541 * Allocate a lport srvice tag.
542 */
543struct bfa_lps_s *
544bfa_lps_alloc(struct bfa_s *bfa)
545{
546 struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa);
547 struct bfa_lps_s *lps = NULL;
548
549 bfa_q_deq(&mod->lps_free_q, &lps);
550
551 if (lps == NULL)
552 return NULL;
553
554 list_add_tail(&lps->qe, &mod->lps_active_q);
555
556 bfa_sm_set_state(lps, bfa_lps_sm_init);
557 return lps;
558}
559
560/**
561 * Free lport service tag. This can be called anytime after an alloc.
562 * No need to wait for any pending login/logout completions.
563 */
564void
565bfa_lps_delete(struct bfa_lps_s *lps)
566{
567 bfa_sm_send_event(lps, BFA_LPS_SM_DELETE);
568}
569
570/**
571 * Initiate a lport login.
572 */
573void
574bfa_lps_flogi(struct bfa_lps_s *lps, void *uarg, u8 alpa, u16 pdusz,
575 wwn_t pwwn, wwn_t nwwn, bfa_boolean_t auth_en)
576{
577 lps->uarg = uarg;
578 lps->alpa = alpa;
579 lps->pdusz = pdusz;
580 lps->pwwn = pwwn;
581 lps->nwwn = nwwn;
582 lps->fdisc = BFA_FALSE;
583 lps->auth_en = auth_en;
584 bfa_sm_send_event(lps, BFA_LPS_SM_LOGIN);
585}
586
587/**
588 * Initiate a lport fdisc login.
589 */
590void
591bfa_lps_fdisc(struct bfa_lps_s *lps, void *uarg, u16 pdusz, wwn_t pwwn,
592 wwn_t nwwn)
593{
594 lps->uarg = uarg;
595 lps->alpa = 0;
596 lps->pdusz = pdusz;
597 lps->pwwn = pwwn;
598 lps->nwwn = nwwn;
599 lps->fdisc = BFA_TRUE;
600 lps->auth_en = BFA_FALSE;
601 bfa_sm_send_event(lps, BFA_LPS_SM_LOGIN);
602}
603
604/**
605 * Initiate a lport logout (flogi).
606 */
607void
608bfa_lps_flogo(struct bfa_lps_s *lps)
609{
610 bfa_sm_send_event(lps, BFA_LPS_SM_LOGOUT);
611}
612
613/**
614 * Initiate a lport FDSIC logout.
615 */
616void
617bfa_lps_fdisclogo(struct bfa_lps_s *lps)
618{
619 bfa_sm_send_event(lps, BFA_LPS_SM_LOGOUT);
620}
621
622/**
623 * Discard a pending login request -- should be called only for
624 * link down handling.
625 */
626void
627bfa_lps_discard(struct bfa_lps_s *lps)
628{
629 bfa_sm_send_event(lps, BFA_LPS_SM_OFFLINE);
630}
631
632/**
633 * Return lport services tag
634 */
635u8
636bfa_lps_get_tag(struct bfa_lps_s *lps)
637{
638 return lps->lp_tag;
639}
640
641/**
642 * Return lport services tag given the pid
643 */
644u8
645bfa_lps_get_tag_from_pid(struct bfa_s *bfa, u32 pid)
646{
647 struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa);
648 struct bfa_lps_s *lps;
649 int i;
650
651 for (i = 0, lps = mod->lps_arr; i < mod->num_lps; i++, lps++) {
652 if (lps->lp_pid == pid)
653 return lps->lp_tag;
654 }
655
656 /* Return base port tag anyway */
657 return 0;
658}
659
660/**
661 * return if fabric login indicates support for NPIV
662 */
663bfa_boolean_t
664bfa_lps_is_npiv_en(struct bfa_lps_s *lps)
665{
666 return lps->npiv_en;
667}
668
669/**
670 * Return TRUE if attached to F-Port, else return FALSE
671 */
672bfa_boolean_t
673bfa_lps_is_fport(struct bfa_lps_s *lps)
674{
675 return lps->fport;
676}
677
678/**
679 * Return TRUE if attached to a Brocade Fabric
680 */
681bfa_boolean_t
682bfa_lps_is_brcd_fabric(struct bfa_lps_s *lps)
683{
684 return lps->brcd_switch;
685}
686/**
687 * return TRUE if authentication is required
688 */
689bfa_boolean_t
690bfa_lps_is_authreq(struct bfa_lps_s *lps)
691{
692 return lps->auth_req;
693}
694
695bfa_eproto_status_t
696bfa_lps_get_extstatus(struct bfa_lps_s *lps)
697{
698 return lps->ext_status;
699}
700
701/**
702 * return port id assigned to the lport
703 */
704u32
705bfa_lps_get_pid(struct bfa_lps_s *lps)
706{
707 return lps->lp_pid;
708}
709
710/**
711 * Return bb_credit assigned in FLOGI response
712 */
713u16
714bfa_lps_get_peer_bbcredit(struct bfa_lps_s *lps)
715{
716 return lps->pr_bbcred;
717}
718
719/**
720 * Return peer port name
721 */
722wwn_t
723bfa_lps_get_peer_pwwn(struct bfa_lps_s *lps)
724{
725 return lps->pr_pwwn;
726}
727
728/**
729 * Return peer node name
730 */
731wwn_t
732bfa_lps_get_peer_nwwn(struct bfa_lps_s *lps)
733{
734 return lps->pr_nwwn;
735}
736
737/**
738 * return reason code if login request is rejected
739 */
740u8
741bfa_lps_get_lsrjt_rsn(struct bfa_lps_s *lps)
742{
743 return lps->lsrjt_rsn;
744}
745
746/**
747 * return explanation code if login request is rejected
748 */
749u8
750bfa_lps_get_lsrjt_expl(struct bfa_lps_s *lps)
751{
752 return lps->lsrjt_expl;
753}
754
755
756/**
757 * LPS firmware message class handler.
758 */
759void
760bfa_lps_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
761{
762 union bfi_lps_i2h_msg_u msg;
763
764 bfa_trc(bfa, m->mhdr.msg_id);
765 msg.msg = m;
766
767 switch (m->mhdr.msg_id) {
768 case BFI_LPS_H2I_LOGIN_RSP:
769 bfa_lps_login_rsp(bfa, msg.login_rsp);
770 break;
771
772 case BFI_LPS_H2I_LOGOUT_RSP:
773 bfa_lps_logout_rsp(bfa, msg.logout_rsp);
774 break;
775
776 default:
777 bfa_trc(bfa, m->mhdr.msg_id);
778 bfa_assert(0);
779 }
780}
781
782
diff --git a/drivers/scsi/bfa/bfa_lps_priv.h b/drivers/scsi/bfa/bfa_lps_priv.h
new file mode 100644
index 000000000000..d16c6ce995df
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_lps_priv.h
@@ -0,0 +1,38 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFA_LPS_PRIV_H__
19#define __BFA_LPS_PRIV_H__
20
21#include <bfa_svc.h>
22
23struct bfa_lps_mod_s {
24 struct list_head lps_free_q;
25 struct list_head lps_active_q;
26 struct bfa_lps_s *lps_arr;
27 int num_lps;
28};
29
30#define BFA_LPS_MOD(__bfa) (&(__bfa)->modules.lps_mod)
31#define BFA_LPS_FROM_TAG(__mod, __tag) (&(__mod)->lps_arr[__tag])
32
33/*
34 * external functions
35 */
36void bfa_lps_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
37
38#endif /* __BFA_LPS_PRIV_H__ */
diff --git a/drivers/scsi/bfa/bfa_module.c b/drivers/scsi/bfa/bfa_module.c
new file mode 100644
index 000000000000..32eda8e1ec65
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_module.c
@@ -0,0 +1,90 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17#include <bfa.h>
18#include <defs/bfa_defs_pci.h>
19#include <cs/bfa_debug.h>
20#include <bfa_iocfc.h>
21
22/**
23 * BFA module list terminated by NULL
24 */
25struct bfa_module_s *hal_mods[] = {
26 &hal_mod_sgpg,
27 &hal_mod_pport,
28 &hal_mod_fcxp,
29 &hal_mod_lps,
30 &hal_mod_uf,
31 &hal_mod_rport,
32 &hal_mod_fcpim,
33#ifdef BFA_CFG_PBIND
34 &hal_mod_pbind,
35#endif
36 NULL
37};
38
39/**
40 * Message handlers for various modules.
41 */
42bfa_isr_func_t bfa_isrs[BFI_MC_MAX] = {
43 bfa_isr_unhandled, /* NONE */
44 bfa_isr_unhandled, /* BFI_MC_IOC */
45 bfa_isr_unhandled, /* BFI_MC_DIAG */
46 bfa_isr_unhandled, /* BFI_MC_FLASH */
47 bfa_isr_unhandled, /* BFI_MC_CEE */
48 bfa_pport_isr, /* BFI_MC_PORT */
49 bfa_isr_unhandled, /* BFI_MC_IOCFC */
50 bfa_isr_unhandled, /* BFI_MC_LL */
51 bfa_uf_isr, /* BFI_MC_UF */
52 bfa_fcxp_isr, /* BFI_MC_FCXP */
53 bfa_lps_isr, /* BFI_MC_LPS */
54 bfa_rport_isr, /* BFI_MC_RPORT */
55 bfa_itnim_isr, /* BFI_MC_ITNIM */
56 bfa_isr_unhandled, /* BFI_MC_IOIM_READ */
57 bfa_isr_unhandled, /* BFI_MC_IOIM_WRITE */
58 bfa_isr_unhandled, /* BFI_MC_IOIM_IO */
59 bfa_ioim_isr, /* BFI_MC_IOIM */
60 bfa_ioim_good_comp_isr, /* BFI_MC_IOIM_IOCOM */
61 bfa_tskim_isr, /* BFI_MC_TSKIM */
62 bfa_isr_unhandled, /* BFI_MC_SBOOT */
63 bfa_isr_unhandled, /* BFI_MC_IPFC */
64 bfa_isr_unhandled, /* BFI_MC_PORT */
65 bfa_isr_unhandled, /* --------- */
66 bfa_isr_unhandled, /* --------- */
67 bfa_isr_unhandled, /* --------- */
68 bfa_isr_unhandled, /* --------- */
69 bfa_isr_unhandled, /* --------- */
70 bfa_isr_unhandled, /* --------- */
71 bfa_isr_unhandled, /* --------- */
72 bfa_isr_unhandled, /* --------- */
73 bfa_isr_unhandled, /* --------- */
74 bfa_isr_unhandled, /* --------- */
75};
76
77/**
78 * Message handlers for mailbox command classes
79 */
80bfa_ioc_mbox_mcfunc_t bfa_mbox_isrs[BFI_MC_MAX] = {
81 NULL,
82 NULL, /* BFI_MC_IOC */
83 NULL, /* BFI_MC_DIAG */
84 NULL, /* BFI_MC_FLASH */
85 NULL, /* BFI_MC_CEE */
86 NULL, /* BFI_MC_PORT */
87 bfa_iocfc_isr, /* BFI_MC_IOCFC */
88 NULL,
89};
90
diff --git a/drivers/scsi/bfa/bfa_modules_priv.h b/drivers/scsi/bfa/bfa_modules_priv.h
new file mode 100644
index 000000000000..96f70534593c
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_modules_priv.h
@@ -0,0 +1,43 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFA_MODULES_PRIV_H__
19#define __BFA_MODULES_PRIV_H__
20
21#include "bfa_uf_priv.h"
22#include "bfa_port_priv.h"
23#include "bfa_rport_priv.h"
24#include "bfa_fcxp_priv.h"
25#include "bfa_lps_priv.h"
26#include "bfa_fcpim_priv.h"
27#include <cee/bfa_cee.h>
28#include <port/bfa_port.h>
29
30
31struct bfa_modules_s {
32 struct bfa_pport_s pport; /* physical port module */
33 struct bfa_fcxp_mod_s fcxp_mod; /* fcxp module */
34 struct bfa_lps_mod_s lps_mod; /* fcxp module */
35 struct bfa_uf_mod_s uf_mod; /* unsolicited frame module */
36 struct bfa_rport_mod_s rport_mod; /* remote port module */
37 struct bfa_fcpim_mod_s fcpim_mod; /* FCP initiator module */
38 struct bfa_sgpg_mod_s sgpg_mod; /* SG page module */
39 struct bfa_cee_s cee; /* CEE Module */
40 struct bfa_port_s port; /* Physical port module */
41};
42
43#endif /* __BFA_MODULES_PRIV_H__ */
diff --git a/drivers/scsi/bfa/bfa_os_inc.h b/drivers/scsi/bfa/bfa_os_inc.h
new file mode 100644
index 000000000000..10a89f75fa94
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_os_inc.h
@@ -0,0 +1,222 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * Contains declarations all OS Specific files needed for BFA layer
20 */
21
22#ifndef __BFA_OS_INC_H__
23#define __BFA_OS_INC_H__
24
25#ifndef __KERNEL__
26#include <stdint.h>
27#else
28#include <linux/types.h>
29
30#include <linux/version.h>
31#include <linux/pci.h>
32
33#include <linux/dma-mapping.h>
34#define SET_MODULE_VERSION(VER)
35
36#include <linux/idr.h>
37
38#include <linux/interrupt.h>
39#include <linux/cdev.h>
40#include <linux/fs.h>
41#include <linux/delay.h>
42#include <linux/vmalloc.h>
43
44#include <linux/workqueue.h>
45
46#include <scsi/scsi.h>
47#include <scsi/scsi_host.h>
48
49#include <scsi/scsi_tcq.h>
50#include <scsi/scsi_transport_fc.h>
51#include <scsi/scsi_transport.h>
52
53#define BFA_ERR KERN_ERR
54#define BFA_WARNING KERN_WARNING
55#define BFA_NOTICE KERN_NOTICE
56#define BFA_INFO KERN_INFO
57#define BFA_DEBUG KERN_DEBUG
58
59#define LOG_BFAD_INIT 0x00000001
60#define LOG_FCP_IO 0x00000002
61
62#ifdef DEBUG
63#define BFA_LOG_TRACE(bfad, level, mask, fmt, arg...) \
64 BFA_LOG(bfad, level, mask, fmt, ## arg)
65#define BFA_DEV_TRACE(bfad, level, fmt, arg...) \
66 BFA_DEV_PRINTF(bfad, level, fmt, ## arg)
67#define BFA_TRACE(level, fmt, arg...) \
68 BFA_PRINTF(level, fmt, ## arg)
69#else
70#define BFA_LOG_TRACE(bfad, level, mask, fmt, arg...)
71#define BFA_DEV_TRACE(bfad, level, fmt, arg...)
72#define BFA_TRACE(level, fmt, arg...)
73#endif
74
75#define BFA_ASSERT(p) do { \
76 if (!(p)) { \
77 printk(KERN_ERR "assert(%s) failed at %s:%d\n", \
78 #p, __FILE__, __LINE__); \
79 BUG(); \
80 } \
81} while (0)
82
83
84#define BFA_LOG(bfad, level, mask, fmt, arg...) \
85do { \
86 if (((mask) & (((struct bfad_s *)(bfad))-> \
87 cfg_data[cfg_log_mask])) || (level[1] <= '3')) \
88 dev_printk(level, &(((struct bfad_s *) \
89 (bfad))->pcidev->dev), fmt, ##arg); \
90} while (0)
91
92#ifndef BFA_DEV_PRINTF
93#define BFA_DEV_PRINTF(bfad, level, fmt, arg...) \
94 dev_printk(level, &(((struct bfad_s *) \
95 (bfad))->pcidev->dev), fmt, ##arg);
96#endif
97
98#define BFA_PRINTF(level, fmt, arg...) \
99 printk(level fmt, ##arg);
100
101int bfa_os_MWB(void *);
102
103#define bfa_os_mmiowb() mmiowb()
104
105#define bfa_swap_3b(_x) \
106 ((((_x) & 0xff) << 16) | \
107 ((_x) & 0x00ff00) | \
108 (((_x) & 0xff0000) >> 16))
109
110#define bfa_swap_8b(_x) \
111 ((((_x) & 0xff00000000000000ull) >> 56) \
112 | (((_x) & 0x00ff000000000000ull) >> 40) \
113 | (((_x) & 0x0000ff0000000000ull) >> 24) \
114 | (((_x) & 0x000000ff00000000ull) >> 8) \
115 | (((_x) & 0x00000000ff000000ull) << 8) \
116 | (((_x) & 0x0000000000ff0000ull) << 24) \
117 | (((_x) & 0x000000000000ff00ull) << 40) \
118 | (((_x) & 0x00000000000000ffull) << 56))
119
120#define bfa_os_swap32(_x) \
121 ((((_x) & 0xff) << 24) | \
122 (((_x) & 0x0000ff00) << 8) | \
123 (((_x) & 0x00ff0000) >> 8) | \
124 (((_x) & 0xff000000) >> 24))
125
126
127#ifndef __BIGENDIAN
128#define bfa_os_htons(_x) ((u16)((((_x) & 0xff00) >> 8) | \
129 (((_x) & 0x00ff) << 8)))
130
131#define bfa_os_htonl(_x) bfa_os_swap32(_x)
132#define bfa_os_htonll(_x) bfa_swap_8b(_x)
133#define bfa_os_hton3b(_x) bfa_swap_3b(_x)
134
135#define bfa_os_wtole(_x) (_x)
136
137#else
138
139#define bfa_os_htons(_x) (_x)
140#define bfa_os_htonl(_x) (_x)
141#define bfa_os_hton3b(_x) (_x)
142#define bfa_os_htonll(_x) (_x)
143#define bfa_os_wtole(_x) bfa_os_swap32(_x)
144
145#endif
146
147#define bfa_os_ntohs(_x) bfa_os_htons(_x)
148#define bfa_os_ntohl(_x) bfa_os_htonl(_x)
149#define bfa_os_ntohll(_x) bfa_os_htonll(_x)
150#define bfa_os_ntoh3b(_x) bfa_os_hton3b(_x)
151
152#define bfa_os_u32(__pa64) ((__pa64) >> 32)
153
154#define bfa_os_memset memset
155#define bfa_os_memcpy memcpy
156#define bfa_os_udelay udelay
157#define bfa_os_vsprintf vsprintf
158
159#define bfa_os_assign(__t, __s) __t = __s
160
161#define bfa_os_addr_t char __iomem *
162#define bfa_os_panic()
163
164#define bfa_os_reg_read(_raddr) bfa_os_wtole(readl(_raddr))
165#define bfa_os_reg_write(_raddr, _val) writel(bfa_os_wtole((_val)), (_raddr))
166#define bfa_os_mem_read(_raddr, _off) \
167 bfa_os_ntohl(readl(((_raddr) + (_off))))
168#define bfa_os_mem_write(_raddr, _off, _val) \
169 writel(bfa_os_htonl((_val)), ((_raddr) + (_off)))
170
171#define BFA_TRC_TS(_trcm) \
172 ({ \
173 struct timeval tv; \
174 \
175 do_gettimeofday(&tv); \
176 (tv.tv_sec*1000000+tv.tv_usec); \
177 })
178
179struct bfa_log_mod_s;
180void bfa_os_printf(struct bfa_log_mod_s *log_mod, u32 msg_id,
181 const char *fmt, ...);
182#endif
183
184#define boolean_t int
185
186/**
187 * For current time stamp, OS API will fill-in
188 */
189struct bfa_timeval_s {
190 u32 tv_sec; /* seconds */
191 u32 tv_usec; /* microseconds */
192};
193
194void bfa_os_gettimeofday(struct bfa_timeval_s *tv);
195
196static inline void
197wwn2str(char *wwn_str, u64 wwn)
198{
199 union {
200 u64 wwn;
201 u8 byte[8];
202 } w;
203
204 w.wwn = wwn;
205 sprintf(wwn_str, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", w.byte[0],
206 w.byte[1], w.byte[2], w.byte[3], w.byte[4], w.byte[5],
207 w.byte[6], w.byte[7]);
208}
209
210static inline void
211fcid2str(char *fcid_str, u32 fcid)
212{
213 union {
214 u32 fcid;
215 u8 byte[4];
216 } f;
217
218 f.fcid = fcid;
219 sprintf(fcid_str, "%02x:%02x:%02x", f.byte[1], f.byte[2], f.byte[3]);
220}
221
222#endif /* __BFA_OS_INC_H__ */
diff --git a/drivers/scsi/bfa/bfa_port.c b/drivers/scsi/bfa/bfa_port.c
new file mode 100644
index 000000000000..cab19028361a
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_port.c
@@ -0,0 +1,460 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#include <defs/bfa_defs_port.h>
19#include <cs/bfa_trc.h>
20#include <cs/bfa_log.h>
21#include <cs/bfa_debug.h>
22#include <port/bfa_port.h>
23#include <bfi/bfi.h>
24#include <bfi/bfi_port.h>
25#include <bfa_ioc.h>
26#include <cna/bfa_cna_trcmod.h>
27
28BFA_TRC_FILE(CNA, PORT);
29
30#define bfa_ioc_portid(__ioc) ((__ioc)->port_id)
31#define bfa_lpuid(__arg) bfa_ioc_portid(&(__arg)->ioc)
32
33static void
34bfa_port_stats_swap(struct bfa_port_s *port, union bfa_pport_stats_u *stats)
35{
36 u32 *dip = (u32 *) stats;
37 u32 t0, t1;
38 int i;
39
40 for (i = 0; i < sizeof(union bfa_pport_stats_u) / sizeof(u32);
41 i += 2) {
42 t0 = dip[i];
43 t1 = dip[i + 1];
44#ifdef __BIGENDIAN
45 dip[i] = bfa_os_ntohl(t0);
46 dip[i + 1] = bfa_os_ntohl(t1);
47#else
48 dip[i] = bfa_os_ntohl(t1);
49 dip[i + 1] = bfa_os_ntohl(t0);
50#endif
51 }
52
53 /** todo
54 * QoS stats r also swapped as 64bit; that structure also
55 * has to use 64 bit counters
56 */
57}
58
59/**
60 * bfa_port_enable_isr()
61 *
62 *
63 * @param[in] port - Pointer to the port module
64 * status - Return status from the f/w
65 *
66 * @return void
67 */
68static void
69bfa_port_enable_isr(struct bfa_port_s *port, bfa_status_t status)
70{
71 bfa_assert(0);
72}
73
74/**
75 * bfa_port_disable_isr()
76 *
77 *
78 * @param[in] port - Pointer to the port module
79 * status - Return status from the f/w
80 *
81 * @return void
82 */
83static void
84bfa_port_disable_isr(struct bfa_port_s *port, bfa_status_t status)
85{
86 bfa_assert(0);
87}
88
89/**
90 * bfa_port_get_stats_isr()
91 *
92 *
93 * @param[in] port - Pointer to the Port module
94 * status - Return status from the f/w
95 *
96 * @return void
97 */
98static void
99bfa_port_get_stats_isr(struct bfa_port_s *port, bfa_status_t status)
100{
101 port->stats_status = status;
102 port->stats_busy = BFA_FALSE;
103
104 if (status == BFA_STATUS_OK) {
105 memcpy(port->stats, port->stats_dma.kva,
106 sizeof(union bfa_pport_stats_u));
107 bfa_port_stats_swap(port, port->stats);
108 }
109
110 if (port->stats_cbfn) {
111 port->stats_cbfn(port->stats_cbarg, status);
112 port->stats_cbfn = NULL;
113 }
114}
115
116/**
117 * bfa_port_clear_stats_isr()
118 *
119 *
120 * @param[in] port - Pointer to the Port module
121 * status - Return status from the f/w
122 *
123 * @return void
124 */
125static void
126bfa_port_clear_stats_isr(struct bfa_port_s *port, bfa_status_t status)
127{
128 port->stats_status = status;
129 port->stats_busy = BFA_FALSE;
130
131 if (port->stats_cbfn) {
132 port->stats_cbfn(port->stats_cbarg, status);
133 port->stats_cbfn = NULL;
134 }
135}
136
137/**
138 * bfa_port_isr()
139 *
140 *
141 * @param[in] Pointer to the Port module data structure.
142 *
143 * @return void
144 */
145static void
146bfa_port_isr(void *cbarg, struct bfi_mbmsg_s *m)
147{
148 struct bfa_port_s *port = (struct bfa_port_s *)cbarg;
149 union bfi_port_i2h_msg_u *i2hmsg;
150
151 i2hmsg = (union bfi_port_i2h_msg_u *)m;
152 bfa_trc(port, m->mh.msg_id);
153
154 switch (m->mh.msg_id) {
155 case BFI_PORT_I2H_ENABLE_RSP:
156 if (port->endis_pending == BFA_FALSE)
157 break;
158 bfa_port_enable_isr(port, i2hmsg->enable_rsp.status);
159 break;
160
161 case BFI_PORT_I2H_DISABLE_RSP:
162 if (port->endis_pending == BFA_FALSE)
163 break;
164 bfa_port_disable_isr(port, i2hmsg->disable_rsp.status);
165 break;
166
167 case BFI_PORT_I2H_GET_STATS_RSP:
168 /*
169 * Stats busy flag is still set? (may be cmd timed out)
170 */
171 if (port->stats_busy == BFA_FALSE)
172 break;
173 bfa_port_get_stats_isr(port, i2hmsg->getstats_rsp.status);
174 break;
175
176 case BFI_PORT_I2H_CLEAR_STATS_RSP:
177 if (port->stats_busy == BFA_FALSE)
178 break;
179 bfa_port_clear_stats_isr(port, i2hmsg->clearstats_rsp.status);
180 break;
181
182 default:
183 bfa_assert(0);
184 }
185}
186
187/**
188 * bfa_port_meminfo()
189 *
190 *
191 * @param[in] void
192 *
193 * @return Size of DMA region
194 */
195u32
196bfa_port_meminfo(void)
197{
198 return BFA_ROUNDUP(sizeof(union bfa_pport_stats_u), BFA_DMA_ALIGN_SZ);
199}
200
201/**
202 * bfa_port_mem_claim()
203 *
204 *
205 * @param[in] port Port module pointer
206 * dma_kva Kernel Virtual Address of Port DMA Memory
207 * dma_pa Physical Address of Port DMA Memory
208 *
209 * @return void
210 */
211void
212bfa_port_mem_claim(struct bfa_port_s *port, u8 *dma_kva, u64 dma_pa)
213{
214 port->stats_dma.kva = dma_kva;
215 port->stats_dma.pa = dma_pa;
216}
217
218/**
219 * bfa_port_enable()
220 *
221 * Send the Port enable request to the f/w
222 *
223 * @param[in] Pointer to the Port module data structure.
224 *
225 * @return Status
226 */
227bfa_status_t
228bfa_port_enable(struct bfa_port_s *port, bfa_port_endis_cbfn_t cbfn,
229 void *cbarg)
230{
231 struct bfi_port_generic_req_s *m;
232
233 /** todo Not implemented */
234 bfa_assert(0);
235
236 if (!bfa_ioc_is_operational(port->ioc)) {
237 bfa_trc(port, BFA_STATUS_IOC_FAILURE);
238 return BFA_STATUS_IOC_FAILURE;
239 }
240
241 if (port->endis_pending) {
242 bfa_trc(port, BFA_STATUS_DEVBUSY);
243 return BFA_STATUS_DEVBUSY;
244 }
245
246 m = (struct bfi_port_generic_req_s *)port->endis_mb.msg;
247
248 port->msgtag++;
249 port->endis_cbfn = cbfn;
250 port->endis_cbarg = cbarg;
251 port->endis_pending = BFA_TRUE;
252
253 bfi_h2i_set(m->mh, BFI_MC_PORT, BFI_PORT_H2I_ENABLE_REQ,
254 bfa_ioc_portid(port->ioc));
255 bfa_ioc_mbox_queue(port->ioc, &port->endis_mb);
256
257 return BFA_STATUS_OK;
258}
259
260/**
261 * bfa_port_disable()
262 *
263 * Send the Port disable request to the f/w
264 *
265 * @param[in] Pointer to the Port module data structure.
266 *
267 * @return Status
268 */
269bfa_status_t
270bfa_port_disable(struct bfa_port_s *port, bfa_port_endis_cbfn_t cbfn,
271 void *cbarg)
272{
273 struct bfi_port_generic_req_s *m;
274
275 /** todo Not implemented */
276 bfa_assert(0);
277
278 if (!bfa_ioc_is_operational(port->ioc)) {
279 bfa_trc(port, BFA_STATUS_IOC_FAILURE);
280 return BFA_STATUS_IOC_FAILURE;
281 }
282
283 if (port->endis_pending) {
284 bfa_trc(port, BFA_STATUS_DEVBUSY);
285 return BFA_STATUS_DEVBUSY;
286 }
287
288 m = (struct bfi_port_generic_req_s *)port->endis_mb.msg;
289
290 port->msgtag++;
291 port->endis_cbfn = cbfn;
292 port->endis_cbarg = cbarg;
293 port->endis_pending = BFA_TRUE;
294
295 bfi_h2i_set(m->mh, BFI_MC_PORT, BFI_PORT_H2I_DISABLE_REQ,
296 bfa_ioc_portid(port->ioc));
297 bfa_ioc_mbox_queue(port->ioc, &port->endis_mb);
298
299 return BFA_STATUS_OK;
300}
301
302/**
303 * bfa_port_get_stats()
304 *
305 * Send the request to the f/w to fetch Port statistics.
306 *
307 * @param[in] Pointer to the Port module data structure.
308 *
309 * @return Status
310 */
311bfa_status_t
312bfa_port_get_stats(struct bfa_port_s *port, union bfa_pport_stats_u *stats,
313 bfa_port_stats_cbfn_t cbfn, void *cbarg)
314{
315 struct bfi_port_get_stats_req_s *m;
316
317 if (!bfa_ioc_is_operational(port->ioc)) {
318 bfa_trc(port, BFA_STATUS_IOC_FAILURE);
319 return BFA_STATUS_IOC_FAILURE;
320 }
321
322 if (port->stats_busy) {
323 bfa_trc(port, BFA_STATUS_DEVBUSY);
324 return BFA_STATUS_DEVBUSY;
325 }
326
327 m = (struct bfi_port_get_stats_req_s *)port->stats_mb.msg;
328
329 port->stats = stats;
330 port->stats_cbfn = cbfn;
331 port->stats_cbarg = cbarg;
332 port->stats_busy = BFA_TRUE;
333 bfa_dma_be_addr_set(m->dma_addr, port->stats_dma.pa);
334
335 bfi_h2i_set(m->mh, BFI_MC_PORT, BFI_PORT_H2I_GET_STATS_REQ,
336 bfa_ioc_portid(port->ioc));
337 bfa_ioc_mbox_queue(port->ioc, &port->stats_mb);
338
339 return BFA_STATUS_OK;
340}
341
342/**
343 * bfa_port_clear_stats()
344 *
345 *
346 * @param[in] Pointer to the Port module data structure.
347 *
348 * @return Status
349 */
350bfa_status_t
351bfa_port_clear_stats(struct bfa_port_s *port, bfa_port_stats_cbfn_t cbfn,
352 void *cbarg)
353{
354 struct bfi_port_generic_req_s *m;
355
356 if (!bfa_ioc_is_operational(port->ioc)) {
357 bfa_trc(port, BFA_STATUS_IOC_FAILURE);
358 return BFA_STATUS_IOC_FAILURE;
359 }
360
361 if (port->stats_busy) {
362 bfa_trc(port, BFA_STATUS_DEVBUSY);
363 return BFA_STATUS_DEVBUSY;
364 }
365
366 m = (struct bfi_port_generic_req_s *)port->stats_mb.msg;
367
368 port->stats_cbfn = cbfn;
369 port->stats_cbarg = cbarg;
370 port->stats_busy = BFA_TRUE;
371
372 bfi_h2i_set(m->mh, BFI_MC_PORT, BFI_PORT_H2I_CLEAR_STATS_REQ,
373 bfa_ioc_portid(port->ioc));
374 bfa_ioc_mbox_queue(port->ioc, &port->stats_mb);
375
376 return BFA_STATUS_OK;
377}
378
379/**
380 * bfa_port_hbfail()
381 *
382 *
383 * @param[in] Pointer to the Port module data structure.
384 *
385 * @return void
386 */
387void
388bfa_port_hbfail(void *arg)
389{
390 struct bfa_port_s *port = (struct bfa_port_s *)arg;
391
392 /*
393 * Fail any pending get_stats/clear_stats requests
394 */
395 if (port->stats_busy) {
396 if (port->stats_cbfn)
397 port->stats_cbfn(port->dev, BFA_STATUS_FAILED);
398 port->stats_cbfn = NULL;
399 port->stats_busy = BFA_FALSE;
400 }
401
402 /*
403 * Clear any enable/disable is pending
404 */
405 if (port->endis_pending) {
406 if (port->endis_cbfn)
407 port->endis_cbfn(port->dev, BFA_STATUS_FAILED);
408 port->endis_cbfn = NULL;
409 port->endis_pending = BFA_FALSE;
410 }
411}
412
413/**
414 * bfa_port_attach()
415 *
416 *
417 * @param[in] port - Pointer to the Port module data structure
418 * ioc - Pointer to the ioc module data structure
419 * dev - Pointer to the device driver module data structure
420 * The device driver specific mbox ISR functions have
421 * this pointer as one of the parameters.
422 * trcmod -
423 * logmod -
424 *
425 * @return void
426 */
427void
428bfa_port_attach(struct bfa_port_s *port, struct bfa_ioc_s *ioc, void *dev,
429 struct bfa_trc_mod_s *trcmod, struct bfa_log_mod_s *logmod)
430{
431 bfa_assert(port);
432
433 port->dev = dev;
434 port->ioc = ioc;
435 port->trcmod = trcmod;
436 port->logmod = logmod;
437
438 port->stats_busy = port->endis_pending = BFA_FALSE;
439 port->stats_cbfn = port->endis_cbfn = NULL;
440
441 bfa_ioc_mbox_regisr(port->ioc, BFI_MC_PORT, bfa_port_isr, port);
442 bfa_ioc_hbfail_init(&port->hbfail, bfa_port_hbfail, port);
443 bfa_ioc_hbfail_register(port->ioc, &port->hbfail);
444
445 bfa_trc(port, 0);
446}
447
448/**
449 * bfa_port_detach()
450 *
451 *
452 * @param[in] port - Pointer to the Port module data structure
453 *
454 * @return void
455 */
456void
457bfa_port_detach(struct bfa_port_s *port)
458{
459 bfa_trc(port, 0);
460}
diff --git a/drivers/scsi/bfa/bfa_port_priv.h b/drivers/scsi/bfa/bfa_port_priv.h
new file mode 100644
index 000000000000..4b97e2759908
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_port_priv.h
@@ -0,0 +1,90 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFA_PORT_PRIV_H__
19#define __BFA_PORT_PRIV_H__
20
21#include <defs/bfa_defs_pport.h>
22#include <bfi/bfi_pport.h>
23#include "bfa_intr_priv.h"
24
25/**
26 * BFA physical port data structure
27 */
28struct bfa_pport_s {
29 struct bfa_s *bfa; /* parent BFA instance */
30 bfa_sm_t sm; /* port state machine */
31 wwn_t nwwn; /* node wwn of physical port */
32 wwn_t pwwn; /* port wwn of physical oprt */
33 enum bfa_pport_speed speed_sup;
34 /* supported speeds */
35 enum bfa_pport_speed speed; /* current speed */
36 enum bfa_pport_topology topology; /* current topology */
37 u8 myalpa; /* my ALPA in LOOP topology */
38 u8 rsvd[3];
39 struct bfa_pport_cfg_s cfg; /* current port configuration */
40 struct bfa_qos_attr_s qos_attr; /* QoS Attributes */
41 struct bfa_qos_vc_attr_s qos_vc_attr; /* VC info from ELP */
42 struct bfa_reqq_wait_s reqq_wait;
43 /* to wait for room in reqq */
44 struct bfa_reqq_wait_s svcreq_wait;
45 /* to wait for room in reqq */
46 struct bfa_reqq_wait_s stats_reqq_wait;
47 /* to wait for room in reqq (stats) */
48 void *event_cbarg;
49 void (*event_cbfn) (void *cbarg,
50 bfa_pport_event_t event);
51 union {
52 union bfi_pport_i2h_msg_u i2hmsg;
53 } event_arg;
54 void *bfad; /* BFA driver handle */
55 struct bfa_cb_qe_s hcb_qe; /* BFA callback queue elem */
56 enum bfa_pport_linkstate hcb_event;
57 /* link event for callback */
58 u32 msgtag; /* fimrware msg tag for reply */
59 u8 *stats_kva;
60 u64 stats_pa;
61 union bfa_pport_stats_u *stats; /* pport stats */
62 u32 mypid : 24;
63 u32 rsvd_b : 8;
64 struct bfa_timer_s timer; /* timer */
65 union bfa_pport_stats_u *stats_ret;
66 /* driver stats location */
67 bfa_status_t stats_status;
68 /* stats/statsclr status */
69 bfa_boolean_t stats_busy;
70 /* outstanding stats/statsclr */
71 bfa_boolean_t stats_qfull;
72 bfa_boolean_t diag_busy;
73 /* diag busy status */
74 bfa_boolean_t beacon;
75 /* port beacon status */
76 bfa_boolean_t link_e2e_beacon;
77 /* link beacon status */
78 bfa_cb_pport_t stats_cbfn;
79 /* driver callback function */
80 void *stats_cbarg;
81 /* *!< user callback arg */
82};
83
84#define BFA_PORT_MOD(__bfa) (&(__bfa)->modules.pport)
85
86/*
87 * public functions
88 */
89void bfa_pport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
90#endif /* __BFA_PORT_PRIV_H__ */
diff --git a/drivers/scsi/bfa/bfa_priv.h b/drivers/scsi/bfa/bfa_priv.h
new file mode 100644
index 000000000000..0747a6b26f7b
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_priv.h
@@ -0,0 +1,113 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFA_PRIV_H__
19#define __BFA_PRIV_H__
20
21#include "bfa_iocfc.h"
22#include "bfa_intr_priv.h"
23#include "bfa_trcmod_priv.h"
24#include "bfa_modules_priv.h"
25#include "bfa_fwimg_priv.h"
26#include <cs/bfa_log.h>
27#include <bfa_timer.h>
28
29/**
30 * Macro to define a new BFA module
31 */
32#define BFA_MODULE(__mod) \
33 static void bfa_ ## __mod ## _meminfo( \
34 struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len, \
35 u32 *dm_len); \
36 static void bfa_ ## __mod ## _attach(struct bfa_s *bfa, \
37 void *bfad, struct bfa_iocfc_cfg_s *cfg, \
38 struct bfa_meminfo_s *meminfo, \
39 struct bfa_pcidev_s *pcidev); \
40 static void bfa_ ## __mod ## _initdone(struct bfa_s *bfa); \
41 static void bfa_ ## __mod ## _detach(struct bfa_s *bfa); \
42 static void bfa_ ## __mod ## _start(struct bfa_s *bfa); \
43 static void bfa_ ## __mod ## _stop(struct bfa_s *bfa); \
44 static void bfa_ ## __mod ## _iocdisable(struct bfa_s *bfa); \
45 \
46 extern struct bfa_module_s hal_mod_ ## __mod; \
47 struct bfa_module_s hal_mod_ ## __mod = { \
48 bfa_ ## __mod ## _meminfo, \
49 bfa_ ## __mod ## _attach, \
50 bfa_ ## __mod ## _initdone, \
51 bfa_ ## __mod ## _detach, \
52 bfa_ ## __mod ## _start, \
53 bfa_ ## __mod ## _stop, \
54 bfa_ ## __mod ## _iocdisable, \
55 }
56
57#define BFA_CACHELINE_SZ (256)
58
59/**
60 * Structure used to interact between different BFA sub modules
61 *
62 * Each sub module needs to implement only the entry points relevant to it (and
63 * can leave entry points as NULL)
64 */
65struct bfa_module_s {
66 void (*meminfo) (struct bfa_iocfc_cfg_s *cfg, u32 *km_len,
67 u32 *dm_len);
68 void (*attach) (struct bfa_s *bfa, void *bfad,
69 struct bfa_iocfc_cfg_s *cfg,
70 struct bfa_meminfo_s *meminfo,
71 struct bfa_pcidev_s *pcidev);
72 void (*initdone) (struct bfa_s *bfa);
73 void (*detach) (struct bfa_s *bfa);
74 void (*start) (struct bfa_s *bfa);
75 void (*stop) (struct bfa_s *bfa);
76 void (*iocdisable) (struct bfa_s *bfa);
77};
78
79extern struct bfa_module_s *hal_mods[];
80
81struct bfa_s {
82 void *bfad; /* BFA driver instance */
83 struct bfa_aen_s *aen; /* AEN module */
84 struct bfa_plog_s *plog; /* portlog buffer */
85 struct bfa_log_mod_s *logm; /* driver logging modulen */
86 struct bfa_trc_mod_s *trcmod; /* driver tracing */
87 struct bfa_ioc_s ioc; /* IOC module */
88 struct bfa_iocfc_s iocfc; /* IOCFC module */
89 struct bfa_timer_mod_s timer_mod; /* timer module */
90 struct bfa_modules_s modules; /* BFA modules */
91 struct list_head comp_q; /* pending completions */
92 bfa_boolean_t rme_process; /* RME processing enabled */
93 struct list_head reqq_waitq[BFI_IOC_MAX_CQS];
94 bfa_boolean_t fcs; /* FCS is attached to BFA */
95 struct bfa_msix_s msix;
96};
97
98extern bfa_isr_func_t bfa_isrs[BFI_MC_MAX];
99extern bfa_ioc_mbox_mcfunc_t bfa_mbox_isrs[];
100extern bfa_boolean_t bfa_auto_recover;
101extern struct bfa_module_s hal_mod_flash;
102extern struct bfa_module_s hal_mod_fcdiag;
103extern struct bfa_module_s hal_mod_sgpg;
104extern struct bfa_module_s hal_mod_pport;
105extern struct bfa_module_s hal_mod_fcxp;
106extern struct bfa_module_s hal_mod_lps;
107extern struct bfa_module_s hal_mod_uf;
108extern struct bfa_module_s hal_mod_rport;
109extern struct bfa_module_s hal_mod_fcpim;
110extern struct bfa_module_s hal_mod_pbind;
111
112#endif /* __BFA_PRIV_H__ */
113
diff --git a/drivers/scsi/bfa/bfa_rport.c b/drivers/scsi/bfa/bfa_rport.c
new file mode 100644
index 000000000000..16da77a8db28
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_rport.c
@@ -0,0 +1,911 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#include <bfa.h>
19#include <bfa_svc.h>
20#include <cs/bfa_debug.h>
21#include <bfi/bfi_rport.h>
22#include "bfa_intr_priv.h"
23
24BFA_TRC_FILE(HAL, RPORT);
25BFA_MODULE(rport);
26
27#define bfa_rport_offline_cb(__rp) do { \
28 if ((__rp)->bfa->fcs) \
29 bfa_cb_rport_offline((__rp)->rport_drv); \
30 else { \
31 bfa_cb_queue((__rp)->bfa, &(__rp)->hcb_qe, \
32 __bfa_cb_rport_offline, (__rp)); \
33 } \
34} while (0)
35
36#define bfa_rport_online_cb(__rp) do { \
37 if ((__rp)->bfa->fcs) \
38 bfa_cb_rport_online((__rp)->rport_drv); \
39 else { \
40 bfa_cb_queue((__rp)->bfa, &(__rp)->hcb_qe, \
41 __bfa_cb_rport_online, (__rp)); \
42 } \
43} while (0)
44
45/*
46 * forward declarations
47 */
48static struct bfa_rport_s *bfa_rport_alloc(struct bfa_rport_mod_s *rp_mod);
49static void bfa_rport_free(struct bfa_rport_s *rport);
50static bfa_boolean_t bfa_rport_send_fwcreate(struct bfa_rport_s *rp);
51static bfa_boolean_t bfa_rport_send_fwdelete(struct bfa_rport_s *rp);
52static bfa_boolean_t bfa_rport_send_fwspeed(struct bfa_rport_s *rp);
53static void __bfa_cb_rport_online(void *cbarg, bfa_boolean_t complete);
54static void __bfa_cb_rport_offline(void *cbarg, bfa_boolean_t complete);
55
56/**
57 * bfa_rport_sm BFA rport state machine
58 */
59
60
61enum bfa_rport_event {
62 BFA_RPORT_SM_CREATE = 1, /* rport create event */
63 BFA_RPORT_SM_DELETE = 2, /* deleting an existing rport */
64 BFA_RPORT_SM_ONLINE = 3, /* rport is online */
65 BFA_RPORT_SM_OFFLINE = 4, /* rport is offline */
66 BFA_RPORT_SM_FWRSP = 5, /* firmware response */
67 BFA_RPORT_SM_HWFAIL = 6, /* IOC h/w failure */
68 BFA_RPORT_SM_QOS_SCN = 7, /* QoS SCN from firmware */
69 BFA_RPORT_SM_SET_SPEED = 8, /* Set Rport Speed */
70 BFA_RPORT_SM_QRESUME = 9, /* space in requeue queue */
71};
72
73static void bfa_rport_sm_uninit(struct bfa_rport_s *rp,
74 enum bfa_rport_event event);
75static void bfa_rport_sm_created(struct bfa_rport_s *rp,
76 enum bfa_rport_event event);
77static void bfa_rport_sm_fwcreate(struct bfa_rport_s *rp,
78 enum bfa_rport_event event);
79static void bfa_rport_sm_online(struct bfa_rport_s *rp,
80 enum bfa_rport_event event);
81static void bfa_rport_sm_fwdelete(struct bfa_rport_s *rp,
82 enum bfa_rport_event event);
83static void bfa_rport_sm_offline(struct bfa_rport_s *rp,
84 enum bfa_rport_event event);
85static void bfa_rport_sm_deleting(struct bfa_rport_s *rp,
86 enum bfa_rport_event event);
87static void bfa_rport_sm_offline_pending(struct bfa_rport_s *rp,
88 enum bfa_rport_event event);
89static void bfa_rport_sm_delete_pending(struct bfa_rport_s *rp,
90 enum bfa_rport_event event);
91static void bfa_rport_sm_iocdisable(struct bfa_rport_s *rp,
92 enum bfa_rport_event event);
93static void bfa_rport_sm_fwcreate_qfull(struct bfa_rport_s *rp,
94 enum bfa_rport_event event);
95static void bfa_rport_sm_fwdelete_qfull(struct bfa_rport_s *rp,
96 enum bfa_rport_event event);
97static void bfa_rport_sm_deleting_qfull(struct bfa_rport_s *rp,
98 enum bfa_rport_event event);
99
100/**
101 * Beginning state, only online event expected.
102 */
103static void
104bfa_rport_sm_uninit(struct bfa_rport_s *rp, enum bfa_rport_event event)
105{
106 bfa_trc(rp->bfa, rp->rport_tag);
107 bfa_trc(rp->bfa, event);
108
109 switch (event) {
110 case BFA_RPORT_SM_CREATE:
111 bfa_stats(rp, sm_un_cr);
112 bfa_sm_set_state(rp, bfa_rport_sm_created);
113 break;
114
115 default:
116 bfa_stats(rp, sm_un_unexp);
117 bfa_assert(0);
118 }
119}
120
121static void
122bfa_rport_sm_created(struct bfa_rport_s *rp, enum bfa_rport_event event)
123{
124 bfa_trc(rp->bfa, rp->rport_tag);
125 bfa_trc(rp->bfa, event);
126
127 switch (event) {
128 case BFA_RPORT_SM_ONLINE:
129 bfa_stats(rp, sm_cr_on);
130 if (bfa_rport_send_fwcreate(rp))
131 bfa_sm_set_state(rp, bfa_rport_sm_fwcreate);
132 else
133 bfa_sm_set_state(rp, bfa_rport_sm_fwcreate_qfull);
134 break;
135
136 case BFA_RPORT_SM_DELETE:
137 bfa_stats(rp, sm_cr_del);
138 bfa_sm_set_state(rp, bfa_rport_sm_uninit);
139 bfa_rport_free(rp);
140 break;
141
142 case BFA_RPORT_SM_HWFAIL:
143 bfa_stats(rp, sm_cr_hwf);
144 bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
145 break;
146
147 default:
148 bfa_stats(rp, sm_cr_unexp);
149 bfa_assert(0);
150 }
151}
152
153/**
154 * Waiting for rport create response from firmware.
155 */
156static void
157bfa_rport_sm_fwcreate(struct bfa_rport_s *rp, enum bfa_rport_event event)
158{
159 bfa_trc(rp->bfa, rp->rport_tag);
160 bfa_trc(rp->bfa, event);
161
162 switch (event) {
163 case BFA_RPORT_SM_FWRSP:
164 bfa_stats(rp, sm_fwc_rsp);
165 bfa_sm_set_state(rp, bfa_rport_sm_online);
166 bfa_rport_online_cb(rp);
167 break;
168
169 case BFA_RPORT_SM_DELETE:
170 bfa_stats(rp, sm_fwc_del);
171 bfa_sm_set_state(rp, bfa_rport_sm_delete_pending);
172 break;
173
174 case BFA_RPORT_SM_OFFLINE:
175 bfa_stats(rp, sm_fwc_off);
176 bfa_sm_set_state(rp, bfa_rport_sm_offline_pending);
177 break;
178
179 case BFA_RPORT_SM_HWFAIL:
180 bfa_stats(rp, sm_fwc_hwf);
181 bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
182 break;
183
184 default:
185 bfa_stats(rp, sm_fwc_unexp);
186 bfa_assert(0);
187 }
188}
189
190/**
191 * Request queue is full, awaiting queue resume to send create request.
192 */
193static void
194bfa_rport_sm_fwcreate_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event)
195{
196 bfa_trc(rp->bfa, rp->rport_tag);
197 bfa_trc(rp->bfa, event);
198
199 switch (event) {
200 case BFA_RPORT_SM_QRESUME:
201 bfa_sm_set_state(rp, bfa_rport_sm_fwcreate);
202 bfa_rport_send_fwcreate(rp);
203 break;
204
205 case BFA_RPORT_SM_DELETE:
206 bfa_stats(rp, sm_fwc_del);
207 bfa_sm_set_state(rp, bfa_rport_sm_uninit);
208 bfa_reqq_wcancel(&rp->reqq_wait);
209 bfa_rport_free(rp);
210 break;
211
212 case BFA_RPORT_SM_OFFLINE:
213 bfa_stats(rp, sm_fwc_off);
214 bfa_sm_set_state(rp, bfa_rport_sm_offline);
215 bfa_reqq_wcancel(&rp->reqq_wait);
216 bfa_rport_offline_cb(rp);
217 break;
218
219 case BFA_RPORT_SM_HWFAIL:
220 bfa_stats(rp, sm_fwc_hwf);
221 bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
222 bfa_reqq_wcancel(&rp->reqq_wait);
223 break;
224
225 default:
226 bfa_stats(rp, sm_fwc_unexp);
227 bfa_assert(0);
228 }
229}
230
231/**
232 * Online state - normal parking state.
233 */
234static void
235bfa_rport_sm_online(struct bfa_rport_s *rp, enum bfa_rport_event event)
236{
237 struct bfi_rport_qos_scn_s *qos_scn;
238
239 bfa_trc(rp->bfa, rp->rport_tag);
240 bfa_trc(rp->bfa, event);
241
242 switch (event) {
243 case BFA_RPORT_SM_OFFLINE:
244 bfa_stats(rp, sm_on_off);
245 if (bfa_rport_send_fwdelete(rp))
246 bfa_sm_set_state(rp, bfa_rport_sm_fwdelete);
247 else
248 bfa_sm_set_state(rp, bfa_rport_sm_fwdelete_qfull);
249 break;
250
251 case BFA_RPORT_SM_DELETE:
252 bfa_stats(rp, sm_on_del);
253 if (bfa_rport_send_fwdelete(rp))
254 bfa_sm_set_state(rp, bfa_rport_sm_deleting);
255 else
256 bfa_sm_set_state(rp, bfa_rport_sm_deleting_qfull);
257 break;
258
259 case BFA_RPORT_SM_HWFAIL:
260 bfa_stats(rp, sm_on_hwf);
261 bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
262 break;
263
264 case BFA_RPORT_SM_SET_SPEED:
265 bfa_rport_send_fwspeed(rp);
266 break;
267
268 case BFA_RPORT_SM_QOS_SCN:
269 qos_scn = (struct bfi_rport_qos_scn_s *) rp->event_arg.fw_msg;
270 rp->qos_attr = qos_scn->new_qos_attr;
271 bfa_trc(rp->bfa, qos_scn->old_qos_attr.qos_flow_id);
272 bfa_trc(rp->bfa, qos_scn->new_qos_attr.qos_flow_id);
273 bfa_trc(rp->bfa, qos_scn->old_qos_attr.qos_priority);
274 bfa_trc(rp->bfa, qos_scn->new_qos_attr.qos_priority);
275
276 qos_scn->old_qos_attr.qos_flow_id =
277 bfa_os_ntohl(qos_scn->old_qos_attr.qos_flow_id);
278 qos_scn->new_qos_attr.qos_flow_id =
279 bfa_os_ntohl(qos_scn->new_qos_attr.qos_flow_id);
280 qos_scn->old_qos_attr.qos_priority =
281 bfa_os_ntohl(qos_scn->old_qos_attr.qos_priority);
282 qos_scn->new_qos_attr.qos_priority =
283 bfa_os_ntohl(qos_scn->new_qos_attr.qos_priority);
284
285 if (qos_scn->old_qos_attr.qos_flow_id !=
286 qos_scn->new_qos_attr.qos_flow_id)
287 bfa_cb_rport_qos_scn_flowid(rp->rport_drv,
288 qos_scn->old_qos_attr,
289 qos_scn->new_qos_attr);
290 if (qos_scn->old_qos_attr.qos_priority !=
291 qos_scn->new_qos_attr.qos_priority)
292 bfa_cb_rport_qos_scn_prio(rp->rport_drv,
293 qos_scn->old_qos_attr,
294 qos_scn->new_qos_attr);
295 break;
296
297 default:
298 bfa_stats(rp, sm_on_unexp);
299 bfa_assert(0);
300 }
301}
302
303/**
304 * Firmware rport is being deleted - awaiting f/w response.
305 */
306static void
307bfa_rport_sm_fwdelete(struct bfa_rport_s *rp, enum bfa_rport_event event)
308{
309 bfa_trc(rp->bfa, rp->rport_tag);
310 bfa_trc(rp->bfa, event);
311
312 switch (event) {
313 case BFA_RPORT_SM_FWRSP:
314 bfa_stats(rp, sm_fwd_rsp);
315 bfa_sm_set_state(rp, bfa_rport_sm_offline);
316 bfa_rport_offline_cb(rp);
317 break;
318
319 case BFA_RPORT_SM_DELETE:
320 bfa_stats(rp, sm_fwd_del);
321 bfa_sm_set_state(rp, bfa_rport_sm_deleting);
322 break;
323
324 case BFA_RPORT_SM_HWFAIL:
325 bfa_stats(rp, sm_fwd_hwf);
326 bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
327 bfa_rport_offline_cb(rp);
328 break;
329
330 default:
331 bfa_stats(rp, sm_fwd_unexp);
332 bfa_assert(0);
333 }
334}
335
336static void
337bfa_rport_sm_fwdelete_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event)
338{
339 bfa_trc(rp->bfa, rp->rport_tag);
340 bfa_trc(rp->bfa, event);
341
342 switch (event) {
343 case BFA_RPORT_SM_QRESUME:
344 bfa_sm_set_state(rp, bfa_rport_sm_fwdelete);
345 bfa_rport_send_fwdelete(rp);
346 break;
347
348 case BFA_RPORT_SM_DELETE:
349 bfa_stats(rp, sm_fwd_del);
350 bfa_sm_set_state(rp, bfa_rport_sm_deleting_qfull);
351 break;
352
353 case BFA_RPORT_SM_HWFAIL:
354 bfa_stats(rp, sm_fwd_hwf);
355 bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
356 bfa_reqq_wcancel(&rp->reqq_wait);
357 bfa_rport_offline_cb(rp);
358 break;
359
360 default:
361 bfa_stats(rp, sm_fwd_unexp);
362 bfa_assert(0);
363 }
364}
365
366/**
367 * Offline state.
368 */
369static void
370bfa_rport_sm_offline(struct bfa_rport_s *rp, enum bfa_rport_event event)
371{
372 bfa_trc(rp->bfa, rp->rport_tag);
373 bfa_trc(rp->bfa, event);
374
375 switch (event) {
376 case BFA_RPORT_SM_DELETE:
377 bfa_stats(rp, sm_off_del);
378 bfa_sm_set_state(rp, bfa_rport_sm_uninit);
379 bfa_rport_free(rp);
380 break;
381
382 case BFA_RPORT_SM_ONLINE:
383 bfa_stats(rp, sm_off_on);
384 if (bfa_rport_send_fwcreate(rp))
385 bfa_sm_set_state(rp, bfa_rport_sm_fwcreate);
386 else
387 bfa_sm_set_state(rp, bfa_rport_sm_fwcreate_qfull);
388 break;
389
390 case BFA_RPORT_SM_HWFAIL:
391 bfa_stats(rp, sm_off_hwf);
392 bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
393 break;
394
395 default:
396 bfa_stats(rp, sm_off_unexp);
397 bfa_assert(0);
398 }
399}
400
401/**
402 * Rport is deleted, waiting for firmware response to delete.
403 */
404static void
405bfa_rport_sm_deleting(struct bfa_rport_s *rp, enum bfa_rport_event event)
406{
407 bfa_trc(rp->bfa, rp->rport_tag);
408 bfa_trc(rp->bfa, event);
409
410 switch (event) {
411 case BFA_RPORT_SM_FWRSP:
412 bfa_stats(rp, sm_del_fwrsp);
413 bfa_sm_set_state(rp, bfa_rport_sm_uninit);
414 bfa_rport_free(rp);
415 break;
416
417 case BFA_RPORT_SM_HWFAIL:
418 bfa_stats(rp, sm_del_hwf);
419 bfa_sm_set_state(rp, bfa_rport_sm_uninit);
420 bfa_rport_free(rp);
421 break;
422
423 default:
424 bfa_assert(0);
425 }
426}
427
428static void
429bfa_rport_sm_deleting_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event)
430{
431 bfa_trc(rp->bfa, rp->rport_tag);
432 bfa_trc(rp->bfa, event);
433
434 switch (event) {
435 case BFA_RPORT_SM_QRESUME:
436 bfa_stats(rp, sm_del_fwrsp);
437 bfa_sm_set_state(rp, bfa_rport_sm_deleting);
438 bfa_rport_send_fwdelete(rp);
439 break;
440
441 case BFA_RPORT_SM_HWFAIL:
442 bfa_stats(rp, sm_del_hwf);
443 bfa_sm_set_state(rp, bfa_rport_sm_uninit);
444 bfa_reqq_wcancel(&rp->reqq_wait);
445 bfa_rport_free(rp);
446 break;
447
448 default:
449 bfa_assert(0);
450 }
451}
452
453/**
454 * Waiting for rport create response from firmware. A delete is pending.
455 */
456static void
457bfa_rport_sm_delete_pending(struct bfa_rport_s *rp,
458 enum bfa_rport_event event)
459{
460 bfa_trc(rp->bfa, rp->rport_tag);
461 bfa_trc(rp->bfa, event);
462
463 switch (event) {
464 case BFA_RPORT_SM_FWRSP:
465 bfa_stats(rp, sm_delp_fwrsp);
466 if (bfa_rport_send_fwdelete(rp))
467 bfa_sm_set_state(rp, bfa_rport_sm_deleting);
468 else
469 bfa_sm_set_state(rp, bfa_rport_sm_deleting_qfull);
470 break;
471
472 case BFA_RPORT_SM_HWFAIL:
473 bfa_stats(rp, sm_delp_hwf);
474 bfa_sm_set_state(rp, bfa_rport_sm_uninit);
475 bfa_rport_free(rp);
476 break;
477
478 default:
479 bfa_stats(rp, sm_delp_unexp);
480 bfa_assert(0);
481 }
482}
483
484/**
485 * Waiting for rport create response from firmware. Rport offline is pending.
486 */
487static void
488bfa_rport_sm_offline_pending(struct bfa_rport_s *rp,
489 enum bfa_rport_event event)
490{
491 bfa_trc(rp->bfa, rp->rport_tag);
492 bfa_trc(rp->bfa, event);
493
494 switch (event) {
495 case BFA_RPORT_SM_FWRSP:
496 bfa_stats(rp, sm_offp_fwrsp);
497 if (bfa_rport_send_fwdelete(rp))
498 bfa_sm_set_state(rp, bfa_rport_sm_fwdelete);
499 else
500 bfa_sm_set_state(rp, bfa_rport_sm_fwdelete_qfull);
501 break;
502
503 case BFA_RPORT_SM_DELETE:
504 bfa_stats(rp, sm_offp_del);
505 bfa_sm_set_state(rp, bfa_rport_sm_delete_pending);
506 break;
507
508 case BFA_RPORT_SM_HWFAIL:
509 bfa_stats(rp, sm_offp_hwf);
510 bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
511 break;
512
513 default:
514 bfa_stats(rp, sm_offp_unexp);
515 bfa_assert(0);
516 }
517}
518
519/**
520 * IOC h/w failed.
521 */
522static void
523bfa_rport_sm_iocdisable(struct bfa_rport_s *rp, enum bfa_rport_event event)
524{
525 bfa_trc(rp->bfa, rp->rport_tag);
526 bfa_trc(rp->bfa, event);
527
528 switch (event) {
529 case BFA_RPORT_SM_OFFLINE:
530 bfa_stats(rp, sm_iocd_off);
531 bfa_rport_offline_cb(rp);
532 break;
533
534 case BFA_RPORT_SM_DELETE:
535 bfa_stats(rp, sm_iocd_del);
536 bfa_sm_set_state(rp, bfa_rport_sm_uninit);
537 bfa_rport_free(rp);
538 break;
539
540 case BFA_RPORT_SM_ONLINE:
541 bfa_stats(rp, sm_iocd_on);
542 if (bfa_rport_send_fwcreate(rp))
543 bfa_sm_set_state(rp, bfa_rport_sm_fwcreate);
544 else
545 bfa_sm_set_state(rp, bfa_rport_sm_fwcreate_qfull);
546 break;
547
548 case BFA_RPORT_SM_HWFAIL:
549 break;
550
551 default:
552 bfa_stats(rp, sm_iocd_unexp);
553 bfa_assert(0);
554 }
555}
556
557
558
559/**
560 * bfa_rport_private BFA rport private functions
561 */
562
563static void
564__bfa_cb_rport_online(void *cbarg, bfa_boolean_t complete)
565{
566 struct bfa_rport_s *rp = cbarg;
567
568 if (complete)
569 bfa_cb_rport_online(rp->rport_drv);
570}
571
572static void
573__bfa_cb_rport_offline(void *cbarg, bfa_boolean_t complete)
574{
575 struct bfa_rport_s *rp = cbarg;
576
577 if (complete)
578 bfa_cb_rport_offline(rp->rport_drv);
579}
580
581static void
582bfa_rport_qresume(void *cbarg)
583{
584 struct bfa_rport_s *rp = cbarg;
585
586 bfa_sm_send_event(rp, BFA_RPORT_SM_QRESUME);
587}
588
589static void
590bfa_rport_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len,
591 u32 *dm_len)
592{
593 if (cfg->fwcfg.num_rports < BFA_RPORT_MIN)
594 cfg->fwcfg.num_rports = BFA_RPORT_MIN;
595
596 *km_len += cfg->fwcfg.num_rports * sizeof(struct bfa_rport_s);
597}
598
599static void
600bfa_rport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
601 struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev)
602{
603 struct bfa_rport_mod_s *mod = BFA_RPORT_MOD(bfa);
604 struct bfa_rport_s *rp;
605 u16 i;
606
607 INIT_LIST_HEAD(&mod->rp_free_q);
608 INIT_LIST_HEAD(&mod->rp_active_q);
609
610 rp = (struct bfa_rport_s *) bfa_meminfo_kva(meminfo);
611 mod->rps_list = rp;
612 mod->num_rports = cfg->fwcfg.num_rports;
613
614 bfa_assert(mod->num_rports
615 && !(mod->num_rports & (mod->num_rports - 1)));
616
617 for (i = 0; i < mod->num_rports; i++, rp++) {
618 bfa_os_memset(rp, 0, sizeof(struct bfa_rport_s));
619 rp->bfa = bfa;
620 rp->rport_tag = i;
621 bfa_sm_set_state(rp, bfa_rport_sm_uninit);
622
623 /**
624 * - is unused
625 */
626 if (i)
627 list_add_tail(&rp->qe, &mod->rp_free_q);
628
629 bfa_reqq_winit(&rp->reqq_wait, bfa_rport_qresume, rp);
630 }
631
632 /**
633 * consume memory
634 */
635 bfa_meminfo_kva(meminfo) = (u8 *) rp;
636}
637
638static void
639bfa_rport_initdone(struct bfa_s *bfa)
640{
641}
642
643static void
644bfa_rport_detach(struct bfa_s *bfa)
645{
646}
647
648static void
649bfa_rport_start(struct bfa_s *bfa)
650{
651}
652
653static void
654bfa_rport_stop(struct bfa_s *bfa)
655{
656}
657
658static void
659bfa_rport_iocdisable(struct bfa_s *bfa)
660{
661 struct bfa_rport_mod_s *mod = BFA_RPORT_MOD(bfa);
662 struct bfa_rport_s *rport;
663 struct list_head *qe, *qen;
664
665 list_for_each_safe(qe, qen, &mod->rp_active_q) {
666 rport = (struct bfa_rport_s *) qe;
667 bfa_sm_send_event(rport, BFA_RPORT_SM_HWFAIL);
668 }
669}
670
671static struct bfa_rport_s *
672bfa_rport_alloc(struct bfa_rport_mod_s *mod)
673{
674 struct bfa_rport_s *rport;
675
676 bfa_q_deq(&mod->rp_free_q, &rport);
677 if (rport)
678 list_add_tail(&rport->qe, &mod->rp_active_q);
679
680 return (rport);
681}
682
683static void
684bfa_rport_free(struct bfa_rport_s *rport)
685{
686 struct bfa_rport_mod_s *mod = BFA_RPORT_MOD(rport->bfa);
687
688 bfa_assert(bfa_q_is_on_q(&mod->rp_active_q, rport));
689 list_del(&rport->qe);
690 list_add_tail(&rport->qe, &mod->rp_free_q);
691}
692
693static bfa_boolean_t
694bfa_rport_send_fwcreate(struct bfa_rport_s *rp)
695{
696 struct bfi_rport_create_req_s *m;
697
698 /**
699 * check for room in queue to send request now
700 */
701 m = bfa_reqq_next(rp->bfa, BFA_REQQ_RPORT);
702 if (!m) {
703 bfa_reqq_wait(rp->bfa, BFA_REQQ_RPORT, &rp->reqq_wait);
704 return BFA_FALSE;
705 }
706
707 bfi_h2i_set(m->mh, BFI_MC_RPORT, BFI_RPORT_H2I_CREATE_REQ,
708 bfa_lpuid(rp->bfa));
709 m->bfa_handle = rp->rport_tag;
710 m->max_frmsz = bfa_os_htons(rp->rport_info.max_frmsz);
711 m->pid = rp->rport_info.pid;
712 m->lp_tag = rp->rport_info.lp_tag;
713 m->local_pid = rp->rport_info.local_pid;
714 m->fc_class = rp->rport_info.fc_class;
715 m->vf_en = rp->rport_info.vf_en;
716 m->vf_id = rp->rport_info.vf_id;
717 m->cisc = rp->rport_info.cisc;
718
719 /**
720 * queue I/O message to firmware
721 */
722 bfa_reqq_produce(rp->bfa, BFA_REQQ_RPORT);
723 return BFA_TRUE;
724}
725
726static bfa_boolean_t
727bfa_rport_send_fwdelete(struct bfa_rport_s *rp)
728{
729 struct bfi_rport_delete_req_s *m;
730
731 /**
732 * check for room in queue to send request now
733 */
734 m = bfa_reqq_next(rp->bfa, BFA_REQQ_RPORT);
735 if (!m) {
736 bfa_reqq_wait(rp->bfa, BFA_REQQ_RPORT, &rp->reqq_wait);
737 return BFA_FALSE;
738 }
739
740 bfi_h2i_set(m->mh, BFI_MC_RPORT, BFI_RPORT_H2I_DELETE_REQ,
741 bfa_lpuid(rp->bfa));
742 m->fw_handle = rp->fw_handle;
743
744 /**
745 * queue I/O message to firmware
746 */
747 bfa_reqq_produce(rp->bfa, BFA_REQQ_RPORT);
748 return BFA_TRUE;
749}
750
751static bfa_boolean_t
752bfa_rport_send_fwspeed(struct bfa_rport_s *rp)
753{
754 struct bfa_rport_speed_req_s *m;
755
756 /**
757 * check for room in queue to send request now
758 */
759 m = bfa_reqq_next(rp->bfa, BFA_REQQ_RPORT);
760 if (!m) {
761 bfa_trc(rp->bfa, rp->rport_info.speed);
762 return BFA_FALSE;
763 }
764
765 bfi_h2i_set(m->mh, BFI_MC_RPORT, BFI_RPORT_H2I_SET_SPEED_REQ,
766 bfa_lpuid(rp->bfa));
767 m->fw_handle = rp->fw_handle;
768 m->speed = (u8)rp->rport_info.speed;
769
770 /**
771 * queue I/O message to firmware
772 */
773 bfa_reqq_produce(rp->bfa, BFA_REQQ_RPORT);
774 return BFA_TRUE;
775}
776
777
778
779/**
780 * bfa_rport_public
781 */
782
783/**
784 * Rport interrupt processing.
785 */
786void
787bfa_rport_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
788{
789 union bfi_rport_i2h_msg_u msg;
790 struct bfa_rport_s *rp;
791
792 bfa_trc(bfa, m->mhdr.msg_id);
793
794 msg.msg = m;
795
796 switch (m->mhdr.msg_id) {
797 case BFI_RPORT_I2H_CREATE_RSP:
798 rp = BFA_RPORT_FROM_TAG(bfa, msg.create_rsp->bfa_handle);
799 rp->fw_handle = msg.create_rsp->fw_handle;
800 rp->qos_attr = msg.create_rsp->qos_attr;
801 bfa_assert(msg.create_rsp->status == BFA_STATUS_OK);
802 bfa_sm_send_event(rp, BFA_RPORT_SM_FWRSP);
803 break;
804
805 case BFI_RPORT_I2H_DELETE_RSP:
806 rp = BFA_RPORT_FROM_TAG(bfa, msg.delete_rsp->bfa_handle);
807 bfa_assert(msg.delete_rsp->status == BFA_STATUS_OK);
808 bfa_sm_send_event(rp, BFA_RPORT_SM_FWRSP);
809 break;
810
811 case BFI_RPORT_I2H_QOS_SCN:
812 rp = BFA_RPORT_FROM_TAG(bfa, msg.qos_scn_evt->bfa_handle);
813 rp->event_arg.fw_msg = msg.qos_scn_evt;
814 bfa_sm_send_event(rp, BFA_RPORT_SM_QOS_SCN);
815 break;
816
817 default:
818 bfa_trc(bfa, m->mhdr.msg_id);
819 bfa_assert(0);
820 }
821}
822
823
824
825/**
826 * bfa_rport_api
827 */
828
829struct bfa_rport_s *
830bfa_rport_create(struct bfa_s *bfa, void *rport_drv)
831{
832 struct bfa_rport_s *rp;
833
834 rp = bfa_rport_alloc(BFA_RPORT_MOD(bfa));
835
836 if (rp == NULL)
837 return (NULL);
838
839 rp->bfa = bfa;
840 rp->rport_drv = rport_drv;
841 bfa_rport_clear_stats(rp);
842
843 bfa_assert(bfa_sm_cmp_state(rp, bfa_rport_sm_uninit));
844 bfa_sm_send_event(rp, BFA_RPORT_SM_CREATE);
845
846 return (rp);
847}
848
849void
850bfa_rport_delete(struct bfa_rport_s *rport)
851{
852 bfa_sm_send_event(rport, BFA_RPORT_SM_DELETE);
853}
854
855void
856bfa_rport_online(struct bfa_rport_s *rport, struct bfa_rport_info_s *rport_info)
857{
858 bfa_assert(rport_info->max_frmsz != 0);
859
860 /**
861 * Some JBODs are seen to be not setting PDU size correctly in PLOGI
862 * responses. Default to minimum size.
863 */
864 if (rport_info->max_frmsz == 0) {
865 bfa_trc(rport->bfa, rport->rport_tag);
866 rport_info->max_frmsz = FC_MIN_PDUSZ;
867 }
868
869 bfa_os_assign(rport->rport_info, *rport_info);
870 bfa_sm_send_event(rport, BFA_RPORT_SM_ONLINE);
871}
872
873void
874bfa_rport_offline(struct bfa_rport_s *rport)
875{
876 bfa_sm_send_event(rport, BFA_RPORT_SM_OFFLINE);
877}
878
879void
880bfa_rport_speed(struct bfa_rport_s *rport, enum bfa_pport_speed speed)
881{
882 bfa_assert(speed != 0);
883 bfa_assert(speed != BFA_PPORT_SPEED_AUTO);
884
885 rport->rport_info.speed = speed;
886 bfa_sm_send_event(rport, BFA_RPORT_SM_SET_SPEED);
887}
888
889void
890bfa_rport_get_stats(struct bfa_rport_s *rport,
891 struct bfa_rport_hal_stats_s *stats)
892{
893 *stats = rport->stats;
894}
895
896void
897bfa_rport_get_qos_attr(struct bfa_rport_s *rport,
898 struct bfa_rport_qos_attr_s *qos_attr)
899{
900 qos_attr->qos_priority = bfa_os_ntohl(rport->qos_attr.qos_priority);
901 qos_attr->qos_flow_id = bfa_os_ntohl(rport->qos_attr.qos_flow_id);
902
903}
904
905void
906bfa_rport_clear_stats(struct bfa_rport_s *rport)
907{
908 bfa_os_memset(&rport->stats, 0, sizeof(rport->stats));
909}
910
911
diff --git a/drivers/scsi/bfa/bfa_rport_priv.h b/drivers/scsi/bfa/bfa_rport_priv.h
new file mode 100644
index 000000000000..6490ce2e990d
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_rport_priv.h
@@ -0,0 +1,45 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFA_RPORT_PRIV_H__
19#define __BFA_RPORT_PRIV_H__
20
21#include <bfa_svc.h>
22
23#define BFA_RPORT_MIN 4
24
25struct bfa_rport_mod_s {
26 struct bfa_rport_s *rps_list; /* list of rports */
27 struct list_head rp_free_q; /* free bfa_rports */
28 struct list_head rp_active_q; /* free bfa_rports */
29 u16 num_rports; /* number of rports */
30};
31
32#define BFA_RPORT_MOD(__bfa) (&(__bfa)->modules.rport_mod)
33
34/**
35 * Convert rport tag to RPORT
36 */
37#define BFA_RPORT_FROM_TAG(__bfa, _tag) \
38 (BFA_RPORT_MOD(__bfa)->rps_list + \
39 ((_tag) & (BFA_RPORT_MOD(__bfa)->num_rports - 1)))
40
41/*
42 * external functions
43 */
44void bfa_rport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
45#endif /* __BFA_RPORT_PRIV_H__ */
diff --git a/drivers/scsi/bfa/bfa_sgpg.c b/drivers/scsi/bfa/bfa_sgpg.c
new file mode 100644
index 000000000000..279d8f9b8907
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_sgpg.c
@@ -0,0 +1,231 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#include <bfa.h>
19
20BFA_TRC_FILE(HAL, SGPG);
21BFA_MODULE(sgpg);
22
23/**
24 * bfa_sgpg_mod BFA SGPG Mode module
25 */
26
27/**
28 * Compute and return memory needed by FCP(im) module.
29 */
30static void
31bfa_sgpg_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len,
32 u32 *dm_len)
33{
34 if (cfg->drvcfg.num_sgpgs < BFA_SGPG_MIN)
35 cfg->drvcfg.num_sgpgs = BFA_SGPG_MIN;
36
37 *km_len += (cfg->drvcfg.num_sgpgs + 1) * sizeof(struct bfa_sgpg_s);
38 *dm_len += (cfg->drvcfg.num_sgpgs + 1) * sizeof(struct bfi_sgpg_s);
39}
40
41
42static void
43bfa_sgpg_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
44 struct bfa_meminfo_s *minfo, struct bfa_pcidev_s *pcidev)
45{
46 struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa);
47 int i;
48 struct bfa_sgpg_s *hsgpg;
49 struct bfi_sgpg_s *sgpg;
50 u64 align_len;
51
52 union {
53 u64 pa;
54 union bfi_addr_u addr;
55 } sgpg_pa;
56
57 INIT_LIST_HEAD(&mod->sgpg_q);
58 INIT_LIST_HEAD(&mod->sgpg_wait_q);
59
60 bfa_trc(bfa, cfg->drvcfg.num_sgpgs);
61
62 mod->num_sgpgs = cfg->drvcfg.num_sgpgs;
63 mod->sgpg_arr_pa = bfa_meminfo_dma_phys(minfo);
64 align_len = (BFA_SGPG_ROUNDUP(mod->sgpg_arr_pa) - mod->sgpg_arr_pa);
65 mod->sgpg_arr_pa += align_len;
66 mod->hsgpg_arr = (struct bfa_sgpg_s *) (bfa_meminfo_kva(minfo) +
67 align_len);
68 mod->sgpg_arr = (struct bfi_sgpg_s *) (bfa_meminfo_dma_virt(minfo) +
69 align_len);
70
71 hsgpg = mod->hsgpg_arr;
72 sgpg = mod->sgpg_arr;
73 sgpg_pa.pa = mod->sgpg_arr_pa;
74 mod->free_sgpgs = mod->num_sgpgs;
75
76 bfa_assert(!(sgpg_pa.pa & (sizeof(struct bfi_sgpg_s) - 1)));
77
78 for (i = 0; i < mod->num_sgpgs; i++) {
79 bfa_os_memset(hsgpg, 0, sizeof(*hsgpg));
80 bfa_os_memset(sgpg, 0, sizeof(*sgpg));
81
82 hsgpg->sgpg = sgpg;
83 hsgpg->sgpg_pa = sgpg_pa.addr;
84 list_add_tail(&hsgpg->qe, &mod->sgpg_q);
85
86 hsgpg++;
87 sgpg++;
88 sgpg_pa.pa += sizeof(struct bfi_sgpg_s);
89 }
90
91 bfa_meminfo_kva(minfo) = (u8 *) hsgpg;
92 bfa_meminfo_dma_virt(minfo) = (u8 *) sgpg;
93 bfa_meminfo_dma_phys(minfo) = sgpg_pa.pa;
94}
95
96static void
97bfa_sgpg_initdone(struct bfa_s *bfa)
98{
99}
100
101static void
102bfa_sgpg_detach(struct bfa_s *bfa)
103{
104}
105
106static void
107bfa_sgpg_start(struct bfa_s *bfa)
108{
109}
110
111static void
112bfa_sgpg_stop(struct bfa_s *bfa)
113{
114}
115
116static void
117bfa_sgpg_iocdisable(struct bfa_s *bfa)
118{
119}
120
121
122
123/**
124 * bfa_sgpg_public BFA SGPG public functions
125 */
126
127bfa_status_t
128bfa_sgpg_malloc(struct bfa_s *bfa, struct list_head *sgpg_q, int nsgpgs)
129{
130 struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa);
131 struct bfa_sgpg_s *hsgpg;
132 int i;
133
134 bfa_trc_fp(bfa, nsgpgs);
135
136 if (mod->free_sgpgs < nsgpgs)
137 return BFA_STATUS_ENOMEM;
138
139 for (i = 0; i < nsgpgs; i++) {
140 bfa_q_deq(&mod->sgpg_q, &hsgpg);
141 bfa_assert(hsgpg);
142 list_add_tail(&hsgpg->qe, sgpg_q);
143 }
144
145 mod->free_sgpgs -= nsgpgs;
146 return BFA_STATUS_OK;
147}
148
149void
150bfa_sgpg_mfree(struct bfa_s *bfa, struct list_head *sgpg_q, int nsgpg)
151{
152 struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa);
153 struct bfa_sgpg_wqe_s *wqe;
154
155 bfa_trc_fp(bfa, nsgpg);
156
157 mod->free_sgpgs += nsgpg;
158 bfa_assert(mod->free_sgpgs <= mod->num_sgpgs);
159
160 list_splice_tail_init(sgpg_q, &mod->sgpg_q);
161
162 if (list_empty(&mod->sgpg_wait_q))
163 return;
164
165 /**
166 * satisfy as many waiting requests as possible
167 */
168 do {
169 wqe = bfa_q_first(&mod->sgpg_wait_q);
170 if (mod->free_sgpgs < wqe->nsgpg)
171 nsgpg = mod->free_sgpgs;
172 else
173 nsgpg = wqe->nsgpg;
174 bfa_sgpg_malloc(bfa, &wqe->sgpg_q, nsgpg);
175 wqe->nsgpg -= nsgpg;
176 if (wqe->nsgpg == 0) {
177 list_del(&wqe->qe);
178 wqe->cbfn(wqe->cbarg);
179 }
180 } while (mod->free_sgpgs && !list_empty(&mod->sgpg_wait_q));
181}
182
183void
184bfa_sgpg_wait(struct bfa_s *bfa, struct bfa_sgpg_wqe_s *wqe, int nsgpg)
185{
186 struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa);
187
188 bfa_assert(nsgpg > 0);
189 bfa_assert(nsgpg > mod->free_sgpgs);
190
191 wqe->nsgpg_total = wqe->nsgpg = nsgpg;
192
193 /**
194 * allocate any left to this one first
195 */
196 if (mod->free_sgpgs) {
197 /**
198 * no one else is waiting for SGPG
199 */
200 bfa_assert(list_empty(&mod->sgpg_wait_q));
201 list_splice_tail_init(&mod->sgpg_q, &wqe->sgpg_q);
202 wqe->nsgpg -= mod->free_sgpgs;
203 mod->free_sgpgs = 0;
204 }
205
206 list_add_tail(&wqe->qe, &mod->sgpg_wait_q);
207}
208
209void
210bfa_sgpg_wcancel(struct bfa_s *bfa, struct bfa_sgpg_wqe_s *wqe)
211{
212 struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa);
213
214 bfa_assert(bfa_q_is_on_q(&mod->sgpg_wait_q, wqe));
215 list_del(&wqe->qe);
216
217 if (wqe->nsgpg_total != wqe->nsgpg)
218 bfa_sgpg_mfree(bfa, &wqe->sgpg_q,
219 wqe->nsgpg_total - wqe->nsgpg);
220}
221
222void
223bfa_sgpg_winit(struct bfa_sgpg_wqe_s *wqe, void (*cbfn) (void *cbarg),
224 void *cbarg)
225{
226 INIT_LIST_HEAD(&wqe->sgpg_q);
227 wqe->cbfn = cbfn;
228 wqe->cbarg = cbarg;
229}
230
231
diff --git a/drivers/scsi/bfa/bfa_sgpg_priv.h b/drivers/scsi/bfa/bfa_sgpg_priv.h
new file mode 100644
index 000000000000..9c2a8cbe7522
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_sgpg_priv.h
@@ -0,0 +1,79 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * hal_sgpg.h BFA SG page module
20 */
21
22#ifndef __BFA_SGPG_PRIV_H__
23#define __BFA_SGPG_PRIV_H__
24
25#include <cs/bfa_q.h>
26
27#define BFA_SGPG_MIN (16)
28
29/**
30 * Alignment macro for SG page allocation
31 */
32#define BFA_SGPG_ROUNDUP(_l) (((_l) + (sizeof(struct bfi_sgpg_s) - 1)) \
33 & ~(sizeof(struct bfi_sgpg_s) - 1))
34
35struct bfa_sgpg_wqe_s {
36 struct list_head qe; /* queue sg page element */
37 int nsgpg; /* pages to be allocated */
38 int nsgpg_total; /* total pages required */
39 void (*cbfn) (void *cbarg);
40 /* callback function */
41 void *cbarg; /* callback arg */
42 struct list_head sgpg_q; /* queue of alloced sgpgs */
43};
44
45struct bfa_sgpg_s {
46 struct list_head qe; /* queue sg page element */
47 struct bfi_sgpg_s *sgpg; /* va of SG page */
48 union bfi_addr_u sgpg_pa;/* pa of SG page */
49};
50
51/**
52 * Given number of SG elements, BFA_SGPG_NPAGE() returns the number of
53 * SG pages required.
54 */
55#define BFA_SGPG_NPAGE(_nsges) (((_nsges) / BFI_SGPG_DATA_SGES) + 1)
56
57struct bfa_sgpg_mod_s {
58 struct bfa_s *bfa;
59 int num_sgpgs; /* number of SG pages */
60 int free_sgpgs; /* number of free SG pages */
61 struct bfa_sgpg_s *hsgpg_arr; /* BFA SG page array */
62 struct bfi_sgpg_s *sgpg_arr; /* actual SG page array */
63 u64 sgpg_arr_pa; /* SG page array DMA addr */
64 struct list_head sgpg_q; /* queue of free SG pages */
65 struct list_head sgpg_wait_q; /* wait queue for SG pages */
66};
67#define BFA_SGPG_MOD(__bfa) (&(__bfa)->modules.sgpg_mod)
68
69bfa_status_t bfa_sgpg_malloc(struct bfa_s *bfa, struct list_head *sgpg_q,
70 int nsgpgs);
71void bfa_sgpg_mfree(struct bfa_s *bfa, struct list_head *sgpg_q,
72 int nsgpgs);
73void bfa_sgpg_winit(struct bfa_sgpg_wqe_s *wqe,
74 void (*cbfn) (void *cbarg), void *cbarg);
75void bfa_sgpg_wait(struct bfa_s *bfa, struct bfa_sgpg_wqe_s *wqe,
76 int nsgpgs);
77void bfa_sgpg_wcancel(struct bfa_s *bfa, struct bfa_sgpg_wqe_s *wqe);
78
79#endif /* __BFA_SGPG_PRIV_H__ */
diff --git a/drivers/scsi/bfa/bfa_sm.c b/drivers/scsi/bfa/bfa_sm.c
new file mode 100644
index 000000000000..5420f4f45e58
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_sm.c
@@ -0,0 +1,38 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * bfasm.c BFA State machine utility functions
20 */
21
22#include <cs/bfa_sm.h>
23
24/**
25 * cs_sm_api
26 */
27
28int
29bfa_sm_to_state(struct bfa_sm_table_s *smt, bfa_sm_t sm)
30{
31 int i = 0;
32
33 while (smt[i].sm && smt[i].sm != sm)
34 i++;
35 return smt[i].state;
36}
37
38
diff --git a/drivers/scsi/bfa/bfa_timer.c b/drivers/scsi/bfa/bfa_timer.c
new file mode 100644
index 000000000000..cb76481f5cb1
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_timer.c
@@ -0,0 +1,90 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#include <bfa_timer.h>
19#include <cs/bfa_debug.h>
20
21void
22bfa_timer_init(struct bfa_timer_mod_s *mod)
23{
24 INIT_LIST_HEAD(&mod->timer_q);
25}
26
27void
28bfa_timer_beat(struct bfa_timer_mod_s *mod)
29{
30 struct list_head *qh = &mod->timer_q;
31 struct list_head *qe, *qe_next;
32 struct bfa_timer_s *elem;
33 struct list_head timedout_q;
34
35 INIT_LIST_HEAD(&timedout_q);
36
37 qe = bfa_q_next(qh);
38
39 while (qe != qh) {
40 qe_next = bfa_q_next(qe);
41
42 elem = (struct bfa_timer_s *) qe;
43 if (elem->timeout <= BFA_TIMER_FREQ) {
44 elem->timeout = 0;
45 list_del(&elem->qe);
46 list_add_tail(&elem->qe, &timedout_q);
47 } else {
48 elem->timeout -= BFA_TIMER_FREQ;
49 }
50
51 qe = qe_next; /* go to next elem */
52 }
53
54 /*
55 * Pop all the timeout entries
56 */
57 while (!list_empty(&timedout_q)) {
58 bfa_q_deq(&timedout_q, &elem);
59 elem->timercb(elem->arg);
60 }
61}
62
63/**
64 * Should be called with lock protection
65 */
66void
67bfa_timer_begin(struct bfa_timer_mod_s *mod, struct bfa_timer_s *timer,
68 void (*timercb) (void *), void *arg, unsigned int timeout)
69{
70
71 bfa_assert(timercb != NULL);
72 bfa_assert(!bfa_q_is_on_q(&mod->timer_q, timer));
73
74 timer->timeout = timeout;
75 timer->timercb = timercb;
76 timer->arg = arg;
77
78 list_add_tail(&timer->qe, &mod->timer_q);
79}
80
81/**
82 * Should be called with lock protection
83 */
84void
85bfa_timer_stop(struct bfa_timer_s *timer)
86{
87 bfa_assert(!list_empty(&timer->qe));
88
89 list_del(&timer->qe);
90}
diff --git a/drivers/scsi/bfa/bfa_trcmod_priv.h b/drivers/scsi/bfa/bfa_trcmod_priv.h
new file mode 100644
index 000000000000..b3562dce7e9f
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_trcmod_priv.h
@@ -0,0 +1,66 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * hal_trcmod.h BFA trace modules
20 */
21
22#ifndef __BFA_TRCMOD_PRIV_H__
23#define __BFA_TRCMOD_PRIV_H__
24
25#include <cs/bfa_trc.h>
26
27/*
28 * !!! Only append to the enums defined here to avoid any versioning
29 * !!! needed between trace utility and driver version
30 */
31enum {
32 BFA_TRC_HAL_IOC = 1,
33 BFA_TRC_HAL_INTR = 2,
34 BFA_TRC_HAL_FCXP = 3,
35 BFA_TRC_HAL_UF = 4,
36 BFA_TRC_HAL_DIAG = 5,
37 BFA_TRC_HAL_RPORT = 6,
38 BFA_TRC_HAL_FCPIM = 7,
39 BFA_TRC_HAL_IOIM = 8,
40 BFA_TRC_HAL_TSKIM = 9,
41 BFA_TRC_HAL_ITNIM = 10,
42 BFA_TRC_HAL_PPORT = 11,
43 BFA_TRC_HAL_SGPG = 12,
44 BFA_TRC_HAL_FLASH = 13,
45 BFA_TRC_HAL_DEBUG = 14,
46 BFA_TRC_HAL_WWN = 15,
47 BFA_TRC_HAL_FLASH_RAW = 16,
48 BFA_TRC_HAL_SBOOT = 17,
49 BFA_TRC_HAL_SBOOT_IO = 18,
50 BFA_TRC_HAL_SBOOT_INTR = 19,
51 BFA_TRC_HAL_SBTEST = 20,
52 BFA_TRC_HAL_IPFC = 21,
53 BFA_TRC_HAL_IOCFC = 22,
54 BFA_TRC_HAL_FCPTM = 23,
55 BFA_TRC_HAL_IOTM = 24,
56 BFA_TRC_HAL_TSKTM = 25,
57 BFA_TRC_HAL_TIN = 26,
58 BFA_TRC_HAL_LPS = 27,
59 BFA_TRC_HAL_FCDIAG = 28,
60 BFA_TRC_HAL_PBIND = 29,
61 BFA_TRC_HAL_IOCFC_CT = 30,
62 BFA_TRC_HAL_IOCFC_CB = 31,
63 BFA_TRC_HAL_IOCFC_Q = 32,
64};
65
66#endif /* __BFA_TRCMOD_PRIV_H__ */
diff --git a/drivers/scsi/bfa/bfa_tskim.c b/drivers/scsi/bfa/bfa_tskim.c
new file mode 100644
index 000000000000..010d40d1e5d3
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_tskim.c
@@ -0,0 +1,689 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#include <bfa.h>
19#include <bfa_cb_ioim_macros.h>
20
21BFA_TRC_FILE(HAL, TSKIM);
22
23/**
24 * task management completion handling
25 */
26#define bfa_tskim_qcomp(__tskim, __cbfn) do { \
27 bfa_cb_queue((__tskim)->bfa, &(__tskim)->hcb_qe, __cbfn, (__tskim)); \
28 bfa_tskim_notify_comp(__tskim); \
29} while (0)
30
31#define bfa_tskim_notify_comp(__tskim) do { \
32 if ((__tskim)->notify) \
33 bfa_itnim_tskdone((__tskim)->itnim); \
34} while (0)
35
36/*
37 * forward declarations
38 */
39static void __bfa_cb_tskim_done(void *cbarg, bfa_boolean_t complete);
40static void __bfa_cb_tskim_failed(void *cbarg, bfa_boolean_t complete);
41static bfa_boolean_t bfa_tskim_match_scope(struct bfa_tskim_s *tskim,
42 lun_t lun);
43static void bfa_tskim_gather_ios(struct bfa_tskim_s *tskim);
44static void bfa_tskim_cleanp_comp(void *tskim_cbarg);
45static void bfa_tskim_cleanup_ios(struct bfa_tskim_s *tskim);
46static bfa_boolean_t bfa_tskim_send(struct bfa_tskim_s *tskim);
47static bfa_boolean_t bfa_tskim_send_abort(struct bfa_tskim_s *tskim);
48static void bfa_tskim_iocdisable_ios(struct bfa_tskim_s *tskim);
49
50/**
51 * bfa_tskim_sm
52 */
53
54enum bfa_tskim_event {
55 BFA_TSKIM_SM_START = 1, /* TM command start */
56 BFA_TSKIM_SM_DONE = 2, /* TM completion */
57 BFA_TSKIM_SM_QRESUME = 3, /* resume after qfull */
58 BFA_TSKIM_SM_HWFAIL = 5, /* IOC h/w failure event */
59 BFA_TSKIM_SM_HCB = 6, /* BFA callback completion */
60 BFA_TSKIM_SM_IOS_DONE = 7, /* IO and sub TM completions */
61 BFA_TSKIM_SM_CLEANUP = 8, /* TM cleanup on ITN offline */
62 BFA_TSKIM_SM_CLEANUP_DONE = 9, /* TM abort completion */
63};
64
65static void bfa_tskim_sm_uninit(struct bfa_tskim_s *tskim,
66 enum bfa_tskim_event event);
67static void bfa_tskim_sm_active(struct bfa_tskim_s *tskim,
68 enum bfa_tskim_event event);
69static void bfa_tskim_sm_cleanup(struct bfa_tskim_s *tskim,
70 enum bfa_tskim_event event);
71static void bfa_tskim_sm_iocleanup(struct bfa_tskim_s *tskim,
72 enum bfa_tskim_event event);
73static void bfa_tskim_sm_qfull(struct bfa_tskim_s *tskim,
74 enum bfa_tskim_event event);
75static void bfa_tskim_sm_cleanup_qfull(struct bfa_tskim_s *tskim,
76 enum bfa_tskim_event event);
77static void bfa_tskim_sm_hcb(struct bfa_tskim_s *tskim,
78 enum bfa_tskim_event event);
79
80/**
81 * Task management command beginning state.
82 */
83static void
84bfa_tskim_sm_uninit(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
85{
86 bfa_trc(tskim->bfa, event);
87
88 switch (event) {
89 case BFA_TSKIM_SM_START:
90 bfa_sm_set_state(tskim, bfa_tskim_sm_active);
91 bfa_tskim_gather_ios(tskim);
92
93 /**
94 * If device is offline, do not send TM on wire. Just cleanup
95 * any pending IO requests and complete TM request.
96 */
97 if (!bfa_itnim_is_online(tskim->itnim)) {
98 bfa_sm_set_state(tskim, bfa_tskim_sm_iocleanup);
99 tskim->tsk_status = BFI_TSKIM_STS_OK;
100 bfa_tskim_cleanup_ios(tskim);
101 return;
102 }
103
104 if (!bfa_tskim_send(tskim)) {
105 bfa_sm_set_state(tskim, bfa_tskim_sm_qfull);
106 bfa_reqq_wait(tskim->bfa, tskim->itnim->reqq,
107 &tskim->reqq_wait);
108 }
109 break;
110
111 default:
112 bfa_assert(0);
113 }
114}
115
116/**
117 * brief
118 * TM command is active, awaiting completion from firmware to
119 * cleanup IO requests in TM scope.
120 */
121static void
122bfa_tskim_sm_active(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
123{
124 bfa_trc(tskim->bfa, event);
125
126 switch (event) {
127 case BFA_TSKIM_SM_DONE:
128 bfa_sm_set_state(tskim, bfa_tskim_sm_iocleanup);
129 bfa_tskim_cleanup_ios(tskim);
130 break;
131
132 case BFA_TSKIM_SM_CLEANUP:
133 bfa_sm_set_state(tskim, bfa_tskim_sm_cleanup);
134 if (!bfa_tskim_send_abort(tskim)) {
135 bfa_sm_set_state(tskim, bfa_tskim_sm_cleanup_qfull);
136 bfa_reqq_wait(tskim->bfa, tskim->itnim->reqq,
137 &tskim->reqq_wait);
138 }
139 break;
140
141 case BFA_TSKIM_SM_HWFAIL:
142 bfa_sm_set_state(tskim, bfa_tskim_sm_hcb);
143 bfa_tskim_iocdisable_ios(tskim);
144 bfa_tskim_qcomp(tskim, __bfa_cb_tskim_failed);
145 break;
146
147 default:
148 bfa_assert(0);
149 }
150}
151
152/**
153 * An active TM is being cleaned up since ITN is offline. Awaiting cleanup
154 * completion event from firmware.
155 */
156static void
157bfa_tskim_sm_cleanup(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
158{
159 bfa_trc(tskim->bfa, event);
160
161 switch (event) {
162 case BFA_TSKIM_SM_DONE:
163 /**
164 * Ignore and wait for ABORT completion from firmware.
165 */
166 break;
167
168 case BFA_TSKIM_SM_CLEANUP_DONE:
169 bfa_sm_set_state(tskim, bfa_tskim_sm_iocleanup);
170 bfa_tskim_cleanup_ios(tskim);
171 break;
172
173 case BFA_TSKIM_SM_HWFAIL:
174 bfa_sm_set_state(tskim, bfa_tskim_sm_hcb);
175 bfa_tskim_iocdisable_ios(tskim);
176 bfa_tskim_qcomp(tskim, __bfa_cb_tskim_failed);
177 break;
178
179 default:
180 bfa_assert(0);
181 }
182}
183
184static void
185bfa_tskim_sm_iocleanup(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
186{
187 bfa_trc(tskim->bfa, event);
188
189 switch (event) {
190 case BFA_TSKIM_SM_IOS_DONE:
191 bfa_sm_set_state(tskim, bfa_tskim_sm_hcb);
192 bfa_tskim_qcomp(tskim, __bfa_cb_tskim_done);
193 break;
194
195 case BFA_TSKIM_SM_CLEANUP:
196 /**
197 * Ignore, TM command completed on wire.
198 * Notify TM conmpletion on IO cleanup completion.
199 */
200 break;
201
202 case BFA_TSKIM_SM_HWFAIL:
203 bfa_sm_set_state(tskim, bfa_tskim_sm_hcb);
204 bfa_tskim_iocdisable_ios(tskim);
205 bfa_tskim_qcomp(tskim, __bfa_cb_tskim_failed);
206 break;
207
208 default:
209 bfa_assert(0);
210 }
211}
212
213/**
214 * Task management command is waiting for room in request CQ
215 */
216static void
217bfa_tskim_sm_qfull(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
218{
219 bfa_trc(tskim->bfa, event);
220
221 switch (event) {
222 case BFA_TSKIM_SM_QRESUME:
223 bfa_sm_set_state(tskim, bfa_tskim_sm_active);
224 bfa_tskim_send(tskim);
225 break;
226
227 case BFA_TSKIM_SM_CLEANUP:
228 /**
229 * No need to send TM on wire since ITN is offline.
230 */
231 bfa_sm_set_state(tskim, bfa_tskim_sm_iocleanup);
232 bfa_reqq_wcancel(&tskim->reqq_wait);
233 bfa_tskim_cleanup_ios(tskim);
234 break;
235
236 case BFA_TSKIM_SM_HWFAIL:
237 bfa_sm_set_state(tskim, bfa_tskim_sm_hcb);
238 bfa_reqq_wcancel(&tskim->reqq_wait);
239 bfa_tskim_iocdisable_ios(tskim);
240 bfa_tskim_qcomp(tskim, __bfa_cb_tskim_failed);
241 break;
242
243 default:
244 bfa_assert(0);
245 }
246}
247
248/**
249 * Task management command is active, awaiting for room in request CQ
250 * to send clean up request.
251 */
252static void
253bfa_tskim_sm_cleanup_qfull(struct bfa_tskim_s *tskim,
254 enum bfa_tskim_event event)
255{
256 bfa_trc(tskim->bfa, event);
257
258 switch (event) {
259 case BFA_TSKIM_SM_DONE:
260 bfa_reqq_wcancel(&tskim->reqq_wait);
261 /**
262 *
263 * Fall through !!!
264 */
265
266 case BFA_TSKIM_SM_QRESUME:
267 bfa_sm_set_state(tskim, bfa_tskim_sm_cleanup);
268 bfa_tskim_send_abort(tskim);
269 break;
270
271 case BFA_TSKIM_SM_HWFAIL:
272 bfa_sm_set_state(tskim, bfa_tskim_sm_hcb);
273 bfa_reqq_wcancel(&tskim->reqq_wait);
274 bfa_tskim_iocdisable_ios(tskim);
275 bfa_tskim_qcomp(tskim, __bfa_cb_tskim_failed);
276 break;
277
278 default:
279 bfa_assert(0);
280 }
281}
282
283/**
284 * BFA callback is pending
285 */
286static void
287bfa_tskim_sm_hcb(struct bfa_tskim_s *tskim, enum bfa_tskim_event event)
288{
289 bfa_trc(tskim->bfa, event);
290
291 switch (event) {
292 case BFA_TSKIM_SM_HCB:
293 bfa_sm_set_state(tskim, bfa_tskim_sm_uninit);
294 bfa_tskim_free(tskim);
295 break;
296
297 case BFA_TSKIM_SM_CLEANUP:
298 bfa_tskim_notify_comp(tskim);
299 break;
300
301 case BFA_TSKIM_SM_HWFAIL:
302 break;
303
304 default:
305 bfa_assert(0);
306 }
307}
308
309
310
311/**
312 * bfa_tskim_private
313 */
314
315static void
316__bfa_cb_tskim_done(void *cbarg, bfa_boolean_t complete)
317{
318 struct bfa_tskim_s *tskim = cbarg;
319
320 if (!complete) {
321 bfa_sm_send_event(tskim, BFA_TSKIM_SM_HCB);
322 return;
323 }
324
325 bfa_stats(tskim->itnim, tm_success);
326 bfa_cb_tskim_done(tskim->bfa->bfad, tskim->dtsk, tskim->tsk_status);
327}
328
329static void
330__bfa_cb_tskim_failed(void *cbarg, bfa_boolean_t complete)
331{
332 struct bfa_tskim_s *tskim = cbarg;
333
334 if (!complete) {
335 bfa_sm_send_event(tskim, BFA_TSKIM_SM_HCB);
336 return;
337 }
338
339 bfa_stats(tskim->itnim, tm_failures);
340 bfa_cb_tskim_done(tskim->bfa->bfad, tskim->dtsk,
341 BFI_TSKIM_STS_FAILED);
342}
343
344static bfa_boolean_t
345bfa_tskim_match_scope(struct bfa_tskim_s *tskim, lun_t lun)
346{
347 switch (tskim->tm_cmnd) {
348 case FCP_TM_TARGET_RESET:
349 return BFA_TRUE;
350
351 case FCP_TM_ABORT_TASK_SET:
352 case FCP_TM_CLEAR_TASK_SET:
353 case FCP_TM_LUN_RESET:
354 case FCP_TM_CLEAR_ACA:
355 return (tskim->lun == lun);
356
357 default:
358 bfa_assert(0);
359 }
360
361 return BFA_FALSE;
362}
363
364/**
365 * Gather affected IO requests and task management commands.
366 */
367static void
368bfa_tskim_gather_ios(struct bfa_tskim_s *tskim)
369{
370 struct bfa_itnim_s *itnim = tskim->itnim;
371 struct bfa_ioim_s *ioim;
372 struct list_head *qe, *qen;
373
374 INIT_LIST_HEAD(&tskim->io_q);
375
376 /**
377 * Gather any active IO requests first.
378 */
379 list_for_each_safe(qe, qen, &itnim->io_q) {
380 ioim = (struct bfa_ioim_s *) qe;
381 if (bfa_tskim_match_scope
382 (tskim, bfa_cb_ioim_get_lun(ioim->dio))) {
383 list_del(&ioim->qe);
384 list_add_tail(&ioim->qe, &tskim->io_q);
385 }
386 }
387
388 /**
389 * Failback any pending IO requests immediately.
390 */
391 list_for_each_safe(qe, qen, &itnim->pending_q) {
392 ioim = (struct bfa_ioim_s *) qe;
393 if (bfa_tskim_match_scope
394 (tskim, bfa_cb_ioim_get_lun(ioim->dio))) {
395 list_del(&ioim->qe);
396 list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q);
397 bfa_ioim_tov(ioim);
398 }
399 }
400}
401
402/**
403 * IO cleanup completion
404 */
405static void
406bfa_tskim_cleanp_comp(void *tskim_cbarg)
407{
408 struct bfa_tskim_s *tskim = tskim_cbarg;
409
410 bfa_stats(tskim->itnim, tm_io_comps);
411 bfa_sm_send_event(tskim, BFA_TSKIM_SM_IOS_DONE);
412}
413
414/**
415 * Gather affected IO requests and task management commands.
416 */
417static void
418bfa_tskim_cleanup_ios(struct bfa_tskim_s *tskim)
419{
420 struct bfa_ioim_s *ioim;
421 struct list_head *qe, *qen;
422
423 bfa_wc_init(&tskim->wc, bfa_tskim_cleanp_comp, tskim);
424
425 list_for_each_safe(qe, qen, &tskim->io_q) {
426 ioim = (struct bfa_ioim_s *) qe;
427 bfa_wc_up(&tskim->wc);
428 bfa_ioim_cleanup_tm(ioim, tskim);
429 }
430
431 bfa_wc_wait(&tskim->wc);
432}
433
434/**
435 * Send task management request to firmware.
436 */
437static bfa_boolean_t
438bfa_tskim_send(struct bfa_tskim_s *tskim)
439{
440 struct bfa_itnim_s *itnim = tskim->itnim;
441 struct bfi_tskim_req_s *m;
442
443 /**
444 * check for room in queue to send request now
445 */
446 m = bfa_reqq_next(tskim->bfa, itnim->reqq);
447 if (!m)
448 return BFA_FALSE;
449
450 /**
451 * build i/o request message next
452 */
453 bfi_h2i_set(m->mh, BFI_MC_TSKIM, BFI_TSKIM_H2I_TM_REQ,
454 bfa_lpuid(tskim->bfa));
455
456 m->tsk_tag = bfa_os_htons(tskim->tsk_tag);
457 m->itn_fhdl = tskim->itnim->rport->fw_handle;
458 m->t_secs = tskim->tsecs;
459 m->lun = tskim->lun;
460 m->tm_flags = tskim->tm_cmnd;
461
462 /**
463 * queue I/O message to firmware
464 */
465 bfa_reqq_produce(tskim->bfa, itnim->reqq);
466 return BFA_TRUE;
467}
468
469/**
470 * Send abort request to cleanup an active TM to firmware.
471 */
472static bfa_boolean_t
473bfa_tskim_send_abort(struct bfa_tskim_s *tskim)
474{
475 struct bfa_itnim_s *itnim = tskim->itnim;
476 struct bfi_tskim_abortreq_s *m;
477
478 /**
479 * check for room in queue to send request now
480 */
481 m = bfa_reqq_next(tskim->bfa, itnim->reqq);
482 if (!m)
483 return BFA_FALSE;
484
485 /**
486 * build i/o request message next
487 */
488 bfi_h2i_set(m->mh, BFI_MC_TSKIM, BFI_TSKIM_H2I_ABORT_REQ,
489 bfa_lpuid(tskim->bfa));
490
491 m->tsk_tag = bfa_os_htons(tskim->tsk_tag);
492
493 /**
494 * queue I/O message to firmware
495 */
496 bfa_reqq_produce(tskim->bfa, itnim->reqq);
497 return BFA_TRUE;
498}
499
500/**
501 * Call to resume task management cmnd waiting for room in request queue.
502 */
503static void
504bfa_tskim_qresume(void *cbarg)
505{
506 struct bfa_tskim_s *tskim = cbarg;
507
508 bfa_fcpim_stats(tskim->fcpim, qresumes);
509 bfa_stats(tskim->itnim, tm_qresumes);
510 bfa_sm_send_event(tskim, BFA_TSKIM_SM_QRESUME);
511}
512
513/**
514 * Cleanup IOs associated with a task mangement command on IOC failures.
515 */
516static void
517bfa_tskim_iocdisable_ios(struct bfa_tskim_s *tskim)
518{
519 struct bfa_ioim_s *ioim;
520 struct list_head *qe, *qen;
521
522 list_for_each_safe(qe, qen, &tskim->io_q) {
523 ioim = (struct bfa_ioim_s *) qe;
524 bfa_ioim_iocdisable(ioim);
525 }
526}
527
528
529
530/**
531 * bfa_tskim_friend
532 */
533
534/**
535 * Notification on completions from related ioim.
536 */
537void
538bfa_tskim_iodone(struct bfa_tskim_s *tskim)
539{
540 bfa_wc_down(&tskim->wc);
541}
542
543/**
544 * Handle IOC h/w failure notification from itnim.
545 */
546void
547bfa_tskim_iocdisable(struct bfa_tskim_s *tskim)
548{
549 tskim->notify = BFA_FALSE;
550 bfa_stats(tskim->itnim, tm_iocdowns);
551 bfa_sm_send_event(tskim, BFA_TSKIM_SM_HWFAIL);
552}
553
554/**
555 * Cleanup TM command and associated IOs as part of ITNIM offline.
556 */
557void
558bfa_tskim_cleanup(struct bfa_tskim_s *tskim)
559{
560 tskim->notify = BFA_TRUE;
561 bfa_stats(tskim->itnim, tm_cleanups);
562 bfa_sm_send_event(tskim, BFA_TSKIM_SM_CLEANUP);
563}
564
565/**
566 * Memory allocation and initialization.
567 */
568void
569bfa_tskim_attach(struct bfa_fcpim_mod_s *fcpim, struct bfa_meminfo_s *minfo)
570{
571 struct bfa_tskim_s *tskim;
572 u16 i;
573
574 INIT_LIST_HEAD(&fcpim->tskim_free_q);
575
576 tskim = (struct bfa_tskim_s *) bfa_meminfo_kva(minfo);
577 fcpim->tskim_arr = tskim;
578
579 for (i = 0; i < fcpim->num_tskim_reqs; i++, tskim++) {
580 /*
581 * initialize TSKIM
582 */
583 bfa_os_memset(tskim, 0, sizeof(struct bfa_tskim_s));
584 tskim->tsk_tag = i;
585 tskim->bfa = fcpim->bfa;
586 tskim->fcpim = fcpim;
587 tskim->notify = BFA_FALSE;
588 bfa_reqq_winit(&tskim->reqq_wait, bfa_tskim_qresume,
589 tskim);
590 bfa_sm_set_state(tskim, bfa_tskim_sm_uninit);
591
592 list_add_tail(&tskim->qe, &fcpim->tskim_free_q);
593 }
594
595 bfa_meminfo_kva(minfo) = (u8 *) tskim;
596}
597
598void
599bfa_tskim_detach(struct bfa_fcpim_mod_s *fcpim)
600{
601 /**
602 * @todo
603 */
604}
605
606void
607bfa_tskim_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
608{
609 struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
610 struct bfi_tskim_rsp_s *rsp = (struct bfi_tskim_rsp_s *) m;
611 struct bfa_tskim_s *tskim;
612 u16 tsk_tag = bfa_os_ntohs(rsp->tsk_tag);
613
614 tskim = BFA_TSKIM_FROM_TAG(fcpim, tsk_tag);
615 bfa_assert(tskim->tsk_tag == tsk_tag);
616
617 tskim->tsk_status = rsp->tsk_status;
618
619 /**
620 * Firmware sends BFI_TSKIM_STS_ABORTED status for abort
621 * requests. All other statuses are for normal completions.
622 */
623 if (rsp->tsk_status == BFI_TSKIM_STS_ABORTED) {
624 bfa_stats(tskim->itnim, tm_cleanup_comps);
625 bfa_sm_send_event(tskim, BFA_TSKIM_SM_CLEANUP_DONE);
626 } else {
627 bfa_stats(tskim->itnim, tm_fw_rsps);
628 bfa_sm_send_event(tskim, BFA_TSKIM_SM_DONE);
629 }
630}
631
632
633
634/**
635 * bfa_tskim_api
636 */
637
638
639struct bfa_tskim_s *
640bfa_tskim_alloc(struct bfa_s *bfa, struct bfad_tskim_s *dtsk)
641{
642 struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa);
643 struct bfa_tskim_s *tskim;
644
645 bfa_q_deq(&fcpim->tskim_free_q, &tskim);
646
647 if (!tskim)
648 bfa_fcpim_stats(fcpim, no_tskims);
649 else
650 tskim->dtsk = dtsk;
651
652 return tskim;
653}
654
655void
656bfa_tskim_free(struct bfa_tskim_s *tskim)
657{
658 bfa_assert(bfa_q_is_on_q_func(&tskim->itnim->tsk_q, &tskim->qe));
659 list_del(&tskim->qe);
660 list_add_tail(&tskim->qe, &tskim->fcpim->tskim_free_q);
661}
662
663/**
664 * Start a task management command.
665 *
666 * @param[in] tskim BFA task management command instance
667 * @param[in] itnim i-t nexus for the task management command
668 * @param[in] lun lun, if applicable
669 * @param[in] tm_cmnd Task management command code.
670 * @param[in] t_secs Timeout in seconds
671 *
672 * @return None.
673 */
674void
675bfa_tskim_start(struct bfa_tskim_s *tskim, struct bfa_itnim_s *itnim, lun_t lun,
676 enum fcp_tm_cmnd tm_cmnd, u8 tsecs)
677{
678 tskim->itnim = itnim;
679 tskim->lun = lun;
680 tskim->tm_cmnd = tm_cmnd;
681 tskim->tsecs = tsecs;
682 tskim->notify = BFA_FALSE;
683 bfa_stats(itnim, tm_cmnds);
684
685 list_add_tail(&tskim->qe, &itnim->tsk_q);
686 bfa_sm_send_event(tskim, BFA_TSKIM_SM_START);
687}
688
689
diff --git a/drivers/scsi/bfa/bfa_uf.c b/drivers/scsi/bfa/bfa_uf.c
new file mode 100644
index 000000000000..ff5f9deb1b22
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_uf.c
@@ -0,0 +1,345 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * bfa_uf.c BFA unsolicited frame receive implementation
20 */
21
22#include <bfa.h>
23#include <bfa_svc.h>
24#include <bfi/bfi_uf.h>
25#include <cs/bfa_debug.h>
26
27BFA_TRC_FILE(HAL, UF);
28BFA_MODULE(uf);
29
30/*
31 *****************************************************************************
32 * Internal functions
33 *****************************************************************************
34 */
35static void
36__bfa_cb_uf_recv(void *cbarg, bfa_boolean_t complete)
37{
38 struct bfa_uf_s *uf = cbarg;
39 struct bfa_uf_mod_s *ufm = BFA_UF_MOD(uf->bfa);
40
41 if (complete)
42 ufm->ufrecv(ufm->cbarg, uf);
43}
44
45static void
46claim_uf_pbs(struct bfa_uf_mod_s *ufm, struct bfa_meminfo_s *mi)
47{
48 u32 uf_pb_tot_sz;
49
50 ufm->uf_pbs_kva = (struct bfa_uf_buf_s *) bfa_meminfo_dma_virt(mi);
51 ufm->uf_pbs_pa = bfa_meminfo_dma_phys(mi);
52 uf_pb_tot_sz = BFA_ROUNDUP((sizeof(struct bfa_uf_buf_s) * ufm->num_ufs),
53 BFA_DMA_ALIGN_SZ);
54
55 bfa_meminfo_dma_virt(mi) += uf_pb_tot_sz;
56 bfa_meminfo_dma_phys(mi) += uf_pb_tot_sz;
57
58 bfa_os_memset((void *)ufm->uf_pbs_kva, 0, uf_pb_tot_sz);
59}
60
61static void
62claim_uf_post_msgs(struct bfa_uf_mod_s *ufm, struct bfa_meminfo_s *mi)
63{
64 struct bfi_uf_buf_post_s *uf_bp_msg;
65 struct bfi_sge_s *sge;
66 union bfi_addr_u sga_zero = { {0} };
67 u16 i;
68 u16 buf_len;
69
70 ufm->uf_buf_posts = (struct bfi_uf_buf_post_s *) bfa_meminfo_kva(mi);
71 uf_bp_msg = ufm->uf_buf_posts;
72
73 for (i = 0, uf_bp_msg = ufm->uf_buf_posts; i < ufm->num_ufs;
74 i++, uf_bp_msg++) {
75 bfa_os_memset(uf_bp_msg, 0, sizeof(struct bfi_uf_buf_post_s));
76
77 uf_bp_msg->buf_tag = i;
78 buf_len = sizeof(struct bfa_uf_buf_s);
79 uf_bp_msg->buf_len = bfa_os_htons(buf_len);
80 bfi_h2i_set(uf_bp_msg->mh, BFI_MC_UF, BFI_UF_H2I_BUF_POST,
81 bfa_lpuid(ufm->bfa));
82
83 sge = uf_bp_msg->sge;
84 sge[0].sg_len = buf_len;
85 sge[0].flags = BFI_SGE_DATA_LAST;
86 bfa_dma_addr_set(sge[0].sga, ufm_pbs_pa(ufm, i));
87 bfa_sge_to_be(sge);
88
89 sge[1].sg_len = buf_len;
90 sge[1].flags = BFI_SGE_PGDLEN;
91 sge[1].sga = sga_zero;
92 bfa_sge_to_be(&sge[1]);
93 }
94
95 /**
96 * advance pointer beyond consumed memory
97 */
98 bfa_meminfo_kva(mi) = (u8 *) uf_bp_msg;
99}
100
101static void
102claim_ufs(struct bfa_uf_mod_s *ufm, struct bfa_meminfo_s *mi)
103{
104 u16 i;
105 struct bfa_uf_s *uf;
106
107 /*
108 * Claim block of memory for UF list
109 */
110 ufm->uf_list = (struct bfa_uf_s *) bfa_meminfo_kva(mi);
111
112 /*
113 * Initialize UFs and queue it in UF free queue
114 */
115 for (i = 0, uf = ufm->uf_list; i < ufm->num_ufs; i++, uf++) {
116 bfa_os_memset(uf, 0, sizeof(struct bfa_uf_s));
117 uf->bfa = ufm->bfa;
118 uf->uf_tag = i;
119 uf->pb_len = sizeof(struct bfa_uf_buf_s);
120 uf->buf_kva = (void *)&ufm->uf_pbs_kva[i];
121 uf->buf_pa = ufm_pbs_pa(ufm, i);
122 list_add_tail(&uf->qe, &ufm->uf_free_q);
123 }
124
125 /**
126 * advance memory pointer
127 */
128 bfa_meminfo_kva(mi) = (u8 *) uf;
129}
130
131static void
132uf_mem_claim(struct bfa_uf_mod_s *ufm, struct bfa_meminfo_s *mi)
133{
134 claim_uf_pbs(ufm, mi);
135 claim_ufs(ufm, mi);
136 claim_uf_post_msgs(ufm, mi);
137}
138
139static void
140bfa_uf_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len, u32 *dm_len)
141{
142 u32 num_ufs = cfg->fwcfg.num_uf_bufs;
143
144 /*
145 * dma-able memory for UF posted bufs
146 */
147 *dm_len += BFA_ROUNDUP((sizeof(struct bfa_uf_buf_s) * num_ufs),
148 BFA_DMA_ALIGN_SZ);
149
150 /*
151 * kernel Virtual memory for UFs and UF buf post msg copies
152 */
153 *ndm_len += sizeof(struct bfa_uf_s) * num_ufs;
154 *ndm_len += sizeof(struct bfi_uf_buf_post_s) * num_ufs;
155}
156
157static void
158bfa_uf_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
159 struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev)
160{
161 struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa);
162
163 bfa_os_memset(ufm, 0, sizeof(struct bfa_uf_mod_s));
164 ufm->bfa = bfa;
165 ufm->num_ufs = cfg->fwcfg.num_uf_bufs;
166 INIT_LIST_HEAD(&ufm->uf_free_q);
167 INIT_LIST_HEAD(&ufm->uf_posted_q);
168
169 uf_mem_claim(ufm, meminfo);
170}
171
172static void
173bfa_uf_initdone(struct bfa_s *bfa)
174{
175}
176
177static void
178bfa_uf_detach(struct bfa_s *bfa)
179{
180}
181
182static struct bfa_uf_s *
183bfa_uf_get(struct bfa_uf_mod_s *uf_mod)
184{
185 struct bfa_uf_s *uf;
186
187 bfa_q_deq(&uf_mod->uf_free_q, &uf);
188 return (uf);
189}
190
191static void
192bfa_uf_put(struct bfa_uf_mod_s *uf_mod, struct bfa_uf_s *uf)
193{
194 list_add_tail(&uf->qe, &uf_mod->uf_free_q);
195}
196
197static bfa_status_t
198bfa_uf_post(struct bfa_uf_mod_s *ufm, struct bfa_uf_s *uf)
199{
200 struct bfi_uf_buf_post_s *uf_post_msg;
201
202 uf_post_msg = bfa_reqq_next(ufm->bfa, BFA_REQQ_FCXP);
203 if (!uf_post_msg)
204 return BFA_STATUS_FAILED;
205
206 bfa_os_memcpy(uf_post_msg, &ufm->uf_buf_posts[uf->uf_tag],
207 sizeof(struct bfi_uf_buf_post_s));
208 bfa_reqq_produce(ufm->bfa, BFA_REQQ_FCXP);
209
210 bfa_trc(ufm->bfa, uf->uf_tag);
211
212 list_add_tail(&uf->qe, &ufm->uf_posted_q);
213 return BFA_STATUS_OK;
214}
215
216static void
217bfa_uf_post_all(struct bfa_uf_mod_s *uf_mod)
218{
219 struct bfa_uf_s *uf;
220
221 while ((uf = bfa_uf_get(uf_mod)) != NULL) {
222 if (bfa_uf_post(uf_mod, uf) != BFA_STATUS_OK)
223 break;
224 }
225}
226
227static void
228uf_recv(struct bfa_s *bfa, struct bfi_uf_frm_rcvd_s *m)
229{
230 struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa);
231 u16 uf_tag = m->buf_tag;
232 struct bfa_uf_buf_s *uf_buf = &ufm->uf_pbs_kva[uf_tag];
233 struct bfa_uf_s *uf = &ufm->uf_list[uf_tag];
234 u8 *buf = &uf_buf->d[0];
235 struct fchs_s *fchs;
236
237 m->frm_len = bfa_os_ntohs(m->frm_len);
238 m->xfr_len = bfa_os_ntohs(m->xfr_len);
239
240 fchs = (struct fchs_s *) uf_buf;
241
242 list_del(&uf->qe); /* dequeue from posted queue */
243
244 uf->data_ptr = buf;
245 uf->data_len = m->xfr_len;
246
247 bfa_assert(uf->data_len >= sizeof(struct fchs_s));
248
249 if (uf->data_len == sizeof(struct fchs_s)) {
250 bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_UF, BFA_PL_EID_RX,
251 uf->data_len, (struct fchs_s *) buf);
252 } else {
253 u32 pld_w0 = *((u32 *) (buf + sizeof(struct fchs_s)));
254 bfa_plog_fchdr_and_pl(bfa->plog, BFA_PL_MID_HAL_UF,
255 BFA_PL_EID_RX, uf->data_len,
256 (struct fchs_s *) buf, pld_w0);
257 }
258
259 bfa_cb_queue(bfa, &uf->hcb_qe, __bfa_cb_uf_recv, uf);
260}
261
262static void
263bfa_uf_stop(struct bfa_s *bfa)
264{
265}
266
267static void
268bfa_uf_iocdisable(struct bfa_s *bfa)
269{
270 struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa);
271 struct bfa_uf_s *uf;
272 struct list_head *qe, *qen;
273
274 list_for_each_safe(qe, qen, &ufm->uf_posted_q) {
275 uf = (struct bfa_uf_s *) qe;
276 list_del(&uf->qe);
277 bfa_uf_put(ufm, uf);
278 }
279}
280
281static void
282bfa_uf_start(struct bfa_s *bfa)
283{
284 bfa_uf_post_all(BFA_UF_MOD(bfa));
285}
286
287
288
289/**
290 * bfa_uf_api
291 */
292
293/**
294 * Register handler for all unsolicted recieve frames.
295 *
296 * @param[in] bfa BFA instance
297 * @param[in] ufrecv receive handler function
298 * @param[in] cbarg receive handler arg
299 */
300void
301bfa_uf_recv_register(struct bfa_s *bfa, bfa_cb_uf_recv_t ufrecv, void *cbarg)
302{
303 struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa);
304
305 ufm->ufrecv = ufrecv;
306 ufm->cbarg = cbarg;
307}
308
309/**
310 * Free an unsolicited frame back to BFA.
311 *
312 * @param[in] uf unsolicited frame to be freed
313 *
314 * @return None
315 */
316void
317bfa_uf_free(struct bfa_uf_s *uf)
318{
319 bfa_uf_put(BFA_UF_MOD(uf->bfa), uf);
320 bfa_uf_post_all(BFA_UF_MOD(uf->bfa));
321}
322
323
324
325/**
326 * uf_pub BFA uf module public functions
327 */
328
329void
330bfa_uf_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
331{
332 bfa_trc(bfa, msg->mhdr.msg_id);
333
334 switch (msg->mhdr.msg_id) {
335 case BFI_UF_I2H_FRM_RCVD:
336 uf_recv(bfa, (struct bfi_uf_frm_rcvd_s *) msg);
337 break;
338
339 default:
340 bfa_trc(bfa, msg->mhdr.msg_id);
341 bfa_assert(0);
342 }
343}
344
345
diff --git a/drivers/scsi/bfa/bfa_uf_priv.h b/drivers/scsi/bfa/bfa_uf_priv.h
new file mode 100644
index 000000000000..bcb490f834f3
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_uf_priv.h
@@ -0,0 +1,47 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17#ifndef __BFA_UF_PRIV_H__
18#define __BFA_UF_PRIV_H__
19
20#include <cs/bfa_sm.h>
21#include <bfa_svc.h>
22#include <bfi/bfi_uf.h>
23
24#define BFA_UF_MIN (4)
25
26struct bfa_uf_mod_s {
27 struct bfa_s *bfa; /* back pointer to BFA */
28 struct bfa_uf_s *uf_list; /* array of UFs */
29 u16 num_ufs; /* num unsolicited rx frames */
30 struct list_head uf_free_q; /* free UFs */
31 struct list_head uf_posted_q; /* UFs posted to IOC */
32 struct bfa_uf_buf_s *uf_pbs_kva; /* list UF bufs request pld */
33 u64 uf_pbs_pa; /* phy addr for UF bufs */
34 struct bfi_uf_buf_post_s *uf_buf_posts;
35 /* pre-built UF post msgs */
36 bfa_cb_uf_recv_t ufrecv; /* uf recv handler function */
37 void *cbarg; /* uf receive handler arg */
38};
39
40#define BFA_UF_MOD(__bfa) (&(__bfa)->modules.uf_mod)
41
42#define ufm_pbs_pa(_ufmod, _uftag) \
43 ((_ufmod)->uf_pbs_pa + sizeof(struct bfa_uf_buf_s) * (_uftag))
44
45void bfa_uf_isr(struct bfa_s *bfa, struct bfi_msg_s *msg);
46
47#endif /* __BFA_UF_PRIV_H__ */
diff --git a/drivers/scsi/bfa/bfad.c b/drivers/scsi/bfa/bfad.c
new file mode 100644
index 000000000000..6f2be5abf561
--- /dev/null
+++ b/drivers/scsi/bfa/bfad.c
@@ -0,0 +1,1182 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * bfad.c Linux driver PCI interface module.
20 */
21
22#include <linux/module.h>
23#include "bfad_drv.h"
24#include "bfad_im.h"
25#include "bfad_tm.h"
26#include "bfad_ipfc.h"
27#include "bfad_trcmod.h"
28#include <fcb/bfa_fcb_vf.h>
29#include <fcb/bfa_fcb_rport.h>
30#include <fcb/bfa_fcb_port.h>
31#include <fcb/bfa_fcb.h>
32
33BFA_TRC_FILE(LDRV, BFAD);
34static DEFINE_MUTEX(bfad_mutex);
35LIST_HEAD(bfad_list);
36static int bfad_inst;
37int bfad_supported_fc4s;
38
39static char *host_name;
40static char *os_name;
41static char *os_patch;
42static int num_rports;
43static int num_ios;
44static int num_tms;
45static int num_fcxps;
46static int num_ufbufs;
47static int reqq_size;
48static int rspq_size;
49static int num_sgpgs;
50static int rport_del_timeout = BFA_FCS_RPORT_DEF_DEL_TIMEOUT;
51static int bfa_io_max_sge = BFAD_IO_MAX_SGE;
52static int log_level = BFA_LOG_WARNING;
53static int ioc_auto_recover = BFA_TRUE;
54static int ipfc_enable = BFA_FALSE;
55static int ipfc_mtu = -1;
56int bfa_lun_queue_depth = BFAD_LUN_QUEUE_DEPTH;
57int bfa_linkup_delay = -1;
58
59module_param(os_name, charp, S_IRUGO | S_IWUSR);
60module_param(os_patch, charp, S_IRUGO | S_IWUSR);
61module_param(host_name, charp, S_IRUGO | S_IWUSR);
62module_param(num_rports, int, S_IRUGO | S_IWUSR);
63module_param(num_ios, int, S_IRUGO | S_IWUSR);
64module_param(num_tms, int, S_IRUGO | S_IWUSR);
65module_param(num_fcxps, int, S_IRUGO | S_IWUSR);
66module_param(num_ufbufs, int, S_IRUGO | S_IWUSR);
67module_param(reqq_size, int, S_IRUGO | S_IWUSR);
68module_param(rspq_size, int, S_IRUGO | S_IWUSR);
69module_param(num_sgpgs, int, S_IRUGO | S_IWUSR);
70module_param(rport_del_timeout, int, S_IRUGO | S_IWUSR);
71module_param(bfa_lun_queue_depth, int, S_IRUGO | S_IWUSR);
72module_param(bfa_io_max_sge, int, S_IRUGO | S_IWUSR);
73module_param(log_level, int, S_IRUGO | S_IWUSR);
74module_param(ioc_auto_recover, int, S_IRUGO | S_IWUSR);
75module_param(ipfc_enable, int, S_IRUGO | S_IWUSR);
76module_param(ipfc_mtu, int, S_IRUGO | S_IWUSR);
77module_param(bfa_linkup_delay, int, S_IRUGO | S_IWUSR);
78
79/*
80 * Stores the module parm num_sgpgs value;
81 * used to reset for bfad next instance.
82 */
83static int num_sgpgs_parm;
84
85static bfa_status_t
86bfad_fc4_probe(struct bfad_s *bfad)
87{
88 int rc;
89
90 rc = bfad_im_probe(bfad);
91 if (rc != BFA_STATUS_OK)
92 goto ext;
93
94 bfad_tm_probe(bfad);
95
96 if (ipfc_enable)
97 bfad_ipfc_probe(bfad);
98ext:
99 return rc;
100}
101
102static void
103bfad_fc4_probe_undo(struct bfad_s *bfad)
104{
105 bfad_im_probe_undo(bfad);
106 bfad_tm_probe_undo(bfad);
107 if (ipfc_enable)
108 bfad_ipfc_probe_undo(bfad);
109}
110
111static void
112bfad_fc4_probe_post(struct bfad_s *bfad)
113{
114 if (bfad->im)
115 bfad_im_probe_post(bfad->im);
116
117 bfad_tm_probe_post(bfad);
118 if (ipfc_enable)
119 bfad_ipfc_probe_post(bfad);
120}
121
122static bfa_status_t
123bfad_fc4_port_new(struct bfad_s *bfad, struct bfad_port_s *port, int roles)
124{
125 int rc = BFA_STATUS_FAILED;
126
127 if (roles & BFA_PORT_ROLE_FCP_IM)
128 rc = bfad_im_port_new(bfad, port);
129 if (rc != BFA_STATUS_OK)
130 goto ext;
131
132 if (roles & BFA_PORT_ROLE_FCP_TM)
133 rc = bfad_tm_port_new(bfad, port);
134 if (rc != BFA_STATUS_OK)
135 goto ext;
136
137 if ((roles & BFA_PORT_ROLE_FCP_IPFC) && ipfc_enable)
138 rc = bfad_ipfc_port_new(bfad, port, port->pvb_type);
139ext:
140 return rc;
141}
142
143static void
144bfad_fc4_port_delete(struct bfad_s *bfad, struct bfad_port_s *port, int roles)
145{
146 if (roles & BFA_PORT_ROLE_FCP_IM)
147 bfad_im_port_delete(bfad, port);
148
149 if (roles & BFA_PORT_ROLE_FCP_TM)
150 bfad_tm_port_delete(bfad, port);
151
152 if ((roles & BFA_PORT_ROLE_FCP_IPFC) && ipfc_enable)
153 bfad_ipfc_port_delete(bfad, port);
154}
155
156/**
157 * BFA callbacks
158 */
159void
160bfad_hcb_comp(void *arg, bfa_status_t status)
161{
162 struct bfad_hal_comp *fcomp = (struct bfad_hal_comp *)arg;
163
164 fcomp->status = status;
165 complete(&fcomp->comp);
166}
167
168/**
169 * bfa_init callback
170 */
171void
172bfa_cb_init(void *drv, bfa_status_t init_status)
173{
174 struct bfad_s *bfad = drv;
175
176 if (init_status == BFA_STATUS_OK)
177 bfad->bfad_flags |= BFAD_HAL_INIT_DONE;
178
179 complete(&bfad->comp);
180}
181
182
183
184/**
185 * BFA_FCS callbacks
186 */
187static struct bfad_port_s *
188bfad_get_drv_port(struct bfad_s *bfad, struct bfad_vf_s *vf_drv,
189 struct bfad_vport_s *vp_drv)
190{
191 return ((vp_drv) ? (&(vp_drv)->drv_port)
192 : ((vf_drv) ? (&(vf_drv)->base_port) : (&(bfad)->pport)));
193}
194
195struct bfad_port_s *
196bfa_fcb_port_new(struct bfad_s *bfad, struct bfa_fcs_port_s *port,
197 enum bfa_port_role roles, struct bfad_vf_s *vf_drv,
198 struct bfad_vport_s *vp_drv)
199{
200 bfa_status_t rc;
201 struct bfad_port_s *port_drv;
202
203 if (!vp_drv && !vf_drv) {
204 port_drv = &bfad->pport;
205 port_drv->pvb_type = BFAD_PORT_PHYS_BASE;
206 } else if (!vp_drv && vf_drv) {
207 port_drv = &vf_drv->base_port;
208 port_drv->pvb_type = BFAD_PORT_VF_BASE;
209 } else if (vp_drv && !vf_drv) {
210 port_drv = &vp_drv->drv_port;
211 port_drv->pvb_type = BFAD_PORT_PHYS_VPORT;
212 } else {
213 port_drv = &vp_drv->drv_port;
214 port_drv->pvb_type = BFAD_PORT_VF_VPORT;
215 }
216
217 port_drv->fcs_port = port;
218 port_drv->roles = roles;
219 rc = bfad_fc4_port_new(bfad, port_drv, roles);
220 if (rc != BFA_STATUS_OK) {
221 bfad_fc4_port_delete(bfad, port_drv, roles);
222 port_drv = NULL;
223 }
224
225 return port_drv;
226}
227
228void
229bfa_fcb_port_delete(struct bfad_s *bfad, enum bfa_port_role roles,
230 struct bfad_vf_s *vf_drv, struct bfad_vport_s *vp_drv)
231{
232 struct bfad_port_s *port_drv;
233
234 /*
235 * this will be only called from rmmod context
236 */
237 if (vp_drv && !vp_drv->comp_del) {
238 port_drv = bfad_get_drv_port(bfad, vf_drv, vp_drv);
239 bfa_trc(bfad, roles);
240 bfad_fc4_port_delete(bfad, port_drv, roles);
241 }
242}
243
244void
245bfa_fcb_port_online(struct bfad_s *bfad, enum bfa_port_role roles,
246 struct bfad_vf_s *vf_drv, struct bfad_vport_s *vp_drv)
247{
248 struct bfad_port_s *port_drv = bfad_get_drv_port(bfad, vf_drv, vp_drv);
249
250 if (roles & BFA_PORT_ROLE_FCP_IM)
251 bfad_im_port_online(bfad, port_drv);
252
253 if (roles & BFA_PORT_ROLE_FCP_TM)
254 bfad_tm_port_online(bfad, port_drv);
255
256 if ((roles & BFA_PORT_ROLE_FCP_IPFC) && ipfc_enable)
257 bfad_ipfc_port_online(bfad, port_drv);
258
259 bfad->bfad_flags |= BFAD_PORT_ONLINE;
260}
261
262void
263bfa_fcb_port_offline(struct bfad_s *bfad, enum bfa_port_role roles,
264 struct bfad_vf_s *vf_drv, struct bfad_vport_s *vp_drv)
265{
266 struct bfad_port_s *port_drv = bfad_get_drv_port(bfad, vf_drv, vp_drv);
267
268 if (roles & BFA_PORT_ROLE_FCP_IM)
269 bfad_im_port_offline(bfad, port_drv);
270
271 if (roles & BFA_PORT_ROLE_FCP_TM)
272 bfad_tm_port_offline(bfad, port_drv);
273
274 if ((roles & BFA_PORT_ROLE_FCP_IPFC) && ipfc_enable)
275 bfad_ipfc_port_offline(bfad, port_drv);
276}
277
278void
279bfa_fcb_vport_delete(struct bfad_vport_s *vport_drv)
280{
281 if (vport_drv->comp_del) {
282 complete(vport_drv->comp_del);
283 return;
284 }
285
286 kfree(vport_drv);
287}
288
289/**
290 * FCS RPORT alloc callback, after successful PLOGI by FCS
291 */
292bfa_status_t
293bfa_fcb_rport_alloc(struct bfad_s *bfad, struct bfa_fcs_rport_s **rport,
294 struct bfad_rport_s **rport_drv)
295{
296 bfa_status_t rc = BFA_STATUS_OK;
297
298 *rport_drv = kzalloc(sizeof(struct bfad_rport_s), GFP_ATOMIC);
299 if (*rport_drv == NULL) {
300 rc = BFA_STATUS_ENOMEM;
301 goto ext;
302 }
303
304 *rport = &(*rport_drv)->fcs_rport;
305
306ext:
307 return rc;
308}
309
310
311
312void
313bfad_hal_mem_release(struct bfad_s *bfad)
314{
315 int i;
316 struct bfa_meminfo_s *hal_meminfo = &bfad->meminfo;
317 struct bfa_mem_elem_s *meminfo_elem;
318
319 for (i = 0; i < BFA_MEM_TYPE_MAX; i++) {
320 meminfo_elem = &hal_meminfo->meminfo[i];
321 if (meminfo_elem->kva != NULL) {
322 switch (meminfo_elem->mem_type) {
323 case BFA_MEM_TYPE_KVA:
324 vfree(meminfo_elem->kva);
325 break;
326 case BFA_MEM_TYPE_DMA:
327 dma_free_coherent(&bfad->pcidev->dev,
328 meminfo_elem->mem_len,
329 meminfo_elem->kva,
330 (dma_addr_t) meminfo_elem->dma);
331 break;
332 default:
333 bfa_assert(0);
334 break;
335 }
336 }
337 }
338
339 memset(hal_meminfo, 0, sizeof(struct bfa_meminfo_s));
340}
341
342void
343bfad_update_hal_cfg(struct bfa_iocfc_cfg_s *bfa_cfg)
344{
345 if (num_rports > 0)
346 bfa_cfg->fwcfg.num_rports = num_rports;
347 if (num_ios > 0)
348 bfa_cfg->fwcfg.num_ioim_reqs = num_ios;
349 if (num_tms > 0)
350 bfa_cfg->fwcfg.num_tskim_reqs = num_tms;
351 if (num_fcxps > 0)
352 bfa_cfg->fwcfg.num_fcxp_reqs = num_fcxps;
353 if (num_ufbufs > 0)
354 bfa_cfg->fwcfg.num_uf_bufs = num_ufbufs;
355 if (reqq_size > 0)
356 bfa_cfg->drvcfg.num_reqq_elems = reqq_size;
357 if (rspq_size > 0)
358 bfa_cfg->drvcfg.num_rspq_elems = rspq_size;
359 if (num_sgpgs > 0)
360 bfa_cfg->drvcfg.num_sgpgs = num_sgpgs;
361
362 /*
363 * populate the hal values back to the driver for sysfs use.
364 * otherwise, the default values will be shown as 0 in sysfs
365 */
366 num_rports = bfa_cfg->fwcfg.num_rports;
367 num_ios = bfa_cfg->fwcfg.num_ioim_reqs;
368 num_tms = bfa_cfg->fwcfg.num_tskim_reqs;
369 num_fcxps = bfa_cfg->fwcfg.num_fcxp_reqs;
370 num_ufbufs = bfa_cfg->fwcfg.num_uf_bufs;
371 reqq_size = bfa_cfg->drvcfg.num_reqq_elems;
372 rspq_size = bfa_cfg->drvcfg.num_rspq_elems;
373 num_sgpgs = bfa_cfg->drvcfg.num_sgpgs;
374}
375
376bfa_status_t
377bfad_hal_mem_alloc(struct bfad_s *bfad)
378{
379 struct bfa_meminfo_s *hal_meminfo = &bfad->meminfo;
380 struct bfa_mem_elem_s *meminfo_elem;
381 bfa_status_t rc = BFA_STATUS_OK;
382 dma_addr_t phys_addr;
383 int retry_count = 0;
384 int reset_value = 1;
385 int min_num_sgpgs = 512;
386 void *kva;
387 int i;
388
389 bfa_cfg_get_default(&bfad->ioc_cfg);
390
391retry:
392 bfad_update_hal_cfg(&bfad->ioc_cfg);
393 bfad->cfg_data.ioc_queue_depth = bfad->ioc_cfg.fwcfg.num_ioim_reqs;
394 bfa_cfg_get_meminfo(&bfad->ioc_cfg, hal_meminfo);
395
396 for (i = 0; i < BFA_MEM_TYPE_MAX; i++) {
397 meminfo_elem = &hal_meminfo->meminfo[i];
398 switch (meminfo_elem->mem_type) {
399 case BFA_MEM_TYPE_KVA:
400 kva = vmalloc(meminfo_elem->mem_len);
401 if (kva == NULL) {
402 bfad_hal_mem_release(bfad);
403 rc = BFA_STATUS_ENOMEM;
404 goto ext;
405 }
406 memset(kva, 0, meminfo_elem->mem_len);
407 meminfo_elem->kva = kva;
408 break;
409 case BFA_MEM_TYPE_DMA:
410 kva = dma_alloc_coherent(&bfad->pcidev->dev,
411 meminfo_elem->mem_len,
412 &phys_addr, GFP_KERNEL);
413 if (kva == NULL) {
414 bfad_hal_mem_release(bfad);
415 /*
416 * If we cannot allocate with default
417 * num_sgpages try with half the value.
418 */
419 if (num_sgpgs > min_num_sgpgs) {
420 printk(KERN_INFO "bfad[%d]: memory"
421 " allocation failed with"
422 " num_sgpgs: %d\n",
423 bfad->inst_no, num_sgpgs);
424 nextLowerInt(&num_sgpgs);
425 printk(KERN_INFO "bfad[%d]: trying to"
426 " allocate memory with"
427 " num_sgpgs: %d\n",
428 bfad->inst_no, num_sgpgs);
429 retry_count++;
430 goto retry;
431 } else {
432 if (num_sgpgs_parm > 0)
433 num_sgpgs = num_sgpgs_parm;
434 else {
435 reset_value =
436 (1 << retry_count);
437 num_sgpgs *= reset_value;
438 }
439 rc = BFA_STATUS_ENOMEM;
440 goto ext;
441 }
442 }
443
444 if (num_sgpgs_parm > 0)
445 num_sgpgs = num_sgpgs_parm;
446 else {
447 reset_value = (1 << retry_count);
448 num_sgpgs *= reset_value;
449 }
450
451 memset(kva, 0, meminfo_elem->mem_len);
452 meminfo_elem->kva = kva;
453 meminfo_elem->dma = phys_addr;
454 break;
455 default:
456 break;
457
458 }
459 }
460ext:
461 return rc;
462}
463
464/**
465 * Create a vport under a vf.
466 */
467bfa_status_t
468bfad_vport_create(struct bfad_s *bfad, u16 vf_id,
469 struct bfa_port_cfg_s *port_cfg)
470{
471 struct bfad_vport_s *vport;
472 int rc = BFA_STATUS_OK;
473 unsigned long flags;
474 struct completion fcomp;
475
476 vport = kzalloc(sizeof(struct bfad_vport_s), GFP_KERNEL);
477 if (!vport) {
478 rc = BFA_STATUS_ENOMEM;
479 goto ext;
480 }
481
482 vport->drv_port.bfad = bfad;
483 spin_lock_irqsave(&bfad->bfad_lock, flags);
484 rc = bfa_fcs_vport_create(&vport->fcs_vport, &bfad->bfa_fcs, vf_id,
485 port_cfg, vport);
486 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
487
488 if (rc != BFA_STATUS_OK)
489 goto ext_free_vport;
490
491 if (port_cfg->roles & BFA_PORT_ROLE_FCP_IM) {
492 rc = bfad_im_scsi_host_alloc(bfad, vport->drv_port.im_port);
493 if (rc != BFA_STATUS_OK)
494 goto ext_free_fcs_vport;
495 }
496
497 spin_lock_irqsave(&bfad->bfad_lock, flags);
498 bfa_fcs_vport_start(&vport->fcs_vport);
499 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
500
501 return BFA_STATUS_OK;
502
503ext_free_fcs_vport:
504 spin_lock_irqsave(&bfad->bfad_lock, flags);
505 vport->comp_del = &fcomp;
506 init_completion(vport->comp_del);
507 bfa_fcs_vport_delete(&vport->fcs_vport);
508 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
509 wait_for_completion(vport->comp_del);
510ext_free_vport:
511 kfree(vport);
512ext:
513 return rc;
514}
515
516/**
517 * Create a vf and its base vport implicitely.
518 */
519bfa_status_t
520bfad_vf_create(struct bfad_s *bfad, u16 vf_id,
521 struct bfa_port_cfg_s *port_cfg)
522{
523 struct bfad_vf_s *vf;
524 int rc = BFA_STATUS_OK;
525
526 vf = kzalloc(sizeof(struct bfad_vf_s), GFP_KERNEL);
527 if (!vf) {
528 rc = BFA_STATUS_FAILED;
529 goto ext;
530 }
531
532 rc = bfa_fcs_vf_create(&vf->fcs_vf, &bfad->bfa_fcs, vf_id, port_cfg,
533 vf);
534 if (rc != BFA_STATUS_OK)
535 kfree(vf);
536ext:
537 return rc;
538}
539
540void
541bfad_bfa_tmo(unsigned long data)
542{
543 struct bfad_s *bfad = (struct bfad_s *)data;
544 unsigned long flags;
545 struct list_head doneq;
546
547 spin_lock_irqsave(&bfad->bfad_lock, flags);
548
549 bfa_timer_tick(&bfad->bfa);
550
551 bfa_comp_deq(&bfad->bfa, &doneq);
552 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
553
554 if (!list_empty(&doneq)) {
555 bfa_comp_process(&bfad->bfa, &doneq);
556 spin_lock_irqsave(&bfad->bfad_lock, flags);
557 bfa_comp_free(&bfad->bfa, &doneq);
558 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
559 }
560
561 mod_timer(&bfad->hal_tmo, jiffies + msecs_to_jiffies(BFA_TIMER_FREQ));
562}
563
564void
565bfad_init_timer(struct bfad_s *bfad)
566{
567 init_timer(&bfad->hal_tmo);
568 bfad->hal_tmo.function = bfad_bfa_tmo;
569 bfad->hal_tmo.data = (unsigned long)bfad;
570
571 mod_timer(&bfad->hal_tmo, jiffies + msecs_to_jiffies(BFA_TIMER_FREQ));
572}
573
574int
575bfad_pci_init(struct pci_dev *pdev, struct bfad_s *bfad)
576{
577 unsigned long bar0_len;
578 int rc = -ENODEV;
579
580 if (pci_enable_device(pdev)) {
581 BFA_PRINTF(BFA_ERR, "pci_enable_device fail %p\n", pdev);
582 goto out;
583 }
584
585 if (pci_request_regions(pdev, BFAD_DRIVER_NAME))
586 goto out_disable_device;
587
588 pci_set_master(pdev);
589
590
591 if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0)
592 if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) {
593 BFA_PRINTF(BFA_ERR, "pci_set_dma_mask fail %p\n", pdev);
594 goto out_release_region;
595 }
596
597 bfad->pci_bar0_map = pci_resource_start(pdev, 0);
598 bar0_len = pci_resource_len(pdev, 0);
599 bfad->pci_bar0_kva = ioremap(bfad->pci_bar0_map, bar0_len);
600
601 if (bfad->pci_bar0_kva == NULL) {
602 BFA_PRINTF(BFA_ERR, "Fail to map bar0\n");
603 goto out_release_region;
604 }
605
606 bfad->hal_pcidev.pci_slot = PCI_SLOT(pdev->devfn);
607 bfad->hal_pcidev.pci_func = PCI_FUNC(pdev->devfn);
608 bfad->hal_pcidev.pci_bar_kva = bfad->pci_bar0_kva;
609 bfad->hal_pcidev.device_id = pdev->device;
610 bfad->pci_name = pci_name(pdev);
611
612 bfad->pci_attr.vendor_id = pdev->vendor;
613 bfad->pci_attr.device_id = pdev->device;
614 bfad->pci_attr.ssid = pdev->subsystem_device;
615 bfad->pci_attr.ssvid = pdev->subsystem_vendor;
616 bfad->pci_attr.pcifn = PCI_FUNC(pdev->devfn);
617
618 bfad->pcidev = pdev;
619 return 0;
620
621out_release_region:
622 pci_release_regions(pdev);
623out_disable_device:
624 pci_disable_device(pdev);
625out:
626 return rc;
627}
628
629void
630bfad_pci_uninit(struct pci_dev *pdev, struct bfad_s *bfad)
631{
632#if defined(__ia64__)
633 pci_iounmap(pdev, bfad->pci_bar0_kva);
634#else
635 iounmap(bfad->pci_bar0_kva);
636#endif
637 pci_release_regions(pdev);
638 pci_disable_device(pdev);
639 pci_set_drvdata(pdev, NULL);
640}
641
642void
643bfad_fcs_port_cfg(struct bfad_s *bfad)
644{
645 struct bfa_port_cfg_s port_cfg;
646 struct bfa_pport_attr_s attr;
647 char symname[BFA_SYMNAME_MAXLEN];
648
649 sprintf(symname, "%s-%d", BFAD_DRIVER_NAME, bfad->inst_no);
650 memcpy(port_cfg.sym_name.symname, symname, strlen(symname));
651 bfa_pport_get_attr(&bfad->bfa, &attr);
652 port_cfg.nwwn = attr.nwwn;
653 port_cfg.pwwn = attr.pwwn;
654
655 bfa_fcs_cfg_base_port(&bfad->bfa_fcs, &port_cfg);
656}
657
658bfa_status_t
659bfad_drv_init(struct bfad_s *bfad)
660{
661 bfa_status_t rc;
662 unsigned long flags;
663 struct bfa_fcs_driver_info_s driver_info;
664 int i;
665
666 bfad->cfg_data.rport_del_timeout = rport_del_timeout;
667 bfad->cfg_data.lun_queue_depth = bfa_lun_queue_depth;
668 bfad->cfg_data.io_max_sge = bfa_io_max_sge;
669 bfad->cfg_data.binding_method = FCP_PWWN_BINDING;
670
671 rc = bfad_hal_mem_alloc(bfad);
672 if (rc != BFA_STATUS_OK) {
673 printk(KERN_WARNING "bfad%d bfad_hal_mem_alloc failure\n",
674 bfad->inst_no);
675 printk(KERN_WARNING
676 "Not enough memory to attach all Brocade HBA ports,"
677 " System may need more memory.\n");
678 goto out_hal_mem_alloc_failure;
679 }
680
681 bfa_init_log(&bfad->bfa, bfad->logmod);
682 bfa_init_trc(&bfad->bfa, bfad->trcmod);
683 bfa_init_aen(&bfad->bfa, bfad->aen);
684 INIT_LIST_HEAD(&bfad->file_q);
685 INIT_LIST_HEAD(&bfad->file_free_q);
686 for (i = 0; i < BFAD_AEN_MAX_APPS; i++) {
687 bfa_q_qe_init(&bfad->file_buf[i].qe);
688 list_add_tail(&bfad->file_buf[i].qe, &bfad->file_free_q);
689 }
690 bfa_init_plog(&bfad->bfa, &bfad->plog_buf);
691 bfa_plog_init(&bfad->plog_buf);
692 bfa_plog_str(&bfad->plog_buf, BFA_PL_MID_DRVR, BFA_PL_EID_DRIVER_START,
693 0, "Driver Attach");
694
695 bfa_attach(&bfad->bfa, bfad, &bfad->ioc_cfg, &bfad->meminfo,
696 &bfad->hal_pcidev);
697
698 init_completion(&bfad->comp);
699
700 /*
701 * Enable Interrupt and wait bfa_init completion
702 */
703 if (bfad_setup_intr(bfad)) {
704 printk(KERN_WARNING "bfad%d: bfad_setup_intr failed\n",
705 bfad->inst_no);
706 goto out_setup_intr_failure;
707 }
708
709 spin_lock_irqsave(&bfad->bfad_lock, flags);
710 bfa_init(&bfad->bfa);
711 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
712
713 /*
714 * Set up interrupt handler for each vectors
715 */
716 if ((bfad->bfad_flags & BFAD_MSIX_ON)
717 && bfad_install_msix_handler(bfad)) {
718 printk(KERN_WARNING "%s: install_msix failed, bfad%d\n",
719 __FUNCTION__, bfad->inst_no);
720 }
721
722 bfad_init_timer(bfad);
723
724 wait_for_completion(&bfad->comp);
725
726 memset(&driver_info, 0, sizeof(driver_info));
727 strncpy(driver_info.version, BFAD_DRIVER_VERSION,
728 sizeof(driver_info.version) - 1);
729 if (host_name)
730 strncpy(driver_info.host_machine_name, host_name,
731 sizeof(driver_info.host_machine_name) - 1);
732 if (os_name)
733 strncpy(driver_info.host_os_name, os_name,
734 sizeof(driver_info.host_os_name) - 1);
735 if (os_patch)
736 strncpy(driver_info.host_os_patch, os_patch,
737 sizeof(driver_info.host_os_patch) - 1);
738
739 strncpy(driver_info.os_device_name, bfad->pci_name,
740 sizeof(driver_info.os_device_name - 1));
741
742 /*
743 * FCS INIT
744 */
745 spin_lock_irqsave(&bfad->bfad_lock, flags);
746 bfa_fcs_log_init(&bfad->bfa_fcs, bfad->logmod);
747 bfa_fcs_trc_init(&bfad->bfa_fcs, bfad->trcmod);
748 bfa_fcs_aen_init(&bfad->bfa_fcs, bfad->aen);
749 bfa_fcs_init(&bfad->bfa_fcs, &bfad->bfa, bfad, BFA_FALSE);
750 bfa_fcs_driver_info_init(&bfad->bfa_fcs, &driver_info);
751 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
752
753 bfad->bfad_flags |= BFAD_DRV_INIT_DONE;
754 return BFA_STATUS_OK;
755
756out_setup_intr_failure:
757 bfa_detach(&bfad->bfa);
758 bfad_hal_mem_release(bfad);
759out_hal_mem_alloc_failure:
760 return BFA_STATUS_FAILED;
761}
762
763void
764bfad_drv_uninit(struct bfad_s *bfad)
765{
766 del_timer_sync(&bfad->hal_tmo);
767 bfa_isr_disable(&bfad->bfa);
768 bfa_detach(&bfad->bfa);
769 bfad_remove_intr(bfad);
770 bfa_assert(list_empty(&bfad->file_q));
771 bfad_hal_mem_release(bfad);
772}
773
774void
775bfad_drv_start(struct bfad_s *bfad)
776{
777 unsigned long flags;
778
779 spin_lock_irqsave(&bfad->bfad_lock, flags);
780 bfa_start(&bfad->bfa);
781 bfa_fcs_start(&bfad->bfa_fcs);
782 bfad->bfad_flags |= BFAD_HAL_START_DONE;
783 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
784
785 bfad_fc4_probe_post(bfad);
786}
787
788void
789bfad_drv_stop(struct bfad_s *bfad)
790{
791 unsigned long flags;
792
793 spin_lock_irqsave(&bfad->bfad_lock, flags);
794 init_completion(&bfad->comp);
795 bfad->pport.flags |= BFAD_PORT_DELETE;
796 bfa_fcs_exit(&bfad->bfa_fcs);
797 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
798 wait_for_completion(&bfad->comp);
799
800 spin_lock_irqsave(&bfad->bfad_lock, flags);
801 init_completion(&bfad->comp);
802 bfa_stop(&bfad->bfa);
803 bfad->bfad_flags &= ~BFAD_HAL_START_DONE;
804 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
805 wait_for_completion(&bfad->comp);
806}
807
808bfa_status_t
809bfad_cfg_pport(struct bfad_s *bfad, enum bfa_port_role role)
810{
811 int rc = BFA_STATUS_OK;
812
813 /*
814 * Allocate scsi_host for the physical port
815 */
816 if ((bfad_supported_fc4s & BFA_PORT_ROLE_FCP_IM)
817 && (role & BFA_PORT_ROLE_FCP_IM)) {
818 if (bfad->pport.im_port == NULL) {
819 rc = BFA_STATUS_FAILED;
820 goto out;
821 }
822
823 rc = bfad_im_scsi_host_alloc(bfad, bfad->pport.im_port);
824 if (rc != BFA_STATUS_OK)
825 goto out;
826
827 bfad->pport.roles |= BFA_PORT_ROLE_FCP_IM;
828 }
829
830 bfad->bfad_flags |= BFAD_CFG_PPORT_DONE;
831
832out:
833 return rc;
834}
835
836void
837bfad_uncfg_pport(struct bfad_s *bfad)
838{
839 if ((bfad->pport.roles & BFA_PORT_ROLE_FCP_IPFC) && ipfc_enable) {
840 bfad_ipfc_port_delete(bfad, &bfad->pport);
841 bfad->pport.roles &= ~BFA_PORT_ROLE_FCP_IPFC;
842 }
843
844 if ((bfad_supported_fc4s & BFA_PORT_ROLE_FCP_IM)
845 && (bfad->pport.roles & BFA_PORT_ROLE_FCP_IM)) {
846 bfad_im_scsi_host_free(bfad, bfad->pport.im_port);
847 bfad_im_port_clean(bfad->pport.im_port);
848 kfree(bfad->pport.im_port);
849 bfad->pport.roles &= ~BFA_PORT_ROLE_FCP_IM;
850 }
851
852 bfad->bfad_flags &= ~BFAD_CFG_PPORT_DONE;
853}
854
855void
856bfad_drv_log_level_set(struct bfad_s *bfad)
857{
858 if (log_level > BFA_LOG_INVALID && log_level <= BFA_LOG_LEVEL_MAX)
859 bfa_log_set_level_all(&bfad->log_data, log_level);
860}
861
862 /*
863 * PCI_entry PCI driver entries * {
864 */
865
866/**
867 * PCI probe entry.
868 */
869int
870bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid)
871{
872 struct bfad_s *bfad;
873 int error = -ENODEV, retval;
874 char buf[16];
875
876 /*
877 * For single port cards - only claim function 0
878 */
879 if ((pdev->device == BFA_PCI_DEVICE_ID_FC_8G1P)
880 && (PCI_FUNC(pdev->devfn) != 0))
881 return -ENODEV;
882
883 BFA_TRACE(BFA_INFO, "bfad_pci_probe entry");
884
885 bfad = kzalloc(sizeof(struct bfad_s), GFP_KERNEL);
886 if (!bfad) {
887 error = -ENOMEM;
888 goto out;
889 }
890
891 bfad->trcmod = kzalloc(sizeof(struct bfa_trc_mod_s), GFP_KERNEL);
892 if (!bfad->trcmod) {
893 printk(KERN_WARNING "Error alloc trace buffer!\n");
894 error = -ENOMEM;
895 goto out_alloc_trace_failure;
896 }
897
898 /*
899 * LOG/TRACE INIT
900 */
901 bfa_trc_init(bfad->trcmod);
902 bfa_trc(bfad, bfad_inst);
903
904 bfad->logmod = &bfad->log_data;
905 sprintf(buf, "%d", bfad_inst);
906 bfa_log_init(bfad->logmod, buf, bfa_os_printf);
907
908 bfad_drv_log_level_set(bfad);
909
910 bfad->aen = &bfad->aen_buf;
911
912 if (!(bfad_load_fwimg(pdev))) {
913 printk(KERN_WARNING "bfad_load_fwimg failure!\n");
914 kfree(bfad->trcmod);
915 goto out_alloc_trace_failure;
916 }
917
918 retval = bfad_pci_init(pdev, bfad);
919 if (retval) {
920 printk(KERN_WARNING "bfad_pci_init failure!\n");
921 error = retval;
922 goto out_pci_init_failure;
923 }
924
925 mutex_lock(&bfad_mutex);
926 bfad->inst_no = bfad_inst++;
927 list_add_tail(&bfad->list_entry, &bfad_list);
928 mutex_unlock(&bfad_mutex);
929
930 spin_lock_init(&bfad->bfad_lock);
931 pci_set_drvdata(pdev, bfad);
932
933 bfad->ref_count = 0;
934 bfad->pport.bfad = bfad;
935
936 retval = bfad_drv_init(bfad);
937 if (retval != BFA_STATUS_OK)
938 goto out_drv_init_failure;
939 if (!(bfad->bfad_flags & BFAD_HAL_INIT_DONE)) {
940 printk(KERN_WARNING "bfad%d: hal init failed\n", bfad->inst_no);
941 goto ok;
942 }
943
944 /*
945 * PPORT FCS config
946 */
947 bfad_fcs_port_cfg(bfad);
948
949 retval = bfad_cfg_pport(bfad, BFA_PORT_ROLE_FCP_IM);
950 if (retval != BFA_STATUS_OK)
951 goto out_cfg_pport_failure;
952
953 /*
954 * BFAD level FC4 (IM/TM/IPFC) specific resource allocation
955 */
956 retval = bfad_fc4_probe(bfad);
957 if (retval != BFA_STATUS_OK) {
958 printk(KERN_WARNING "bfad_fc4_probe failed\n");
959 goto out_fc4_probe_failure;
960 }
961
962 bfad_drv_start(bfad);
963
964 /*
965 * If bfa_linkup_delay is set to -1 default; try to retrive the
966 * value using the bfad_os_get_linkup_delay(); else use the
967 * passed in module param value as the bfa_linkup_delay.
968 */
969 if (bfa_linkup_delay < 0) {
970 bfa_linkup_delay = bfad_os_get_linkup_delay(bfad);
971 bfad_os_rport_online_wait(bfad);
972 bfa_linkup_delay = -1;
973 } else {
974 bfad_os_rport_online_wait(bfad);
975 }
976
977 bfa_log(bfad->logmod, BFA_LOG_LINUX_DEVICE_CLAIMED, bfad->pci_name);
978ok:
979 return 0;
980
981out_fc4_probe_failure:
982 bfad_fc4_probe_undo(bfad);
983 bfad_uncfg_pport(bfad);
984out_cfg_pport_failure:
985 bfad_drv_uninit(bfad);
986out_drv_init_failure:
987 mutex_lock(&bfad_mutex);
988 bfad_inst--;
989 list_del(&bfad->list_entry);
990 mutex_unlock(&bfad_mutex);
991 bfad_pci_uninit(pdev, bfad);
992out_pci_init_failure:
993 kfree(bfad->trcmod);
994out_alloc_trace_failure:
995 kfree(bfad);
996out:
997 return error;
998}
999
1000/**
1001 * PCI remove entry.
1002 */
1003void
1004bfad_pci_remove(struct pci_dev *pdev)
1005{
1006 struct bfad_s *bfad = pci_get_drvdata(pdev);
1007 unsigned long flags;
1008
1009 bfa_trc(bfad, bfad->inst_no);
1010
1011 if ((bfad->bfad_flags & BFAD_DRV_INIT_DONE)
1012 && !(bfad->bfad_flags & BFAD_HAL_INIT_DONE)) {
1013
1014 spin_lock_irqsave(&bfad->bfad_lock, flags);
1015 init_completion(&bfad->comp);
1016 bfa_stop(&bfad->bfa);
1017 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1018 wait_for_completion(&bfad->comp);
1019
1020 bfad_remove_intr(bfad);
1021 del_timer_sync(&bfad->hal_tmo);
1022 goto hal_detach;
1023 } else if (!(bfad->bfad_flags & BFAD_DRV_INIT_DONE)) {
1024 goto remove_sysfs;
1025 }
1026
1027 if (bfad->bfad_flags & BFAD_HAL_START_DONE)
1028 bfad_drv_stop(bfad);
1029
1030 bfad_remove_intr(bfad);
1031
1032 del_timer_sync(&bfad->hal_tmo);
1033 bfad_fc4_probe_undo(bfad);
1034
1035 if (bfad->bfad_flags & BFAD_CFG_PPORT_DONE)
1036 bfad_uncfg_pport(bfad);
1037
1038hal_detach:
1039 spin_lock_irqsave(&bfad->bfad_lock, flags);
1040 bfa_detach(&bfad->bfa);
1041 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1042 bfad_hal_mem_release(bfad);
1043remove_sysfs:
1044
1045 mutex_lock(&bfad_mutex);
1046 bfad_inst--;
1047 list_del(&bfad->list_entry);
1048 mutex_unlock(&bfad_mutex);
1049 bfad_pci_uninit(pdev, bfad);
1050
1051 kfree(bfad->trcmod);
1052 kfree(bfad);
1053}
1054
1055
1056static struct pci_device_id bfad_id_table[] = {
1057 {
1058 .vendor = BFA_PCI_VENDOR_ID_BROCADE,
1059 .device = BFA_PCI_DEVICE_ID_FC_8G2P,
1060 .subvendor = PCI_ANY_ID,
1061 .subdevice = PCI_ANY_ID,
1062 },
1063 {
1064 .vendor = BFA_PCI_VENDOR_ID_BROCADE,
1065 .device = BFA_PCI_DEVICE_ID_FC_8G1P,
1066 .subvendor = PCI_ANY_ID,
1067 .subdevice = PCI_ANY_ID,
1068 },
1069 {
1070 .vendor = BFA_PCI_VENDOR_ID_BROCADE,
1071 .device = BFA_PCI_DEVICE_ID_CT,
1072 .subvendor = PCI_ANY_ID,
1073 .subdevice = PCI_ANY_ID,
1074 .class = (PCI_CLASS_SERIAL_FIBER << 8),
1075 .class_mask = ~0,
1076 },
1077
1078 {0, 0},
1079};
1080
1081MODULE_DEVICE_TABLE(pci, bfad_id_table);
1082
1083static struct pci_driver bfad_pci_driver = {
1084 .name = BFAD_DRIVER_NAME,
1085 .id_table = bfad_id_table,
1086 .probe = bfad_pci_probe,
1087 .remove = __devexit_p(bfad_pci_remove),
1088};
1089
1090/**
1091 * Linux driver module functions
1092 */
1093bfa_status_t
1094bfad_fc4_module_init(void)
1095{
1096 int rc;
1097
1098 rc = bfad_im_module_init();
1099 if (rc != BFA_STATUS_OK)
1100 goto ext;
1101
1102 bfad_tm_module_init();
1103 if (ipfc_enable)
1104 bfad_ipfc_module_init();
1105ext:
1106 return rc;
1107}
1108
1109void
1110bfad_fc4_module_exit(void)
1111{
1112 if (ipfc_enable)
1113 bfad_ipfc_module_exit();
1114 bfad_tm_module_exit();
1115 bfad_im_module_exit();
1116}
1117
1118/**
1119 * Driver module init.
1120 */
1121static int __init
1122bfad_init(void)
1123{
1124 int error = 0;
1125
1126 printk(KERN_INFO "Brocade BFA FC/FCOE SCSI driver - version: %s\n",
1127 BFAD_DRIVER_VERSION);
1128
1129 if (num_sgpgs > 0)
1130 num_sgpgs_parm = num_sgpgs;
1131
1132 error = bfad_fc4_module_init();
1133 if (error) {
1134 error = -ENOMEM;
1135 printk(KERN_WARNING "bfad_fc4_module_init failure\n");
1136 goto ext;
1137 }
1138
1139 if (!strcmp(FCPI_NAME, " fcpim"))
1140 bfad_supported_fc4s |= BFA_PORT_ROLE_FCP_IM;
1141 if (!strcmp(FCPT_NAME, " fcptm"))
1142 bfad_supported_fc4s |= BFA_PORT_ROLE_FCP_TM;
1143 if (!strcmp(IPFC_NAME, " ipfc"))
1144 bfad_supported_fc4s |= BFA_PORT_ROLE_FCP_IPFC;
1145
1146 bfa_ioc_auto_recover(ioc_auto_recover);
1147 bfa_fcs_rport_set_del_timeout(rport_del_timeout);
1148 error = pci_register_driver(&bfad_pci_driver);
1149
1150 if (error) {
1151 printk(KERN_WARNING "bfad pci_register_driver failure\n");
1152 goto ext;
1153 }
1154
1155 return 0;
1156
1157ext:
1158 bfad_fc4_module_exit();
1159 return error;
1160}
1161
1162/**
1163 * Driver module exit.
1164 */
1165static void __exit
1166bfad_exit(void)
1167{
1168 pci_unregister_driver(&bfad_pci_driver);
1169 bfad_fc4_module_exit();
1170 bfad_free_fwimg();
1171}
1172
1173#define BFAD_PROTO_NAME FCPI_NAME FCPT_NAME IPFC_NAME
1174
1175module_init(bfad_init);
1176module_exit(bfad_exit);
1177MODULE_LICENSE("GPL");
1178MODULE_DESCRIPTION("Brocade Fibre Channel HBA Driver" BFAD_PROTO_NAME);
1179MODULE_AUTHOR("Brocade Communications Systems, Inc.");
1180MODULE_VERSION(BFAD_DRIVER_VERSION);
1181
1182
diff --git a/drivers/scsi/bfa/bfad_attr.c b/drivers/scsi/bfa/bfad_attr.c
new file mode 100644
index 000000000000..9129ae3040ff
--- /dev/null
+++ b/drivers/scsi/bfa/bfad_attr.c
@@ -0,0 +1,649 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * bfa_attr.c Linux driver configuration interface module.
20 */
21
22#include "bfad_drv.h"
23#include "bfad_im.h"
24#include "bfad_trcmod.h"
25#include "bfad_attr.h"
26
27/**
28 * FC_transport_template FC transport template
29 */
30
31/**
32 * FC transport template entry, get SCSI target port ID.
33 */
34void
35bfad_im_get_starget_port_id(struct scsi_target *starget)
36{
37 struct Scsi_Host *shost;
38 struct bfad_im_port_s *im_port;
39 struct bfad_s *bfad;
40 struct bfad_itnim_s *itnim = NULL;
41 u32 fc_id = -1;
42 unsigned long flags;
43
44 shost = bfad_os_starget_to_shost(starget);
45 im_port = (struct bfad_im_port_s *) shost->hostdata[0];
46 bfad = im_port->bfad;
47 spin_lock_irqsave(&bfad->bfad_lock, flags);
48
49 itnim = bfad_os_get_itnim(im_port, starget->id);
50 if (itnim)
51 fc_id = bfa_fcs_itnim_get_fcid(&itnim->fcs_itnim);
52
53 fc_starget_port_id(starget) = fc_id;
54 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
55}
56
57/**
58 * FC transport template entry, get SCSI target nwwn.
59 */
60void
61bfad_im_get_starget_node_name(struct scsi_target *starget)
62{
63 struct Scsi_Host *shost;
64 struct bfad_im_port_s *im_port;
65 struct bfad_s *bfad;
66 struct bfad_itnim_s *itnim = NULL;
67 u64 node_name = 0;
68 unsigned long flags;
69
70 shost = bfad_os_starget_to_shost(starget);
71 im_port = (struct bfad_im_port_s *) shost->hostdata[0];
72 bfad = im_port->bfad;
73 spin_lock_irqsave(&bfad->bfad_lock, flags);
74
75 itnim = bfad_os_get_itnim(im_port, starget->id);
76 if (itnim)
77 node_name = bfa_fcs_itnim_get_nwwn(&itnim->fcs_itnim);
78
79 fc_starget_node_name(starget) = bfa_os_htonll(node_name);
80 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
81}
82
83/**
84 * FC transport template entry, get SCSI target pwwn.
85 */
86void
87bfad_im_get_starget_port_name(struct scsi_target *starget)
88{
89 struct Scsi_Host *shost;
90 struct bfad_im_port_s *im_port;
91 struct bfad_s *bfad;
92 struct bfad_itnim_s *itnim = NULL;
93 u64 port_name = 0;
94 unsigned long flags;
95
96 shost = bfad_os_starget_to_shost(starget);
97 im_port = (struct bfad_im_port_s *) shost->hostdata[0];
98 bfad = im_port->bfad;
99 spin_lock_irqsave(&bfad->bfad_lock, flags);
100
101 itnim = bfad_os_get_itnim(im_port, starget->id);
102 if (itnim)
103 port_name = bfa_fcs_itnim_get_pwwn(&itnim->fcs_itnim);
104
105 fc_starget_port_name(starget) = bfa_os_htonll(port_name);
106 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
107}
108
109/**
110 * FC transport template entry, get SCSI host port ID.
111 */
112void
113bfad_im_get_host_port_id(struct Scsi_Host *shost)
114{
115 struct bfad_im_port_s *im_port =
116 (struct bfad_im_port_s *) shost->hostdata[0];
117 struct bfad_port_s *port = im_port->port;
118
119 fc_host_port_id(shost) =
120 bfa_os_hton3b(bfa_fcs_port_get_fcid(port->fcs_port));
121}
122
123
124
125
126
127struct Scsi_Host *
128bfad_os_starget_to_shost(struct scsi_target *starget)
129{
130 return dev_to_shost(starget->dev.parent);
131}
132
133/**
134 * FC transport template entry, get SCSI host port type.
135 */
136static void
137bfad_im_get_host_port_type(struct Scsi_Host *shost)
138{
139 struct bfad_im_port_s *im_port =
140 (struct bfad_im_port_s *) shost->hostdata[0];
141 struct bfad_s *bfad = im_port->bfad;
142 struct bfa_pport_attr_s attr;
143
144 bfa_pport_get_attr(&bfad->bfa, &attr);
145
146 switch (attr.port_type) {
147 case BFA_PPORT_TYPE_NPORT:
148 fc_host_port_type(shost) = FC_PORTTYPE_NPORT;
149 break;
150 case BFA_PPORT_TYPE_NLPORT:
151 fc_host_port_type(shost) = FC_PORTTYPE_NLPORT;
152 break;
153 case BFA_PPORT_TYPE_P2P:
154 fc_host_port_type(shost) = FC_PORTTYPE_PTP;
155 break;
156 case BFA_PPORT_TYPE_LPORT:
157 fc_host_port_type(shost) = FC_PORTTYPE_LPORT;
158 break;
159 default:
160 fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN;
161 break;
162 }
163}
164
165/**
166 * FC transport template entry, get SCSI host port state.
167 */
168static void
169bfad_im_get_host_port_state(struct Scsi_Host *shost)
170{
171 struct bfad_im_port_s *im_port =
172 (struct bfad_im_port_s *) shost->hostdata[0];
173 struct bfad_s *bfad = im_port->bfad;
174 struct bfa_pport_attr_s attr;
175
176 bfa_pport_get_attr(&bfad->bfa, &attr);
177
178 switch (attr.port_state) {
179 case BFA_PPORT_ST_LINKDOWN:
180 fc_host_port_state(shost) = FC_PORTSTATE_LINKDOWN;
181 break;
182 case BFA_PPORT_ST_LINKUP:
183 fc_host_port_state(shost) = FC_PORTSTATE_ONLINE;
184 break;
185 case BFA_PPORT_ST_UNINIT:
186 case BFA_PPORT_ST_ENABLING_QWAIT:
187 case BFA_PPORT_ST_ENABLING:
188 case BFA_PPORT_ST_DISABLING_QWAIT:
189 case BFA_PPORT_ST_DISABLING:
190 case BFA_PPORT_ST_DISABLED:
191 case BFA_PPORT_ST_STOPPED:
192 case BFA_PPORT_ST_IOCDOWN:
193 default:
194 fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN;
195 break;
196 }
197}
198
199/**
200 * FC transport template entry, get SCSI host active fc4s.
201 */
202static void
203bfad_im_get_host_active_fc4s(struct Scsi_Host *shost)
204{
205 struct bfad_im_port_s *im_port =
206 (struct bfad_im_port_s *) shost->hostdata[0];
207 struct bfad_port_s *port = im_port->port;
208
209 memset(fc_host_active_fc4s(shost), 0,
210 sizeof(fc_host_active_fc4s(shost)));
211
212 if (port->supported_fc4s &
213 (BFA_PORT_ROLE_FCP_IM | BFA_PORT_ROLE_FCP_TM))
214 fc_host_active_fc4s(shost)[2] = 1;
215
216 if (port->supported_fc4s & BFA_PORT_ROLE_FCP_IPFC)
217 fc_host_active_fc4s(shost)[3] = 0x20;
218
219 fc_host_active_fc4s(shost)[7] = 1;
220}
221
222/**
223 * FC transport template entry, get SCSI host link speed.
224 */
225static void
226bfad_im_get_host_speed(struct Scsi_Host *shost)
227{
228 struct bfad_im_port_s *im_port =
229 (struct bfad_im_port_s *) shost->hostdata[0];
230 struct bfad_s *bfad = im_port->bfad;
231 struct bfa_pport_attr_s attr;
232
233 bfa_pport_get_attr(&bfad->bfa, &attr);
234 switch (attr.speed) {
235 case BFA_PPORT_SPEED_8GBPS:
236 fc_host_speed(shost) = FC_PORTSPEED_8GBIT;
237 break;
238 case BFA_PPORT_SPEED_4GBPS:
239 fc_host_speed(shost) = FC_PORTSPEED_4GBIT;
240 break;
241 case BFA_PPORT_SPEED_2GBPS:
242 fc_host_speed(shost) = FC_PORTSPEED_2GBIT;
243 break;
244 case BFA_PPORT_SPEED_1GBPS:
245 fc_host_speed(shost) = FC_PORTSPEED_1GBIT;
246 break;
247 default:
248 fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN;
249 break;
250 }
251}
252
253/**
254 * FC transport template entry, get SCSI host port type.
255 */
256static void
257bfad_im_get_host_fabric_name(struct Scsi_Host *shost)
258{
259 struct bfad_im_port_s *im_port =
260 (struct bfad_im_port_s *) shost->hostdata[0];
261 struct bfad_port_s *port = im_port->port;
262 wwn_t fabric_nwwn = 0;
263
264 fabric_nwwn = bfa_fcs_port_get_fabric_name(port->fcs_port);
265
266 fc_host_fabric_name(shost) = bfa_os_htonll(fabric_nwwn);
267
268}
269
270/**
271 * FC transport template entry, get BFAD statistics.
272 */
273static struct fc_host_statistics *
274bfad_im_get_stats(struct Scsi_Host *shost)
275{
276 struct bfad_im_port_s *im_port =
277 (struct bfad_im_port_s *) shost->hostdata[0];
278 struct bfad_s *bfad = im_port->bfad;
279 struct bfad_hal_comp fcomp;
280 struct fc_host_statistics *hstats;
281 bfa_status_t rc;
282 unsigned long flags;
283
284 hstats = &bfad->link_stats;
285 init_completion(&fcomp.comp);
286 spin_lock_irqsave(&bfad->bfad_lock, flags);
287 memset(hstats, 0, sizeof(struct fc_host_statistics));
288 rc = bfa_pport_get_stats(&bfad->bfa,
289 (union bfa_pport_stats_u *) hstats,
290 bfad_hcb_comp, &fcomp);
291 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
292 if (rc != BFA_STATUS_OK)
293 return NULL;
294
295 wait_for_completion(&fcomp.comp);
296
297 return hstats;
298}
299
300/**
301 * FC transport template entry, reset BFAD statistics.
302 */
303static void
304bfad_im_reset_stats(struct Scsi_Host *shost)
305{
306 struct bfad_im_port_s *im_port =
307 (struct bfad_im_port_s *) shost->hostdata[0];
308 struct bfad_s *bfad = im_port->bfad;
309 struct bfad_hal_comp fcomp;
310 unsigned long flags;
311 bfa_status_t rc;
312
313 init_completion(&fcomp.comp);
314 spin_lock_irqsave(&bfad->bfad_lock, flags);
315 rc = bfa_pport_clear_stats(&bfad->bfa, bfad_hcb_comp, &fcomp);
316 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
317
318 if (rc != BFA_STATUS_OK)
319 return;
320
321 wait_for_completion(&fcomp.comp);
322
323 return;
324}
325
326/**
327 * FC transport template entry, get rport loss timeout.
328 */
329static void
330bfad_im_get_rport_loss_tmo(struct fc_rport *rport)
331{
332 struct bfad_itnim_data_s *itnim_data = rport->dd_data;
333 struct bfad_itnim_s *itnim = itnim_data->itnim;
334 struct bfad_s *bfad = itnim->im->bfad;
335 unsigned long flags;
336
337 spin_lock_irqsave(&bfad->bfad_lock, flags);
338 rport->dev_loss_tmo = bfa_fcpim_path_tov_get(&bfad->bfa);
339 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
340}
341
342/**
343 * FC transport template entry, set rport loss timeout.
344 */
345static void
346bfad_im_set_rport_loss_tmo(struct fc_rport *rport, u32 timeout)
347{
348 struct bfad_itnim_data_s *itnim_data = rport->dd_data;
349 struct bfad_itnim_s *itnim = itnim_data->itnim;
350 struct bfad_s *bfad = itnim->im->bfad;
351 unsigned long flags;
352
353 if (timeout > 0) {
354 spin_lock_irqsave(&bfad->bfad_lock, flags);
355 bfa_fcpim_path_tov_set(&bfad->bfa, timeout);
356 rport->dev_loss_tmo = bfa_fcpim_path_tov_get(&bfad->bfa);
357 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
358 }
359
360}
361
362struct fc_function_template bfad_im_fc_function_template = {
363
364 /* Target dynamic attributes */
365 .get_starget_port_id = bfad_im_get_starget_port_id,
366 .show_starget_port_id = 1,
367 .get_starget_node_name = bfad_im_get_starget_node_name,
368 .show_starget_node_name = 1,
369 .get_starget_port_name = bfad_im_get_starget_port_name,
370 .show_starget_port_name = 1,
371
372 /* Host dynamic attribute */
373 .get_host_port_id = bfad_im_get_host_port_id,
374 .show_host_port_id = 1,
375
376 /* Host fixed attributes */
377 .show_host_node_name = 1,
378 .show_host_port_name = 1,
379 .show_host_supported_classes = 1,
380 .show_host_supported_fc4s = 1,
381 .show_host_supported_speeds = 1,
382 .show_host_maxframe_size = 1,
383
384 /* More host dynamic attributes */
385 .show_host_port_type = 1,
386 .get_host_port_type = bfad_im_get_host_port_type,
387 .show_host_port_state = 1,
388 .get_host_port_state = bfad_im_get_host_port_state,
389 .show_host_active_fc4s = 1,
390 .get_host_active_fc4s = bfad_im_get_host_active_fc4s,
391 .show_host_speed = 1,
392 .get_host_speed = bfad_im_get_host_speed,
393 .show_host_fabric_name = 1,
394 .get_host_fabric_name = bfad_im_get_host_fabric_name,
395
396 .show_host_symbolic_name = 1,
397
398 /* Statistics */
399 .get_fc_host_stats = bfad_im_get_stats,
400 .reset_fc_host_stats = bfad_im_reset_stats,
401
402 /* Allocation length for host specific data */
403 .dd_fcrport_size = sizeof(struct bfad_itnim_data_s *),
404
405 /* Remote port fixed attributes */
406 .show_rport_maxframe_size = 1,
407 .show_rport_supported_classes = 1,
408 .show_rport_dev_loss_tmo = 1,
409 .get_rport_dev_loss_tmo = bfad_im_get_rport_loss_tmo,
410 .set_rport_dev_loss_tmo = bfad_im_set_rport_loss_tmo,
411};
412
413/**
414 * Scsi_Host_attrs SCSI host attributes
415 */
416static ssize_t
417bfad_im_serial_num_show(struct device *dev, struct device_attribute *attr,
418 char *buf)
419{
420 struct Scsi_Host *shost = class_to_shost(dev);
421 struct bfad_im_port_s *im_port =
422 (struct bfad_im_port_s *) shost->hostdata[0];
423 struct bfad_s *bfad = im_port->bfad;
424 struct bfa_ioc_attr_s ioc_attr;
425
426 memset(&ioc_attr, 0, sizeof(ioc_attr));
427 bfa_get_attr(&bfad->bfa, &ioc_attr);
428 return snprintf(buf, PAGE_SIZE, "%s\n",
429 ioc_attr.adapter_attr.serial_num);
430}
431
432static ssize_t
433bfad_im_model_show(struct device *dev, struct device_attribute *attr,
434 char *buf)
435{
436 struct Scsi_Host *shost = class_to_shost(dev);
437 struct bfad_im_port_s *im_port =
438 (struct bfad_im_port_s *) shost->hostdata[0];
439 struct bfad_s *bfad = im_port->bfad;
440 struct bfa_ioc_attr_s ioc_attr;
441
442 memset(&ioc_attr, 0, sizeof(ioc_attr));
443 bfa_get_attr(&bfad->bfa, &ioc_attr);
444 return snprintf(buf, PAGE_SIZE, "%s\n", ioc_attr.adapter_attr.model);
445}
446
447static ssize_t
448bfad_im_model_desc_show(struct device *dev, struct device_attribute *attr,
449 char *buf)
450{
451 struct Scsi_Host *shost = class_to_shost(dev);
452 struct bfad_im_port_s *im_port =
453 (struct bfad_im_port_s *) shost->hostdata[0];
454 struct bfad_s *bfad = im_port->bfad;
455 struct bfa_ioc_attr_s ioc_attr;
456
457 memset(&ioc_attr, 0, sizeof(ioc_attr));
458 bfa_get_attr(&bfad->bfa, &ioc_attr);
459 return snprintf(buf, PAGE_SIZE, "%s\n",
460 ioc_attr.adapter_attr.model_descr);
461}
462
463static ssize_t
464bfad_im_node_name_show(struct device *dev, struct device_attribute *attr,
465 char *buf)
466{
467 struct Scsi_Host *shost = class_to_shost(dev);
468 struct bfad_im_port_s *im_port =
469 (struct bfad_im_port_s *) shost->hostdata[0];
470 struct bfad_port_s *port = im_port->port;
471 u64 nwwn;
472
473 nwwn = bfa_fcs_port_get_nwwn(port->fcs_port);
474 return snprintf(buf, PAGE_SIZE, "0x%llx\n", bfa_os_htonll(nwwn));
475}
476
477static ssize_t
478bfad_im_symbolic_name_show(struct device *dev, struct device_attribute *attr,
479 char *buf)
480{
481 struct Scsi_Host *shost = class_to_shost(dev);
482 struct bfad_im_port_s *im_port =
483 (struct bfad_im_port_s *) shost->hostdata[0];
484 struct bfad_s *bfad = im_port->bfad;
485 struct bfa_ioc_attr_s ioc_attr;
486
487 memset(&ioc_attr, 0, sizeof(ioc_attr));
488 bfa_get_attr(&bfad->bfa, &ioc_attr);
489
490 return snprintf(buf, PAGE_SIZE, "Brocade %s FV%s DV%s\n",
491 ioc_attr.adapter_attr.model,
492 ioc_attr.adapter_attr.fw_ver, BFAD_DRIVER_VERSION);
493}
494
495static ssize_t
496bfad_im_hw_version_show(struct device *dev, struct device_attribute *attr,
497 char *buf)
498{
499 struct Scsi_Host *shost = class_to_shost(dev);
500 struct bfad_im_port_s *im_port =
501 (struct bfad_im_port_s *) shost->hostdata[0];
502 struct bfad_s *bfad = im_port->bfad;
503 struct bfa_ioc_attr_s ioc_attr;
504
505 memset(&ioc_attr, 0, sizeof(ioc_attr));
506 bfa_get_attr(&bfad->bfa, &ioc_attr);
507 return snprintf(buf, PAGE_SIZE, "%s\n", ioc_attr.adapter_attr.hw_ver);
508}
509
510static ssize_t
511bfad_im_drv_version_show(struct device *dev, struct device_attribute *attr,
512 char *buf)
513{
514 return snprintf(buf, PAGE_SIZE, "%s\n", BFAD_DRIVER_VERSION);
515}
516
517static ssize_t
518bfad_im_optionrom_version_show(struct device *dev,
519 struct device_attribute *attr, char *buf)
520{
521 struct Scsi_Host *shost = class_to_shost(dev);
522 struct bfad_im_port_s *im_port =
523 (struct bfad_im_port_s *) shost->hostdata[0];
524 struct bfad_s *bfad = im_port->bfad;
525 struct bfa_ioc_attr_s ioc_attr;
526
527 memset(&ioc_attr, 0, sizeof(ioc_attr));
528 bfa_get_attr(&bfad->bfa, &ioc_attr);
529 return snprintf(buf, PAGE_SIZE, "%s\n",
530 ioc_attr.adapter_attr.optrom_ver);
531}
532
533static ssize_t
534bfad_im_fw_version_show(struct device *dev, struct device_attribute *attr,
535 char *buf)
536{
537 struct Scsi_Host *shost = class_to_shost(dev);
538 struct bfad_im_port_s *im_port =
539 (struct bfad_im_port_s *) shost->hostdata[0];
540 struct bfad_s *bfad = im_port->bfad;
541 struct bfa_ioc_attr_s ioc_attr;
542
543 memset(&ioc_attr, 0, sizeof(ioc_attr));
544 bfa_get_attr(&bfad->bfa, &ioc_attr);
545 return snprintf(buf, PAGE_SIZE, "%s\n", ioc_attr.adapter_attr.fw_ver);
546}
547
548static ssize_t
549bfad_im_num_of_ports_show(struct device *dev, struct device_attribute *attr,
550 char *buf)
551{
552 struct Scsi_Host *shost = class_to_shost(dev);
553 struct bfad_im_port_s *im_port =
554 (struct bfad_im_port_s *) shost->hostdata[0];
555 struct bfad_s *bfad = im_port->bfad;
556 struct bfa_ioc_attr_s ioc_attr;
557
558 memset(&ioc_attr, 0, sizeof(ioc_attr));
559 bfa_get_attr(&bfad->bfa, &ioc_attr);
560 return snprintf(buf, PAGE_SIZE, "%d\n", ioc_attr.adapter_attr.nports);
561}
562
563static ssize_t
564bfad_im_drv_name_show(struct device *dev, struct device_attribute *attr,
565 char *buf)
566{
567 return snprintf(buf, PAGE_SIZE, "%s\n", BFAD_DRIVER_NAME);
568}
569
570static ssize_t
571bfad_im_num_of_discovered_ports_show(struct device *dev,
572 struct device_attribute *attr, char *buf)
573{
574 struct Scsi_Host *shost = class_to_shost(dev);
575 struct bfad_im_port_s *im_port =
576 (struct bfad_im_port_s *) shost->hostdata[0];
577 struct bfad_port_s *port = im_port->port;
578 struct bfad_s *bfad = im_port->bfad;
579 int nrports = 2048;
580 wwn_t *rports = NULL;
581 unsigned long flags;
582
583 rports = kzalloc(sizeof(wwn_t) * nrports , GFP_ATOMIC);
584 if (rports == NULL)
585 return -ENOMEM;
586
587 spin_lock_irqsave(&bfad->bfad_lock, flags);
588 bfa_fcs_port_get_rports(port->fcs_port, rports, &nrports);
589 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
590 kfree(rports);
591
592 return snprintf(buf, PAGE_SIZE, "%d\n", nrports);
593}
594
595static DEVICE_ATTR(serial_number, S_IRUGO,
596 bfad_im_serial_num_show, NULL);
597static DEVICE_ATTR(model, S_IRUGO, bfad_im_model_show, NULL);
598static DEVICE_ATTR(model_description, S_IRUGO,
599 bfad_im_model_desc_show, NULL);
600static DEVICE_ATTR(node_name, S_IRUGO, bfad_im_node_name_show, NULL);
601static DEVICE_ATTR(symbolic_name, S_IRUGO,
602 bfad_im_symbolic_name_show, NULL);
603static DEVICE_ATTR(hardware_version, S_IRUGO,
604 bfad_im_hw_version_show, NULL);
605static DEVICE_ATTR(driver_version, S_IRUGO,
606 bfad_im_drv_version_show, NULL);
607static DEVICE_ATTR(option_rom_version, S_IRUGO,
608 bfad_im_optionrom_version_show, NULL);
609static DEVICE_ATTR(firmware_version, S_IRUGO,
610 bfad_im_fw_version_show, NULL);
611static DEVICE_ATTR(number_of_ports, S_IRUGO,
612 bfad_im_num_of_ports_show, NULL);
613static DEVICE_ATTR(driver_name, S_IRUGO, bfad_im_drv_name_show, NULL);
614static DEVICE_ATTR(number_of_discovered_ports, S_IRUGO,
615 bfad_im_num_of_discovered_ports_show, NULL);
616
617struct device_attribute *bfad_im_host_attrs[] = {
618 &dev_attr_serial_number,
619 &dev_attr_model,
620 &dev_attr_model_description,
621 &dev_attr_node_name,
622 &dev_attr_symbolic_name,
623 &dev_attr_hardware_version,
624 &dev_attr_driver_version,
625 &dev_attr_option_rom_version,
626 &dev_attr_firmware_version,
627 &dev_attr_number_of_ports,
628 &dev_attr_driver_name,
629 &dev_attr_number_of_discovered_ports,
630 NULL,
631};
632
633struct device_attribute *bfad_im_vport_attrs[] = {
634 &dev_attr_serial_number,
635 &dev_attr_model,
636 &dev_attr_model_description,
637 &dev_attr_node_name,
638 &dev_attr_symbolic_name,
639 &dev_attr_hardware_version,
640 &dev_attr_driver_version,
641 &dev_attr_option_rom_version,
642 &dev_attr_firmware_version,
643 &dev_attr_number_of_ports,
644 &dev_attr_driver_name,
645 &dev_attr_number_of_discovered_ports,
646 NULL,
647};
648
649
diff --git a/drivers/scsi/bfa/bfad_attr.h b/drivers/scsi/bfa/bfad_attr.h
new file mode 100644
index 000000000000..4d3312da6a81
--- /dev/null
+++ b/drivers/scsi/bfa/bfad_attr.h
@@ -0,0 +1,65 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFAD_ATTR_H__
19#define __BFAD_ATTR_H__
20/**
21 * bfad_attr.h VMware driver configuration interface module.
22 */
23
24/**
25 * FC_transport_template FC transport template
26 */
27
28struct Scsi_Host*
29bfad_os_dev_to_shost(struct scsi_target *starget);
30
31/**
32 * FC transport template entry, get SCSI target port ID.
33 */
34void
35bfad_im_get_starget_port_id(struct scsi_target *starget);
36
37/**
38 * FC transport template entry, get SCSI target nwwn.
39 */
40void
41bfad_im_get_starget_node_name(struct scsi_target *starget);
42
43/**
44 * FC transport template entry, get SCSI target pwwn.
45 */
46void
47bfad_im_get_starget_port_name(struct scsi_target *starget);
48
49/**
50 * FC transport template entry, get SCSI host port ID.
51 */
52void
53bfad_im_get_host_port_id(struct Scsi_Host *shost);
54
55/**
56 * FC transport template entry, issue a LIP.
57 */
58int
59bfad_im_issue_fc_host_lip(struct Scsi_Host *shost);
60
61struct Scsi_Host*
62bfad_os_starget_to_shost(struct scsi_target *starget);
63
64
65#endif /* __BFAD_ATTR_H__ */
diff --git a/drivers/scsi/bfa/bfad_drv.h b/drivers/scsi/bfa/bfad_drv.h
new file mode 100644
index 000000000000..172c81e25c1c
--- /dev/null
+++ b/drivers/scsi/bfa/bfad_drv.h
@@ -0,0 +1,295 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * Contains base driver definitions.
20 */
21
22/**
23 * bfa_drv.h Linux driver data structures.
24 */
25
26#ifndef __BFAD_DRV_H__
27#define __BFAD_DRV_H__
28
29#include "bfa_os_inc.h"
30
31#include <bfa.h>
32#include <bfa_svc.h>
33#include <fcs/bfa_fcs.h>
34#include <defs/bfa_defs_pci.h>
35#include <defs/bfa_defs_port.h>
36#include <defs/bfa_defs_rport.h>
37#include <fcs/bfa_fcs_rport.h>
38#include <defs/bfa_defs_vport.h>
39#include <fcs/bfa_fcs_vport.h>
40
41#include <cs/bfa_plog.h>
42#include "aen/bfa_aen.h"
43#include <log/bfa_log_linux.h>
44
45#define BFAD_DRIVER_NAME "bfa"
46#ifdef BFA_DRIVER_VERSION
47#define BFAD_DRIVER_VERSION BFA_DRIVER_VERSION
48#else
49#define BFAD_DRIVER_VERSION "2.0.0.0"
50#endif
51
52
53#define BFAD_IRQ_FLAGS IRQF_SHARED
54
55/*
56 * BFAD flags
57 */
58#define BFAD_MSIX_ON 0x00000001
59#define BFAD_HAL_INIT_DONE 0x00000002
60#define BFAD_DRV_INIT_DONE 0x00000004
61#define BFAD_CFG_PPORT_DONE 0x00000008
62#define BFAD_HAL_START_DONE 0x00000010
63#define BFAD_PORT_ONLINE 0x00000020
64#define BFAD_RPORT_ONLINE 0x00000040
65
66#define BFAD_PORT_DELETE 0x00000001
67
68/*
69 * BFAD related definition
70 */
71#define SCSI_SCAN_DELAY HZ
72#define BFAD_STOP_TIMEOUT 30
73#define BFAD_SUSPEND_TIMEOUT BFAD_STOP_TIMEOUT
74
75/*
76 * BFAD configuration parameter default values
77 */
78#define BFAD_LUN_QUEUE_DEPTH 32
79#define BFAD_IO_MAX_SGE SG_ALL
80
81#define bfad_isr_t irq_handler_t
82
83#define MAX_MSIX_ENTRY 22
84
85struct bfad_msix_s {
86 struct bfad_s *bfad;
87 struct msix_entry msix;
88};
89
90enum bfad_port_pvb_type {
91 BFAD_PORT_PHYS_BASE = 0,
92 BFAD_PORT_PHYS_VPORT = 1,
93 BFAD_PORT_VF_BASE = 2,
94 BFAD_PORT_VF_VPORT = 3,
95};
96
97/*
98 * PORT data structure
99 */
100struct bfad_port_s {
101 struct list_head list_entry;
102 struct bfad_s *bfad;
103 struct bfa_fcs_port_s *fcs_port;
104 u32 roles;
105 s32 flags;
106 u32 supported_fc4s;
107 u8 ipfc_flags;
108 enum bfad_port_pvb_type pvb_type;
109 struct bfad_im_port_s *im_port; /* IM specific data */
110 struct bfad_tm_port_s *tm_port; /* TM specific data */
111 struct bfad_ipfc_port_s *ipfc_port; /* IPFC specific data */
112};
113
114/*
115 * VPORT data structure
116 */
117struct bfad_vport_s {
118 struct bfad_port_s drv_port;
119 struct bfa_fcs_vport_s fcs_vport;
120 struct completion *comp_del;
121};
122
123/*
124 * VF data structure
125 */
126struct bfad_vf_s {
127 bfa_fcs_vf_t fcs_vf;
128 struct bfad_port_s base_port; /* base port for vf */
129 struct bfad_s *bfad;
130};
131
132struct bfad_cfg_param_s {
133 u32 rport_del_timeout;
134 u32 ioc_queue_depth;
135 u32 lun_queue_depth;
136 u32 io_max_sge;
137 u32 binding_method;
138};
139
140#define BFAD_AEN_MAX_APPS 8
141struct bfad_aen_file_s {
142 struct list_head qe;
143 struct bfad_s *bfad;
144 s32 ri;
145 s32 app_id;
146};
147
148/*
149 * BFAD (PCI function) data structure
150 */
151struct bfad_s {
152 struct list_head list_entry;
153 struct bfa_s bfa;
154 struct bfa_fcs_s bfa_fcs;
155 struct pci_dev *pcidev;
156 const char *pci_name;
157 struct bfa_pcidev_s hal_pcidev;
158 struct bfa_ioc_pci_attr_s pci_attr;
159 unsigned long pci_bar0_map;
160 void __iomem *pci_bar0_kva;
161 struct completion comp;
162 struct completion suspend;
163 struct completion disable_comp;
164 bfa_boolean_t disable_active;
165 struct bfad_port_s pport; /* physical port of the BFAD */
166 struct bfa_meminfo_s meminfo;
167 struct bfa_iocfc_cfg_s ioc_cfg;
168 u32 inst_no; /* BFAD instance number */
169 u32 bfad_flags;
170 spinlock_t bfad_lock;
171 struct bfad_cfg_param_s cfg_data;
172 struct bfad_msix_s msix_tab[MAX_MSIX_ENTRY];
173 int nvec;
174 char adapter_name[BFA_ADAPTER_SYM_NAME_LEN];
175 char port_name[BFA_ADAPTER_SYM_NAME_LEN];
176 struct timer_list hal_tmo;
177 unsigned long hs_start;
178 struct bfad_im_s *im; /* IM specific data */
179 struct bfad_tm_s *tm; /* TM specific data */
180 struct bfad_ipfc_s *ipfc; /* IPFC specific data */
181 struct bfa_log_mod_s log_data;
182 struct bfa_trc_mod_s *trcmod;
183 struct bfa_log_mod_s *logmod;
184 struct bfa_aen_s *aen;
185 struct bfa_aen_s aen_buf;
186 struct bfad_aen_file_s file_buf[BFAD_AEN_MAX_APPS];
187 struct list_head file_q;
188 struct list_head file_free_q;
189 struct bfa_plog_s plog_buf;
190 int ref_count;
191 bfa_boolean_t ipfc_enabled;
192 struct fc_host_statistics link_stats;
193
194 struct kobject *bfa_kobj;
195 struct kobject *ioc_kobj;
196 struct kobject *pport_kobj;
197 struct kobject *lport_kobj;
198};
199
200/*
201 * RPORT data structure
202 */
203struct bfad_rport_s {
204 struct bfa_fcs_rport_s fcs_rport;
205};
206
207struct bfad_buf_info {
208 void *virt;
209 dma_addr_t phys;
210 u32 size;
211};
212
213struct bfad_fcxp {
214 struct bfad_port_s *port;
215 struct bfa_rport_s *bfa_rport;
216 bfa_status_t req_status;
217 u16 tag;
218 u16 rsp_len;
219 u16 rsp_maxlen;
220 u8 use_ireqbuf;
221 u8 use_irspbuf;
222 u32 num_req_sgles;
223 u32 num_rsp_sgles;
224 struct fchs_s fchs;
225 void *reqbuf_info;
226 void *rspbuf_info;
227 struct bfa_sge_s *req_sge;
228 struct bfa_sge_s *rsp_sge;
229 fcxp_send_cb_t send_cbfn;
230 void *send_cbarg;
231 void *bfa_fcxp;
232 struct completion comp;
233};
234
235struct bfad_hal_comp {
236 bfa_status_t status;
237 struct completion comp;
238};
239
240/*
241 * Macro to obtain the immediate lower power
242 * of two for the integer.
243 */
244#define nextLowerInt(x) \
245do { \
246 int j; \
247 (*x)--; \
248 for (j = 1; j < (sizeof(int) * 8); j <<= 1) \
249 (*x) = (*x) | (*x) >> j; \
250 (*x)++; \
251 (*x) = (*x) >> 1; \
252} while (0)
253
254
255bfa_status_t bfad_vport_create(struct bfad_s *bfad, u16 vf_id,
256 struct bfa_port_cfg_s *port_cfg);
257bfa_status_t bfad_vf_create(struct bfad_s *bfad, u16 vf_id,
258 struct bfa_port_cfg_s *port_cfg);
259bfa_status_t bfad_cfg_pport(struct bfad_s *bfad, enum bfa_port_role role);
260bfa_status_t bfad_drv_init(struct bfad_s *bfad);
261void bfad_drv_start(struct bfad_s *bfad);
262void bfad_uncfg_pport(struct bfad_s *bfad);
263void bfad_drv_stop(struct bfad_s *bfad);
264void bfad_remove_intr(struct bfad_s *bfad);
265void bfad_hal_mem_release(struct bfad_s *bfad);
266void bfad_hcb_comp(void *arg, bfa_status_t status);
267
268int bfad_setup_intr(struct bfad_s *bfad);
269void bfad_remove_intr(struct bfad_s *bfad);
270
271void bfad_update_hal_cfg(struct bfa_iocfc_cfg_s *bfa_cfg);
272bfa_status_t bfad_hal_mem_alloc(struct bfad_s *bfad);
273void bfad_bfa_tmo(unsigned long data);
274void bfad_init_timer(struct bfad_s *bfad);
275int bfad_pci_init(struct pci_dev *pdev, struct bfad_s *bfad);
276void bfad_pci_uninit(struct pci_dev *pdev, struct bfad_s *bfad);
277void bfad_fcs_port_cfg(struct bfad_s *bfad);
278void bfad_drv_uninit(struct bfad_s *bfad);
279void bfad_drv_log_level_set(struct bfad_s *bfad);
280bfa_status_t bfad_fc4_module_init(void);
281void bfad_fc4_module_exit(void);
282
283void bfad_pci_remove(struct pci_dev *pdev);
284int bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid);
285void bfad_os_rport_online_wait(struct bfad_s *bfad);
286int bfad_os_get_linkup_delay(struct bfad_s *bfad);
287int bfad_install_msix_handler(struct bfad_s *bfad);
288
289extern struct idr bfad_im_port_index;
290extern struct list_head bfad_list;
291extern int bfa_lun_queue_depth;
292extern int bfad_supported_fc4s;
293extern int bfa_linkup_delay;
294
295#endif /* __BFAD_DRV_H__ */
diff --git a/drivers/scsi/bfa/bfad_fwimg.c b/drivers/scsi/bfa/bfad_fwimg.c
new file mode 100644
index 000000000000..b2f6949bc8d3
--- /dev/null
+++ b/drivers/scsi/bfa/bfad_fwimg.c
@@ -0,0 +1,95 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * bfad_fwimg.c Linux driver PCI interface module.
20 */
21#include <bfa_os_inc.h>
22#include <bfad_drv.h>
23#include <bfad_im_compat.h>
24#include <defs/bfa_defs_version.h>
25#include <linux/errno.h>
26#include <linux/sched.h>
27#include <linux/init.h>
28#include <linux/fs.h>
29#include <asm/uaccess.h>
30#include <asm/fcntl.h>
31#include <linux/pci.h>
32#include <linux/firmware.h>
33#include <bfa_fwimg_priv.h>
34#include <bfa.h>
35
36u32 bfi_image_ct_size;
37u32 bfi_image_cb_size;
38u32 *bfi_image_ct;
39u32 *bfi_image_cb;
40
41
42#define BFAD_FW_FILE_CT "ctfw.bin"
43#define BFAD_FW_FILE_CB "cbfw.bin"
44
45u32 *
46bfad_read_firmware(struct pci_dev *pdev, u32 **bfi_image,
47 u32 *bfi_image_size, char *fw_name)
48{
49 const struct firmware *fw;
50
51 if (request_firmware(&fw, fw_name, &pdev->dev)) {
52 printk(KERN_ALERT "Can't locate firmware %s\n", fw_name);
53 goto error;
54 }
55
56 *bfi_image = vmalloc(fw->size);
57 if (NULL == *bfi_image) {
58 printk(KERN_ALERT "Fail to allocate buffer for fw image "
59 "size=%x!\n", (u32) fw->size);
60 goto error;
61 }
62
63 memcpy(*bfi_image, fw->data, fw->size);
64 *bfi_image_size = fw->size/sizeof(u32);
65
66 return(*bfi_image);
67
68error:
69 return(NULL);
70}
71
72u32 *
73bfad_get_firmware_buf(struct pci_dev *pdev)
74{
75 if (pdev->device == BFA_PCI_DEVICE_ID_CT) {
76 if (bfi_image_ct_size == 0)
77 bfad_read_firmware(pdev, &bfi_image_ct,
78 &bfi_image_ct_size, BFAD_FW_FILE_CT);
79 return(bfi_image_ct);
80 } else {
81 if (bfi_image_cb_size == 0)
82 bfad_read_firmware(pdev, &bfi_image_cb,
83 &bfi_image_cb_size, BFAD_FW_FILE_CB);
84 return(bfi_image_cb);
85 }
86}
87
88u32 *
89bfi_image_ct_get_chunk(u32 off)
90{ return (u32 *)(bfi_image_ct + off); }
91
92u32 *
93bfi_image_cb_get_chunk(u32 off)
94{ return (u32 *)(bfi_image_cb + off); }
95
diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c
new file mode 100644
index 000000000000..158c99243c08
--- /dev/null
+++ b/drivers/scsi/bfa/bfad_im.c
@@ -0,0 +1,1230 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * bfad_im.c Linux driver IM module.
20 */
21
22#include "bfad_drv.h"
23#include "bfad_im.h"
24#include "bfad_trcmod.h"
25#include "bfa_cb_ioim_macros.h"
26#include <fcb/bfa_fcb_fcpim.h>
27
28BFA_TRC_FILE(LDRV, IM);
29
30DEFINE_IDR(bfad_im_port_index);
31struct scsi_transport_template *bfad_im_scsi_transport_template;
32static void bfad_im_itnim_work_handler(struct work_struct *work);
33static int bfad_im_queuecommand(struct scsi_cmnd *cmnd,
34 void (*done)(struct scsi_cmnd *));
35static int bfad_im_slave_alloc(struct scsi_device *sdev);
36
37void
38bfa_cb_ioim_done(void *drv, struct bfad_ioim_s *dio,
39 enum bfi_ioim_status io_status, u8 scsi_status,
40 int sns_len, u8 *sns_info, s32 residue)
41{
42 struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
43 struct bfad_s *bfad = drv;
44 struct bfad_itnim_data_s *itnim_data;
45 struct bfad_itnim_s *itnim;
46
47 switch (io_status) {
48 case BFI_IOIM_STS_OK:
49 bfa_trc(bfad, scsi_status);
50 cmnd->result = ScsiResult(DID_OK, scsi_status);
51 scsi_set_resid(cmnd, 0);
52
53 if (sns_len > 0) {
54 bfa_trc(bfad, sns_len);
55 if (sns_len > SCSI_SENSE_BUFFERSIZE)
56 sns_len = SCSI_SENSE_BUFFERSIZE;
57 memcpy(cmnd->sense_buffer, sns_info, sns_len);
58 }
59 if (residue > 0)
60 scsi_set_resid(cmnd, residue);
61 break;
62
63 case BFI_IOIM_STS_ABORTED:
64 case BFI_IOIM_STS_TIMEDOUT:
65 case BFI_IOIM_STS_PATHTOV:
66 default:
67 cmnd->result = ScsiResult(DID_ERROR, 0);
68 }
69
70 /* Unmap DMA, if host is NULL, it means a scsi passthru cmd */
71 if (cmnd->device->host != NULL)
72 scsi_dma_unmap(cmnd);
73
74 cmnd->host_scribble = NULL;
75 bfa_trc(bfad, cmnd->result);
76
77 itnim_data = cmnd->device->hostdata;
78 if (itnim_data) {
79 itnim = itnim_data->itnim;
80 if (!cmnd->result && itnim &&
81 (bfa_lun_queue_depth > cmnd->device->queue_depth)) {
82 /* Queue depth adjustment for good status completion */
83 bfad_os_ramp_up_qdepth(itnim, cmnd->device);
84 } else if (cmnd->result == SAM_STAT_TASK_SET_FULL && itnim) {
85 /* qfull handling */
86 bfad_os_handle_qfull(itnim, cmnd->device);
87 }
88 }
89
90 cmnd->scsi_done(cmnd);
91}
92
93void
94bfa_cb_ioim_good_comp(void *drv, struct bfad_ioim_s *dio)
95{
96 struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
97 struct bfad_itnim_data_s *itnim_data;
98 struct bfad_itnim_s *itnim;
99
100 cmnd->result = ScsiResult(DID_OK, SCSI_STATUS_GOOD);
101
102 /* Unmap DMA, if host is NULL, it means a scsi passthru cmd */
103 if (cmnd->device->host != NULL)
104 scsi_dma_unmap(cmnd);
105
106 cmnd->host_scribble = NULL;
107
108 /* Queue depth adjustment */
109 if (bfa_lun_queue_depth > cmnd->device->queue_depth) {
110 itnim_data = cmnd->device->hostdata;
111 if (itnim_data) {
112 itnim = itnim_data->itnim;
113 if (itnim)
114 bfad_os_ramp_up_qdepth(itnim, cmnd->device);
115 }
116 }
117
118 cmnd->scsi_done(cmnd);
119}
120
121void
122bfa_cb_ioim_abort(void *drv, struct bfad_ioim_s *dio)
123{
124 struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dio;
125 struct bfad_s *bfad = drv;
126
127 cmnd->result = ScsiResult(DID_ERROR, 0);
128
129 /* Unmap DMA, if host is NULL, it means a scsi passthru cmd */
130 if (cmnd->device->host != NULL)
131 scsi_dma_unmap(cmnd);
132
133 bfa_trc(bfad, cmnd->result);
134 cmnd->host_scribble = NULL;
135}
136
137void
138bfa_cb_tskim_done(void *bfad, struct bfad_tskim_s *dtsk,
139 enum bfi_tskim_status tsk_status)
140{
141 struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dtsk;
142 wait_queue_head_t *wq;
143
144 cmnd->SCp.Status |= tsk_status << 1;
145 set_bit(IO_DONE_BIT, (unsigned long *)&cmnd->SCp.Status);
146 wq = (wait_queue_head_t *) cmnd->SCp.ptr;
147 cmnd->SCp.ptr = NULL;
148
149 if (wq)
150 wake_up(wq);
151}
152
153void
154bfa_cb_ioim_resfree(void *drv)
155{
156}
157
158/**
159 * Scsi_Host_template SCSI host template
160 */
161/**
162 * Scsi_Host template entry, returns BFAD PCI info.
163 */
164static const char *
165bfad_im_info(struct Scsi_Host *shost)
166{
167 static char bfa_buf[256];
168 struct bfad_im_port_s *im_port =
169 (struct bfad_im_port_s *) shost->hostdata[0];
170 struct bfa_ioc_attr_s ioc_attr;
171 struct bfad_s *bfad = im_port->bfad;
172
173 memset(&ioc_attr, 0, sizeof(ioc_attr));
174 bfa_get_attr(&bfad->bfa, &ioc_attr);
175
176 memset(bfa_buf, 0, sizeof(bfa_buf));
177 snprintf(bfa_buf, sizeof(bfa_buf),
178 "Brocade FC/FCOE Adapter, " "model: %s hwpath: %s driver: %s",
179 ioc_attr.adapter_attr.model, bfad->pci_name,
180 BFAD_DRIVER_VERSION);
181 return bfa_buf;
182}
183
184/**
185 * Scsi_Host template entry, aborts the specified SCSI command.
186 *
187 * Returns: SUCCESS or FAILED.
188 */
189static int
190bfad_im_abort_handler(struct scsi_cmnd *cmnd)
191{
192 struct Scsi_Host *shost = cmnd->device->host;
193 struct bfad_im_port_s *im_port =
194 (struct bfad_im_port_s *) shost->hostdata[0];
195 struct bfad_s *bfad = im_port->bfad;
196 struct bfa_ioim_s *hal_io;
197 unsigned long flags;
198 u32 timeout;
199 int rc = FAILED;
200
201 spin_lock_irqsave(&bfad->bfad_lock, flags);
202 hal_io = (struct bfa_ioim_s *) cmnd->host_scribble;
203 if (!hal_io) {
204 /* IO has been completed, retrun success */
205 rc = SUCCESS;
206 goto out;
207 }
208 if (hal_io->dio != (struct bfad_ioim_s *) cmnd) {
209 rc = FAILED;
210 goto out;
211 }
212
213 bfa_trc(bfad, hal_io->iotag);
214 bfa_log(bfad->logmod, BFA_LOG_LINUX_SCSI_ABORT,
215 im_port->shost->host_no, cmnd, hal_io->iotag);
216 bfa_ioim_abort(hal_io);
217 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
218
219 /* Need to wait until the command get aborted */
220 timeout = 10;
221 while ((struct bfa_ioim_s *) cmnd->host_scribble == hal_io) {
222 set_current_state(TASK_UNINTERRUPTIBLE);
223 schedule_timeout(timeout);
224 if (timeout < 4 * HZ)
225 timeout *= 2;
226 }
227
228 cmnd->scsi_done(cmnd);
229 bfa_trc(bfad, hal_io->iotag);
230 bfa_log(bfad->logmod, BFA_LOG_LINUX_SCSI_ABORT_COMP,
231 im_port->shost->host_no, cmnd, hal_io->iotag);
232 return SUCCESS;
233out:
234 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
235 return rc;
236}
237
238static bfa_status_t
239bfad_im_target_reset_send(struct bfad_s *bfad, struct scsi_cmnd *cmnd,
240 struct bfad_itnim_s *itnim)
241{
242 struct bfa_tskim_s *tskim;
243 struct bfa_itnim_s *bfa_itnim;
244 bfa_status_t rc = BFA_STATUS_OK;
245
246 bfa_itnim = bfa_fcs_itnim_get_halitn(&itnim->fcs_itnim);
247 tskim = bfa_tskim_alloc(&bfad->bfa, (struct bfad_tskim_s *) cmnd);
248 if (!tskim) {
249 BFA_DEV_PRINTF(bfad, BFA_ERR,
250 "target reset, fail to allocate tskim\n");
251 rc = BFA_STATUS_FAILED;
252 goto out;
253 }
254
255 /*
256 * Set host_scribble to NULL to avoid aborting a task command if
257 * happens.
258 */
259 cmnd->host_scribble = NULL;
260 cmnd->SCp.Status = 0;
261 bfa_itnim = bfa_fcs_itnim_get_halitn(&itnim->fcs_itnim);
262 bfa_tskim_start(tskim, bfa_itnim, (lun_t)0,
263 FCP_TM_TARGET_RESET, BFAD_TARGET_RESET_TMO);
264out:
265 return rc;
266}
267
268/**
269 * Scsi_Host template entry, resets a LUN and abort its all commands.
270 *
271 * Returns: SUCCESS or FAILED.
272 *
273 */
274static int
275bfad_im_reset_lun_handler(struct scsi_cmnd *cmnd)
276{
277 struct Scsi_Host *shost = cmnd->device->host;
278 struct bfad_im_port_s *im_port =
279 (struct bfad_im_port_s *) shost->hostdata[0];
280 struct bfad_itnim_data_s *itnim_data = cmnd->device->hostdata;
281 struct bfad_s *bfad = im_port->bfad;
282 struct bfa_tskim_s *tskim;
283 struct bfad_itnim_s *itnim;
284 struct bfa_itnim_s *bfa_itnim;
285 DECLARE_WAIT_QUEUE_HEAD(wq);
286 int rc = SUCCESS;
287 unsigned long flags;
288 enum bfi_tskim_status task_status;
289
290 spin_lock_irqsave(&bfad->bfad_lock, flags);
291 itnim = itnim_data->itnim;
292 if (!itnim) {
293 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
294 rc = FAILED;
295 goto out;
296 }
297
298 tskim = bfa_tskim_alloc(&bfad->bfa, (struct bfad_tskim_s *) cmnd);
299 if (!tskim) {
300 BFA_DEV_PRINTF(bfad, BFA_ERR,
301 "LUN reset, fail to allocate tskim");
302 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
303 rc = FAILED;
304 goto out;
305 }
306
307 /**
308 * Set host_scribble to NULL to avoid aborting a task command
309 * if happens.
310 */
311 cmnd->host_scribble = NULL;
312 cmnd->SCp.ptr = (char *)&wq;
313 cmnd->SCp.Status = 0;
314 bfa_itnim = bfa_fcs_itnim_get_halitn(&itnim->fcs_itnim);
315 bfa_tskim_start(tskim, bfa_itnim,
316 bfad_int_to_lun(cmnd->device->lun),
317 FCP_TM_LUN_RESET, BFAD_LUN_RESET_TMO);
318 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
319
320 wait_event(wq, test_bit(IO_DONE_BIT,
321 (unsigned long *)&cmnd->SCp.Status));
322
323 task_status = cmnd->SCp.Status >> 1;
324 if (task_status != BFI_TSKIM_STS_OK) {
325 BFA_DEV_PRINTF(bfad, BFA_ERR, "LUN reset failure, status: %d\n",
326 task_status);
327 rc = FAILED;
328 }
329
330out:
331 return rc;
332}
333
334/**
335 * Scsi_Host template entry, resets the bus and abort all commands.
336 */
337static int
338bfad_im_reset_bus_handler(struct scsi_cmnd *cmnd)
339{
340 struct Scsi_Host *shost = cmnd->device->host;
341 struct bfad_im_port_s *im_port =
342 (struct bfad_im_port_s *) shost->hostdata[0];
343 struct bfad_s *bfad = im_port->bfad;
344 struct bfad_itnim_s *itnim;
345 unsigned long flags;
346 u32 i, rc, err_cnt = 0;
347 DECLARE_WAIT_QUEUE_HEAD(wq);
348 enum bfi_tskim_status task_status;
349
350 spin_lock_irqsave(&bfad->bfad_lock, flags);
351 for (i = 0; i < MAX_FCP_TARGET; i++) {
352 itnim = bfad_os_get_itnim(im_port, i);
353 if (itnim) {
354 cmnd->SCp.ptr = (char *)&wq;
355 rc = bfad_im_target_reset_send(bfad, cmnd, itnim);
356 if (rc != BFA_STATUS_OK) {
357 err_cnt++;
358 continue;
359 }
360
361 /* wait target reset to complete */
362 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
363 wait_event(wq, test_bit(IO_DONE_BIT,
364 (unsigned long *)&cmnd->SCp.Status));
365 spin_lock_irqsave(&bfad->bfad_lock, flags);
366
367 task_status = cmnd->SCp.Status >> 1;
368 if (task_status != BFI_TSKIM_STS_OK) {
369 BFA_DEV_PRINTF(bfad, BFA_ERR,
370 "target reset failure,"
371 " status: %d\n", task_status);
372 err_cnt++;
373 }
374 }
375 }
376 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
377
378 if (err_cnt)
379 return FAILED;
380
381 return SUCCESS;
382}
383
384/**
385 * Scsi_Host template entry slave_destroy.
386 */
387static void
388bfad_im_slave_destroy(struct scsi_device *sdev)
389{
390 sdev->hostdata = NULL;
391 return;
392}
393
394/**
395 * BFA FCS itnim callbacks
396 */
397
398/**
399 * BFA FCS itnim alloc callback, after successful PRLI
400 * Context: Interrupt
401 */
402void
403bfa_fcb_itnim_alloc(struct bfad_s *bfad, struct bfa_fcs_itnim_s **itnim,
404 struct bfad_itnim_s **itnim_drv)
405{
406 *itnim_drv = kzalloc(sizeof(struct bfad_itnim_s), GFP_ATOMIC);
407 if (*itnim_drv == NULL)
408 return;
409
410 (*itnim_drv)->im = bfad->im;
411 *itnim = &(*itnim_drv)->fcs_itnim;
412 (*itnim_drv)->state = ITNIM_STATE_NONE;
413
414 /*
415 * Initiaze the itnim_work
416 */
417 INIT_WORK(&(*itnim_drv)->itnim_work, bfad_im_itnim_work_handler);
418 bfad->bfad_flags |= BFAD_RPORT_ONLINE;
419}
420
421/**
422 * BFA FCS itnim free callback.
423 * Context: Interrupt. bfad_lock is held
424 */
425void
426bfa_fcb_itnim_free(struct bfad_s *bfad, struct bfad_itnim_s *itnim_drv)
427{
428 struct bfad_port_s *port;
429 wwn_t wwpn;
430 u32 fcid;
431 char wwpn_str[32], fcid_str[16];
432
433 /* online to free state transtion should not happen */
434 bfa_assert(itnim_drv->state != ITNIM_STATE_ONLINE);
435
436 itnim_drv->queue_work = 1;
437 /* offline request is not yet done, use the same request to free */
438 if (itnim_drv->state == ITNIM_STATE_OFFLINE_PENDING)
439 itnim_drv->queue_work = 0;
440
441 itnim_drv->state = ITNIM_STATE_FREE;
442 port = bfa_fcs_itnim_get_drvport(&itnim_drv->fcs_itnim);
443 itnim_drv->im_port = port->im_port;
444 wwpn = bfa_fcs_itnim_get_pwwn(&itnim_drv->fcs_itnim);
445 fcid = bfa_fcs_itnim_get_fcid(&itnim_drv->fcs_itnim);
446 wwn2str(wwpn_str, wwpn);
447 fcid2str(fcid_str, fcid);
448 bfa_log(bfad->logmod, BFA_LOG_LINUX_ITNIM_FREE,
449 port->im_port->shost->host_no,
450 fcid_str, wwpn_str);
451 bfad_os_itnim_process(itnim_drv);
452}
453
454/**
455 * BFA FCS itnim online callback.
456 * Context: Interrupt. bfad_lock is held
457 */
458void
459bfa_fcb_itnim_online(struct bfad_itnim_s *itnim_drv)
460{
461 struct bfad_port_s *port;
462
463 itnim_drv->bfa_itnim = bfa_fcs_itnim_get_halitn(&itnim_drv->fcs_itnim);
464 port = bfa_fcs_itnim_get_drvport(&itnim_drv->fcs_itnim);
465 itnim_drv->state = ITNIM_STATE_ONLINE;
466 itnim_drv->queue_work = 1;
467 itnim_drv->im_port = port->im_port;
468 bfad_os_itnim_process(itnim_drv);
469}
470
471/**
472 * BFA FCS itnim offline callback.
473 * Context: Interrupt. bfad_lock is held
474 */
475void
476bfa_fcb_itnim_offline(struct bfad_itnim_s *itnim_drv)
477{
478 struct bfad_port_s *port;
479 struct bfad_s *bfad;
480
481 port = bfa_fcs_itnim_get_drvport(&itnim_drv->fcs_itnim);
482 bfad = port->bfad;
483 if ((bfad->pport.flags & BFAD_PORT_DELETE) ||
484 (port->flags & BFAD_PORT_DELETE)) {
485 itnim_drv->state = ITNIM_STATE_OFFLINE;
486 return;
487 }
488 itnim_drv->im_port = port->im_port;
489 itnim_drv->state = ITNIM_STATE_OFFLINE_PENDING;
490 itnim_drv->queue_work = 1;
491 bfad_os_itnim_process(itnim_drv);
492}
493
494/**
495 * BFA FCS itnim timeout callback.
496 * Context: Interrupt. bfad_lock is held
497 */
498void bfa_fcb_itnim_tov(struct bfad_itnim_s *itnim)
499{
500 itnim->state = ITNIM_STATE_TIMEOUT;
501}
502
503/**
504 * Path TOV processing begin notification -- dummy for linux
505 */
506void
507bfa_fcb_itnim_tov_begin(struct bfad_itnim_s *itnim)
508{
509}
510
511
512
513/**
514 * Allocate a Scsi_Host for a port.
515 */
516int
517bfad_im_scsi_host_alloc(struct bfad_s *bfad, struct bfad_im_port_s *im_port)
518{
519 int error = 1;
520
521 if (!idr_pre_get(&bfad_im_port_index, GFP_KERNEL)) {
522 printk(KERN_WARNING "idr_pre_get failure\n");
523 goto out;
524 }
525
526 error = idr_get_new(&bfad_im_port_index, im_port,
527 &im_port->idr_id);
528 if (error) {
529 printk(KERN_WARNING "idr_get_new failure\n");
530 goto out;
531 }
532
533 im_port->shost = bfad_os_scsi_host_alloc(im_port, bfad);
534 if (!im_port->shost) {
535 error = 1;
536 goto out_free_idr;
537 }
538
539 im_port->shost->hostdata[0] = (unsigned long)im_port;
540 im_port->shost->unique_id = im_port->idr_id;
541 im_port->shost->this_id = -1;
542 im_port->shost->max_id = MAX_FCP_TARGET;
543 im_port->shost->max_lun = MAX_FCP_LUN;
544 im_port->shost->max_cmd_len = 16;
545 im_port->shost->can_queue = bfad->cfg_data.ioc_queue_depth;
546 im_port->shost->transportt = bfad_im_scsi_transport_template;
547
548 error = bfad_os_scsi_add_host(im_port->shost, im_port, bfad);
549 if (error) {
550 printk(KERN_WARNING "bfad_os_scsi_add_host failure %d\n",
551 error);
552 goto out_fc_rel;
553 }
554
555 /* setup host fixed attribute if the lk supports */
556 bfad_os_fc_host_init(im_port);
557
558 return 0;
559
560out_fc_rel:
561 scsi_host_put(im_port->shost);
562out_free_idr:
563 idr_remove(&bfad_im_port_index, im_port->idr_id);
564out:
565 return error;
566}
567
568void
569bfad_im_scsi_host_free(struct bfad_s *bfad, struct bfad_im_port_s *im_port)
570{
571 unsigned long flags;
572
573 bfa_trc(bfad, bfad->inst_no);
574 bfa_log(bfad->logmod, BFA_LOG_LINUX_SCSI_HOST_FREE,
575 im_port->shost->host_no);
576
577 fc_remove_host(im_port->shost);
578
579 scsi_remove_host(im_port->shost);
580 scsi_host_put(im_port->shost);
581
582 spin_lock_irqsave(&bfad->bfad_lock, flags);
583 idr_remove(&bfad_im_port_index, im_port->idr_id);
584 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
585}
586
587static void
588bfad_im_port_delete_handler(struct work_struct *work)
589{
590 struct bfad_im_port_s *im_port =
591 container_of(work, struct bfad_im_port_s, port_delete_work);
592
593 bfad_im_scsi_host_free(im_port->bfad, im_port);
594 bfad_im_port_clean(im_port);
595 kfree(im_port);
596}
597
598bfa_status_t
599bfad_im_port_new(struct bfad_s *bfad, struct bfad_port_s *port)
600{
601 int rc = BFA_STATUS_OK;
602 struct bfad_im_port_s *im_port;
603
604 im_port = kzalloc(sizeof(struct bfad_im_port_s), GFP_ATOMIC);
605 if (im_port == NULL) {
606 rc = BFA_STATUS_ENOMEM;
607 goto ext;
608 }
609 port->im_port = im_port;
610 im_port->port = port;
611 im_port->bfad = bfad;
612
613 INIT_WORK(&im_port->port_delete_work, bfad_im_port_delete_handler);
614 INIT_LIST_HEAD(&im_port->itnim_mapped_list);
615 INIT_LIST_HEAD(&im_port->binding_list);
616
617ext:
618 return rc;
619}
620
621void
622bfad_im_port_delete(struct bfad_s *bfad, struct bfad_port_s *port)
623{
624 struct bfad_im_port_s *im_port = port->im_port;
625
626 queue_work(bfad->im->drv_workq,
627 &im_port->port_delete_work);
628}
629
630void
631bfad_im_port_clean(struct bfad_im_port_s *im_port)
632{
633 struct bfad_fcp_binding *bp, *bp_new;
634 unsigned long flags;
635 struct bfad_s *bfad = im_port->bfad;
636
637 spin_lock_irqsave(&bfad->bfad_lock, flags);
638 list_for_each_entry_safe(bp, bp_new, &im_port->binding_list,
639 list_entry) {
640 list_del(&bp->list_entry);
641 kfree(bp);
642 }
643
644 /* the itnim_mapped_list must be empty at this time */
645 bfa_assert(list_empty(&im_port->itnim_mapped_list));
646
647 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
648}
649
650void
651bfad_im_port_online(struct bfad_s *bfad, struct bfad_port_s *port)
652{
653}
654
655void
656bfad_im_port_offline(struct bfad_s *bfad, struct bfad_port_s *port)
657{
658}
659
660bfa_status_t
661bfad_im_probe(struct bfad_s *bfad)
662{
663 struct bfad_im_s *im;
664 bfa_status_t rc = BFA_STATUS_OK;
665
666 im = kzalloc(sizeof(struct bfad_im_s), GFP_KERNEL);
667 if (im == NULL) {
668 rc = BFA_STATUS_ENOMEM;
669 goto ext;
670 }
671
672 bfad->im = im;
673 im->bfad = bfad;
674
675 if (bfad_os_thread_workq(bfad) != BFA_STATUS_OK) {
676 kfree(im);
677 rc = BFA_STATUS_FAILED;
678 }
679
680ext:
681 return rc;
682}
683
684void
685bfad_im_probe_undo(struct bfad_s *bfad)
686{
687 if (bfad->im) {
688 bfad_os_destroy_workq(bfad->im);
689 kfree(bfad->im);
690 bfad->im = NULL;
691 }
692}
693
694
695
696
697int
698bfad_os_scsi_add_host(struct Scsi_Host *shost, struct bfad_im_port_s *im_port,
699 struct bfad_s *bfad)
700{
701 struct device *dev;
702
703 if (im_port->port->pvb_type == BFAD_PORT_PHYS_BASE)
704 dev = &bfad->pcidev->dev;
705 else
706 dev = &bfad->pport.im_port->shost->shost_gendev;
707
708 return scsi_add_host(shost, dev);
709}
710
711struct Scsi_Host *
712bfad_os_scsi_host_alloc(struct bfad_im_port_s *im_port, struct bfad_s *bfad)
713{
714 struct scsi_host_template *sht;
715
716 if (im_port->port->pvb_type == BFAD_PORT_PHYS_BASE)
717 sht = &bfad_im_scsi_host_template;
718 else
719 sht = &bfad_im_vport_template;
720
721 sht->sg_tablesize = bfad->cfg_data.io_max_sge;
722
723 return scsi_host_alloc(sht, sizeof(unsigned long));
724}
725
726void
727bfad_os_scsi_host_free(struct bfad_s *bfad, struct bfad_im_port_s *im_port)
728{
729 flush_workqueue(bfad->im->drv_workq);
730 bfad_im_scsi_host_free(im_port->bfad, im_port);
731 bfad_im_port_clean(im_port);
732 kfree(im_port);
733}
734
735void
736bfad_os_destroy_workq(struct bfad_im_s *im)
737{
738 if (im && im->drv_workq) {
739 destroy_workqueue(im->drv_workq);
740 im->drv_workq = NULL;
741 }
742}
743
744bfa_status_t
745bfad_os_thread_workq(struct bfad_s *bfad)
746{
747 struct bfad_im_s *im = bfad->im;
748
749 bfa_trc(bfad, 0);
750 snprintf(im->drv_workq_name, BFAD_KOBJ_NAME_LEN, "bfad_wq_%d",
751 bfad->inst_no);
752 im->drv_workq = create_singlethread_workqueue(im->drv_workq_name);
753 if (!im->drv_workq)
754 return BFA_STATUS_FAILED;
755
756 return BFA_STATUS_OK;
757}
758
759/**
760 * Scsi_Host template entry.
761 *
762 * Description:
763 * OS entry point to adjust the queue_depths on a per-device basis.
764 * Called once per device during the bus scan.
765 * Return non-zero if fails.
766 */
767static int
768bfad_im_slave_configure(struct scsi_device *sdev)
769{
770 if (sdev->tagged_supported)
771 scsi_activate_tcq(sdev, bfa_lun_queue_depth);
772 else
773 scsi_deactivate_tcq(sdev, bfa_lun_queue_depth);
774
775 return 0;
776}
777
778struct scsi_host_template bfad_im_scsi_host_template = {
779 .module = THIS_MODULE,
780 .name = BFAD_DRIVER_NAME,
781 .info = bfad_im_info,
782 .queuecommand = bfad_im_queuecommand,
783 .eh_abort_handler = bfad_im_abort_handler,
784 .eh_device_reset_handler = bfad_im_reset_lun_handler,
785 .eh_bus_reset_handler = bfad_im_reset_bus_handler,
786
787 .slave_alloc = bfad_im_slave_alloc,
788 .slave_configure = bfad_im_slave_configure,
789 .slave_destroy = bfad_im_slave_destroy,
790
791 .this_id = -1,
792 .sg_tablesize = BFAD_IO_MAX_SGE,
793 .cmd_per_lun = 3,
794 .use_clustering = ENABLE_CLUSTERING,
795 .shost_attrs = bfad_im_host_attrs,
796 .max_sectors = 0xFFFF,
797};
798
799struct scsi_host_template bfad_im_vport_template = {
800 .module = THIS_MODULE,
801 .name = BFAD_DRIVER_NAME,
802 .info = bfad_im_info,
803 .queuecommand = bfad_im_queuecommand,
804 .eh_abort_handler = bfad_im_abort_handler,
805 .eh_device_reset_handler = bfad_im_reset_lun_handler,
806 .eh_bus_reset_handler = bfad_im_reset_bus_handler,
807
808 .slave_alloc = bfad_im_slave_alloc,
809 .slave_configure = bfad_im_slave_configure,
810 .slave_destroy = bfad_im_slave_destroy,
811
812 .this_id = -1,
813 .sg_tablesize = BFAD_IO_MAX_SGE,
814 .cmd_per_lun = 3,
815 .use_clustering = ENABLE_CLUSTERING,
816 .shost_attrs = bfad_im_vport_attrs,
817 .max_sectors = 0xFFFF,
818};
819
820void
821bfad_im_probe_post(struct bfad_im_s *im)
822{
823 flush_workqueue(im->drv_workq);
824}
825
826bfa_status_t
827bfad_im_module_init(void)
828{
829 bfad_im_scsi_transport_template =
830 fc_attach_transport(&bfad_im_fc_function_template);
831 if (!bfad_im_scsi_transport_template)
832 return BFA_STATUS_ENOMEM;
833
834 return BFA_STATUS_OK;
835}
836
837void
838bfad_im_module_exit(void)
839{
840 if (bfad_im_scsi_transport_template)
841 fc_release_transport(bfad_im_scsi_transport_template);
842}
843
844void
845bfad_os_itnim_process(struct bfad_itnim_s *itnim_drv)
846{
847 struct bfad_im_s *im = itnim_drv->im;
848
849 if (itnim_drv->queue_work)
850 queue_work(im->drv_workq, &itnim_drv->itnim_work);
851}
852
853void
854bfad_os_ramp_up_qdepth(struct bfad_itnim_s *itnim, struct scsi_device *sdev)
855{
856 struct scsi_device *tmp_sdev;
857
858 if (((jiffies - itnim->last_ramp_up_time) >
859 BFA_QUEUE_FULL_RAMP_UP_TIME * HZ) &&
860 ((jiffies - itnim->last_queue_full_time) >
861 BFA_QUEUE_FULL_RAMP_UP_TIME * HZ)) {
862 shost_for_each_device(tmp_sdev, sdev->host) {
863 if (bfa_lun_queue_depth > tmp_sdev->queue_depth) {
864 if (tmp_sdev->id != sdev->id)
865 continue;
866 if (tmp_sdev->ordered_tags)
867 scsi_adjust_queue_depth(tmp_sdev,
868 MSG_ORDERED_TAG,
869 tmp_sdev->queue_depth + 1);
870 else
871 scsi_adjust_queue_depth(tmp_sdev,
872 MSG_SIMPLE_TAG,
873 tmp_sdev->queue_depth + 1);
874
875 itnim->last_ramp_up_time = jiffies;
876 }
877 }
878 }
879}
880
881void
882bfad_os_handle_qfull(struct bfad_itnim_s *itnim, struct scsi_device *sdev)
883{
884 struct scsi_device *tmp_sdev;
885
886 itnim->last_queue_full_time = jiffies;
887
888 shost_for_each_device(tmp_sdev, sdev->host) {
889 if (tmp_sdev->id != sdev->id)
890 continue;
891 scsi_track_queue_full(tmp_sdev, tmp_sdev->queue_depth - 1);
892 }
893}
894
895
896
897
898struct bfad_itnim_s *
899bfad_os_get_itnim(struct bfad_im_port_s *im_port, int id)
900{
901 struct bfad_itnim_s *itnim = NULL;
902
903 /* Search the mapped list for this target ID */
904 list_for_each_entry(itnim, &im_port->itnim_mapped_list, list_entry) {
905 if (id == itnim->scsi_tgt_id)
906 return itnim;
907 }
908
909 return NULL;
910}
911
912/**
913 * Scsi_Host template entry slave_alloc
914 */
915static int
916bfad_im_slave_alloc(struct scsi_device *sdev)
917{
918 struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
919
920 if (!rport || fc_remote_port_chkready(rport))
921 return -ENXIO;
922
923 sdev->hostdata = rport->dd_data;
924
925 return 0;
926}
927
928void
929bfad_os_fc_host_init(struct bfad_im_port_s *im_port)
930{
931 struct Scsi_Host *host = im_port->shost;
932 struct bfad_s *bfad = im_port->bfad;
933 struct bfad_port_s *port = im_port->port;
934 union attr {
935 struct bfa_pport_attr_s pattr;
936 struct bfa_ioc_attr_s ioc_attr;
937 } attr;
938
939 fc_host_node_name(host) =
940 bfa_os_htonll((bfa_fcs_port_get_nwwn(port->fcs_port)));
941 fc_host_port_name(host) =
942 bfa_os_htonll((bfa_fcs_port_get_pwwn(port->fcs_port)));
943
944 fc_host_supported_classes(host) = FC_COS_CLASS3;
945
946 memset(fc_host_supported_fc4s(host), 0,
947 sizeof(fc_host_supported_fc4s(host)));
948 if (bfad_supported_fc4s & (BFA_PORT_ROLE_FCP_IM | BFA_PORT_ROLE_FCP_TM))
949 /* For FCP type 0x08 */
950 fc_host_supported_fc4s(host)[2] = 1;
951 if (bfad_supported_fc4s | BFA_PORT_ROLE_FCP_IPFC)
952 /* For LLC/SNAP type 0x05 */
953 fc_host_supported_fc4s(host)[3] = 0x20;
954 /* For fibre channel services type 0x20 */
955 fc_host_supported_fc4s(host)[7] = 1;
956
957 memset(&attr.ioc_attr, 0, sizeof(attr.ioc_attr));
958 bfa_get_attr(&bfad->bfa, &attr.ioc_attr);
959 sprintf(fc_host_symbolic_name(host), "Brocade %s FV%s DV%s",
960 attr.ioc_attr.adapter_attr.model,
961 attr.ioc_attr.adapter_attr.fw_ver, BFAD_DRIVER_VERSION);
962
963 fc_host_supported_speeds(host) = 0;
964 fc_host_supported_speeds(host) |=
965 FC_PORTSPEED_8GBIT | FC_PORTSPEED_4GBIT | FC_PORTSPEED_2GBIT |
966 FC_PORTSPEED_1GBIT;
967
968 memset(&attr.pattr, 0, sizeof(attr.pattr));
969 bfa_pport_get_attr(&bfad->bfa, &attr.pattr);
970 fc_host_maxframe_size(host) = attr.pattr.pport_cfg.maxfrsize;
971}
972
973static void
974bfad_im_fc_rport_add(struct bfad_im_port_s *im_port, struct bfad_itnim_s *itnim)
975{
976 struct fc_rport_identifiers rport_ids;
977 struct fc_rport *fc_rport;
978 struct bfad_itnim_data_s *itnim_data;
979
980 rport_ids.node_name =
981 bfa_os_htonll(bfa_fcs_itnim_get_nwwn(&itnim->fcs_itnim));
982 rport_ids.port_name =
983 bfa_os_htonll(bfa_fcs_itnim_get_pwwn(&itnim->fcs_itnim));
984 rport_ids.port_id =
985 bfa_os_hton3b(bfa_fcs_itnim_get_fcid(&itnim->fcs_itnim));
986 rport_ids.roles = FC_RPORT_ROLE_UNKNOWN;
987
988 itnim->fc_rport = fc_rport =
989 fc_remote_port_add(im_port->shost, 0, &rport_ids);
990
991 if (!fc_rport)
992 return;
993
994 fc_rport->maxframe_size =
995 bfa_fcs_itnim_get_maxfrsize(&itnim->fcs_itnim);
996 fc_rport->supported_classes = bfa_fcs_itnim_get_cos(&itnim->fcs_itnim);
997
998 itnim_data = fc_rport->dd_data;
999 itnim_data->itnim = itnim;
1000
1001 rport_ids.roles |= FC_RPORT_ROLE_FCP_TARGET;
1002
1003 if (rport_ids.roles != FC_RPORT_ROLE_UNKNOWN)
1004 fc_remote_port_rolechg(fc_rport, rport_ids.roles);
1005
1006 if ((fc_rport->scsi_target_id != -1)
1007 && (fc_rport->scsi_target_id < MAX_FCP_TARGET))
1008 itnim->scsi_tgt_id = fc_rport->scsi_target_id;
1009
1010 return;
1011}
1012
1013/**
1014 * Work queue handler using FC transport service
1015* Context: kernel
1016 */
1017static void
1018bfad_im_itnim_work_handler(struct work_struct *work)
1019{
1020 struct bfad_itnim_s *itnim = container_of(work, struct bfad_itnim_s,
1021 itnim_work);
1022 struct bfad_im_s *im = itnim->im;
1023 struct bfad_s *bfad = im->bfad;
1024 struct bfad_im_port_s *im_port;
1025 unsigned long flags;
1026 struct fc_rport *fc_rport;
1027 wwn_t wwpn;
1028 u32 fcid;
1029 char wwpn_str[32], fcid_str[16];
1030
1031 spin_lock_irqsave(&bfad->bfad_lock, flags);
1032 im_port = itnim->im_port;
1033 bfa_trc(bfad, itnim->state);
1034 switch (itnim->state) {
1035 case ITNIM_STATE_ONLINE:
1036 if (!itnim->fc_rport) {
1037 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1038 bfad_im_fc_rport_add(im_port, itnim);
1039 spin_lock_irqsave(&bfad->bfad_lock, flags);
1040 wwpn = bfa_fcs_itnim_get_pwwn(&itnim->fcs_itnim);
1041 fcid = bfa_fcs_itnim_get_fcid(&itnim->fcs_itnim);
1042 wwn2str(wwpn_str, wwpn);
1043 fcid2str(fcid_str, fcid);
1044 list_add_tail(&itnim->list_entry,
1045 &im_port->itnim_mapped_list);
1046 bfa_log(bfad->logmod, BFA_LOG_LINUX_ITNIM_ONLINE,
1047 im_port->shost->host_no,
1048 itnim->scsi_tgt_id,
1049 fcid_str, wwpn_str);
1050 } else {
1051 printk(KERN_WARNING
1052 "%s: itnim %llx is already in online state\n",
1053 __FUNCTION__,
1054 bfa_fcs_itnim_get_pwwn(&itnim->fcs_itnim));
1055 }
1056
1057 break;
1058 case ITNIM_STATE_OFFLINE_PENDING:
1059 itnim->state = ITNIM_STATE_OFFLINE;
1060 if (itnim->fc_rport) {
1061 fc_rport = itnim->fc_rport;
1062 ((struct bfad_itnim_data_s *)
1063 fc_rport->dd_data)->itnim = NULL;
1064 itnim->fc_rport = NULL;
1065 if (!(im_port->port->flags & BFAD_PORT_DELETE)) {
1066 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1067 fc_rport->dev_loss_tmo =
1068 bfa_fcpim_path_tov_get(&bfad->bfa) + 1;
1069 fc_remote_port_delete(fc_rport);
1070 spin_lock_irqsave(&bfad->bfad_lock, flags);
1071 }
1072 wwpn = bfa_fcs_itnim_get_pwwn(&itnim->fcs_itnim);
1073 fcid = bfa_fcs_itnim_get_fcid(&itnim->fcs_itnim);
1074 wwn2str(wwpn_str, wwpn);
1075 fcid2str(fcid_str, fcid);
1076 list_del(&itnim->list_entry);
1077 bfa_log(bfad->logmod, BFA_LOG_LINUX_ITNIM_OFFLINE,
1078 im_port->shost->host_no,
1079 itnim->scsi_tgt_id,
1080 fcid_str, wwpn_str);
1081 }
1082 break;
1083 case ITNIM_STATE_FREE:
1084 if (itnim->fc_rport) {
1085 fc_rport = itnim->fc_rport;
1086 ((struct bfad_itnim_data_s *)
1087 fc_rport->dd_data)->itnim = NULL;
1088 itnim->fc_rport = NULL;
1089 if (!(im_port->port->flags & BFAD_PORT_DELETE)) {
1090 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1091 fc_rport->dev_loss_tmo =
1092 bfa_fcpim_path_tov_get(&bfad->bfa) + 1;
1093 fc_remote_port_delete(fc_rport);
1094 spin_lock_irqsave(&bfad->bfad_lock, flags);
1095 }
1096 list_del(&itnim->list_entry);
1097 }
1098
1099 kfree(itnim);
1100 break;
1101 default:
1102 bfa_assert(0);
1103 break;
1104 }
1105
1106 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1107}
1108
1109/**
1110 * Scsi_Host template entry, queue a SCSI command to the BFAD.
1111 */
1112static int
1113bfad_im_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
1114{
1115 struct bfad_im_port_s *im_port =
1116 (struct bfad_im_port_s *) cmnd->device->host->hostdata[0];
1117 struct bfad_s *bfad = im_port->bfad;
1118 struct bfad_itnim_data_s *itnim_data = cmnd->device->hostdata;
1119 struct bfad_itnim_s *itnim;
1120 struct bfa_ioim_s *hal_io;
1121 unsigned long flags;
1122 int rc;
1123 s16 sg_cnt = 0;
1124 struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device));
1125
1126 rc = fc_remote_port_chkready(rport);
1127 if (rc) {
1128 cmnd->result = rc;
1129 done(cmnd);
1130 return 0;
1131 }
1132
1133 sg_cnt = scsi_dma_map(cmnd);
1134
1135 if (sg_cnt < 0)
1136 return SCSI_MLQUEUE_HOST_BUSY;
1137
1138 cmnd->scsi_done = done;
1139
1140 spin_lock_irqsave(&bfad->bfad_lock, flags);
1141 if (!(bfad->bfad_flags & BFAD_HAL_START_DONE)) {
1142 printk(KERN_WARNING
1143 "bfad%d, queuecommand %p %x failed, BFA stopped\n",
1144 bfad->inst_no, cmnd, cmnd->cmnd[0]);
1145 cmnd->result = ScsiResult(DID_NO_CONNECT, 0);
1146 goto out_fail_cmd;
1147 }
1148
1149 itnim = itnim_data->itnim;
1150 if (!itnim) {
1151 cmnd->result = ScsiResult(DID_IMM_RETRY, 0);
1152 goto out_fail_cmd;
1153 }
1154
1155 hal_io = bfa_ioim_alloc(&bfad->bfa, (struct bfad_ioim_s *) cmnd,
1156 itnim->bfa_itnim, sg_cnt);
1157 if (!hal_io) {
1158 printk(KERN_WARNING "hal_io failure\n");
1159 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1160 scsi_dma_unmap(cmnd);
1161 return SCSI_MLQUEUE_HOST_BUSY;
1162 }
1163
1164 cmnd->host_scribble = (char *)hal_io;
1165 bfa_trc_fp(bfad, hal_io->iotag);
1166 bfa_ioim_start(hal_io);
1167 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1168
1169 return 0;
1170
1171out_fail_cmd:
1172 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1173 scsi_dma_unmap(cmnd);
1174 if (done)
1175 done(cmnd);
1176
1177 return 0;
1178}
1179
1180void
1181bfad_os_rport_online_wait(struct bfad_s *bfad)
1182{
1183 int i;
1184 int rport_delay = 10;
1185
1186 for (i = 0; !(bfad->bfad_flags & BFAD_PORT_ONLINE)
1187 && i < bfa_linkup_delay; i++)
1188 schedule_timeout_uninterruptible(HZ);
1189
1190 if (bfad->bfad_flags & BFAD_PORT_ONLINE) {
1191 rport_delay = rport_delay < bfa_linkup_delay ?
1192 rport_delay : bfa_linkup_delay;
1193 for (i = 0; !(bfad->bfad_flags & BFAD_RPORT_ONLINE)
1194 && i < rport_delay; i++)
1195 schedule_timeout_uninterruptible(HZ);
1196
1197 if (rport_delay > 0 && (bfad->bfad_flags & BFAD_RPORT_ONLINE))
1198 schedule_timeout_uninterruptible(rport_delay * HZ);
1199 }
1200}
1201
1202int
1203bfad_os_get_linkup_delay(struct bfad_s *bfad)
1204{
1205
1206 u8 nwwns = 0;
1207 wwn_t *wwns;
1208 int ldelay;
1209
1210 /*
1211 * Querying for the boot target port wwns
1212 * -- read from boot information in flash.
1213 * If nwwns > 0 => boot over SAN and set bfa_linkup_delay = 30
1214 * else => local boot machine set bfa_linkup_delay = 10
1215 */
1216
1217 bfa_iocfc_get_bootwwns(&bfad->bfa, &nwwns, &wwns);
1218
1219 if (nwwns > 0) {
1220 /* If boot over SAN; linkup_delay = 30sec */
1221 ldelay = 30;
1222 } else {
1223 /* If local boot; linkup_delay = 10sec */
1224 ldelay = 0;
1225 }
1226
1227 return ldelay;
1228}
1229
1230
diff --git a/drivers/scsi/bfa/bfad_im.h b/drivers/scsi/bfa/bfad_im.h
new file mode 100644
index 000000000000..189a5b29e21a
--- /dev/null
+++ b/drivers/scsi/bfa/bfad_im.h
@@ -0,0 +1,150 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFAD_IM_H__
19#define __BFAD_IM_H__
20
21#include "fcs/bfa_fcs_fcpim.h"
22#include "bfad_im_compat.h"
23
24#define FCPI_NAME " fcpim"
25
26void bfad_flags_set(struct bfad_s *bfad, u32 flags);
27bfa_status_t bfad_im_module_init(void);
28void bfad_im_module_exit(void);
29bfa_status_t bfad_im_probe(struct bfad_s *bfad);
30void bfad_im_probe_undo(struct bfad_s *bfad);
31void bfad_im_probe_post(struct bfad_im_s *im);
32bfa_status_t bfad_im_port_new(struct bfad_s *bfad, struct bfad_port_s *port);
33void bfad_im_port_delete(struct bfad_s *bfad, struct bfad_port_s *port);
34void bfad_im_port_online(struct bfad_s *bfad, struct bfad_port_s *port);
35void bfad_im_port_offline(struct bfad_s *bfad, struct bfad_port_s *port);
36void bfad_im_port_clean(struct bfad_im_port_s *im_port);
37int bfad_im_scsi_host_alloc(struct bfad_s *bfad,
38 struct bfad_im_port_s *im_port);
39void bfad_im_scsi_host_free(struct bfad_s *bfad,
40 struct bfad_im_port_s *im_port);
41
42#define MAX_FCP_TARGET 1024
43#define MAX_FCP_LUN 16384
44#define BFAD_TARGET_RESET_TMO 60
45#define BFAD_LUN_RESET_TMO 60
46#define ScsiResult(host_code, scsi_code) (((host_code) << 16) | scsi_code)
47#define BFA_QUEUE_FULL_RAMP_UP_TIME 120
48#define BFAD_KOBJ_NAME_LEN 20
49
50/*
51 * itnim flags
52 */
53#define ITNIM_MAPPED 0x00000001
54
55#define SCSI_TASK_MGMT 0x00000001
56#define IO_DONE_BIT 0
57
58struct bfad_itnim_data_s {
59 struct bfad_itnim_s *itnim;
60};
61
62struct bfad_im_port_s {
63 struct bfad_s *bfad;
64 struct bfad_port_s *port;
65 struct work_struct port_delete_work;
66 int idr_id;
67 u16 cur_scsi_id;
68 struct list_head binding_list;
69 struct Scsi_Host *shost;
70 struct list_head itnim_mapped_list;
71};
72
73enum bfad_itnim_state {
74 ITNIM_STATE_NONE,
75 ITNIM_STATE_ONLINE,
76 ITNIM_STATE_OFFLINE_PENDING,
77 ITNIM_STATE_OFFLINE,
78 ITNIM_STATE_TIMEOUT,
79 ITNIM_STATE_FREE,
80};
81
82/*
83 * Per itnim data structure
84 */
85struct bfad_itnim_s {
86 struct list_head list_entry;
87 struct bfa_fcs_itnim_s fcs_itnim;
88 struct work_struct itnim_work;
89 u32 flags;
90 enum bfad_itnim_state state;
91 struct bfad_im_s *im;
92 struct bfad_im_port_s *im_port;
93 struct bfad_rport_s *drv_rport;
94 struct fc_rport *fc_rport;
95 struct bfa_itnim_s *bfa_itnim;
96 u16 scsi_tgt_id;
97 u16 queue_work;
98 unsigned long last_ramp_up_time;
99 unsigned long last_queue_full_time;
100};
101
102enum bfad_binding_type {
103 FCP_PWWN_BINDING = 0x1,
104 FCP_NWWN_BINDING = 0x2,
105 FCP_FCID_BINDING = 0x3,
106};
107
108struct bfad_fcp_binding {
109 struct list_head list_entry;
110 enum bfad_binding_type binding_type;
111 u16 scsi_target_id;
112 u32 fc_id;
113 wwn_t nwwn;
114 wwn_t pwwn;
115};
116
117struct bfad_im_s {
118 struct bfad_s *bfad;
119 struct workqueue_struct *drv_workq;
120 char drv_workq_name[BFAD_KOBJ_NAME_LEN];
121};
122
123struct Scsi_Host *bfad_os_scsi_host_alloc(struct bfad_im_port_s *im_port,
124 struct bfad_s *);
125bfa_status_t bfad_os_thread_workq(struct bfad_s *bfad);
126void bfad_os_destroy_workq(struct bfad_im_s *im);
127void bfad_os_itnim_process(struct bfad_itnim_s *itnim_drv);
128void bfad_os_fc_host_init(struct bfad_im_port_s *im_port);
129void bfad_os_init_work(struct bfad_im_port_s *im_port);
130void bfad_os_scsi_host_free(struct bfad_s *bfad,
131 struct bfad_im_port_s *im_port);
132void bfad_os_ramp_up_qdepth(struct bfad_itnim_s *itnim,
133 struct scsi_device *sdev);
134void bfad_os_handle_qfull(struct bfad_itnim_s *itnim, struct scsi_device *sdev);
135struct bfad_itnim_s *bfad_os_get_itnim(struct bfad_im_port_s *im_port, int id);
136int bfad_os_scsi_add_host(struct Scsi_Host *shost,
137 struct bfad_im_port_s *im_port, struct bfad_s *bfad);
138
139/*
140 * scsi_host_template entries
141 */
142void bfad_im_itnim_unmap(struct bfad_im_port_s *im_port,
143 struct bfad_itnim_s *itnim);
144
145extern struct scsi_host_template bfad_im_scsi_host_template;
146extern struct scsi_host_template bfad_im_vport_template;
147extern struct fc_function_template bfad_im_fc_function_template;
148extern struct scsi_transport_template *bfad_im_scsi_transport_template;
149
150#endif
diff --git a/drivers/scsi/bfa/bfad_im_compat.h b/drivers/scsi/bfa/bfad_im_compat.h
new file mode 100644
index 000000000000..1d3e74ec338c
--- /dev/null
+++ b/drivers/scsi/bfa/bfad_im_compat.h
@@ -0,0 +1,46 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFAD_IM_COMPAT_H__
19#define __BFAD_IM_COMPAT_H__
20
21extern u32 *bfi_image_buf;
22extern u32 bfi_image_size;
23
24extern struct device_attribute *bfad_im_host_attrs[];
25extern struct device_attribute *bfad_im_vport_attrs[];
26
27u32 *bfad_get_firmware_buf(struct pci_dev *pdev);
28u32 *bfad_read_firmware(struct pci_dev *pdev, u32 **bfi_image,
29 u32 *bfi_image_size, char *fw_name);
30
31static inline u32 *
32bfad_load_fwimg(struct pci_dev *pdev)
33{
34 return(bfad_get_firmware_buf(pdev));
35}
36
37static inline void
38bfad_free_fwimg(void)
39{
40 if (bfi_image_ct_size && bfi_image_ct)
41 vfree(bfi_image_ct);
42 if (bfi_image_cb_size && bfi_image_cb)
43 vfree(bfi_image_cb);
44}
45
46#endif
diff --git a/drivers/scsi/bfa/bfad_intr.c b/drivers/scsi/bfa/bfad_intr.c
new file mode 100644
index 000000000000..f104e029cac9
--- /dev/null
+++ b/drivers/scsi/bfa/bfad_intr.c
@@ -0,0 +1,214 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#include "bfad_drv.h"
19#include "bfad_trcmod.h"
20
21BFA_TRC_FILE(LDRV, INTR);
22
23/**
24 * bfa_isr BFA driver interrupt functions
25 */
26irqreturn_t bfad_intx(int irq, void *dev_id);
27static int msix_disable;
28module_param(msix_disable, int, S_IRUGO | S_IWUSR);
29/**
30 * Line based interrupt handler.
31 */
32irqreturn_t
33bfad_intx(int irq, void *dev_id)
34{
35 struct bfad_s *bfad = dev_id;
36 struct list_head doneq;
37 unsigned long flags;
38 bfa_boolean_t rc;
39
40 spin_lock_irqsave(&bfad->bfad_lock, flags);
41 rc = bfa_intx(&bfad->bfa);
42 if (!rc) {
43 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
44 return IRQ_NONE;
45 }
46
47 bfa_comp_deq(&bfad->bfa, &doneq);
48 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
49
50 if (!list_empty(&doneq)) {
51 bfa_comp_process(&bfad->bfa, &doneq);
52
53 spin_lock_irqsave(&bfad->bfad_lock, flags);
54 bfa_comp_free(&bfad->bfa, &doneq);
55 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
56 bfa_trc_fp(bfad, irq);
57 }
58
59 return IRQ_HANDLED;
60
61}
62
63static irqreturn_t
64bfad_msix(int irq, void *dev_id)
65{
66 struct bfad_msix_s *vec = dev_id;
67 struct bfad_s *bfad = vec->bfad;
68 struct list_head doneq;
69 unsigned long flags;
70
71 spin_lock_irqsave(&bfad->bfad_lock, flags);
72
73 bfa_msix(&bfad->bfa, vec->msix.entry);
74 bfa_comp_deq(&bfad->bfa, &doneq);
75 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
76
77 if (!list_empty(&doneq)) {
78 bfa_comp_process(&bfad->bfa, &doneq);
79
80 spin_lock_irqsave(&bfad->bfad_lock, flags);
81 bfa_comp_free(&bfad->bfa, &doneq);
82 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
83 }
84
85 return IRQ_HANDLED;
86}
87
88/**
89 * Initialize the MSIX entry table.
90 */
91static void
92bfad_init_msix_entry(struct bfad_s *bfad, struct msix_entry *msix_entries,
93 int mask, int max_bit)
94{
95 int i;
96 int match = 0x00000001;
97
98 for (i = 0, bfad->nvec = 0; i < MAX_MSIX_ENTRY; i++) {
99 if (mask & match) {
100 bfad->msix_tab[bfad->nvec].msix.entry = i;
101 bfad->msix_tab[bfad->nvec].bfad = bfad;
102 msix_entries[bfad->nvec].entry = i;
103 bfad->nvec++;
104 }
105
106 match <<= 1;
107 }
108
109}
110
111int
112bfad_install_msix_handler(struct bfad_s *bfad)
113{
114 int i, error = 0;
115
116 for (i = 0; i < bfad->nvec; i++) {
117 error = request_irq(bfad->msix_tab[i].msix.vector,
118 (irq_handler_t) bfad_msix, 0,
119 BFAD_DRIVER_NAME, &bfad->msix_tab[i]);
120 bfa_trc(bfad, i);
121 bfa_trc(bfad, bfad->msix_tab[i].msix.vector);
122 if (error) {
123 int j;
124
125 for (j = 0; j < i; j++)
126 free_irq(bfad->msix_tab[j].msix.vector,
127 &bfad->msix_tab[j]);
128
129 return 1;
130 }
131 }
132
133 return 0;
134}
135
136/**
137 * Setup MSIX based interrupt.
138 */
139int
140bfad_setup_intr(struct bfad_s *bfad)
141{
142 int error = 0;
143 u32 mask = 0, i, num_bit = 0, max_bit = 0;
144 struct msix_entry msix_entries[MAX_MSIX_ENTRY];
145
146 /* Call BFA to get the msix map for this PCI function. */
147 bfa_msix_getvecs(&bfad->bfa, &mask, &num_bit, &max_bit);
148
149 /* Set up the msix entry table */
150 bfad_init_msix_entry(bfad, msix_entries, mask, max_bit);
151
152 if (!msix_disable) {
153 error = pci_enable_msix(bfad->pcidev, msix_entries, bfad->nvec);
154 if (error) {
155 /*
156 * Only error number of vector is available.
157 * We don't have a mechanism to map multiple
158 * interrupts into one vector, so even if we
159 * can try to request less vectors, we don't
160 * know how to associate interrupt events to
161 * vectors. Linux doesn't dupicate vectors
162 * in the MSIX table for this case.
163 */
164
165 printk(KERN_WARNING "bfad%d: "
166 "pci_enable_msix failed (%d),"
167 " use line based.\n", bfad->inst_no, error);
168
169 goto line_based;
170 }
171
172 /* Save the vectors */
173 for (i = 0; i < bfad->nvec; i++) {
174 bfa_trc(bfad, msix_entries[i].vector);
175 bfad->msix_tab[i].msix.vector = msix_entries[i].vector;
176 }
177
178 bfa_msix_init(&bfad->bfa, bfad->nvec);
179
180 bfad->bfad_flags |= BFAD_MSIX_ON;
181
182 return error;
183 }
184
185line_based:
186 error = 0;
187 if (request_irq
188 (bfad->pcidev->irq, (irq_handler_t) bfad_intx, BFAD_IRQ_FLAGS,
189 BFAD_DRIVER_NAME, bfad) != 0) {
190 /* Enable interrupt handler failed */
191 return 1;
192 }
193
194 return error;
195}
196
197void
198bfad_remove_intr(struct bfad_s *bfad)
199{
200 int i;
201
202 if (bfad->bfad_flags & BFAD_MSIX_ON) {
203 for (i = 0; i < bfad->nvec; i++)
204 free_irq(bfad->msix_tab[i].msix.vector,
205 &bfad->msix_tab[i]);
206
207 pci_disable_msix(bfad->pcidev);
208 bfad->bfad_flags &= ~BFAD_MSIX_ON;
209 } else {
210 free_irq(bfad->pcidev->irq, bfad);
211 }
212}
213
214
diff --git a/drivers/scsi/bfa/bfad_ipfc.h b/drivers/scsi/bfa/bfad_ipfc.h
new file mode 100644
index 000000000000..718bc5227671
--- /dev/null
+++ b/drivers/scsi/bfa/bfad_ipfc.h
@@ -0,0 +1,42 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17#ifndef __BFA_DRV_IPFC_H__
18#define __BFA_DRV_IPFC_H__
19
20
21#define IPFC_NAME ""
22
23#define bfad_ipfc_module_init(x) do {} while (0)
24#define bfad_ipfc_module_exit(x) do {} while (0)
25#define bfad_ipfc_probe(x) do {} while (0)
26#define bfad_ipfc_probe_undo(x) do {} while (0)
27#define bfad_ipfc_port_config(x, y) BFA_STATUS_OK
28#define bfad_ipfc_port_unconfig(x, y) do {} while (0)
29
30#define bfad_ipfc_probe_post(x) do {} while (0)
31#define bfad_ipfc_port_new(x, y, z) BFA_STATUS_OK
32#define bfad_ipfc_port_delete(x, y) do {} while (0)
33#define bfad_ipfc_port_online(x, y) do {} while (0)
34#define bfad_ipfc_port_offline(x, y) do {} while (0)
35
36#define bfad_ip_get_attr(x) BFA_STATUS_FAILED
37#define bfad_ip_reset_drv_stats(x) BFA_STATUS_FAILED
38#define bfad_ip_get_drv_stats(x, y) BFA_STATUS_FAILED
39#define bfad_ip_enable_ipfc(x, y, z) BFA_STATUS_FAILED
40
41
42#endif
diff --git a/drivers/scsi/bfa/bfad_os.c b/drivers/scsi/bfa/bfad_os.c
new file mode 100644
index 000000000000..faf47b4f1a38
--- /dev/null
+++ b/drivers/scsi/bfa/bfad_os.c
@@ -0,0 +1,50 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * bfad_os.c Linux driver OS specific calls.
20 */
21
22#include "bfa_os_inc.h"
23#include "bfad_drv.h"
24
25void
26bfa_os_gettimeofday(struct bfa_timeval_s *tv)
27{
28 struct timeval tmp_tv;
29
30 do_gettimeofday(&tmp_tv);
31 tv->tv_sec = (u32) tmp_tv.tv_sec;
32 tv->tv_usec = (u32) tmp_tv.tv_usec;
33}
34
35void
36bfa_os_printf(struct bfa_log_mod_s *log_mod, u32 msg_id,
37 const char *fmt, ...)
38{
39 va_list ap;
40 #define BFA_STRING_256 256
41 char tmp[BFA_STRING_256];
42
43 va_start(ap, fmt);
44 vsprintf(tmp, fmt, ap);
45 va_end(ap);
46
47 printk(tmp);
48}
49
50
diff --git a/drivers/scsi/bfa/bfad_tm.h b/drivers/scsi/bfa/bfad_tm.h
new file mode 100644
index 000000000000..4901b1b7df02
--- /dev/null
+++ b/drivers/scsi/bfa/bfad_tm.h
@@ -0,0 +1,59 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/*
19 * Brocade Fibre Channel HBA Linux Target Mode Driver
20 */
21
22/**
23 * tm/dummy/bfad_tm.h BFA callback dummy header file for BFA Linux target mode PCI interface module.
24 */
25
26#ifndef __BFAD_TM_H__
27#define __BFAD_TM_H__
28
29#include <defs/bfa_defs_status.h>
30
31#define FCPT_NAME ""
32
33/*
34 * Called from base Linux driver on (De)Init events
35 */
36
37/* attach tgt template with scst */
38#define bfad_tm_module_init() do {} while (0)
39
40/* detach/release tgt template */
41#define bfad_tm_module_exit() do {} while (0)
42
43#define bfad_tm_probe(x) do {} while (0)
44#define bfad_tm_probe_undo(x) do {} while (0)
45#define bfad_tm_probe_post(x) do {} while (0)
46
47/*
48 * Called by base Linux driver but triggered by BFA FCS on config events
49 */
50#define bfad_tm_port_new(x, y) BFA_STATUS_OK
51#define bfad_tm_port_delete(x, y) do {} while (0)
52
53/*
54 * Called by base Linux driver but triggered by BFA FCS on PLOGI/O events
55 */
56#define bfad_tm_port_online(x, y) do {} while (0)
57#define bfad_tm_port_offline(x, y) do {} while (0)
58
59#endif
diff --git a/drivers/scsi/bfa/bfad_trcmod.h b/drivers/scsi/bfa/bfad_trcmod.h
new file mode 100644
index 000000000000..2827b2acd041
--- /dev/null
+++ b/drivers/scsi/bfa/bfad_trcmod.h
@@ -0,0 +1,52 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * bfad_trcmod.h Linux driver trace modules
20 */
21
22
23#ifndef __BFAD_TRCMOD_H__
24#define __BFAD_TRCMOD_H__
25
26#include <cs/bfa_trc.h>
27
28/*
29 * !!! Only append to the enums defined here to avoid any versioning
30 * !!! needed between trace utility and driver version
31 */
32enum {
33 /* 2.6 Driver */
34 BFA_TRC_LDRV_BFAD = 1,
35 BFA_TRC_LDRV_BFAD_2_6 = 2,
36 BFA_TRC_LDRV_BFAD_2_6_9 = 3,
37 BFA_TRC_LDRV_BFAD_2_6_10 = 4,
38 BFA_TRC_LDRV_INTR = 5,
39 BFA_TRC_LDRV_IOCTL = 6,
40 BFA_TRC_LDRV_OS = 7,
41 BFA_TRC_LDRV_IM = 8,
42 BFA_TRC_LDRV_IM_2_6 = 9,
43 BFA_TRC_LDRV_IM_2_6_9 = 10,
44 BFA_TRC_LDRV_IM_2_6_10 = 11,
45 BFA_TRC_LDRV_TM = 12,
46 BFA_TRC_LDRV_IPFC = 13,
47 BFA_TRC_LDRV_IM_2_4 = 14,
48 BFA_TRC_LDRV_IM_VMW = 15,
49 BFA_TRC_LDRV_IM_LT_2_6_10 = 16,
50};
51
52#endif /* __BFAD_TRCMOD_H__ */
diff --git a/drivers/scsi/bfa/fab.c b/drivers/scsi/bfa/fab.c
new file mode 100644
index 000000000000..7e3a4d5d7bb4
--- /dev/null
+++ b/drivers/scsi/bfa/fab.c
@@ -0,0 +1,62 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#include <bfa.h>
19#include <bfa_svc.h>
20#include "fcs_lport.h"
21#include "fcs_rport.h"
22#include "lport_priv.h"
23
24/**
25 * fab.c port fab implementation.
26 */
27
28/**
29 * bfa_fcs_port_fab_public port fab public functions
30 */
31
32/**
33 * Called by port to initialize fabric services of the base port.
34 */
35void
36bfa_fcs_port_fab_init(struct bfa_fcs_port_s *port)
37{
38 bfa_fcs_port_ns_init(port);
39 bfa_fcs_port_scn_init(port);
40 bfa_fcs_port_ms_init(port);
41}
42
43/**
44 * Called by port to notify transition to online state.
45 */
46void
47bfa_fcs_port_fab_online(struct bfa_fcs_port_s *port)
48{
49 bfa_fcs_port_ns_online(port);
50 bfa_fcs_port_scn_online(port);
51}
52
53/**
54 * Called by port to notify transition to offline state.
55 */
56void
57bfa_fcs_port_fab_offline(struct bfa_fcs_port_s *port)
58{
59 bfa_fcs_port_ns_offline(port);
60 bfa_fcs_port_scn_offline(port);
61 bfa_fcs_port_ms_offline(port);
62}
diff --git a/drivers/scsi/bfa/fabric.c b/drivers/scsi/bfa/fabric.c
new file mode 100644
index 000000000000..a8b14c47b009
--- /dev/null
+++ b/drivers/scsi/bfa/fabric.c
@@ -0,0 +1,1278 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * fabric.c Fabric module implementation.
20 */
21
22#include "fcs_fabric.h"
23#include "fcs_lport.h"
24#include "fcs_vport.h"
25#include "fcs_trcmod.h"
26#include "fcs_fcxp.h"
27#include "fcs_auth.h"
28#include "fcs.h"
29#include "fcbuild.h"
30#include <log/bfa_log_fcs.h>
31#include <aen/bfa_aen_port.h>
32#include <bfa_svc.h>
33
34BFA_TRC_FILE(FCS, FABRIC);
35
36#define BFA_FCS_FABRIC_RETRY_DELAY (2000) /* Milliseconds */
37#define BFA_FCS_FABRIC_CLEANUP_DELAY (10000) /* Milliseconds */
38
39#define bfa_fcs_fabric_set_opertype(__fabric) do { \
40 if (bfa_pport_get_topology((__fabric)->fcs->bfa) \
41 == BFA_PPORT_TOPOLOGY_P2P) \
42 (__fabric)->oper_type = BFA_PPORT_TYPE_NPORT; \
43 else \
44 (__fabric)->oper_type = BFA_PPORT_TYPE_NLPORT; \
45} while (0)
46
47/*
48 * forward declarations
49 */
50static void bfa_fcs_fabric_init(struct bfa_fcs_fabric_s *fabric);
51static void bfa_fcs_fabric_login(struct bfa_fcs_fabric_s *fabric);
52static void bfa_fcs_fabric_notify_online(struct bfa_fcs_fabric_s *fabric);
53static void bfa_fcs_fabric_notify_offline(struct bfa_fcs_fabric_s *fabric);
54static void bfa_fcs_fabric_delay(void *cbarg);
55static void bfa_fcs_fabric_delete(struct bfa_fcs_fabric_s *fabric);
56static void bfa_fcs_fabric_delete_comp(void *cbarg);
57static void bfa_fcs_fabric_process_uf(struct bfa_fcs_fabric_s *fabric,
58 struct fchs_s *fchs, u16 len);
59static void bfa_fcs_fabric_process_flogi(struct bfa_fcs_fabric_s *fabric,
60 struct fchs_s *fchs, u16 len);
61static void bfa_fcs_fabric_send_flogi_acc(struct bfa_fcs_fabric_s *fabric);
62static void bfa_fcs_fabric_flogiacc_comp(void *fcsarg,
63 struct bfa_fcxp_s *fcxp,
64 void *cbarg, bfa_status_t status,
65 u32 rsp_len,
66 u32 resid_len,
67 struct fchs_s *rspfchs);
68/**
69 * fcs_fabric_sm fabric state machine functions
70 */
71
72/**
73 * Fabric state machine events
74 */
75enum bfa_fcs_fabric_event {
76 BFA_FCS_FABRIC_SM_CREATE = 1, /* fabric create from driver */
77 BFA_FCS_FABRIC_SM_DELETE = 2, /* fabric delete from driver */
78 BFA_FCS_FABRIC_SM_LINK_DOWN = 3, /* link down from port */
79 BFA_FCS_FABRIC_SM_LINK_UP = 4, /* link up from port */
80 BFA_FCS_FABRIC_SM_CONT_OP = 5, /* continue op from flogi/auth */
81 BFA_FCS_FABRIC_SM_RETRY_OP = 6, /* continue op from flogi/auth */
82 BFA_FCS_FABRIC_SM_NO_FABRIC = 7, /* no fabric from flogi/auth
83 */
84 BFA_FCS_FABRIC_SM_PERF_EVFP = 8, /* perform EVFP from
85 *flogi/auth */
86 BFA_FCS_FABRIC_SM_ISOLATE = 9, /* isolate from EVFP processing */
87 BFA_FCS_FABRIC_SM_NO_TAGGING = 10,/* no VFT tagging from EVFP */
88 BFA_FCS_FABRIC_SM_DELAYED = 11, /* timeout delay event */
89 BFA_FCS_FABRIC_SM_AUTH_FAILED = 12, /* authentication failed */
90 BFA_FCS_FABRIC_SM_AUTH_SUCCESS = 13, /* authentication successful
91 */
92 BFA_FCS_FABRIC_SM_DELCOMP = 14, /* all vports deleted event */
93 BFA_FCS_FABRIC_SM_LOOPBACK = 15, /* Received our own FLOGI */
94 BFA_FCS_FABRIC_SM_START = 16, /* fabric delete from driver */
95};
96
97static void bfa_fcs_fabric_sm_uninit(struct bfa_fcs_fabric_s *fabric,
98 enum bfa_fcs_fabric_event event);
99static void bfa_fcs_fabric_sm_created(struct bfa_fcs_fabric_s *fabric,
100 enum bfa_fcs_fabric_event event);
101static void bfa_fcs_fabric_sm_linkdown(struct bfa_fcs_fabric_s *fabric,
102 enum bfa_fcs_fabric_event event);
103static void bfa_fcs_fabric_sm_flogi(struct bfa_fcs_fabric_s *fabric,
104 enum bfa_fcs_fabric_event event);
105static void bfa_fcs_fabric_sm_flogi_retry(struct bfa_fcs_fabric_s *fabric,
106 enum bfa_fcs_fabric_event event);
107static void bfa_fcs_fabric_sm_auth(struct bfa_fcs_fabric_s *fabric,
108 enum bfa_fcs_fabric_event event);
109static void bfa_fcs_fabric_sm_auth_failed(struct bfa_fcs_fabric_s *fabric,
110 enum bfa_fcs_fabric_event event);
111static void bfa_fcs_fabric_sm_loopback(struct bfa_fcs_fabric_s *fabric,
112 enum bfa_fcs_fabric_event event);
113static void bfa_fcs_fabric_sm_nofabric(struct bfa_fcs_fabric_s *fabric,
114 enum bfa_fcs_fabric_event event);
115static void bfa_fcs_fabric_sm_online(struct bfa_fcs_fabric_s *fabric,
116 enum bfa_fcs_fabric_event event);
117static void bfa_fcs_fabric_sm_evfp(struct bfa_fcs_fabric_s *fabric,
118 enum bfa_fcs_fabric_event event);
119static void bfa_fcs_fabric_sm_evfp_done(struct bfa_fcs_fabric_s *fabric,
120 enum bfa_fcs_fabric_event event);
121static void bfa_fcs_fabric_sm_isolated(struct bfa_fcs_fabric_s *fabric,
122 enum bfa_fcs_fabric_event event);
123static void bfa_fcs_fabric_sm_deleting(struct bfa_fcs_fabric_s *fabric,
124 enum bfa_fcs_fabric_event event);
125/**
126 * Beginning state before fabric creation.
127 */
128static void
129bfa_fcs_fabric_sm_uninit(struct bfa_fcs_fabric_s *fabric,
130 enum bfa_fcs_fabric_event event)
131{
132 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
133 bfa_trc(fabric->fcs, event);
134
135 switch (event) {
136 case BFA_FCS_FABRIC_SM_CREATE:
137 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_created);
138 bfa_fcs_fabric_init(fabric);
139 bfa_fcs_lport_init(&fabric->bport, fabric->fcs, FC_VF_ID_NULL,
140 &fabric->bport.port_cfg, NULL);
141 break;
142
143 case BFA_FCS_FABRIC_SM_LINK_UP:
144 case BFA_FCS_FABRIC_SM_LINK_DOWN:
145 break;
146
147 default:
148 bfa_sm_fault(fabric->fcs, event);
149 }
150}
151
152/**
153 * Beginning state before fabric creation.
154 */
155static void
156bfa_fcs_fabric_sm_created(struct bfa_fcs_fabric_s *fabric,
157 enum bfa_fcs_fabric_event event)
158{
159 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
160 bfa_trc(fabric->fcs, event);
161
162 switch (event) {
163 case BFA_FCS_FABRIC_SM_START:
164 if (bfa_pport_is_linkup(fabric->fcs->bfa)) {
165 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi);
166 bfa_fcs_fabric_login(fabric);
167 } else
168 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
169 break;
170
171 case BFA_FCS_FABRIC_SM_LINK_UP:
172 case BFA_FCS_FABRIC_SM_LINK_DOWN:
173 break;
174
175 case BFA_FCS_FABRIC_SM_DELETE:
176 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_uninit);
177 bfa_fcs_modexit_comp(fabric->fcs);
178 break;
179
180 default:
181 bfa_sm_fault(fabric->fcs, event);
182 }
183}
184
185/**
186 * Link is down, awaiting LINK UP event from port. This is also the
187 * first state at fabric creation.
188 */
189static void
190bfa_fcs_fabric_sm_linkdown(struct bfa_fcs_fabric_s *fabric,
191 enum bfa_fcs_fabric_event event)
192{
193 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
194 bfa_trc(fabric->fcs, event);
195
196 switch (event) {
197 case BFA_FCS_FABRIC_SM_LINK_UP:
198 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi);
199 bfa_fcs_fabric_login(fabric);
200 break;
201
202 case BFA_FCS_FABRIC_SM_RETRY_OP:
203 break;
204
205 case BFA_FCS_FABRIC_SM_DELETE:
206 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
207 bfa_fcs_fabric_delete(fabric);
208 break;
209
210 default:
211 bfa_sm_fault(fabric->fcs, event);
212 }
213}
214
215/**
216 * FLOGI is in progress, awaiting FLOGI reply.
217 */
218static void
219bfa_fcs_fabric_sm_flogi(struct bfa_fcs_fabric_s *fabric,
220 enum bfa_fcs_fabric_event event)
221{
222 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
223 bfa_trc(fabric->fcs, event);
224
225 switch (event) {
226 case BFA_FCS_FABRIC_SM_CONT_OP:
227
228 bfa_pport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit);
229 fabric->fab_type = BFA_FCS_FABRIC_SWITCHED;
230
231 if (fabric->auth_reqd && fabric->is_auth) {
232 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_auth);
233 bfa_trc(fabric->fcs, event);
234 } else {
235 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_online);
236 bfa_fcs_fabric_notify_online(fabric);
237 }
238 break;
239
240 case BFA_FCS_FABRIC_SM_RETRY_OP:
241 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi_retry);
242 bfa_timer_start(fabric->fcs->bfa, &fabric->delay_timer,
243 bfa_fcs_fabric_delay, fabric,
244 BFA_FCS_FABRIC_RETRY_DELAY);
245 break;
246
247 case BFA_FCS_FABRIC_SM_LOOPBACK:
248 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_loopback);
249 bfa_lps_discard(fabric->lps);
250 bfa_fcs_fabric_set_opertype(fabric);
251 break;
252
253 case BFA_FCS_FABRIC_SM_NO_FABRIC:
254 fabric->fab_type = BFA_FCS_FABRIC_N2N;
255 bfa_pport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit);
256 bfa_fcs_fabric_notify_online(fabric);
257 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_nofabric);
258 break;
259
260 case BFA_FCS_FABRIC_SM_LINK_DOWN:
261 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
262 bfa_lps_discard(fabric->lps);
263 break;
264
265 case BFA_FCS_FABRIC_SM_DELETE:
266 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
267 bfa_lps_discard(fabric->lps);
268 bfa_fcs_fabric_delete(fabric);
269 break;
270
271 default:
272 bfa_sm_fault(fabric->fcs, event);
273 }
274}
275
276
277static void
278bfa_fcs_fabric_sm_flogi_retry(struct bfa_fcs_fabric_s *fabric,
279 enum bfa_fcs_fabric_event event)
280{
281 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
282 bfa_trc(fabric->fcs, event);
283
284 switch (event) {
285 case BFA_FCS_FABRIC_SM_DELAYED:
286 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_flogi);
287 bfa_fcs_fabric_login(fabric);
288 break;
289
290 case BFA_FCS_FABRIC_SM_LINK_DOWN:
291 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
292 bfa_timer_stop(&fabric->delay_timer);
293 break;
294
295 case BFA_FCS_FABRIC_SM_DELETE:
296 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
297 bfa_timer_stop(&fabric->delay_timer);
298 bfa_fcs_fabric_delete(fabric);
299 break;
300
301 default:
302 bfa_sm_fault(fabric->fcs, event);
303 }
304}
305
306/**
307 * Authentication is in progress, awaiting authentication results.
308 */
309static void
310bfa_fcs_fabric_sm_auth(struct bfa_fcs_fabric_s *fabric,
311 enum bfa_fcs_fabric_event event)
312{
313 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
314 bfa_trc(fabric->fcs, event);
315
316 switch (event) {
317 case BFA_FCS_FABRIC_SM_AUTH_FAILED:
318 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_auth_failed);
319 bfa_lps_discard(fabric->lps);
320 break;
321
322 case BFA_FCS_FABRIC_SM_AUTH_SUCCESS:
323 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_online);
324 bfa_fcs_fabric_notify_online(fabric);
325 break;
326
327 case BFA_FCS_FABRIC_SM_PERF_EVFP:
328 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_evfp);
329 break;
330
331 case BFA_FCS_FABRIC_SM_LINK_DOWN:
332 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
333 bfa_lps_discard(fabric->lps);
334 break;
335
336 case BFA_FCS_FABRIC_SM_DELETE:
337 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
338 bfa_fcs_fabric_delete(fabric);
339 break;
340
341 default:
342 bfa_sm_fault(fabric->fcs, event);
343 }
344}
345
346/**
347 * Authentication failed
348 */
349static void
350bfa_fcs_fabric_sm_auth_failed(struct bfa_fcs_fabric_s *fabric,
351 enum bfa_fcs_fabric_event event)
352{
353 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
354 bfa_trc(fabric->fcs, event);
355
356 switch (event) {
357 case BFA_FCS_FABRIC_SM_LINK_DOWN:
358 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
359 bfa_fcs_fabric_notify_offline(fabric);
360 break;
361
362 case BFA_FCS_FABRIC_SM_DELETE:
363 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
364 bfa_fcs_fabric_delete(fabric);
365 break;
366
367 default:
368 bfa_sm_fault(fabric->fcs, event);
369 }
370}
371
372/**
373 * Port is in loopback mode.
374 */
375static void
376bfa_fcs_fabric_sm_loopback(struct bfa_fcs_fabric_s *fabric,
377 enum bfa_fcs_fabric_event event)
378{
379 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
380 bfa_trc(fabric->fcs, event);
381
382 switch (event) {
383 case BFA_FCS_FABRIC_SM_LINK_DOWN:
384 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
385 bfa_fcs_fabric_notify_offline(fabric);
386 break;
387
388 case BFA_FCS_FABRIC_SM_DELETE:
389 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
390 bfa_fcs_fabric_delete(fabric);
391 break;
392
393 default:
394 bfa_sm_fault(fabric->fcs, event);
395 }
396}
397
398/**
399 * There is no attached fabric - private loop or NPort-to-NPort topology.
400 */
401static void
402bfa_fcs_fabric_sm_nofabric(struct bfa_fcs_fabric_s *fabric,
403 enum bfa_fcs_fabric_event event)
404{
405 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
406 bfa_trc(fabric->fcs, event);
407
408 switch (event) {
409 case BFA_FCS_FABRIC_SM_LINK_DOWN:
410 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
411 bfa_lps_discard(fabric->lps);
412 bfa_fcs_fabric_notify_offline(fabric);
413 break;
414
415 case BFA_FCS_FABRIC_SM_DELETE:
416 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
417 bfa_fcs_fabric_delete(fabric);
418 break;
419
420 case BFA_FCS_FABRIC_SM_NO_FABRIC:
421 bfa_trc(fabric->fcs, fabric->bb_credit);
422 bfa_pport_set_tx_bbcredit(fabric->fcs->bfa, fabric->bb_credit);
423 break;
424
425 default:
426 bfa_sm_fault(fabric->fcs, event);
427 }
428}
429
430/**
431 * Fabric is online - normal operating state.
432 */
433static void
434bfa_fcs_fabric_sm_online(struct bfa_fcs_fabric_s *fabric,
435 enum bfa_fcs_fabric_event event)
436{
437 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
438 bfa_trc(fabric->fcs, event);
439
440 switch (event) {
441 case BFA_FCS_FABRIC_SM_LINK_DOWN:
442 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_linkdown);
443 bfa_lps_discard(fabric->lps);
444 bfa_fcs_fabric_notify_offline(fabric);
445 break;
446
447 case BFA_FCS_FABRIC_SM_DELETE:
448 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_deleting);
449 bfa_fcs_fabric_delete(fabric);
450 break;
451
452 case BFA_FCS_FABRIC_SM_AUTH_FAILED:
453 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_auth_failed);
454 bfa_lps_discard(fabric->lps);
455 break;
456
457 case BFA_FCS_FABRIC_SM_AUTH_SUCCESS:
458 break;
459
460 default:
461 bfa_sm_fault(fabric->fcs, event);
462 }
463}
464
465/**
466 * Exchanging virtual fabric parameters.
467 */
468static void
469bfa_fcs_fabric_sm_evfp(struct bfa_fcs_fabric_s *fabric,
470 enum bfa_fcs_fabric_event event)
471{
472 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
473 bfa_trc(fabric->fcs, event);
474
475 switch (event) {
476 case BFA_FCS_FABRIC_SM_CONT_OP:
477 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_evfp_done);
478 break;
479
480 case BFA_FCS_FABRIC_SM_ISOLATE:
481 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_isolated);
482 break;
483
484 default:
485 bfa_sm_fault(fabric->fcs, event);
486 }
487}
488
489/**
490 * EVFP exchange complete and VFT tagging is enabled.
491 */
492static void
493bfa_fcs_fabric_sm_evfp_done(struct bfa_fcs_fabric_s *fabric,
494 enum bfa_fcs_fabric_event event)
495{
496 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
497 bfa_trc(fabric->fcs, event);
498}
499
500/**
501 * Port is isolated after EVFP exchange due to VF_ID mismatch (N and F).
502 */
503static void
504bfa_fcs_fabric_sm_isolated(struct bfa_fcs_fabric_s *fabric,
505 enum bfa_fcs_fabric_event event)
506{
507 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
508 bfa_trc(fabric->fcs, event);
509
510 bfa_log(fabric->fcs->logm, BFA_LOG_FCS_FABRIC_ISOLATED,
511 fabric->bport.port_cfg.pwwn, fabric->fcs->port_vfid,
512 fabric->event_arg.swp_vfid);
513}
514
515/**
516 * Fabric is being deleted, awaiting vport delete completions.
517 */
518static void
519bfa_fcs_fabric_sm_deleting(struct bfa_fcs_fabric_s *fabric,
520 enum bfa_fcs_fabric_event event)
521{
522 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
523 bfa_trc(fabric->fcs, event);
524
525 switch (event) {
526 case BFA_FCS_FABRIC_SM_DELCOMP:
527 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_uninit);
528 bfa_fcs_modexit_comp(fabric->fcs);
529 break;
530
531 case BFA_FCS_FABRIC_SM_LINK_UP:
532 break;
533
534 case BFA_FCS_FABRIC_SM_LINK_DOWN:
535 bfa_fcs_fabric_notify_offline(fabric);
536 break;
537
538 default:
539 bfa_sm_fault(fabric->fcs, event);
540 }
541}
542
543
544
545/**
546 * fcs_fabric_private fabric private functions
547 */
548
549static void
550bfa_fcs_fabric_init(struct bfa_fcs_fabric_s *fabric)
551{
552 struct bfa_port_cfg_s *port_cfg = &fabric->bport.port_cfg;
553
554 port_cfg->roles = BFA_PORT_ROLE_FCP_IM;
555 port_cfg->nwwn = bfa_ioc_get_nwwn(&fabric->fcs->bfa->ioc);
556 port_cfg->pwwn = bfa_ioc_get_pwwn(&fabric->fcs->bfa->ioc);
557}
558
559/**
560 * Port Symbolic Name Creation for base port.
561 */
562void
563bfa_fcs_fabric_psymb_init(struct bfa_fcs_fabric_s *fabric)
564{
565 struct bfa_port_cfg_s *port_cfg = &fabric->bport.port_cfg;
566 struct bfa_adapter_attr_s adapter_attr;
567 struct bfa_fcs_driver_info_s *driver_info = &fabric->fcs->driver_info;
568
569 bfa_os_memset((void *)&adapter_attr, 0,
570 sizeof(struct bfa_adapter_attr_s));
571 bfa_ioc_get_adapter_attr(&fabric->fcs->bfa->ioc, &adapter_attr);
572
573 /*
574 * Model name/number
575 */
576 strncpy((char *)&port_cfg->sym_name, adapter_attr.model,
577 BFA_FCS_PORT_SYMBNAME_MODEL_SZ);
578 strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
579 sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
580
581 /*
582 * Driver Version
583 */
584 strncat((char *)&port_cfg->sym_name, (char *)driver_info->version,
585 BFA_FCS_PORT_SYMBNAME_VERSION_SZ);
586 strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
587 sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
588
589 /*
590 * Host machine name
591 */
592 strncat((char *)&port_cfg->sym_name,
593 (char *)driver_info->host_machine_name,
594 BFA_FCS_PORT_SYMBNAME_MACHINENAME_SZ);
595 strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
596 sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
597
598 /*
599 * Host OS Info :
600 * If OS Patch Info is not there, do not truncate any bytes from the
601 * OS name string and instead copy the entire OS info string (64 bytes).
602 */
603 if (driver_info->host_os_patch[0] == '\0') {
604 strncat((char *)&port_cfg->sym_name,
605 (char *)driver_info->host_os_name, BFA_FCS_OS_STR_LEN);
606 strncat((char *)&port_cfg->sym_name,
607 BFA_FCS_PORT_SYMBNAME_SEPARATOR,
608 sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
609 } else {
610 strncat((char *)&port_cfg->sym_name,
611 (char *)driver_info->host_os_name,
612 BFA_FCS_PORT_SYMBNAME_OSINFO_SZ);
613 strncat((char *)&port_cfg->sym_name,
614 BFA_FCS_PORT_SYMBNAME_SEPARATOR,
615 sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
616
617 /*
618 * Append host OS Patch Info
619 */
620 strncat((char *)&port_cfg->sym_name,
621 (char *)driver_info->host_os_patch,
622 BFA_FCS_PORT_SYMBNAME_OSPATCH_SZ);
623 }
624
625 /*
626 * null terminate
627 */
628 port_cfg->sym_name.symname[BFA_SYMNAME_MAXLEN - 1] = 0;
629}
630
631/**
632 * bfa lps login completion callback
633 */
634void
635bfa_cb_lps_flogi_comp(void *bfad, void *uarg, bfa_status_t status)
636{
637 struct bfa_fcs_fabric_s *fabric = uarg;
638
639 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
640 bfa_trc(fabric->fcs, status);
641
642 switch (status) {
643 case BFA_STATUS_OK:
644 fabric->stats.flogi_accepts++;
645 break;
646
647 case BFA_STATUS_INVALID_MAC:
648 /*
649 * Only for CNA
650 */
651 fabric->stats.flogi_acc_err++;
652 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_RETRY_OP);
653
654 return;
655
656 case BFA_STATUS_EPROTOCOL:
657 switch (bfa_lps_get_extstatus(fabric->lps)) {
658 case BFA_EPROTO_BAD_ACCEPT:
659 fabric->stats.flogi_acc_err++;
660 break;
661
662 case BFA_EPROTO_UNKNOWN_RSP:
663 fabric->stats.flogi_unknown_rsp++;
664 break;
665
666 default:
667 break;
668 }
669 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_RETRY_OP);
670
671 return;
672
673 case BFA_STATUS_FABRIC_RJT:
674 fabric->stats.flogi_rejects++;
675 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_RETRY_OP);
676 return;
677
678 default:
679 fabric->stats.flogi_rsp_err++;
680 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_RETRY_OP);
681 return;
682 }
683
684 fabric->bb_credit = bfa_lps_get_peer_bbcredit(fabric->lps);
685 bfa_trc(fabric->fcs, fabric->bb_credit);
686
687 if (!bfa_lps_is_brcd_fabric(fabric->lps))
688 fabric->fabric_name = bfa_lps_get_peer_nwwn(fabric->lps);
689
690 /*
691 * Check port type. It should be 1 = F-port.
692 */
693 if (bfa_lps_is_fport(fabric->lps)) {
694 fabric->bport.pid = bfa_lps_get_pid(fabric->lps);
695 fabric->is_npiv = bfa_lps_is_npiv_en(fabric->lps);
696 fabric->is_auth = bfa_lps_is_authreq(fabric->lps);
697 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_CONT_OP);
698 } else {
699 /*
700 * Nport-2-Nport direct attached
701 */
702 fabric->bport.port_topo.pn2n.rem_port_wwn =
703 bfa_lps_get_peer_pwwn(fabric->lps);
704 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_NO_FABRIC);
705 }
706
707 bfa_trc(fabric->fcs, fabric->bport.pid);
708 bfa_trc(fabric->fcs, fabric->is_npiv);
709 bfa_trc(fabric->fcs, fabric->is_auth);
710}
711
712/**
713 * Allocate and send FLOGI.
714 */
715static void
716bfa_fcs_fabric_login(struct bfa_fcs_fabric_s *fabric)
717{
718 struct bfa_s *bfa = fabric->fcs->bfa;
719 struct bfa_port_cfg_s *pcfg = &fabric->bport.port_cfg;
720 u8 alpa = 0;
721
722 if (bfa_pport_get_topology(bfa) == BFA_PPORT_TOPOLOGY_LOOP)
723 alpa = bfa_pport_get_myalpa(bfa);
724
725 bfa_lps_flogi(fabric->lps, fabric, alpa, bfa_pport_get_maxfrsize(bfa),
726 pcfg->pwwn, pcfg->nwwn, fabric->auth_reqd);
727
728 fabric->stats.flogi_sent++;
729}
730
731static void
732bfa_fcs_fabric_notify_online(struct bfa_fcs_fabric_s *fabric)
733{
734 struct bfa_fcs_vport_s *vport;
735 struct list_head *qe, *qen;
736
737 bfa_trc(fabric->fcs, fabric->fabric_name);
738
739 bfa_fcs_fabric_set_opertype(fabric);
740 fabric->stats.fabric_onlines++;
741
742 /**
743 * notify online event to base and then virtual ports
744 */
745 bfa_fcs_port_online(&fabric->bport);
746
747 list_for_each_safe(qe, qen, &fabric->vport_q) {
748 vport = (struct bfa_fcs_vport_s *)qe;
749 bfa_fcs_vport_online(vport);
750 }
751}
752
753static void
754bfa_fcs_fabric_notify_offline(struct bfa_fcs_fabric_s *fabric)
755{
756 struct bfa_fcs_vport_s *vport;
757 struct list_head *qe, *qen;
758
759 bfa_trc(fabric->fcs, fabric->fabric_name);
760 fabric->stats.fabric_offlines++;
761
762 /**
763 * notify offline event first to vports and then base port.
764 */
765 list_for_each_safe(qe, qen, &fabric->vport_q) {
766 vport = (struct bfa_fcs_vport_s *)qe;
767 bfa_fcs_vport_offline(vport);
768 }
769
770 bfa_fcs_port_offline(&fabric->bport);
771
772 fabric->fabric_name = 0;
773 fabric->fabric_ip_addr[0] = 0;
774}
775
776static void
777bfa_fcs_fabric_delay(void *cbarg)
778{
779 struct bfa_fcs_fabric_s *fabric = cbarg;
780
781 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_DELAYED);
782}
783
784/**
785 * Delete all vports and wait for vport delete completions.
786 */
787static void
788bfa_fcs_fabric_delete(struct bfa_fcs_fabric_s *fabric)
789{
790 struct bfa_fcs_vport_s *vport;
791 struct list_head *qe, *qen;
792
793 list_for_each_safe(qe, qen, &fabric->vport_q) {
794 vport = (struct bfa_fcs_vport_s *)qe;
795 bfa_fcs_vport_delete(vport);
796 }
797
798 bfa_fcs_port_delete(&fabric->bport);
799 bfa_wc_wait(&fabric->wc);
800}
801
802static void
803bfa_fcs_fabric_delete_comp(void *cbarg)
804{
805 struct bfa_fcs_fabric_s *fabric = cbarg;
806
807 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_DELCOMP);
808}
809
810
811
812/**
813 * fcs_fabric_public fabric public functions
814 */
815
816/**
817 * Module initialization
818 */
819void
820bfa_fcs_fabric_modinit(struct bfa_fcs_s *fcs)
821{
822 struct bfa_fcs_fabric_s *fabric;
823
824 fabric = &fcs->fabric;
825 bfa_os_memset(fabric, 0, sizeof(struct bfa_fcs_fabric_s));
826
827 /**
828 * Initialize base fabric.
829 */
830 fabric->fcs = fcs;
831 INIT_LIST_HEAD(&fabric->vport_q);
832 INIT_LIST_HEAD(&fabric->vf_q);
833 fabric->lps = bfa_lps_alloc(fcs->bfa);
834 bfa_assert(fabric->lps);
835
836 /**
837 * Initialize fabric delete completion handler. Fabric deletion is complete
838 * when the last vport delete is complete.
839 */
840 bfa_wc_init(&fabric->wc, bfa_fcs_fabric_delete_comp, fabric);
841 bfa_wc_up(&fabric->wc); /* For the base port */
842
843 bfa_sm_set_state(fabric, bfa_fcs_fabric_sm_uninit);
844 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_CREATE);
845 bfa_trc(fcs, 0);
846}
847
848/**
849 * Module cleanup
850 */
851void
852bfa_fcs_fabric_modexit(struct bfa_fcs_s *fcs)
853{
854 struct bfa_fcs_fabric_s *fabric;
855
856 bfa_trc(fcs, 0);
857
858 /**
859 * Cleanup base fabric.
860 */
861 fabric = &fcs->fabric;
862 bfa_lps_delete(fabric->lps);
863 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_DELETE);
864}
865
866/**
867 * Fabric module start -- kick starts FCS actions
868 */
869void
870bfa_fcs_fabric_modstart(struct bfa_fcs_s *fcs)
871{
872 struct bfa_fcs_fabric_s *fabric;
873
874 bfa_trc(fcs, 0);
875 fabric = &fcs->fabric;
876 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_START);
877}
878
879/**
880 * Suspend fabric activity as part of driver suspend.
881 */
882void
883bfa_fcs_fabric_modsusp(struct bfa_fcs_s *fcs)
884{
885}
886
887bfa_boolean_t
888bfa_fcs_fabric_is_loopback(struct bfa_fcs_fabric_s *fabric)
889{
890 return (bfa_sm_cmp_state(fabric, bfa_fcs_fabric_sm_loopback));
891}
892
893enum bfa_pport_type
894bfa_fcs_fabric_port_type(struct bfa_fcs_fabric_s *fabric)
895{
896 return fabric->oper_type;
897}
898
899/**
900 * Link up notification from BFA physical port module.
901 */
902void
903bfa_fcs_fabric_link_up(struct bfa_fcs_fabric_s *fabric)
904{
905 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
906 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_LINK_UP);
907}
908
909/**
910 * Link down notification from BFA physical port module.
911 */
912void
913bfa_fcs_fabric_link_down(struct bfa_fcs_fabric_s *fabric)
914{
915 bfa_trc(fabric->fcs, fabric->bport.port_cfg.pwwn);
916 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_LINK_DOWN);
917}
918
919/**
920 * A child vport is being created in the fabric.
921 *
922 * Call from vport module at vport creation. A list of base port and vports
923 * belonging to a fabric is maintained to propagate link events.
924 *
925 * param[in] fabric - Fabric instance. This can be a base fabric or vf.
926 * param[in] vport - Vport being created.
927 *
928 * @return None (always succeeds)
929 */
930void
931bfa_fcs_fabric_addvport(struct bfa_fcs_fabric_s *fabric,
932 struct bfa_fcs_vport_s *vport)
933{
934 /**
935 * - add vport to fabric's vport_q
936 */
937 bfa_trc(fabric->fcs, fabric->vf_id);
938
939 list_add_tail(&vport->qe, &fabric->vport_q);
940 fabric->num_vports++;
941 bfa_wc_up(&fabric->wc);
942}
943
944/**
945 * A child vport is being deleted from fabric.
946 *
947 * Vport is being deleted.
948 */
949void
950bfa_fcs_fabric_delvport(struct bfa_fcs_fabric_s *fabric,
951 struct bfa_fcs_vport_s *vport)
952{
953 list_del(&vport->qe);
954 fabric->num_vports--;
955 bfa_wc_down(&fabric->wc);
956}
957
958/**
959 * Base port is deleted.
960 */
961void
962bfa_fcs_fabric_port_delete_comp(struct bfa_fcs_fabric_s *fabric)
963{
964 bfa_wc_down(&fabric->wc);
965}
966
967/**
968 * Check if fabric is online.
969 *
970 * param[in] fabric - Fabric instance. This can be a base fabric or vf.
971 *
972 * @return TRUE/FALSE
973 */
974int
975bfa_fcs_fabric_is_online(struct bfa_fcs_fabric_s *fabric)
976{
977 return (bfa_sm_cmp_state(fabric, bfa_fcs_fabric_sm_online));
978}
979
980
981bfa_status_t
982bfa_fcs_fabric_addvf(struct bfa_fcs_fabric_s *vf, struct bfa_fcs_s *fcs,
983 struct bfa_port_cfg_s *port_cfg,
984 struct bfad_vf_s *vf_drv)
985{
986 bfa_sm_set_state(vf, bfa_fcs_fabric_sm_uninit);
987 return BFA_STATUS_OK;
988}
989
990/**
991 * Lookup for a vport withing a fabric given its pwwn
992 */
993struct bfa_fcs_vport_s *
994bfa_fcs_fabric_vport_lookup(struct bfa_fcs_fabric_s *fabric, wwn_t pwwn)
995{
996 struct bfa_fcs_vport_s *vport;
997 struct list_head *qe;
998
999 list_for_each(qe, &fabric->vport_q) {
1000 vport = (struct bfa_fcs_vport_s *)qe;
1001 if (bfa_fcs_port_get_pwwn(&vport->lport) == pwwn)
1002 return vport;
1003 }
1004
1005 return NULL;
1006}
1007
1008/**
1009 * In a given fabric, return the number of lports.
1010 *
1011 * param[in] fabric - Fabric instance. This can be a base fabric or vf.
1012 *
1013* @return : 1 or more.
1014 */
1015u16
1016bfa_fcs_fabric_vport_count(struct bfa_fcs_fabric_s *fabric)
1017{
1018 return (fabric->num_vports);
1019}
1020
1021/**
1022 * Unsolicited frame receive handling.
1023 */
1024void
1025bfa_fcs_fabric_uf_recv(struct bfa_fcs_fabric_s *fabric, struct fchs_s *fchs,
1026 u16 len)
1027{
1028 u32 pid = fchs->d_id;
1029 struct bfa_fcs_vport_s *vport;
1030 struct list_head *qe;
1031 struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
1032 struct fc_logi_s *flogi = (struct fc_logi_s *) els_cmd;
1033
1034 bfa_trc(fabric->fcs, len);
1035 bfa_trc(fabric->fcs, pid);
1036
1037 /**
1038 * Look for our own FLOGI frames being looped back. This means an
1039 * external loopback cable is in place. Our own FLOGI frames are
1040 * sometimes looped back when switch port gets temporarily bypassed.
1041 */
1042 if ((pid == bfa_os_ntoh3b(FC_FABRIC_PORT))
1043 && (els_cmd->els_code == FC_ELS_FLOGI)
1044 && (flogi->port_name == bfa_fcs_port_get_pwwn(&fabric->bport))) {
1045 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_LOOPBACK);
1046 return;
1047 }
1048
1049 /**
1050 * FLOGI/EVFP exchanges should be consumed by base fabric.
1051 */
1052 if (fchs->d_id == bfa_os_hton3b(FC_FABRIC_PORT)) {
1053 bfa_trc(fabric->fcs, pid);
1054 bfa_fcs_fabric_process_uf(fabric, fchs, len);
1055 return;
1056 }
1057
1058 if (fabric->bport.pid == pid) {
1059 /**
1060 * All authentication frames should be routed to auth
1061 */
1062 bfa_trc(fabric->fcs, els_cmd->els_code);
1063 if (els_cmd->els_code == FC_ELS_AUTH) {
1064 bfa_trc(fabric->fcs, els_cmd->els_code);
1065 fabric->auth.response = (u8 *) els_cmd;
1066 return;
1067 }
1068
1069 bfa_trc(fabric->fcs, *(u8 *) ((u8 *) fchs));
1070 bfa_fcs_port_uf_recv(&fabric->bport, fchs, len);
1071 return;
1072 }
1073
1074 /**
1075 * look for a matching local port ID
1076 */
1077 list_for_each(qe, &fabric->vport_q) {
1078 vport = (struct bfa_fcs_vport_s *)qe;
1079 if (vport->lport.pid == pid) {
1080 bfa_fcs_port_uf_recv(&vport->lport, fchs, len);
1081 return;
1082 }
1083 }
1084 bfa_trc(fabric->fcs, els_cmd->els_code);
1085 bfa_fcs_port_uf_recv(&fabric->bport, fchs, len);
1086}
1087
1088/**
1089 * Unsolicited frames to be processed by fabric.
1090 */
1091static void
1092bfa_fcs_fabric_process_uf(struct bfa_fcs_fabric_s *fabric, struct fchs_s *fchs,
1093 u16 len)
1094{
1095 struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
1096
1097 bfa_trc(fabric->fcs, els_cmd->els_code);
1098
1099 switch (els_cmd->els_code) {
1100 case FC_ELS_FLOGI:
1101 bfa_fcs_fabric_process_flogi(fabric, fchs, len);
1102 break;
1103
1104 default:
1105 /*
1106 * need to generate a LS_RJT
1107 */
1108 break;
1109 }
1110}
1111
1112/**
1113 * Process incoming FLOGI
1114 */
1115static void
1116bfa_fcs_fabric_process_flogi(struct bfa_fcs_fabric_s *fabric,
1117 struct fchs_s *fchs, u16 len)
1118{
1119 struct fc_logi_s *flogi = (struct fc_logi_s *) (fchs + 1);
1120 struct bfa_fcs_port_s *bport = &fabric->bport;
1121
1122 bfa_trc(fabric->fcs, fchs->s_id);
1123
1124 fabric->stats.flogi_rcvd++;
1125 /*
1126 * Check port type. It should be 0 = n-port.
1127 */
1128 if (flogi->csp.port_type) {
1129 /*
1130 * @todo: may need to send a LS_RJT
1131 */
1132 bfa_trc(fabric->fcs, flogi->port_name);
1133 fabric->stats.flogi_rejected++;
1134 return;
1135 }
1136
1137 fabric->bb_credit = bfa_os_ntohs(flogi->csp.bbcred);
1138 bport->port_topo.pn2n.rem_port_wwn = flogi->port_name;
1139 bport->port_topo.pn2n.reply_oxid = fchs->ox_id;
1140
1141 /*
1142 * Send a Flogi Acc
1143 */
1144 bfa_fcs_fabric_send_flogi_acc(fabric);
1145 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_NO_FABRIC);
1146}
1147
1148static void
1149bfa_fcs_fabric_send_flogi_acc(struct bfa_fcs_fabric_s *fabric)
1150{
1151 struct bfa_port_cfg_s *pcfg = &fabric->bport.port_cfg;
1152 struct bfa_fcs_port_n2n_s *n2n_port = &fabric->bport.port_topo.pn2n;
1153 struct bfa_s *bfa = fabric->fcs->bfa;
1154 struct bfa_fcxp_s *fcxp;
1155 u16 reqlen;
1156 struct fchs_s fchs;
1157
1158 fcxp = bfa_fcs_fcxp_alloc(fabric->fcs);
1159 /**
1160 * Do not expect this failure -- expect remote node to retry
1161 */
1162 if (!fcxp)
1163 return;
1164
1165 reqlen = fc_flogi_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1166 bfa_os_hton3b(FC_FABRIC_PORT),
1167 n2n_port->reply_oxid, pcfg->pwwn,
1168 pcfg->nwwn, bfa_pport_get_maxfrsize(bfa),
1169 bfa_pport_get_rx_bbcredit(bfa));
1170
1171 bfa_fcxp_send(fcxp, NULL, fabric->vf_id, bfa_lps_get_tag(fabric->lps),
1172 BFA_FALSE, FC_CLASS_3, reqlen, &fchs,
1173 bfa_fcs_fabric_flogiacc_comp, fabric,
1174 FC_MAX_PDUSZ, 0); /* Timeout 0 indicates no
1175 * response expected
1176 */
1177}
1178
1179/**
1180 * Flogi Acc completion callback.
1181 */
1182static void
1183bfa_fcs_fabric_flogiacc_comp(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
1184 bfa_status_t status, u32 rsp_len,
1185 u32 resid_len, struct fchs_s *rspfchs)
1186{
1187 struct bfa_fcs_fabric_s *fabric = cbarg;
1188
1189 bfa_trc(fabric->fcs, status);
1190}
1191
1192/*
1193 *
1194 * @param[in] fabric - fabric
1195 * @param[in] result - 1
1196 *
1197 * @return - none
1198 */
1199void
1200bfa_fcs_auth_finished(struct bfa_fcs_fabric_s *fabric, enum auth_status status)
1201{
1202 bfa_trc(fabric->fcs, status);
1203
1204 if (status == FC_AUTH_STATE_SUCCESS)
1205 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_AUTH_SUCCESS);
1206 else
1207 bfa_sm_send_event(fabric, BFA_FCS_FABRIC_SM_AUTH_FAILED);
1208}
1209
1210/**
1211 * Send AEN notification
1212 */
1213static void
1214bfa_fcs_fabric_aen_post(struct bfa_fcs_port_s *port,
1215 enum bfa_port_aen_event event)
1216{
1217 union bfa_aen_data_u aen_data;
1218 struct bfa_log_mod_s *logmod = port->fcs->logm;
1219 wwn_t pwwn = bfa_fcs_port_get_pwwn(port);
1220 wwn_t fwwn = bfa_fcs_port_get_fabric_name(port);
1221 char pwwn_ptr[BFA_STRING_32];
1222 char fwwn_ptr[BFA_STRING_32];
1223
1224 wwn2str(pwwn_ptr, pwwn);
1225 wwn2str(fwwn_ptr, fwwn);
1226
1227 switch (event) {
1228 case BFA_PORT_AEN_FABRIC_NAME_CHANGE:
1229 bfa_log(logmod, BFA_AEN_PORT_FABRIC_NAME_CHANGE, pwwn_ptr,
1230 fwwn_ptr);
1231 break;
1232 default:
1233 break;
1234 }
1235
1236 aen_data.port.pwwn = pwwn;
1237 aen_data.port.fwwn = fwwn;
1238}
1239
1240/*
1241 *
1242 * @param[in] fabric - fabric
1243 * @param[in] wwn_t - new fabric name
1244 *
1245 * @return - none
1246 */
1247void
1248bfa_fcs_fabric_set_fabric_name(struct bfa_fcs_fabric_s *fabric,
1249 wwn_t fabric_name)
1250{
1251 bfa_trc(fabric->fcs, fabric_name);
1252
1253 if (fabric->fabric_name == 0) {
1254 /*
1255 * With BRCD switches, we don't get Fabric Name in FLOGI.
1256 * Don't generate a fabric name change event in this case.
1257 */
1258 fabric->fabric_name = fabric_name;
1259 } else {
1260 fabric->fabric_name = fabric_name;
1261 /*
1262 * Generate a Event
1263 */
1264 bfa_fcs_fabric_aen_post(&fabric->bport,
1265 BFA_PORT_AEN_FABRIC_NAME_CHANGE);
1266 }
1267
1268}
1269
1270/**
1271 * Not used by FCS.
1272 */
1273void
1274bfa_cb_lps_flogo_comp(void *bfad, void *uarg)
1275{
1276}
1277
1278
diff --git a/drivers/scsi/bfa/fcbuild.c b/drivers/scsi/bfa/fcbuild.c
new file mode 100644
index 000000000000..d174706b9caa
--- /dev/null
+++ b/drivers/scsi/bfa/fcbuild.c
@@ -0,0 +1,1449 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17/*
18 * fcbuild.c - FC link service frame building and parsing routines
19 */
20
21#include <bfa_os_inc.h>
22#include "fcbuild.h"
23
24/*
25 * static build functions
26 */
27static void fc_els_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
28 u16 ox_id);
29static void fc_bls_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
30 u16 ox_id);
31static struct fchs_s fc_els_req_tmpl;
32static struct fchs_s fc_els_rsp_tmpl;
33static struct fchs_s fc_bls_req_tmpl;
34static struct fchs_s fc_bls_rsp_tmpl;
35static struct fc_ba_acc_s ba_acc_tmpl;
36static struct fc_logi_s plogi_tmpl;
37static struct fc_prli_s prli_tmpl;
38static struct fc_rrq_s rrq_tmpl;
39static struct fchs_s fcp_fchs_tmpl;
40
41void
42fcbuild_init(void)
43{
44 /*
45 * fc_els_req_tmpl
46 */
47 fc_els_req_tmpl.routing = FC_RTG_EXT_LINK;
48 fc_els_req_tmpl.cat_info = FC_CAT_LD_REQUEST;
49 fc_els_req_tmpl.type = FC_TYPE_ELS;
50 fc_els_req_tmpl.f_ctl =
51 bfa_os_hton3b(FCTL_SEQ_INI | FCTL_FS_EXCH | FCTL_END_SEQ |
52 FCTL_SI_XFER);
53 fc_els_req_tmpl.rx_id = FC_RXID_ANY;
54
55 /*
56 * fc_els_rsp_tmpl
57 */
58 fc_els_rsp_tmpl.routing = FC_RTG_EXT_LINK;
59 fc_els_rsp_tmpl.cat_info = FC_CAT_LD_REPLY;
60 fc_els_rsp_tmpl.type = FC_TYPE_ELS;
61 fc_els_rsp_tmpl.f_ctl =
62 bfa_os_hton3b(FCTL_EC_RESP | FCTL_SEQ_INI | FCTL_LS_EXCH |
63 FCTL_END_SEQ | FCTL_SI_XFER);
64 fc_els_rsp_tmpl.rx_id = FC_RXID_ANY;
65
66 /*
67 * fc_bls_req_tmpl
68 */
69 fc_bls_req_tmpl.routing = FC_RTG_BASIC_LINK;
70 fc_bls_req_tmpl.type = FC_TYPE_BLS;
71 fc_bls_req_tmpl.f_ctl = bfa_os_hton3b(FCTL_END_SEQ | FCTL_SI_XFER);
72 fc_bls_req_tmpl.rx_id = FC_RXID_ANY;
73
74 /*
75 * fc_bls_rsp_tmpl
76 */
77 fc_bls_rsp_tmpl.routing = FC_RTG_BASIC_LINK;
78 fc_bls_rsp_tmpl.cat_info = FC_CAT_BA_ACC;
79 fc_bls_rsp_tmpl.type = FC_TYPE_BLS;
80 fc_bls_rsp_tmpl.f_ctl =
81 bfa_os_hton3b(FCTL_EC_RESP | FCTL_SEQ_INI | FCTL_LS_EXCH |
82 FCTL_END_SEQ | FCTL_SI_XFER);
83 fc_bls_rsp_tmpl.rx_id = FC_RXID_ANY;
84
85 /*
86 * ba_acc_tmpl
87 */
88 ba_acc_tmpl.seq_id_valid = 0;
89 ba_acc_tmpl.low_seq_cnt = 0;
90 ba_acc_tmpl.high_seq_cnt = 0xFFFF;
91
92 /*
93 * plogi_tmpl
94 */
95 plogi_tmpl.csp.verhi = FC_PH_VER_PH_3;
96 plogi_tmpl.csp.verlo = FC_PH_VER_4_3;
97 plogi_tmpl.csp.bbcred = bfa_os_htons(0x0004);
98 plogi_tmpl.csp.ciro = 0x1;
99 plogi_tmpl.csp.cisc = 0x0;
100 plogi_tmpl.csp.altbbcred = 0x0;
101 plogi_tmpl.csp.conseq = bfa_os_htons(0x00FF);
102 plogi_tmpl.csp.ro_bitmap = bfa_os_htons(0x0002);
103 plogi_tmpl.csp.e_d_tov = bfa_os_htonl(2000);
104
105 plogi_tmpl.class3.class_valid = 1;
106 plogi_tmpl.class3.sequential = 1;
107 plogi_tmpl.class3.conseq = 0xFF;
108 plogi_tmpl.class3.ospx = 1;
109
110 /*
111 * prli_tmpl
112 */
113 prli_tmpl.command = FC_ELS_PRLI;
114 prli_tmpl.pglen = 0x10;
115 prli_tmpl.pagebytes = bfa_os_htons(0x0014);
116 prli_tmpl.parampage.type = FC_TYPE_FCP;
117 prli_tmpl.parampage.imagepair = 1;
118 prli_tmpl.parampage.servparams.rxrdisab = 1;
119
120 /*
121 * rrq_tmpl
122 */
123 rrq_tmpl.els_cmd.els_code = FC_ELS_RRQ;
124
125 /*
126 * fcp_fchs_tmpl
127 */
128 fcp_fchs_tmpl.routing = FC_RTG_FC4_DEV_DATA;
129 fcp_fchs_tmpl.cat_info = FC_CAT_UNSOLICIT_CMD;
130 fcp_fchs_tmpl.type = FC_TYPE_FCP;
131 fcp_fchs_tmpl.f_ctl =
132 bfa_os_hton3b(FCTL_FS_EXCH | FCTL_END_SEQ | FCTL_SI_XFER);
133 fcp_fchs_tmpl.seq_id = 1;
134 fcp_fchs_tmpl.rx_id = FC_RXID_ANY;
135}
136
137static void
138fc_gs_fchdr_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
139 u32 ox_id)
140{
141 bfa_os_memset(fchs, 0, sizeof(struct fchs_s));
142
143 fchs->routing = FC_RTG_FC4_DEV_DATA;
144 fchs->cat_info = FC_CAT_UNSOLICIT_CTRL;
145 fchs->type = FC_TYPE_SERVICES;
146 fchs->f_ctl =
147 bfa_os_hton3b(FCTL_SEQ_INI | FCTL_FS_EXCH | FCTL_END_SEQ |
148 FCTL_SI_XFER);
149 fchs->rx_id = FC_RXID_ANY;
150 fchs->d_id = (d_id);
151 fchs->s_id = (s_id);
152 fchs->ox_id = bfa_os_htons(ox_id);
153
154 /**
155 * @todo no need to set ox_id for request
156 * no need to set rx_id for response
157 */
158}
159
160void
161fc_els_req_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
162 u16 ox_id)
163{
164 bfa_os_memcpy(fchs, &fc_els_req_tmpl, sizeof(struct fchs_s));
165 fchs->d_id = (d_id);
166 fchs->s_id = (s_id);
167 fchs->ox_id = bfa_os_htons(ox_id);
168}
169
170static void
171fc_els_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
172 u16 ox_id)
173{
174 bfa_os_memcpy(fchs, &fc_els_rsp_tmpl, sizeof(struct fchs_s));
175 fchs->d_id = d_id;
176 fchs->s_id = s_id;
177 fchs->ox_id = ox_id;
178}
179
180enum fc_parse_status
181fc_els_rsp_parse(struct fchs_s *fchs, int len)
182{
183 struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
184 struct fc_ls_rjt_s *ls_rjt = (struct fc_ls_rjt_s *) els_cmd;
185
186 len = len;
187
188 switch (els_cmd->els_code) {
189 case FC_ELS_LS_RJT:
190 if (ls_rjt->reason_code == FC_LS_RJT_RSN_LOGICAL_BUSY)
191 return (FC_PARSE_BUSY);
192 else
193 return (FC_PARSE_FAILURE);
194
195 case FC_ELS_ACC:
196 return (FC_PARSE_OK);
197 }
198 return (FC_PARSE_OK);
199}
200
201static void
202fc_bls_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
203 u16 ox_id)
204{
205 bfa_os_memcpy(fchs, &fc_bls_rsp_tmpl, sizeof(struct fchs_s));
206 fchs->d_id = d_id;
207 fchs->s_id = s_id;
208 fchs->ox_id = ox_id;
209}
210
211static u16
212fc_plogi_x_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
213 u16 ox_id, wwn_t port_name, wwn_t node_name,
214 u16 pdu_size, u8 els_code)
215{
216 struct fc_logi_s *plogi = (struct fc_logi_s *) (pld);
217
218 bfa_os_memcpy(plogi, &plogi_tmpl, sizeof(struct fc_logi_s));
219
220 plogi->els_cmd.els_code = els_code;
221 if (els_code == FC_ELS_PLOGI)
222 fc_els_req_build(fchs, d_id, s_id, ox_id);
223 else
224 fc_els_rsp_build(fchs, d_id, s_id, ox_id);
225
226 plogi->csp.rxsz = plogi->class3.rxsz = bfa_os_htons(pdu_size);
227
228 bfa_os_memcpy(&plogi->port_name, &port_name, sizeof(wwn_t));
229 bfa_os_memcpy(&plogi->node_name, &node_name, sizeof(wwn_t));
230
231 return (sizeof(struct fc_logi_s));
232}
233
234u16
235fc_flogi_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id,
236 u16 ox_id, wwn_t port_name, wwn_t node_name,
237 u16 pdu_size, u8 set_npiv, u8 set_auth,
238 u16 local_bb_credits)
239{
240 u32 d_id = bfa_os_hton3b(FC_FABRIC_PORT);
241 u32 *vvl_info;
242
243 bfa_os_memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s));
244
245 flogi->els_cmd.els_code = FC_ELS_FLOGI;
246 fc_els_req_build(fchs, d_id, s_id, ox_id);
247
248 flogi->csp.rxsz = flogi->class3.rxsz = bfa_os_htons(pdu_size);
249 flogi->port_name = port_name;
250 flogi->node_name = node_name;
251
252 /*
253 * Set the NPIV Capability Bit ( word 1, bit 31) of Common
254 * Service Parameters.
255 */
256 flogi->csp.ciro = set_npiv;
257
258 /* set AUTH capability */
259 flogi->csp.security = set_auth;
260
261 flogi->csp.bbcred = bfa_os_htons(local_bb_credits);
262
263 /* Set brcd token in VVL */
264 vvl_info = (u32 *)&flogi->vvl[0];
265
266 /* set the flag to indicate the presence of VVL */
267 flogi->csp.npiv_supp = 1; /* @todo. field name is not correct */
268 vvl_info[0] = bfa_os_htonl(FLOGI_VVL_BRCD);
269
270 return (sizeof(struct fc_logi_s));
271}
272
273u16
274fc_flogi_acc_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id,
275 u16 ox_id, wwn_t port_name, wwn_t node_name,
276 u16 pdu_size, u16 local_bb_credits)
277{
278 u32 d_id = 0;
279
280 bfa_os_memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s));
281 fc_els_rsp_build(fchs, d_id, s_id, ox_id);
282
283 flogi->els_cmd.els_code = FC_ELS_ACC;
284 flogi->csp.rxsz = flogi->class3.rxsz = bfa_os_htons(pdu_size);
285 flogi->port_name = port_name;
286 flogi->node_name = node_name;
287
288 flogi->csp.bbcred = bfa_os_htons(local_bb_credits);
289
290 return (sizeof(struct fc_logi_s));
291}
292
293u16
294fc_fdisc_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id,
295 u16 ox_id, wwn_t port_name, wwn_t node_name,
296 u16 pdu_size)
297{
298 u32 d_id = bfa_os_hton3b(FC_FABRIC_PORT);
299
300 bfa_os_memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s));
301
302 flogi->els_cmd.els_code = FC_ELS_FDISC;
303 fc_els_req_build(fchs, d_id, s_id, ox_id);
304
305 flogi->csp.rxsz = flogi->class3.rxsz = bfa_os_htons(pdu_size);
306 flogi->port_name = port_name;
307 flogi->node_name = node_name;
308
309 return (sizeof(struct fc_logi_s));
310}
311
312u16
313fc_plogi_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
314 u16 ox_id, wwn_t port_name, wwn_t node_name,
315 u16 pdu_size)
316{
317 return fc_plogi_x_build(fchs, pld, d_id, s_id, ox_id, port_name,
318 node_name, pdu_size, FC_ELS_PLOGI);
319}
320
321u16
322fc_plogi_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
323 u16 ox_id, wwn_t port_name, wwn_t node_name,
324 u16 pdu_size)
325{
326 return fc_plogi_x_build(fchs, pld, d_id, s_id, ox_id, port_name,
327 node_name, pdu_size, FC_ELS_ACC);
328}
329
330enum fc_parse_status
331fc_plogi_rsp_parse(struct fchs_s *fchs, int len, wwn_t port_name)
332{
333 struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
334 struct fc_logi_s *plogi;
335 struct fc_ls_rjt_s *ls_rjt;
336
337 switch (els_cmd->els_code) {
338 case FC_ELS_LS_RJT:
339 ls_rjt = (struct fc_ls_rjt_s *) (fchs + 1);
340 if (ls_rjt->reason_code == FC_LS_RJT_RSN_LOGICAL_BUSY)
341 return (FC_PARSE_BUSY);
342 else
343 return (FC_PARSE_FAILURE);
344 case FC_ELS_ACC:
345 plogi = (struct fc_logi_s *) (fchs + 1);
346 if (len < sizeof(struct fc_logi_s))
347 return (FC_PARSE_FAILURE);
348
349 if (!wwn_is_equal(plogi->port_name, port_name))
350 return (FC_PARSE_FAILURE);
351
352 if (!plogi->class3.class_valid)
353 return (FC_PARSE_FAILURE);
354
355 if (bfa_os_ntohs(plogi->class3.rxsz) < (FC_MIN_PDUSZ))
356 return (FC_PARSE_FAILURE);
357
358 return (FC_PARSE_OK);
359 default:
360 return (FC_PARSE_FAILURE);
361 }
362}
363
364enum fc_parse_status
365fc_plogi_parse(struct fchs_s *fchs)
366{
367 struct fc_logi_s *plogi = (struct fc_logi_s *) (fchs + 1);
368
369 if (plogi->class3.class_valid != 1)
370 return FC_PARSE_FAILURE;
371
372 if ((bfa_os_ntohs(plogi->class3.rxsz) < FC_MIN_PDUSZ)
373 || (bfa_os_ntohs(plogi->class3.rxsz) > FC_MAX_PDUSZ)
374 || (plogi->class3.rxsz == 0))
375 return (FC_PARSE_FAILURE);
376
377 return FC_PARSE_OK;
378}
379
380u16
381fc_prli_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
382 u16 ox_id)
383{
384 struct fc_prli_s *prli = (struct fc_prli_s *) (pld);
385
386 fc_els_req_build(fchs, d_id, s_id, ox_id);
387 bfa_os_memcpy(prli, &prli_tmpl, sizeof(struct fc_prli_s));
388
389 prli->command = FC_ELS_PRLI;
390 prli->parampage.servparams.initiator = 1;
391 prli->parampage.servparams.retry = 1;
392 prli->parampage.servparams.rec_support = 1;
393 prli->parampage.servparams.task_retry_id = 0;
394 prli->parampage.servparams.confirm = 1;
395
396 return (sizeof(struct fc_prli_s));
397}
398
399u16
400fc_prli_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
401 u16 ox_id, enum bfa_port_role role)
402{
403 struct fc_prli_s *prli = (struct fc_prli_s *) (pld);
404
405 fc_els_rsp_build(fchs, d_id, s_id, ox_id);
406 bfa_os_memcpy(prli, &prli_tmpl, sizeof(struct fc_prli_s));
407
408 prli->command = FC_ELS_ACC;
409
410 if ((role & BFA_PORT_ROLE_FCP_TM) == BFA_PORT_ROLE_FCP_TM)
411 prli->parampage.servparams.target = 1;
412 else
413 prli->parampage.servparams.initiator = 1;
414
415 prli->parampage.rspcode = FC_PRLI_ACC_XQTD;
416
417 return (sizeof(struct fc_prli_s));
418}
419
420enum fc_parse_status
421fc_prli_rsp_parse(struct fc_prli_s *prli, int len)
422{
423 if (len < sizeof(struct fc_prli_s))
424 return (FC_PARSE_FAILURE);
425
426 if (prli->command != FC_ELS_ACC)
427 return (FC_PARSE_FAILURE);
428
429 if ((prli->parampage.rspcode != FC_PRLI_ACC_XQTD)
430 && (prli->parampage.rspcode != FC_PRLI_ACC_PREDEF_IMG))
431 return (FC_PARSE_FAILURE);
432
433 if (prli->parampage.servparams.target != 1)
434 return (FC_PARSE_FAILURE);
435
436 return (FC_PARSE_OK);
437}
438
439enum fc_parse_status
440fc_prli_parse(struct fc_prli_s *prli)
441{
442 if (prli->parampage.type != FC_TYPE_FCP)
443 return (FC_PARSE_FAILURE);
444
445 if (!prli->parampage.imagepair)
446 return (FC_PARSE_FAILURE);
447
448 if (!prli->parampage.servparams.initiator)
449 return (FC_PARSE_FAILURE);
450
451 return (FC_PARSE_OK);
452}
453
454u16
455fc_logo_build(struct fchs_s *fchs, struct fc_logo_s *logo, u32 d_id,
456 u32 s_id, u16 ox_id, wwn_t port_name)
457{
458 fc_els_req_build(fchs, d_id, s_id, ox_id);
459
460 memset(logo, '\0', sizeof(struct fc_logo_s));
461 logo->els_cmd.els_code = FC_ELS_LOGO;
462 logo->nport_id = (s_id);
463 logo->orig_port_name = port_name;
464
465 return (sizeof(struct fc_logo_s));
466}
467
468static u16
469fc_adisc_x_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id,
470 u32 s_id, u16 ox_id, wwn_t port_name,
471 wwn_t node_name, u8 els_code)
472{
473 memset(adisc, '\0', sizeof(struct fc_adisc_s));
474
475 adisc->els_cmd.els_code = els_code;
476
477 if (els_code == FC_ELS_ADISC)
478 fc_els_req_build(fchs, d_id, s_id, ox_id);
479 else
480 fc_els_rsp_build(fchs, d_id, s_id, ox_id);
481
482 adisc->orig_HA = 0;
483 adisc->orig_port_name = port_name;
484 adisc->orig_node_name = node_name;
485 adisc->nport_id = (s_id);
486
487 return (sizeof(struct fc_adisc_s));
488}
489
490u16
491fc_adisc_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id,
492 u32 s_id, u16 ox_id, wwn_t port_name,
493 wwn_t node_name)
494{
495 return fc_adisc_x_build(fchs, adisc, d_id, s_id, ox_id, port_name,
496 node_name, FC_ELS_ADISC);
497}
498
499u16
500fc_adisc_acc_build(struct fchs_s *fchs, struct fc_adisc_s *adisc, u32 d_id,
501 u32 s_id, u16 ox_id, wwn_t port_name,
502 wwn_t node_name)
503{
504 return fc_adisc_x_build(fchs, adisc, d_id, s_id, ox_id, port_name,
505 node_name, FC_ELS_ACC);
506}
507
508enum fc_parse_status
509fc_adisc_rsp_parse(struct fc_adisc_s *adisc, int len, wwn_t port_name,
510 wwn_t node_name)
511{
512
513 if (len < sizeof(struct fc_adisc_s))
514 return (FC_PARSE_FAILURE);
515
516 if (adisc->els_cmd.els_code != FC_ELS_ACC)
517 return (FC_PARSE_FAILURE);
518
519 if (!wwn_is_equal(adisc->orig_port_name, port_name))
520 return (FC_PARSE_FAILURE);
521
522 return (FC_PARSE_OK);
523}
524
525enum fc_parse_status
526fc_adisc_parse(struct fchs_s *fchs, void *pld, u32 host_dap,
527 wwn_t node_name, wwn_t port_name)
528{
529 struct fc_adisc_s *adisc = (struct fc_adisc_s *) pld;
530
531 if (adisc->els_cmd.els_code != FC_ELS_ACC)
532 return (FC_PARSE_FAILURE);
533
534 if ((adisc->nport_id == (host_dap))
535 && wwn_is_equal(adisc->orig_port_name, port_name)
536 && wwn_is_equal(adisc->orig_node_name, node_name))
537 return (FC_PARSE_OK);
538
539 return (FC_PARSE_FAILURE);
540}
541
542enum fc_parse_status
543fc_pdisc_parse(struct fchs_s *fchs, wwn_t node_name, wwn_t port_name)
544{
545 struct fc_logi_s *pdisc = (struct fc_logi_s *) (fchs + 1);
546
547 if (pdisc->class3.class_valid != 1)
548 return FC_PARSE_FAILURE;
549
550 if ((bfa_os_ntohs(pdisc->class3.rxsz) <
551 (FC_MIN_PDUSZ - sizeof(struct fchs_s)))
552 || (pdisc->class3.rxsz == 0))
553 return (FC_PARSE_FAILURE);
554
555 if (!wwn_is_equal(pdisc->port_name, port_name))
556 return (FC_PARSE_FAILURE);
557
558 if (!wwn_is_equal(pdisc->node_name, node_name))
559 return (FC_PARSE_FAILURE);
560
561 return FC_PARSE_OK;
562}
563
564u16
565fc_abts_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id)
566{
567 bfa_os_memcpy(fchs, &fc_bls_req_tmpl, sizeof(struct fchs_s));
568 fchs->cat_info = FC_CAT_ABTS;
569 fchs->d_id = (d_id);
570 fchs->s_id = (s_id);
571 fchs->ox_id = bfa_os_htons(ox_id);
572
573 return (sizeof(struct fchs_s));
574}
575
576enum fc_parse_status
577fc_abts_rsp_parse(struct fchs_s *fchs, int len)
578{
579 if ((fchs->cat_info == FC_CAT_BA_ACC)
580 || (fchs->cat_info == FC_CAT_BA_RJT))
581 return (FC_PARSE_OK);
582
583 return (FC_PARSE_FAILURE);
584}
585
586u16
587fc_rrq_build(struct fchs_s *fchs, struct fc_rrq_s *rrq, u32 d_id,
588 u32 s_id, u16 ox_id, u16 rrq_oxid)
589{
590 fc_els_req_build(fchs, d_id, s_id, ox_id);
591
592 /*
593 * build rrq payload
594 */
595 bfa_os_memcpy(rrq, &rrq_tmpl, sizeof(struct fc_rrq_s));
596 rrq->s_id = (s_id);
597 rrq->ox_id = bfa_os_htons(rrq_oxid);
598 rrq->rx_id = FC_RXID_ANY;
599
600 return (sizeof(struct fc_rrq_s));
601}
602
603u16
604fc_logo_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id,
605 u16 ox_id)
606{
607 struct fc_els_cmd_s *acc = pld;
608
609 fc_els_rsp_build(fchs, d_id, s_id, ox_id);
610
611 memset(acc, 0, sizeof(struct fc_els_cmd_s));
612 acc->els_code = FC_ELS_ACC;
613
614 return (sizeof(struct fc_els_cmd_s));
615}
616
617u16
618fc_ls_rjt_build(struct fchs_s *fchs, struct fc_ls_rjt_s *ls_rjt, u32 d_id,
619 u32 s_id, u16 ox_id, u8 reason_code,
620 u8 reason_code_expl)
621{
622 fc_els_rsp_build(fchs, d_id, s_id, ox_id);
623 memset(ls_rjt, 0, sizeof(struct fc_ls_rjt_s));
624
625 ls_rjt->els_cmd.els_code = FC_ELS_LS_RJT;
626 ls_rjt->reason_code = reason_code;
627 ls_rjt->reason_code_expl = reason_code_expl;
628 ls_rjt->vendor_unique = 0x00;
629
630 return (sizeof(struct fc_ls_rjt_s));
631}
632
633u16
634fc_ba_acc_build(struct fchs_s *fchs, struct fc_ba_acc_s *ba_acc, u32 d_id,
635 u32 s_id, u16 ox_id, u16 rx_id)
636{
637 fc_bls_rsp_build(fchs, d_id, s_id, ox_id);
638
639 bfa_os_memcpy(ba_acc, &ba_acc_tmpl, sizeof(struct fc_ba_acc_s));
640
641 fchs->rx_id = rx_id;
642
643 ba_acc->ox_id = fchs->ox_id;
644 ba_acc->rx_id = fchs->rx_id;
645
646 return (sizeof(struct fc_ba_acc_s));
647}
648
649u16
650fc_ls_acc_build(struct fchs_s *fchs, struct fc_els_cmd_s *els_cmd,
651 u32 d_id, u32 s_id, u16 ox_id)
652{
653 fc_els_rsp_build(fchs, d_id, s_id, ox_id);
654 memset(els_cmd, 0, sizeof(struct fc_els_cmd_s));
655 els_cmd->els_code = FC_ELS_ACC;
656
657 return (sizeof(struct fc_els_cmd_s));
658}
659
660int
661fc_logout_params_pages(struct fchs_s *fc_frame, u8 els_code)
662{
663 int num_pages = 0;
664 struct fc_prlo_s *prlo;
665 struct fc_tprlo_s *tprlo;
666
667 if (els_code == FC_ELS_PRLO) {
668 prlo = (struct fc_prlo_s *) (fc_frame + 1);
669 num_pages = (bfa_os_ntohs(prlo->payload_len) - 4) / 16;
670 } else {
671 tprlo = (struct fc_tprlo_s *) (fc_frame + 1);
672 num_pages = (bfa_os_ntohs(tprlo->payload_len) - 4) / 16;
673 }
674 return num_pages;
675}
676
677u16
678fc_tprlo_acc_build(struct fchs_s *fchs, struct fc_tprlo_acc_s *tprlo_acc,
679 u32 d_id, u32 s_id, u16 ox_id,
680 int num_pages)
681{
682 int page;
683
684 fc_els_rsp_build(fchs, d_id, s_id, ox_id);
685
686 memset(tprlo_acc, 0, (num_pages * 16) + 4);
687 tprlo_acc->command = FC_ELS_ACC;
688
689 tprlo_acc->page_len = 0x10;
690 tprlo_acc->payload_len = bfa_os_htons((num_pages * 16) + 4);
691
692 for (page = 0; page < num_pages; page++) {
693 tprlo_acc->tprlo_acc_params[page].opa_valid = 0;
694 tprlo_acc->tprlo_acc_params[page].rpa_valid = 0;
695 tprlo_acc->tprlo_acc_params[page].fc4type_csp = FC_TYPE_FCP;
696 tprlo_acc->tprlo_acc_params[page].orig_process_assc = 0;
697 tprlo_acc->tprlo_acc_params[page].resp_process_assc = 0;
698 }
699 return (bfa_os_ntohs(tprlo_acc->payload_len));
700}
701
702u16
703fc_prlo_acc_build(struct fchs_s *fchs, struct fc_prlo_acc_s *prlo_acc,
704 u32 d_id, u32 s_id, u16 ox_id,
705 int num_pages)
706{
707 int page;
708
709 fc_els_rsp_build(fchs, d_id, s_id, ox_id);
710
711 memset(prlo_acc, 0, (num_pages * 16) + 4);
712 prlo_acc->command = FC_ELS_ACC;
713 prlo_acc->page_len = 0x10;
714 prlo_acc->payload_len = bfa_os_htons((num_pages * 16) + 4);
715
716 for (page = 0; page < num_pages; page++) {
717 prlo_acc->prlo_acc_params[page].opa_valid = 0;
718 prlo_acc->prlo_acc_params[page].rpa_valid = 0;
719 prlo_acc->prlo_acc_params[page].fc4type_csp = FC_TYPE_FCP;
720 prlo_acc->prlo_acc_params[page].orig_process_assc = 0;
721 prlo_acc->prlo_acc_params[page].resp_process_assc = 0;
722 }
723
724 return (bfa_os_ntohs(prlo_acc->payload_len));
725}
726
727u16
728fc_rnid_build(struct fchs_s *fchs, struct fc_rnid_cmd_s *rnid, u32 d_id,
729 u32 s_id, u16 ox_id, u32 data_format)
730{
731 fc_els_req_build(fchs, d_id, s_id, ox_id);
732
733 memset(rnid, 0, sizeof(struct fc_rnid_cmd_s));
734
735 rnid->els_cmd.els_code = FC_ELS_RNID;
736 rnid->node_id_data_format = data_format;
737
738 return (sizeof(struct fc_rnid_cmd_s));
739}
740
741u16
742fc_rnid_acc_build(struct fchs_s *fchs, struct fc_rnid_acc_s *rnid_acc,
743 u32 d_id, u32 s_id, u16 ox_id,
744 u32 data_format,
745 struct fc_rnid_common_id_data_s *common_id_data,
746 struct fc_rnid_general_topology_data_s *gen_topo_data)
747{
748 memset(rnid_acc, 0, sizeof(struct fc_rnid_acc_s));
749
750 fc_els_rsp_build(fchs, d_id, s_id, ox_id);
751
752 rnid_acc->els_cmd.els_code = FC_ELS_ACC;
753 rnid_acc->node_id_data_format = data_format;
754 rnid_acc->common_id_data_length =
755 sizeof(struct fc_rnid_common_id_data_s);
756 rnid_acc->common_id_data = *common_id_data;
757
758 if (data_format == RNID_NODEID_DATA_FORMAT_DISCOVERY) {
759 rnid_acc->specific_id_data_length =
760 sizeof(struct fc_rnid_general_topology_data_s);
761 bfa_os_assign(rnid_acc->gen_topology_data, *gen_topo_data);
762 return (sizeof(struct fc_rnid_acc_s));
763 } else {
764 return (sizeof(struct fc_rnid_acc_s) -
765 sizeof(struct fc_rnid_general_topology_data_s));
766 }
767
768}
769
770u16
771fc_rpsc_build(struct fchs_s *fchs, struct fc_rpsc_cmd_s *rpsc, u32 d_id,
772 u32 s_id, u16 ox_id)
773{
774 fc_els_req_build(fchs, d_id, s_id, ox_id);
775
776 memset(rpsc, 0, sizeof(struct fc_rpsc_cmd_s));
777
778 rpsc->els_cmd.els_code = FC_ELS_RPSC;
779 return (sizeof(struct fc_rpsc_cmd_s));
780}
781
782u16
783fc_rpsc2_build(struct fchs_s *fchs, struct fc_rpsc2_cmd_s *rpsc2,
784 u32 d_id, u32 s_id, u32 *pid_list,
785 u16 npids)
786{
787 u32 dctlr_id = FC_DOMAIN_CTRLR(bfa_os_hton3b(d_id));
788 int i = 0;
789
790 fc_els_req_build(fchs, bfa_os_hton3b(dctlr_id), s_id, 0);
791
792 memset(rpsc2, 0, sizeof(struct fc_rpsc2_cmd_s));
793
794 rpsc2->els_cmd.els_code = FC_ELS_RPSC;
795 rpsc2->token = bfa_os_htonl(FC_BRCD_TOKEN);
796 rpsc2->num_pids = bfa_os_htons(npids);
797 for (i = 0; i < npids; i++)
798 rpsc2->pid_list[i].pid = pid_list[i];
799
800 return (sizeof(struct fc_rpsc2_cmd_s) + ((npids - 1) *
801 (sizeof(u32))));
802}
803
804u16
805fc_rpsc_acc_build(struct fchs_s *fchs, struct fc_rpsc_acc_s *rpsc_acc,
806 u32 d_id, u32 s_id, u16 ox_id,
807 struct fc_rpsc_speed_info_s *oper_speed)
808{
809 memset(rpsc_acc, 0, sizeof(struct fc_rpsc_acc_s));
810
811 fc_els_rsp_build(fchs, d_id, s_id, ox_id);
812
813 rpsc_acc->command = FC_ELS_ACC;
814 rpsc_acc->num_entries = bfa_os_htons(1);
815
816 rpsc_acc->speed_info[0].port_speed_cap =
817 bfa_os_htons(oper_speed->port_speed_cap);
818
819 rpsc_acc->speed_info[0].port_op_speed =
820 bfa_os_htons(oper_speed->port_op_speed);
821
822 return (sizeof(struct fc_rpsc_acc_s));
823
824}
825
826/*
827 * TBD -
828 * . get rid of unnecessary memsets
829 */
830
831u16
832fc_logo_rsp_parse(struct fchs_s *fchs, int len)
833{
834 struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
835
836 len = len;
837 if (els_cmd->els_code != FC_ELS_ACC)
838 return FC_PARSE_FAILURE;
839
840 return FC_PARSE_OK;
841}
842
843u16
844fc_pdisc_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
845 u16 ox_id, wwn_t port_name, wwn_t node_name,
846 u16 pdu_size)
847{
848 struct fc_logi_s *pdisc = (struct fc_logi_s *) (fchs + 1);
849
850 bfa_os_memcpy(pdisc, &plogi_tmpl, sizeof(struct fc_logi_s));
851
852 pdisc->els_cmd.els_code = FC_ELS_PDISC;
853 fc_els_req_build(fchs, d_id, s_id, ox_id);
854
855 pdisc->csp.rxsz = pdisc->class3.rxsz = bfa_os_htons(pdu_size);
856 pdisc->port_name = port_name;
857 pdisc->node_name = node_name;
858
859 return (sizeof(struct fc_logi_s));
860}
861
862u16
863fc_pdisc_rsp_parse(struct fchs_s *fchs, int len, wwn_t port_name)
864{
865 struct fc_logi_s *pdisc = (struct fc_logi_s *) (fchs + 1);
866
867 if (len < sizeof(struct fc_logi_s))
868 return (FC_PARSE_LEN_INVAL);
869
870 if (pdisc->els_cmd.els_code != FC_ELS_ACC)
871 return (FC_PARSE_ACC_INVAL);
872
873 if (!wwn_is_equal(pdisc->port_name, port_name))
874 return (FC_PARSE_PWWN_NOT_EQUAL);
875
876 if (!pdisc->class3.class_valid)
877 return (FC_PARSE_NWWN_NOT_EQUAL);
878
879 if (bfa_os_ntohs(pdisc->class3.rxsz) < (FC_MIN_PDUSZ))
880 return (FC_PARSE_RXSZ_INVAL);
881
882 return (FC_PARSE_OK);
883}
884
885u16
886fc_prlo_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id,
887 int num_pages)
888{
889 struct fc_prlo_s *prlo = (struct fc_prlo_s *) (fchs + 1);
890 int page;
891
892 fc_els_req_build(fchs, d_id, s_id, ox_id);
893 memset(prlo, 0, (num_pages * 16) + 4);
894 prlo->command = FC_ELS_PRLO;
895 prlo->page_len = 0x10;
896 prlo->payload_len = bfa_os_htons((num_pages * 16) + 4);
897
898 for (page = 0; page < num_pages; page++) {
899 prlo->prlo_params[page].type = FC_TYPE_FCP;
900 prlo->prlo_params[page].opa_valid = 0;
901 prlo->prlo_params[page].rpa_valid = 0;
902 prlo->prlo_params[page].orig_process_assc = 0;
903 prlo->prlo_params[page].resp_process_assc = 0;
904 }
905
906 return (bfa_os_ntohs(prlo->payload_len));
907}
908
909u16
910fc_prlo_rsp_parse(struct fchs_s *fchs, int len)
911{
912 struct fc_prlo_acc_s *prlo = (struct fc_prlo_acc_s *) (fchs + 1);
913 int num_pages = 0;
914 int page = 0;
915
916 len = len;
917
918 if (prlo->command != FC_ELS_ACC)
919 return (FC_PARSE_FAILURE);
920
921 num_pages = ((bfa_os_ntohs(prlo->payload_len)) - 4) / 16;
922
923 for (page = 0; page < num_pages; page++) {
924 if (prlo->prlo_acc_params[page].type != FC_TYPE_FCP)
925 return FC_PARSE_FAILURE;
926
927 if (prlo->prlo_acc_params[page].opa_valid != 0)
928 return FC_PARSE_FAILURE;
929
930 if (prlo->prlo_acc_params[page].rpa_valid != 0)
931 return FC_PARSE_FAILURE;
932
933 if (prlo->prlo_acc_params[page].orig_process_assc != 0)
934 return FC_PARSE_FAILURE;
935
936 if (prlo->prlo_acc_params[page].resp_process_assc != 0)
937 return FC_PARSE_FAILURE;
938 }
939 return (FC_PARSE_OK);
940
941}
942
943u16
944fc_tprlo_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
945 u16 ox_id, int num_pages,
946 enum fc_tprlo_type tprlo_type, u32 tpr_id)
947{
948 struct fc_tprlo_s *tprlo = (struct fc_tprlo_s *) (fchs + 1);
949 int page;
950
951 fc_els_req_build(fchs, d_id, s_id, ox_id);
952 memset(tprlo, 0, (num_pages * 16) + 4);
953 tprlo->command = FC_ELS_TPRLO;
954 tprlo->page_len = 0x10;
955 tprlo->payload_len = bfa_os_htons((num_pages * 16) + 4);
956
957 for (page = 0; page < num_pages; page++) {
958 tprlo->tprlo_params[page].type = FC_TYPE_FCP;
959 tprlo->tprlo_params[page].opa_valid = 0;
960 tprlo->tprlo_params[page].rpa_valid = 0;
961 tprlo->tprlo_params[page].orig_process_assc = 0;
962 tprlo->tprlo_params[page].resp_process_assc = 0;
963 if (tprlo_type == FC_GLOBAL_LOGO) {
964 tprlo->tprlo_params[page].global_process_logout = 1;
965 } else if (tprlo_type == FC_TPR_LOGO) {
966 tprlo->tprlo_params[page].tpo_nport_valid = 1;
967 tprlo->tprlo_params[page].tpo_nport_id = (tpr_id);
968 }
969 }
970
971 return (bfa_os_ntohs(tprlo->payload_len));
972}
973
974u16
975fc_tprlo_rsp_parse(struct fchs_s *fchs, int len)
976{
977 struct fc_tprlo_acc_s *tprlo = (struct fc_tprlo_acc_s *) (fchs + 1);
978 int num_pages = 0;
979 int page = 0;
980
981 len = len;
982
983 if (tprlo->command != FC_ELS_ACC)
984 return (FC_PARSE_ACC_INVAL);
985
986 num_pages = (bfa_os_ntohs(tprlo->payload_len) - 4) / 16;
987
988 for (page = 0; page < num_pages; page++) {
989 if (tprlo->tprlo_acc_params[page].type != FC_TYPE_FCP)
990 return (FC_PARSE_NOT_FCP);
991 if (tprlo->tprlo_acc_params[page].opa_valid != 0)
992 return (FC_PARSE_OPAFLAG_INVAL);
993 if (tprlo->tprlo_acc_params[page].rpa_valid != 0)
994 return (FC_PARSE_RPAFLAG_INVAL);
995 if (tprlo->tprlo_acc_params[page].orig_process_assc != 0)
996 return (FC_PARSE_OPA_INVAL);
997 if (tprlo->tprlo_acc_params[page].resp_process_assc != 0)
998 return (FC_PARSE_RPA_INVAL);
999 }
1000 return (FC_PARSE_OK);
1001}
1002
1003enum fc_parse_status
1004fc_rrq_rsp_parse(struct fchs_s *fchs, int len)
1005{
1006 struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
1007
1008 len = len;
1009 if (els_cmd->els_code != FC_ELS_ACC)
1010 return FC_PARSE_FAILURE;
1011
1012 return FC_PARSE_OK;
1013}
1014
1015u16
1016fc_ba_rjt_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
1017 u16 ox_id, u32 reason_code,
1018 u32 reason_expl)
1019{
1020 struct fc_ba_rjt_s *ba_rjt = (struct fc_ba_rjt_s *) (fchs + 1);
1021
1022 fc_bls_rsp_build(fchs, d_id, s_id, ox_id);
1023
1024 fchs->cat_info = FC_CAT_BA_RJT;
1025 ba_rjt->reason_code = reason_code;
1026 ba_rjt->reason_expl = reason_expl;
1027 return (sizeof(struct fc_ba_rjt_s));
1028}
1029
1030static void
1031fc_gs_cthdr_build(struct ct_hdr_s *cthdr, u32 s_id, u16 cmd_code)
1032{
1033 bfa_os_memset(cthdr, 0, sizeof(struct ct_hdr_s));
1034 cthdr->rev_id = CT_GS3_REVISION;
1035 cthdr->gs_type = CT_GSTYPE_DIRSERVICE;
1036 cthdr->gs_sub_type = CT_GSSUBTYPE_NAMESERVER;
1037 cthdr->cmd_rsp_code = bfa_os_htons(cmd_code);
1038}
1039
1040static void
1041fc_gs_fdmi_cthdr_build(struct ct_hdr_s *cthdr, u32 s_id, u16 cmd_code)
1042{
1043 bfa_os_memset(cthdr, 0, sizeof(struct ct_hdr_s));
1044 cthdr->rev_id = CT_GS3_REVISION;
1045 cthdr->gs_type = CT_GSTYPE_MGMTSERVICE;
1046 cthdr->gs_sub_type = CT_GSSUBTYPE_HBA_MGMTSERVER;
1047 cthdr->cmd_rsp_code = bfa_os_htons(cmd_code);
1048}
1049
1050static void
1051fc_gs_ms_cthdr_build(struct ct_hdr_s *cthdr, u32 s_id, u16 cmd_code,
1052 u8 sub_type)
1053{
1054 bfa_os_memset(cthdr, 0, sizeof(struct ct_hdr_s));
1055 cthdr->rev_id = CT_GS3_REVISION;
1056 cthdr->gs_type = CT_GSTYPE_MGMTSERVICE;
1057 cthdr->gs_sub_type = sub_type;
1058 cthdr->cmd_rsp_code = bfa_os_htons(cmd_code);
1059}
1060
1061u16
1062fc_gidpn_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
1063 wwn_t port_name)
1064{
1065
1066 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1067 struct fcgs_gidpn_req_s *gidpn =
1068 (struct fcgs_gidpn_req_s *) (cthdr + 1);
1069 u32 d_id = bfa_os_hton3b(FC_NAME_SERVER);
1070
1071 fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
1072 fc_gs_cthdr_build(cthdr, s_id, GS_GID_PN);
1073
1074 bfa_os_memset(gidpn, 0, sizeof(struct fcgs_gidpn_req_s));
1075 gidpn->port_name = port_name;
1076 return (sizeof(struct fcgs_gidpn_req_s) + sizeof(struct ct_hdr_s));
1077}
1078
1079u16
1080fc_gpnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
1081 u32 port_id)
1082{
1083
1084 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1085 fcgs_gpnid_req_t *gpnid = (fcgs_gpnid_req_t *) (cthdr + 1);
1086 u32 d_id = bfa_os_hton3b(FC_NAME_SERVER);
1087
1088 fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
1089 fc_gs_cthdr_build(cthdr, s_id, GS_GPN_ID);
1090
1091 bfa_os_memset(gpnid, 0, sizeof(fcgs_gpnid_req_t));
1092 gpnid->dap = port_id;
1093 return (sizeof(fcgs_gpnid_req_t) + sizeof(struct ct_hdr_s));
1094}
1095
1096u16
1097fc_gnnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
1098 u32 port_id)
1099{
1100
1101 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1102 fcgs_gnnid_req_t *gnnid = (fcgs_gnnid_req_t *) (cthdr + 1);
1103 u32 d_id = bfa_os_hton3b(FC_NAME_SERVER);
1104
1105 fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
1106 fc_gs_cthdr_build(cthdr, s_id, GS_GNN_ID);
1107
1108 bfa_os_memset(gnnid, 0, sizeof(fcgs_gnnid_req_t));
1109 gnnid->dap = port_id;
1110 return (sizeof(fcgs_gnnid_req_t) + sizeof(struct ct_hdr_s));
1111}
1112
1113u16
1114fc_ct_rsp_parse(struct ct_hdr_s *cthdr)
1115{
1116 if (bfa_os_ntohs(cthdr->cmd_rsp_code) != CT_RSP_ACCEPT) {
1117 if (cthdr->reason_code == CT_RSN_LOGICAL_BUSY)
1118 return FC_PARSE_BUSY;
1119 else
1120 return FC_PARSE_FAILURE;
1121 }
1122
1123 return FC_PARSE_OK;
1124}
1125
1126u16
1127fc_scr_build(struct fchs_s *fchs, struct fc_scr_s *scr, u8 set_br_reg,
1128 u32 s_id, u16 ox_id)
1129{
1130 u32 d_id = bfa_os_hton3b(FC_FABRIC_CONTROLLER);
1131
1132 fc_els_req_build(fchs, d_id, s_id, ox_id);
1133
1134 bfa_os_memset(scr, 0, sizeof(struct fc_scr_s));
1135 scr->command = FC_ELS_SCR;
1136 scr->reg_func = FC_SCR_REG_FUNC_FULL;
1137 if (set_br_reg)
1138 scr->vu_reg_func = FC_VU_SCR_REG_FUNC_FABRIC_NAME_CHANGE;
1139
1140 return (sizeof(struct fc_scr_s));
1141}
1142
1143u16
1144fc_rscn_build(struct fchs_s *fchs, struct fc_rscn_pl_s *rscn, u32 s_id,
1145 u16 ox_id)
1146{
1147 u32 d_id = bfa_os_hton3b(FC_FABRIC_CONTROLLER);
1148 u16 payldlen;
1149
1150 fc_els_req_build(fchs, d_id, s_id, ox_id);
1151 rscn->command = FC_ELS_RSCN;
1152 rscn->pagelen = sizeof(rscn->event[0]);
1153
1154 payldlen = sizeof(u32) + rscn->pagelen;
1155 rscn->payldlen = bfa_os_htons(payldlen);
1156
1157 rscn->event[0].format = FC_RSCN_FORMAT_PORTID;
1158 rscn->event[0].portid = s_id;
1159
1160 return (sizeof(struct fc_rscn_pl_s));
1161}
1162
1163u16
1164fc_rftid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
1165 enum bfa_port_role roles)
1166{
1167 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1168 struct fcgs_rftid_req_s *rftid =
1169 (struct fcgs_rftid_req_s *) (cthdr + 1);
1170 u32 type_value, d_id = bfa_os_hton3b(FC_NAME_SERVER);
1171 u8 index;
1172
1173 fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
1174 fc_gs_cthdr_build(cthdr, s_id, GS_RFT_ID);
1175
1176 bfa_os_memset(rftid, 0, sizeof(struct fcgs_rftid_req_s));
1177
1178 rftid->dap = s_id;
1179
1180 /* By default, FCP FC4 Type is registered */
1181 index = FC_TYPE_FCP >> 5;
1182 type_value = 1 << (FC_TYPE_FCP % 32);
1183 rftid->fc4_type[index] = bfa_os_htonl(type_value);
1184
1185 if (roles & BFA_PORT_ROLE_FCP_IPFC) {
1186 index = FC_TYPE_IP >> 5;
1187 type_value = 1 << (FC_TYPE_IP % 32);
1188 rftid->fc4_type[index] |= bfa_os_htonl(type_value);
1189 }
1190
1191 return (sizeof(struct fcgs_rftid_req_s) + sizeof(struct ct_hdr_s));
1192}
1193
1194u16
1195fc_rftid_build_sol(struct fchs_s *fchs, void *pyld, u32 s_id,
1196 u16 ox_id, u8 *fc4_bitmap,
1197 u32 bitmap_size)
1198{
1199 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1200 struct fcgs_rftid_req_s *rftid =
1201 (struct fcgs_rftid_req_s *) (cthdr + 1);
1202 u32 d_id = bfa_os_hton3b(FC_NAME_SERVER);
1203
1204 fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
1205 fc_gs_cthdr_build(cthdr, s_id, GS_RFT_ID);
1206
1207 bfa_os_memset(rftid, 0, sizeof(struct fcgs_rftid_req_s));
1208
1209 rftid->dap = s_id;
1210 bfa_os_memcpy((void *)rftid->fc4_type, (void *)fc4_bitmap,
1211 (bitmap_size < 32 ? bitmap_size : 32));
1212
1213 return (sizeof(struct fcgs_rftid_req_s) + sizeof(struct ct_hdr_s));
1214}
1215
1216u16
1217fc_rffid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
1218 u8 fc4_type, u8 fc4_ftrs)
1219{
1220 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1221 struct fcgs_rffid_req_s *rffid =
1222 (struct fcgs_rffid_req_s *) (cthdr + 1);
1223 u32 d_id = bfa_os_hton3b(FC_NAME_SERVER);
1224
1225 fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
1226 fc_gs_cthdr_build(cthdr, s_id, GS_RFF_ID);
1227
1228 bfa_os_memset(rffid, 0, sizeof(struct fcgs_rffid_req_s));
1229
1230 rffid->dap = s_id;
1231 rffid->fc4ftr_bits = fc4_ftrs;
1232 rffid->fc4_type = fc4_type;
1233
1234 return (sizeof(struct fcgs_rffid_req_s) + sizeof(struct ct_hdr_s));
1235}
1236
1237u16
1238fc_rspnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id,
1239 u8 *name)
1240{
1241
1242 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1243 struct fcgs_rspnid_req_s *rspnid =
1244 (struct fcgs_rspnid_req_s *) (cthdr + 1);
1245 u32 d_id = bfa_os_hton3b(FC_NAME_SERVER);
1246
1247 fc_gs_fchdr_build(fchs, d_id, s_id, ox_id);
1248 fc_gs_cthdr_build(cthdr, s_id, GS_RSPN_ID);
1249
1250 bfa_os_memset(rspnid, 0, sizeof(struct fcgs_rspnid_req_s));
1251
1252 rspnid->dap = s_id;
1253 rspnid->spn_len = (u8) strlen((char *)name);
1254 strncpy((char *)rspnid->spn, (char *)name, rspnid->spn_len);
1255
1256 return (sizeof(struct fcgs_rspnid_req_s) + sizeof(struct ct_hdr_s));
1257}
1258
1259u16
1260fc_gid_ft_build(struct fchs_s *fchs, void *pyld, u32 s_id,
1261 u8 fc4_type)
1262{
1263
1264 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1265 struct fcgs_gidft_req_s *gidft =
1266 (struct fcgs_gidft_req_s *) (cthdr + 1);
1267 u32 d_id = bfa_os_hton3b(FC_NAME_SERVER);
1268
1269 fc_gs_fchdr_build(fchs, d_id, s_id, 0);
1270
1271 fc_gs_cthdr_build(cthdr, s_id, GS_GID_FT);
1272
1273 bfa_os_memset(gidft, 0, sizeof(struct fcgs_gidft_req_s));
1274 gidft->fc4_type = fc4_type;
1275 gidft->domain_id = 0;
1276 gidft->area_id = 0;
1277
1278 return (sizeof(struct fcgs_gidft_req_s) + sizeof(struct ct_hdr_s));
1279}
1280
1281u16
1282fc_rpnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id,
1283 wwn_t port_name)
1284{
1285 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1286 struct fcgs_rpnid_req_s *rpnid =
1287 (struct fcgs_rpnid_req_s *) (cthdr + 1);
1288 u32 d_id = bfa_os_hton3b(FC_NAME_SERVER);
1289
1290 fc_gs_fchdr_build(fchs, d_id, s_id, 0);
1291 fc_gs_cthdr_build(cthdr, s_id, GS_RPN_ID);
1292
1293 bfa_os_memset(rpnid, 0, sizeof(struct fcgs_rpnid_req_s));
1294 rpnid->port_id = port_id;
1295 rpnid->port_name = port_name;
1296
1297 return (sizeof(struct fcgs_rpnid_req_s) + sizeof(struct ct_hdr_s));
1298}
1299
1300u16
1301fc_rnnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id,
1302 wwn_t node_name)
1303{
1304 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1305 struct fcgs_rnnid_req_s *rnnid =
1306 (struct fcgs_rnnid_req_s *) (cthdr + 1);
1307 u32 d_id = bfa_os_hton3b(FC_NAME_SERVER);
1308
1309 fc_gs_fchdr_build(fchs, d_id, s_id, 0);
1310 fc_gs_cthdr_build(cthdr, s_id, GS_RNN_ID);
1311
1312 bfa_os_memset(rnnid, 0, sizeof(struct fcgs_rnnid_req_s));
1313 rnnid->port_id = port_id;
1314 rnnid->node_name = node_name;
1315
1316 return (sizeof(struct fcgs_rnnid_req_s) + sizeof(struct ct_hdr_s));
1317}
1318
1319u16
1320fc_rcsid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id,
1321 u32 cos)
1322{
1323 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1324 struct fcgs_rcsid_req_s *rcsid =
1325 (struct fcgs_rcsid_req_s *) (cthdr + 1);
1326 u32 d_id = bfa_os_hton3b(FC_NAME_SERVER);
1327
1328 fc_gs_fchdr_build(fchs, d_id, s_id, 0);
1329 fc_gs_cthdr_build(cthdr, s_id, GS_RCS_ID);
1330
1331 bfa_os_memset(rcsid, 0, sizeof(struct fcgs_rcsid_req_s));
1332 rcsid->port_id = port_id;
1333 rcsid->cos = cos;
1334
1335 return (sizeof(struct fcgs_rcsid_req_s) + sizeof(struct ct_hdr_s));
1336}
1337
1338u16
1339fc_rptid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id,
1340 u8 port_type)
1341{
1342 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1343 struct fcgs_rptid_req_s *rptid =
1344 (struct fcgs_rptid_req_s *) (cthdr + 1);
1345 u32 d_id = bfa_os_hton3b(FC_NAME_SERVER);
1346
1347 fc_gs_fchdr_build(fchs, d_id, s_id, 0);
1348 fc_gs_cthdr_build(cthdr, s_id, GS_RPT_ID);
1349
1350 bfa_os_memset(rptid, 0, sizeof(struct fcgs_rptid_req_s));
1351 rptid->port_id = port_id;
1352 rptid->port_type = port_type;
1353
1354 return (sizeof(struct fcgs_rptid_req_s) + sizeof(struct ct_hdr_s));
1355}
1356
1357u16
1358fc_ganxt_build(struct fchs_s *fchs, void *pyld, u32 s_id, u32 port_id)
1359{
1360 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1361 struct fcgs_ganxt_req_s *ganxt =
1362 (struct fcgs_ganxt_req_s *) (cthdr + 1);
1363 u32 d_id = bfa_os_hton3b(FC_NAME_SERVER);
1364
1365 fc_gs_fchdr_build(fchs, d_id, s_id, 0);
1366 fc_gs_cthdr_build(cthdr, s_id, GS_GA_NXT);
1367
1368 bfa_os_memset(ganxt, 0, sizeof(struct fcgs_ganxt_req_s));
1369 ganxt->port_id = port_id;
1370
1371 return (sizeof(struct ct_hdr_s) + sizeof(struct fcgs_ganxt_req_s));
1372}
1373
1374/*
1375 * Builds fc hdr and ct hdr for FDMI requests.
1376 */
1377u16
1378fc_fdmi_reqhdr_build(struct fchs_s *fchs, void *pyld, u32 s_id,
1379 u16 cmd_code)
1380{
1381
1382 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1383 u32 d_id = bfa_os_hton3b(FC_MGMT_SERVER);
1384
1385 fc_gs_fchdr_build(fchs, d_id, s_id, 0);
1386 fc_gs_fdmi_cthdr_build(cthdr, s_id, cmd_code);
1387
1388 return (sizeof(struct ct_hdr_s));
1389}
1390
1391/*
1392 * Given a FC4 Type, this function returns a fc4 type bitmask
1393 */
1394void
1395fc_get_fc4type_bitmask(u8 fc4_type, u8 *bit_mask)
1396{
1397 u8 index;
1398 u32 *ptr = (u32 *) bit_mask;
1399 u32 type_value;
1400
1401 /*
1402 * @todo : Check for bitmask size
1403 */
1404
1405 index = fc4_type >> 5;
1406 type_value = 1 << (fc4_type % 32);
1407 ptr[index] = bfa_os_htonl(type_value);
1408
1409}
1410
1411/*
1412 * GMAL Request
1413 */
1414u16
1415fc_gmal_req_build(struct fchs_s *fchs, void *pyld, u32 s_id, wwn_t wwn)
1416{
1417 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1418 fcgs_gmal_req_t *gmal = (fcgs_gmal_req_t *) (cthdr + 1);
1419 u32 d_id = bfa_os_hton3b(FC_MGMT_SERVER);
1420
1421 fc_gs_fchdr_build(fchs, d_id, s_id, 0);
1422 fc_gs_ms_cthdr_build(cthdr, s_id, GS_FC_GMAL_CMD,
1423 CT_GSSUBTYPE_CFGSERVER);
1424
1425 bfa_os_memset(gmal, 0, sizeof(fcgs_gmal_req_t));
1426 gmal->wwn = wwn;
1427
1428 return (sizeof(struct ct_hdr_s) + sizeof(fcgs_gmal_req_t));
1429}
1430
1431/*
1432 * GFN (Get Fabric Name) Request
1433 */
1434u16
1435fc_gfn_req_build(struct fchs_s *fchs, void *pyld, u32 s_id, wwn_t wwn)
1436{
1437 struct ct_hdr_s *cthdr = (struct ct_hdr_s *) pyld;
1438 fcgs_gfn_req_t *gfn = (fcgs_gfn_req_t *) (cthdr + 1);
1439 u32 d_id = bfa_os_hton3b(FC_MGMT_SERVER);
1440
1441 fc_gs_fchdr_build(fchs, d_id, s_id, 0);
1442 fc_gs_ms_cthdr_build(cthdr, s_id, GS_FC_GFN_CMD,
1443 CT_GSSUBTYPE_CFGSERVER);
1444
1445 bfa_os_memset(gfn, 0, sizeof(fcgs_gfn_req_t));
1446 gfn->wwn = wwn;
1447
1448 return (sizeof(struct ct_hdr_s) + sizeof(fcgs_gfn_req_t));
1449}
diff --git a/drivers/scsi/bfa/fcbuild.h b/drivers/scsi/bfa/fcbuild.h
new file mode 100644
index 000000000000..4d248424f7b3
--- /dev/null
+++ b/drivers/scsi/bfa/fcbuild.h
@@ -0,0 +1,273 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17/*
18 * fcbuild.h - FC link service frame building and parsing routines
19 */
20
21#ifndef __FCBUILD_H__
22#define __FCBUILD_H__
23
24#include <bfa_os_inc.h>
25#include <protocol/fc.h>
26#include <protocol/fcp.h>
27#include <protocol/ct.h>
28#include <defs/bfa_defs_port.h>
29#include <defs/bfa_defs_pport.h>
30
31/*
32 * Utility Macros/functions
33 */
34
35#define fcif_sof_set(_ifhdr, _sof) (_ifhdr)->sof = FC_ ## _sof
36#define fcif_eof_set(_ifhdr, _eof) (_ifhdr)->eof = FC_ ## _eof
37
38#define wwn_is_equal(_wwn1, _wwn2) \
39 (memcmp(&(_wwn1), &(_wwn2), sizeof(wwn_t)) == 0)
40
41#define fc_roundup(_l, _s) (((_l) + ((_s) - 1)) & ~((_s) - 1))
42
43/*
44 * Given the fc response length, this routine will return
45 * the length of the actual payload bytes following the CT header.
46 *
47 * Assumes the input response length does not include the crc, eof, etc.
48 */
49static inline u32
50fc_get_ctresp_pyld_len(u32 resp_len)
51{
52 return (resp_len - sizeof(struct ct_hdr_s));
53}
54
55/*
56 * Convert bfa speed to rpsc speed value.
57 */
58static inline enum bfa_pport_speed
59fc_rpsc_operspeed_to_bfa_speed(enum fc_rpsc_op_speed_s speed)
60{
61 switch (speed) {
62
63 case RPSC_OP_SPEED_1G:
64 return BFA_PPORT_SPEED_1GBPS;
65
66 case RPSC_OP_SPEED_2G:
67 return BFA_PPORT_SPEED_2GBPS;
68
69 case RPSC_OP_SPEED_4G:
70 return BFA_PPORT_SPEED_4GBPS;
71
72 case RPSC_OP_SPEED_8G:
73 return BFA_PPORT_SPEED_8GBPS;
74
75 default:
76 return BFA_PPORT_SPEED_UNKNOWN;
77 }
78}
79
80/*
81 * Convert RPSC speed to bfa speed value.
82 */
83static inline enum fc_rpsc_op_speed_s
84fc_bfa_speed_to_rpsc_operspeed(enum bfa_pport_speed op_speed)
85{
86 switch (op_speed) {
87
88 case BFA_PPORT_SPEED_1GBPS:
89 return RPSC_OP_SPEED_1G;
90
91 case BFA_PPORT_SPEED_2GBPS:
92 return RPSC_OP_SPEED_2G;
93
94 case BFA_PPORT_SPEED_4GBPS:
95 return RPSC_OP_SPEED_4G;
96
97 case BFA_PPORT_SPEED_8GBPS:
98 return RPSC_OP_SPEED_8G;
99
100 default:
101 return RPSC_OP_SPEED_NOT_EST;
102 }
103}
104enum fc_parse_status {
105 FC_PARSE_OK = 0,
106 FC_PARSE_FAILURE = 1,
107 FC_PARSE_BUSY = 2,
108 FC_PARSE_LEN_INVAL,
109 FC_PARSE_ACC_INVAL,
110 FC_PARSE_PWWN_NOT_EQUAL,
111 FC_PARSE_NWWN_NOT_EQUAL,
112 FC_PARSE_RXSZ_INVAL,
113 FC_PARSE_NOT_FCP,
114 FC_PARSE_OPAFLAG_INVAL,
115 FC_PARSE_RPAFLAG_INVAL,
116 FC_PARSE_OPA_INVAL,
117 FC_PARSE_RPA_INVAL,
118
119};
120
121struct fc_templates_s {
122 struct fchs_s fc_els_req;
123 struct fchs_s fc_bls_req;
124 struct fc_logi_s plogi;
125 struct fc_rrq_s rrq;
126};
127
128void fcbuild_init(void);
129
130u16 fc_flogi_build(struct fchs_s *fchs, struct fc_logi_s *flogi,
131 u32 s_id, u16 ox_id, wwn_t port_name,
132 wwn_t node_name, u16 pdu_size, u8 set_npiv,
133 u8 set_auth, u16 local_bb_credits);
134u16 fc_fdisc_build(struct fchs_s *buf, struct fc_logi_s *flogi,
135 u32 s_id, u16 ox_id, wwn_t port_name,
136 wwn_t node_name, u16 pdu_size);
137u16 fc_flogi_acc_build(struct fchs_s *fchs, struct fc_logi_s *flogi,
138 u32 s_id, u16 ox_id, wwn_t port_name,
139 wwn_t node_name, u16 pdu_size,
140 u16 local_bb_credits);
141u16 fc_plogi_build(struct fchs_s *fchs, void *pld, u32 d_id,
142 u32 s_id, u16 ox_id, wwn_t port_name,
143 wwn_t node_name, u16 pdu_size);
144enum fc_parse_status fc_plogi_parse(struct fchs_s *fchs);
145u16 fc_abts_build(struct fchs_s *buf, u32 d_id, u32 s_id,
146 u16 ox_id);
147enum fc_parse_status fc_abts_rsp_parse(struct fchs_s *buf, int len);
148u16 fc_rrq_build(struct fchs_s *buf, struct fc_rrq_s *rrq, u32 d_id,
149 u32 s_id, u16 ox_id, u16 rrq_oxid);
150enum fc_parse_status fc_rrq_rsp_parse(struct fchs_s *buf, int len);
151u16 fc_rspnid_build(struct fchs_s *fchs, void *pld, u32 s_id,
152 u16 ox_id, u8 *name);
153u16 fc_rftid_build(struct fchs_s *fchs, void *pld, u32 s_id,
154 u16 ox_id, enum bfa_port_role role);
155u16 fc_rftid_build_sol(struct fchs_s *fchs, void *pyld, u32 s_id,
156 u16 ox_id, u8 *fc4_bitmap,
157 u32 bitmap_size);
158u16 fc_rffid_build(struct fchs_s *fchs, void *pyld, u32 s_id,
159 u16 ox_id, u8 fc4_type, u8 fc4_ftrs);
160u16 fc_gidpn_build(struct fchs_s *fchs, void *pyld, u32 s_id,
161 u16 ox_id, wwn_t port_name);
162u16 fc_gpnid_build(struct fchs_s *fchs, void *pld, u32 s_id,
163 u16 ox_id, u32 port_id);
164u16 fc_scr_build(struct fchs_s *fchs, struct fc_scr_s *scr,
165 u8 set_br_reg, u32 s_id, u16 ox_id);
166u16 fc_plogi_acc_build(struct fchs_s *fchs, void *pld, u32 d_id,
167 u32 s_id, u16 ox_id,
168 wwn_t port_name, wwn_t node_name, u16 pdu_size);
169
170u16 fc_adisc_build(struct fchs_s *fchs, struct fc_adisc_s *adisc,
171 u32 d_id, u32 s_id, u16 ox_id,
172 wwn_t port_name, wwn_t node_name);
173enum fc_parse_status fc_adisc_parse(struct fchs_s *fchs, void *pld,
174 u32 host_dap,
175 wwn_t node_name, wwn_t port_name);
176enum fc_parse_status fc_adisc_rsp_parse(struct fc_adisc_s *adisc, int len,
177 wwn_t port_name, wwn_t node_name);
178u16 fc_adisc_acc_build(struct fchs_s *fchs, struct fc_adisc_s *adisc,
179 u32 d_id, u32 s_id, u16 ox_id,
180 wwn_t port_name, wwn_t node_name);
181u16 fc_ls_rjt_build(struct fchs_s *fchs, struct fc_ls_rjt_s *ls_rjt,
182 u32 d_id, u32 s_id, u16 ox_id,
183 u8 reason_code, u8 reason_code_expl);
184u16 fc_ls_acc_build(struct fchs_s *fchs, struct fc_els_cmd_s *els_cmd,
185 u32 d_id, u32 s_id, u16 ox_id);
186u16 fc_prli_build(struct fchs_s *fchs, void *pld, u32 d_id,
187 u32 s_id, u16 ox_id);
188enum fc_parse_status fc_prli_rsp_parse(struct fc_prli_s *prli, int len);
189
190u16 fc_prli_acc_build(struct fchs_s *fchs, void *pld, u32 d_id,
191 u32 s_id, u16 ox_id,
192 enum bfa_port_role role);
193u16 fc_rnid_build(struct fchs_s *fchs, struct fc_rnid_cmd_s *rnid,
194 u32 d_id, u32 s_id, u16 ox_id,
195 u32 data_format);
196u16 fc_rnid_acc_build(struct fchs_s *fchs, struct fc_rnid_acc_s *rnid_acc,
197 u32 d_id, u32 s_id, u16 ox_id,
198 u32 data_format,
199 struct fc_rnid_common_id_data_s *common_id_data,
200 struct fc_rnid_general_topology_data_s *
201 gen_topo_data);
202u16 fc_rpsc2_build(struct fchs_s *fchs, struct fc_rpsc2_cmd_s *rps2c,
203 u32 d_id, u32 s_id,
204 u32 *pid_list, u16 npids);
205u16 fc_rpsc_build(struct fchs_s *fchs, struct fc_rpsc_cmd_s *rpsc,
206 u32 d_id, u32 s_id, u16 ox_id);
207u16 fc_rpsc_acc_build(struct fchs_s *fchs, struct fc_rpsc_acc_s *rpsc_acc,
208 u32 d_id, u32 s_id, u16 ox_id,
209 struct fc_rpsc_speed_info_s *oper_speed);
210u16 fc_gid_ft_build(struct fchs_s *fchs, void *pld, u32 s_id,
211 u8 fc4_type);
212u16 fc_rpnid_build(struct fchs_s *fchs, void *pyld, u32 s_id,
213 u32 port_id, wwn_t port_name);
214u16 fc_rnnid_build(struct fchs_s *fchs, void *pyld, u32 s_id,
215 u32 port_id, wwn_t node_name);
216u16 fc_rcsid_build(struct fchs_s *fchs, void *pyld, u32 s_id,
217 u32 port_id, u32 cos);
218u16 fc_rptid_build(struct fchs_s *fchs, void *pyld, u32 s_id,
219 u32 port_id, u8 port_type);
220u16 fc_ganxt_build(struct fchs_s *fchs, void *pyld, u32 s_id,
221 u32 port_id);
222u16 fc_logo_build(struct fchs_s *fchs, struct fc_logo_s *logo,
223 u32 d_id, u32 s_id, u16 ox_id,
224 wwn_t port_name);
225u16 fc_logo_acc_build(struct fchs_s *fchs, void *pld, u32 d_id,
226 u32 s_id, u16 ox_id);
227u16 fc_fdmi_reqhdr_build(struct fchs_s *fchs, void *pyld, u32 s_id,
228 u16 cmd_code);
229u16 fc_gmal_req_build(struct fchs_s *fchs, void *pyld, u32 s_id,
230 wwn_t wwn);
231u16 fc_gfn_req_build(struct fchs_s *fchs, void *pyld, u32 s_id,
232 wwn_t wwn);
233void fc_get_fc4type_bitmask(u8 fc4_type, u8 *bit_mask);
234void fc_els_req_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
235 u16 ox_id);
236enum fc_parse_status fc_els_rsp_parse(struct fchs_s *fchs, int len);
237enum fc_parse_status fc_plogi_rsp_parse(struct fchs_s *fchs, int len,
238 wwn_t port_name);
239enum fc_parse_status fc_prli_parse(struct fc_prli_s *prli);
240enum fc_parse_status fc_pdisc_parse(struct fchs_s *fchs, wwn_t node_name,
241 wwn_t port_name);
242u16 fc_ba_acc_build(struct fchs_s *fchs, struct fc_ba_acc_s *ba_acc,
243 u32 d_id, u32 s_id, u16 ox_id,
244 u16 rx_id);
245int fc_logout_params_pages(struct fchs_s *fc_frame, u8 els_code);
246u16 fc_tprlo_acc_build(struct fchs_s *fchs,
247 struct fc_tprlo_acc_s *tprlo_acc,
248 u32 d_id, u32 s_id, u16 ox_id,
249 int num_pages);
250u16 fc_prlo_acc_build(struct fchs_s *fchs, struct fc_prlo_acc_s *prlo_acc,
251 u32 d_id, u32 s_id, u16 ox_id,
252 int num_pages);
253u16 fc_logo_rsp_parse(struct fchs_s *fchs, int len);
254u16 fc_pdisc_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
255 u16 ox_id, wwn_t port_name, wwn_t node_name,
256 u16 pdu_size);
257u16 fc_pdisc_rsp_parse(struct fchs_s *fchs, int len, wwn_t port_name);
258u16 fc_prlo_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
259 u16 ox_id, int num_pages);
260u16 fc_prlo_rsp_parse(struct fchs_s *fchs, int len);
261u16 fc_tprlo_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
262 u16 ox_id, int num_pages,
263 enum fc_tprlo_type tprlo_type, u32 tpr_id);
264u16 fc_tprlo_rsp_parse(struct fchs_s *fchs, int len);
265u16 fc_ba_rjt_build(struct fchs_s *fchs, u32 d_id, u32 s_id,
266 u16 ox_id, u32 reason_code,
267 u32 reason_expl);
268u16 fc_gnnid_build(struct fchs_s *fchs, void *pyld, u32 s_id,
269 u16 ox_id, u32 port_id);
270u16 fc_ct_rsp_parse(struct ct_hdr_s *cthdr);
271u16 fc_rscn_build(struct fchs_s *fchs, struct fc_rscn_pl_s *rscn,
272 u32 s_id, u16 ox_id);
273#endif
diff --git a/drivers/scsi/bfa/fcpim.c b/drivers/scsi/bfa/fcpim.c
new file mode 100644
index 000000000000..8ce5d8934677
--- /dev/null
+++ b/drivers/scsi/bfa/fcpim.c
@@ -0,0 +1,844 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * fcpim.c - FCP initiator mode i-t nexus state machine
20 */
21
22#include <bfa.h>
23#include <bfa_svc.h>
24#include "fcs_fcpim.h"
25#include "fcs_rport.h"
26#include "fcs_lport.h"
27#include "fcs_trcmod.h"
28#include "fcs_fcxp.h"
29#include "fcs.h"
30#include <fcs/bfa_fcs_fcpim.h>
31#include <fcb/bfa_fcb_fcpim.h>
32#include <aen/bfa_aen_itnim.h>
33
34BFA_TRC_FILE(FCS, FCPIM);
35
36/*
37 * forward declarations
38 */
39static void bfa_fcs_itnim_timeout(void *arg);
40static void bfa_fcs_itnim_free(struct bfa_fcs_itnim_s *itnim);
41static void bfa_fcs_itnim_send_prli(void *itnim_cbarg,
42 struct bfa_fcxp_s *fcxp_alloced);
43static void bfa_fcs_itnim_prli_response(void *fcsarg,
44 struct bfa_fcxp_s *fcxp,
45 void *cbarg,
46 bfa_status_t req_status,
47 u32 rsp_len,
48 u32 resid_len,
49 struct fchs_s *rsp_fchs);
50static void bfa_fcs_itnim_aen_post(struct bfa_fcs_itnim_s *itnim,
51 enum bfa_itnim_aen_event event);
52
53/**
54 * fcs_itnim_sm FCS itnim state machine events
55 */
56
57enum bfa_fcs_itnim_event {
58 BFA_FCS_ITNIM_SM_ONLINE = 1, /* rport online event */
59 BFA_FCS_ITNIM_SM_OFFLINE = 2, /* rport offline */
60 BFA_FCS_ITNIM_SM_FRMSENT = 3, /* prli frame is sent */
61 BFA_FCS_ITNIM_SM_RSP_OK = 4, /* good response */
62 BFA_FCS_ITNIM_SM_RSP_ERROR = 5, /* error response */
63 BFA_FCS_ITNIM_SM_TIMEOUT = 6, /* delay timeout */
64 BFA_FCS_ITNIM_SM_HCB_OFFLINE = 7, /* BFA online callback */
65 BFA_FCS_ITNIM_SM_HCB_ONLINE = 8, /* BFA offline callback */
66 BFA_FCS_ITNIM_SM_INITIATOR = 9, /* rport is initiator */
67 BFA_FCS_ITNIM_SM_DELETE = 10, /* delete event from rport */
68 BFA_FCS_ITNIM_SM_PRLO = 11, /* delete event from rport */
69};
70
71static void bfa_fcs_itnim_sm_offline(struct bfa_fcs_itnim_s *itnim,
72 enum bfa_fcs_itnim_event event);
73static void bfa_fcs_itnim_sm_prli_send(struct bfa_fcs_itnim_s *itnim,
74 enum bfa_fcs_itnim_event event);
75static void bfa_fcs_itnim_sm_prli(struct bfa_fcs_itnim_s *itnim,
76 enum bfa_fcs_itnim_event event);
77static void bfa_fcs_itnim_sm_prli_retry(struct bfa_fcs_itnim_s *itnim,
78 enum bfa_fcs_itnim_event event);
79static void bfa_fcs_itnim_sm_hcb_online(struct bfa_fcs_itnim_s *itnim,
80 enum bfa_fcs_itnim_event event);
81static void bfa_fcs_itnim_sm_online(struct bfa_fcs_itnim_s *itnim,
82 enum bfa_fcs_itnim_event event);
83static void bfa_fcs_itnim_sm_hcb_offline(struct bfa_fcs_itnim_s *itnim,
84 enum bfa_fcs_itnim_event event);
85static void bfa_fcs_itnim_sm_initiator(struct bfa_fcs_itnim_s *itnim,
86 enum bfa_fcs_itnim_event event);
87
88static struct bfa_sm_table_s itnim_sm_table[] = {
89 {BFA_SM(bfa_fcs_itnim_sm_offline), BFA_ITNIM_OFFLINE},
90 {BFA_SM(bfa_fcs_itnim_sm_prli_send), BFA_ITNIM_PRLI_SEND},
91 {BFA_SM(bfa_fcs_itnim_sm_prli), BFA_ITNIM_PRLI_SENT},
92 {BFA_SM(bfa_fcs_itnim_sm_prli_retry), BFA_ITNIM_PRLI_RETRY},
93 {BFA_SM(bfa_fcs_itnim_sm_hcb_online), BFA_ITNIM_HCB_ONLINE},
94 {BFA_SM(bfa_fcs_itnim_sm_online), BFA_ITNIM_ONLINE},
95 {BFA_SM(bfa_fcs_itnim_sm_hcb_offline), BFA_ITNIM_HCB_OFFLINE},
96 {BFA_SM(bfa_fcs_itnim_sm_initiator), BFA_ITNIM_INITIATIOR},
97};
98
99/**
100 * fcs_itnim_sm FCS itnim state machine
101 */
102
103static void
104bfa_fcs_itnim_sm_offline(struct bfa_fcs_itnim_s *itnim,
105 enum bfa_fcs_itnim_event event)
106{
107 bfa_trc(itnim->fcs, itnim->rport->pwwn);
108 bfa_trc(itnim->fcs, event);
109
110 switch (event) {
111 case BFA_FCS_ITNIM_SM_ONLINE:
112 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_prli_send);
113 bfa_fcs_itnim_send_prli(itnim, NULL);
114 break;
115
116 case BFA_FCS_ITNIM_SM_OFFLINE:
117 bfa_fcs_rport_itnim_ack(itnim->rport);
118 break;
119
120 case BFA_FCS_ITNIM_SM_INITIATOR:
121 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_initiator);
122 break;
123
124 case BFA_FCS_ITNIM_SM_DELETE:
125 bfa_fcs_itnim_free(itnim);
126 break;
127
128 default:
129 bfa_assert(0);
130 }
131
132}
133
134static void
135bfa_fcs_itnim_sm_prli_send(struct bfa_fcs_itnim_s *itnim,
136 enum bfa_fcs_itnim_event event)
137{
138 bfa_trc(itnim->fcs, itnim->rport->pwwn);
139 bfa_trc(itnim->fcs, event);
140
141 switch (event) {
142 case BFA_FCS_ITNIM_SM_FRMSENT:
143 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_prli);
144 break;
145
146 case BFA_FCS_ITNIM_SM_INITIATOR:
147 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_initiator);
148 bfa_fcxp_walloc_cancel(itnim->fcs->bfa, &itnim->fcxp_wqe);
149 break;
150
151 case BFA_FCS_ITNIM_SM_OFFLINE:
152 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
153 bfa_fcxp_walloc_cancel(itnim->fcs->bfa, &itnim->fcxp_wqe);
154 bfa_fcs_rport_itnim_ack(itnim->rport);
155 break;
156
157 case BFA_FCS_ITNIM_SM_DELETE:
158 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
159 bfa_fcxp_walloc_cancel(itnim->fcs->bfa, &itnim->fcxp_wqe);
160 bfa_fcs_itnim_free(itnim);
161 break;
162
163 default:
164 bfa_assert(0);
165 }
166}
167
168static void
169bfa_fcs_itnim_sm_prli(struct bfa_fcs_itnim_s *itnim,
170 enum bfa_fcs_itnim_event event)
171{
172 bfa_trc(itnim->fcs, itnim->rport->pwwn);
173 bfa_trc(itnim->fcs, event);
174
175 switch (event) {
176 case BFA_FCS_ITNIM_SM_RSP_OK:
177 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_hcb_online);
178 bfa_itnim_online(itnim->bfa_itnim, itnim->seq_rec);
179 break;
180
181 case BFA_FCS_ITNIM_SM_RSP_ERROR:
182 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_prli_retry);
183 bfa_timer_start(itnim->fcs->bfa, &itnim->timer,
184 bfa_fcs_itnim_timeout, itnim,
185 BFA_FCS_RETRY_TIMEOUT);
186 break;
187
188 case BFA_FCS_ITNIM_SM_OFFLINE:
189 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
190 bfa_fcxp_discard(itnim->fcxp);
191 bfa_fcs_rport_itnim_ack(itnim->rport);
192 break;
193
194 case BFA_FCS_ITNIM_SM_INITIATOR:
195 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_initiator);
196 /*
197 * dont discard fcxp. accept will reach same state
198 */
199 break;
200
201 case BFA_FCS_ITNIM_SM_DELETE:
202 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
203 bfa_fcxp_discard(itnim->fcxp);
204 bfa_fcs_itnim_free(itnim);
205 break;
206
207 default:
208 bfa_assert(0);
209 }
210}
211
212static void
213bfa_fcs_itnim_sm_prli_retry(struct bfa_fcs_itnim_s *itnim,
214 enum bfa_fcs_itnim_event event)
215{
216 bfa_trc(itnim->fcs, itnim->rport->pwwn);
217 bfa_trc(itnim->fcs, event);
218
219 switch (event) {
220 case BFA_FCS_ITNIM_SM_TIMEOUT:
221 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_prli_send);
222 bfa_fcs_itnim_send_prli(itnim, NULL);
223 break;
224
225 case BFA_FCS_ITNIM_SM_OFFLINE:
226 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
227 bfa_timer_stop(&itnim->timer);
228 bfa_fcs_rport_itnim_ack(itnim->rport);
229 break;
230
231 case BFA_FCS_ITNIM_SM_INITIATOR:
232 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_initiator);
233 bfa_timer_stop(&itnim->timer);
234 break;
235
236 case BFA_FCS_ITNIM_SM_DELETE:
237 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
238 bfa_timer_stop(&itnim->timer);
239 bfa_fcs_itnim_free(itnim);
240 break;
241
242 default:
243 bfa_assert(0);
244 }
245}
246
247static void
248bfa_fcs_itnim_sm_hcb_online(struct bfa_fcs_itnim_s *itnim,
249 enum bfa_fcs_itnim_event event)
250{
251 bfa_trc(itnim->fcs, itnim->rport->pwwn);
252 bfa_trc(itnim->fcs, event);
253
254 switch (event) {
255 case BFA_FCS_ITNIM_SM_HCB_ONLINE:
256 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_online);
257 bfa_fcb_itnim_online(itnim->itnim_drv);
258 bfa_fcs_itnim_aen_post(itnim, BFA_ITNIM_AEN_ONLINE);
259 break;
260
261 case BFA_FCS_ITNIM_SM_OFFLINE:
262 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
263 bfa_itnim_offline(itnim->bfa_itnim);
264 bfa_fcs_rport_itnim_ack(itnim->rport);
265 break;
266
267 case BFA_FCS_ITNIM_SM_DELETE:
268 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
269 bfa_fcs_itnim_free(itnim);
270 break;
271
272 default:
273 bfa_assert(0);
274 }
275}
276
277static void
278bfa_fcs_itnim_sm_online(struct bfa_fcs_itnim_s *itnim,
279 enum bfa_fcs_itnim_event event)
280{
281 bfa_trc(itnim->fcs, itnim->rport->pwwn);
282 bfa_trc(itnim->fcs, event);
283
284 switch (event) {
285 case BFA_FCS_ITNIM_SM_OFFLINE:
286 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_hcb_offline);
287 bfa_fcb_itnim_offline(itnim->itnim_drv);
288 bfa_itnim_offline(itnim->bfa_itnim);
289 if (bfa_fcs_port_is_online(itnim->rport->port) == BFA_TRUE) {
290 bfa_fcs_itnim_aen_post(itnim, BFA_ITNIM_AEN_DISCONNECT);
291 } else {
292 bfa_fcs_itnim_aen_post(itnim, BFA_ITNIM_AEN_OFFLINE);
293 }
294 break;
295
296 case BFA_FCS_ITNIM_SM_DELETE:
297 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
298 bfa_fcs_itnim_free(itnim);
299 break;
300
301 default:
302 bfa_assert(0);
303 }
304}
305
306static void
307bfa_fcs_itnim_sm_hcb_offline(struct bfa_fcs_itnim_s *itnim,
308 enum bfa_fcs_itnim_event event)
309{
310 bfa_trc(itnim->fcs, itnim->rport->pwwn);
311 bfa_trc(itnim->fcs, event);
312
313 switch (event) {
314 case BFA_FCS_ITNIM_SM_HCB_OFFLINE:
315 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
316 bfa_fcs_rport_itnim_ack(itnim->rport);
317 break;
318
319 case BFA_FCS_ITNIM_SM_DELETE:
320 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
321 bfa_fcs_itnim_free(itnim);
322 break;
323
324 default:
325 bfa_assert(0);
326 }
327}
328
329/*
330 * This state is set when a discovered rport is also in intiator mode.
331 * This ITN is marked as no_op and is not active and will not be truned into
332 * online state.
333 */
334static void
335bfa_fcs_itnim_sm_initiator(struct bfa_fcs_itnim_s *itnim,
336 enum bfa_fcs_itnim_event event)
337{
338 bfa_trc(itnim->fcs, itnim->rport->pwwn);
339 bfa_trc(itnim->fcs, event);
340
341 switch (event) {
342 case BFA_FCS_ITNIM_SM_OFFLINE:
343 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
344 bfa_fcs_rport_itnim_ack(itnim->rport);
345 break;
346
347 case BFA_FCS_ITNIM_SM_RSP_ERROR:
348 case BFA_FCS_ITNIM_SM_ONLINE:
349 case BFA_FCS_ITNIM_SM_INITIATOR:
350 break;
351
352 case BFA_FCS_ITNIM_SM_DELETE:
353 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
354 bfa_fcs_itnim_free(itnim);
355 break;
356
357 default:
358 bfa_assert(0);
359 }
360}
361
362
363
364/**
365 * itnim_private FCS ITNIM private interfaces
366 */
367
368static void
369bfa_fcs_itnim_aen_post(struct bfa_fcs_itnim_s *itnim,
370 enum bfa_itnim_aen_event event)
371{
372 struct bfa_fcs_rport_s *rport = itnim->rport;
373 union bfa_aen_data_u aen_data;
374 struct bfa_log_mod_s *logmod = rport->fcs->logm;
375 wwn_t lpwwn = bfa_fcs_port_get_pwwn(rport->port);
376 wwn_t rpwwn = rport->pwwn;
377 char lpwwn_ptr[BFA_STRING_32];
378 char rpwwn_ptr[BFA_STRING_32];
379
380 /*
381 * Don't post events for well known addresses
382 */
383 if (BFA_FCS_PID_IS_WKA(rport->pid))
384 return;
385
386 wwn2str(lpwwn_ptr, lpwwn);
387 wwn2str(rpwwn_ptr, rpwwn);
388
389 switch (event) {
390 case BFA_ITNIM_AEN_ONLINE:
391 bfa_log(logmod, BFA_AEN_ITNIM_ONLINE, rpwwn_ptr, lpwwn_ptr);
392 break;
393 case BFA_ITNIM_AEN_OFFLINE:
394 bfa_log(logmod, BFA_AEN_ITNIM_OFFLINE, rpwwn_ptr, lpwwn_ptr);
395 break;
396 case BFA_ITNIM_AEN_DISCONNECT:
397 bfa_log(logmod, BFA_AEN_ITNIM_DISCONNECT, rpwwn_ptr, lpwwn_ptr);
398 break;
399 default:
400 break;
401 }
402
403 aen_data.itnim.vf_id = rport->port->fabric->vf_id;
404 aen_data.itnim.ppwwn =
405 bfa_fcs_port_get_pwwn(bfa_fcs_get_base_port(itnim->fcs));
406 aen_data.itnim.lpwwn = lpwwn;
407 aen_data.itnim.rpwwn = rpwwn;
408}
409
410static void
411bfa_fcs_itnim_send_prli(void *itnim_cbarg, struct bfa_fcxp_s *fcxp_alloced)
412{
413 struct bfa_fcs_itnim_s *itnim = itnim_cbarg;
414 struct bfa_fcs_rport_s *rport = itnim->rport;
415 struct bfa_fcs_port_s *port = rport->port;
416 struct fchs_s fchs;
417 struct bfa_fcxp_s *fcxp;
418 int len;
419
420 bfa_trc(itnim->fcs, itnim->rport->pwwn);
421
422 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
423 if (!fcxp) {
424 itnim->stats.fcxp_alloc_wait++;
425 bfa_fcxp_alloc_wait(port->fcs->bfa, &itnim->fcxp_wqe,
426 bfa_fcs_itnim_send_prli, itnim);
427 return;
428 }
429 itnim->fcxp = fcxp;
430
431 len = fc_prli_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), itnim->rport->pid,
432 bfa_fcs_port_get_fcid(port), 0);
433
434 bfa_fcxp_send(fcxp, rport->bfa_rport, port->fabric->vf_id, port->lp_tag,
435 BFA_FALSE, FC_CLASS_3, len, &fchs,
436 bfa_fcs_itnim_prli_response, (void *)itnim, FC_MAX_PDUSZ,
437 FC_RA_TOV);
438
439 itnim->stats.prli_sent++;
440 bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_FRMSENT);
441}
442
443static void
444bfa_fcs_itnim_prli_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
445 bfa_status_t req_status, u32 rsp_len,
446 u32 resid_len, struct fchs_s *rsp_fchs)
447{
448 struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *)cbarg;
449 struct fc_els_cmd_s *els_cmd;
450 struct fc_prli_s *prli_resp;
451 struct fc_ls_rjt_s *ls_rjt;
452 struct fc_prli_params_s *sparams;
453
454 bfa_trc(itnim->fcs, req_status);
455
456 /*
457 * Sanity Checks
458 */
459 if (req_status != BFA_STATUS_OK) {
460 itnim->stats.prli_rsp_err++;
461 bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_RSP_ERROR);
462 return;
463 }
464
465 els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp);
466
467 if (els_cmd->els_code == FC_ELS_ACC) {
468 prli_resp = (struct fc_prli_s *) els_cmd;
469
470 if (fc_prli_rsp_parse(prli_resp, rsp_len) != FC_PARSE_OK) {
471 bfa_trc(itnim->fcs, rsp_len);
472 /*
473 * Check if this r-port is also in Initiator mode.
474 * If so, we need to set this ITN as a no-op.
475 */
476 if (prli_resp->parampage.servparams.initiator) {
477 bfa_trc(itnim->fcs, prli_resp->parampage.type);
478 itnim->rport->scsi_function =
479 BFA_RPORT_INITIATOR;
480 itnim->stats.prli_rsp_acc++;
481 bfa_sm_send_event(itnim,
482 BFA_FCS_ITNIM_SM_INITIATOR);
483 return;
484 }
485
486 itnim->stats.prli_rsp_parse_err++;
487 return;
488 }
489 itnim->rport->scsi_function = BFA_RPORT_TARGET;
490
491 sparams = &prli_resp->parampage.servparams;
492 itnim->seq_rec = sparams->retry;
493 itnim->rec_support = sparams->rec_support;
494 itnim->task_retry_id = sparams->task_retry_id;
495 itnim->conf_comp = sparams->confirm;
496
497 itnim->stats.prli_rsp_acc++;
498 bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_RSP_OK);
499 } else {
500 ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
501
502 bfa_trc(itnim->fcs, ls_rjt->reason_code);
503 bfa_trc(itnim->fcs, ls_rjt->reason_code_expl);
504
505 itnim->stats.prli_rsp_rjt++;
506 bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_RSP_ERROR);
507 }
508}
509
510static void
511bfa_fcs_itnim_timeout(void *arg)
512{
513 struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *)arg;
514
515 itnim->stats.timeout++;
516 bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_TIMEOUT);
517}
518
519static void
520bfa_fcs_itnim_free(struct bfa_fcs_itnim_s *itnim)
521{
522 bfa_itnim_delete(itnim->bfa_itnim);
523 bfa_fcb_itnim_free(itnim->fcs->bfad, itnim->itnim_drv);
524}
525
526
527
528/**
529 * itnim_public FCS ITNIM public interfaces
530 */
531
532/**
533 * Called by rport when a new rport is created.
534 *
535 * @param[in] rport - remote port.
536 */
537struct bfa_fcs_itnim_s *
538bfa_fcs_itnim_create(struct bfa_fcs_rport_s *rport)
539{
540 struct bfa_fcs_port_s *port = rport->port;
541 struct bfa_fcs_itnim_s *itnim;
542 struct bfad_itnim_s *itnim_drv;
543 struct bfa_itnim_s *bfa_itnim;
544
545 /*
546 * call bfad to allocate the itnim
547 */
548 bfa_fcb_itnim_alloc(port->fcs->bfad, &itnim, &itnim_drv);
549 if (itnim == NULL) {
550 bfa_trc(port->fcs, rport->pwwn);
551 return NULL;
552 }
553
554 /*
555 * Initialize itnim
556 */
557 itnim->rport = rport;
558 itnim->fcs = rport->fcs;
559 itnim->itnim_drv = itnim_drv;
560
561 /*
562 * call BFA to create the itnim
563 */
564 bfa_itnim = bfa_itnim_create(port->fcs->bfa, rport->bfa_rport, itnim);
565
566 if (bfa_itnim == NULL) {
567 bfa_trc(port->fcs, rport->pwwn);
568 bfa_fcb_itnim_free(port->fcs->bfad, itnim_drv);
569 bfa_assert(0);
570 return NULL;
571 }
572
573 itnim->bfa_itnim = bfa_itnim;
574 itnim->seq_rec = BFA_FALSE;
575 itnim->rec_support = BFA_FALSE;
576 itnim->conf_comp = BFA_FALSE;
577 itnim->task_retry_id = BFA_FALSE;
578
579 /*
580 * Set State machine
581 */
582 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline);
583
584 return itnim;
585}
586
587/**
588 * Called by rport to delete the instance of FCPIM.
589 *
590 * @param[in] rport - remote port.
591 */
592void
593bfa_fcs_itnim_delete(struct bfa_fcs_itnim_s *itnim)
594{
595 bfa_trc(itnim->fcs, itnim->rport->pid);
596 bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_DELETE);
597}
598
599/**
600 * Notification from rport that PLOGI is complete to initiate FC-4 session.
601 */
602void
603bfa_fcs_itnim_rport_online(struct bfa_fcs_itnim_s *itnim)
604{
605 itnim->stats.onlines++;
606
607 if (!BFA_FCS_PID_IS_WKA(itnim->rport->pid)) {
608 bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_ONLINE);
609 } else {
610 /*
611 * For well known addresses, we set the itnim to initiator
612 * state
613 */
614 itnim->stats.initiator++;
615 bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_INITIATOR);
616 }
617}
618
619/**
620 * Called by rport to handle a remote device offline.
621 */
622void
623bfa_fcs_itnim_rport_offline(struct bfa_fcs_itnim_s *itnim)
624{
625 itnim->stats.offlines++;
626 bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_OFFLINE);
627}
628
629/**
630 * Called by rport when remote port is known to be an initiator from
631 * PRLI received.
632 */
633void
634bfa_fcs_itnim_is_initiator(struct bfa_fcs_itnim_s *itnim)
635{
636 bfa_trc(itnim->fcs, itnim->rport->pid);
637 itnim->stats.initiator++;
638 bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_INITIATOR);
639}
640
641/**
642 * Called by rport to check if the itnim is online.
643 */
644bfa_status_t
645bfa_fcs_itnim_get_online_state(struct bfa_fcs_itnim_s *itnim)
646{
647 bfa_trc(itnim->fcs, itnim->rport->pid);
648 switch (bfa_sm_to_state(itnim_sm_table, itnim->sm)) {
649 case BFA_ITNIM_ONLINE:
650 case BFA_ITNIM_INITIATIOR:
651 return BFA_STATUS_OK;
652
653 default:
654 return BFA_STATUS_NO_FCPIM_NEXUS;
655
656 }
657}
658
659/**
660 * BFA completion callback for bfa_itnim_online().
661 */
662void
663bfa_cb_itnim_online(void *cbarg)
664{
665 struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *)cbarg;
666
667 bfa_trc(itnim->fcs, itnim->rport->pwwn);
668 bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_HCB_ONLINE);
669}
670
671/**
672 * BFA completion callback for bfa_itnim_offline().
673 */
674void
675bfa_cb_itnim_offline(void *cb_arg)
676{
677 struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *)cb_arg;
678
679 bfa_trc(itnim->fcs, itnim->rport->pwwn);
680 bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_HCB_OFFLINE);
681}
682
683/**
684 * Mark the beginning of PATH TOV handling. IO completion callbacks
685 * are still pending.
686 */
687void
688bfa_cb_itnim_tov_begin(void *cb_arg)
689{
690 struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *)cb_arg;
691
692 bfa_trc(itnim->fcs, itnim->rport->pwwn);
693 bfa_fcb_itnim_tov_begin(itnim->itnim_drv);
694}
695
696/**
697 * Mark the end of PATH TOV handling. All pending IOs are already cleaned up.
698 */
699void
700bfa_cb_itnim_tov(void *cb_arg)
701{
702 struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *)cb_arg;
703
704 bfa_trc(itnim->fcs, itnim->rport->pwwn);
705 bfa_fcb_itnim_tov(itnim->itnim_drv);
706}
707
708/**
709 * BFA notification to FCS/driver for second level error recovery.
710 *
711 * Atleast one I/O request has timedout and target is unresponsive to
712 * repeated abort requests. Second level error recovery should be initiated
713 * by starting implicit logout and recovery procedures.
714 */
715void
716bfa_cb_itnim_sler(void *cb_arg)
717{
718 struct bfa_fcs_itnim_s *itnim = (struct bfa_fcs_itnim_s *)cb_arg;
719
720 itnim->stats.sler++;
721 bfa_trc(itnim->fcs, itnim->rport->pwwn);
722 bfa_fcs_rport_logo_imp(itnim->rport);
723}
724
725struct bfa_fcs_itnim_s *
726bfa_fcs_itnim_lookup(struct bfa_fcs_port_s *port, wwn_t rpwwn)
727{
728 struct bfa_fcs_rport_s *rport;
729 rport = bfa_fcs_rport_lookup(port, rpwwn);
730
731 if (!rport)
732 return NULL;
733
734 bfa_assert(rport->itnim != NULL);
735 return (rport->itnim);
736}
737
738bfa_status_t
739bfa_fcs_itnim_attr_get(struct bfa_fcs_port_s *port, wwn_t rpwwn,
740 struct bfa_itnim_attr_s *attr)
741{
742 struct bfa_fcs_itnim_s *itnim = NULL;
743
744 itnim = bfa_fcs_itnim_lookup(port, rpwwn);
745
746 if (itnim == NULL)
747 return BFA_STATUS_NO_FCPIM_NEXUS;
748
749 attr->state = bfa_sm_to_state(itnim_sm_table, itnim->sm);
750 attr->retry = itnim->seq_rec;
751 attr->rec_support = itnim->rec_support;
752 attr->conf_comp = itnim->conf_comp;
753 attr->task_retry_id = itnim->task_retry_id;
754
755 return BFA_STATUS_OK;
756}
757
758bfa_status_t
759bfa_fcs_itnim_stats_get(struct bfa_fcs_port_s *port, wwn_t rpwwn,
760 struct bfa_itnim_stats_s *stats)
761{
762 struct bfa_fcs_itnim_s *itnim = NULL;
763
764 bfa_assert(port != NULL);
765
766 itnim = bfa_fcs_itnim_lookup(port, rpwwn);
767
768 if (itnim == NULL)
769 return BFA_STATUS_NO_FCPIM_NEXUS;
770
771 bfa_os_memcpy(stats, &itnim->stats, sizeof(struct bfa_itnim_stats_s));
772
773 return BFA_STATUS_OK;
774}
775
776bfa_status_t
777bfa_fcs_itnim_stats_clear(struct bfa_fcs_port_s *port, wwn_t rpwwn)
778{
779 struct bfa_fcs_itnim_s *itnim = NULL;
780
781 bfa_assert(port != NULL);
782
783 itnim = bfa_fcs_itnim_lookup(port, rpwwn);
784
785 if (itnim == NULL)
786 return BFA_STATUS_NO_FCPIM_NEXUS;
787
788 bfa_os_memset(&itnim->stats, 0, sizeof(struct bfa_itnim_stats_s));
789 return BFA_STATUS_OK;
790}
791
792void
793bfa_fcs_fcpim_uf_recv(struct bfa_fcs_itnim_s *itnim, struct fchs_s *fchs,
794 u16 len)
795{
796 struct fc_els_cmd_s *els_cmd;
797
798 bfa_trc(itnim->fcs, fchs->type);
799
800 if (fchs->type != FC_TYPE_ELS)
801 return;
802
803 els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
804
805 bfa_trc(itnim->fcs, els_cmd->els_code);
806
807 switch (els_cmd->els_code) {
808 case FC_ELS_PRLO:
809 /* bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_PRLO); */
810 break;
811
812 default:
813 bfa_assert(0);
814 }
815}
816
817void
818bfa_fcs_itnim_pause(struct bfa_fcs_itnim_s *itnim)
819{
820}
821
822void
823bfa_fcs_itnim_resume(struct bfa_fcs_itnim_s *itnim)
824{
825}
826
827/**
828 * Module initialization
829 */
830void
831bfa_fcs_fcpim_modinit(struct bfa_fcs_s *fcs)
832{
833}
834
835/**
836 * Module cleanup
837 */
838void
839bfa_fcs_fcpim_modexit(struct bfa_fcs_s *fcs)
840{
841 bfa_fcs_modexit_comp(fcs);
842}
843
844
diff --git a/drivers/scsi/bfa/fcptm.c b/drivers/scsi/bfa/fcptm.c
new file mode 100644
index 000000000000..8c8b08c72e7a
--- /dev/null
+++ b/drivers/scsi/bfa/fcptm.c
@@ -0,0 +1,68 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * This file contains dummy FCPTM routines to aid in Initiator Mode only
20 * compilation of OS driver.
21 *
22 */
23
24#include "bfa_os_inc.h"
25#include "fcs_rport.h"
26#include "fcs_fcptm.h"
27#include "fcs/bfa_fcs_rport.h"
28
29struct bfa_fcs_tin_s *
30bfa_fcs_tin_create(struct bfa_fcs_rport_s *rport)
31{
32 return NULL;
33}
34
35void
36bfa_fcs_tin_delete(struct bfa_fcs_tin_s *tin)
37{
38}
39
40void
41bfa_fcs_tin_rport_offline(struct bfa_fcs_tin_s *tin)
42{
43}
44
45void
46bfa_fcs_tin_rport_online(struct bfa_fcs_tin_s *tin)
47{
48}
49
50void
51bfa_fcs_tin_rx_prli(struct bfa_fcs_tin_s *tin, struct fchs_s *fchs, u16 len)
52{
53}
54
55void
56bfa_fcs_fcptm_uf_recv(struct bfa_fcs_tin_s *tin, struct fchs_s *fchs, u16 len)
57{
58}
59
60void
61bfa_fcs_tin_pause(struct bfa_fcs_tin_s *tin)
62{
63}
64
65void
66bfa_fcs_tin_resume(struct bfa_fcs_tin_s *tin)
67{
68}
diff --git a/drivers/scsi/bfa/fcs.h b/drivers/scsi/bfa/fcs.h
new file mode 100644
index 000000000000..deee685e8478
--- /dev/null
+++ b/drivers/scsi/bfa/fcs.h
@@ -0,0 +1,30 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * fcs.h FCS module functions
20 */
21
22
23#ifndef __FCS_H__
24#define __FCS_H__
25
26#define __fcs_min_cfg(__fcs) (__fcs)->min_cfg
27
28void bfa_fcs_modexit_comp(struct bfa_fcs_s *fcs);
29
30#endif /* __FCS_H__ */
diff --git a/drivers/scsi/bfa/fcs_auth.h b/drivers/scsi/bfa/fcs_auth.h
new file mode 100644
index 000000000000..65d155fea3d7
--- /dev/null
+++ b/drivers/scsi/bfa/fcs_auth.h
@@ -0,0 +1,37 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * fcs_uf.h FCS unsolicited frame receive
20 */
21
22
23#ifndef __FCS_AUTH_H__
24#define __FCS_AUTH_H__
25
26#include <fcs/bfa_fcs.h>
27#include <fcs/bfa_fcs_vport.h>
28#include <fcs/bfa_fcs_lport.h>
29
30/*
31 * fcs friend functions: only between fcs modules
32 */
33void bfa_fcs_auth_uf_recv(struct bfa_fcs_fabric_s *fabric, int len);
34void bfa_fcs_auth_start(struct bfa_fcs_fabric_s *fabric);
35void bfa_fcs_auth_stop(struct bfa_fcs_fabric_s *fabric);
36
37#endif /* __FCS_UF_H__ */
diff --git a/drivers/scsi/bfa/fcs_fabric.h b/drivers/scsi/bfa/fcs_fabric.h
new file mode 100644
index 000000000000..eee960820f86
--- /dev/null
+++ b/drivers/scsi/bfa/fcs_fabric.h
@@ -0,0 +1,61 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * fcs_lport.h FCS logical port interfaces
20 */
21
22#ifndef __FCS_FABRIC_H__
23#define __FCS_FABRIC_H__
24
25#include <fcs/bfa_fcs.h>
26#include <fcs/bfa_fcs_vport.h>
27#include <fcs/bfa_fcs_lport.h>
28
29/*
30* fcs friend functions: only between fcs modules
31 */
32void bfa_fcs_fabric_modinit(struct bfa_fcs_s *fcs);
33void bfa_fcs_fabric_modexit(struct bfa_fcs_s *fcs);
34void bfa_fcs_fabric_modsusp(struct bfa_fcs_s *fcs);
35void bfa_fcs_fabric_link_up(struct bfa_fcs_fabric_s *fabric);
36void bfa_fcs_fabric_link_down(struct bfa_fcs_fabric_s *fabric);
37void bfa_fcs_fabric_addvport(struct bfa_fcs_fabric_s *fabric,
38 struct bfa_fcs_vport_s *vport);
39void bfa_fcs_fabric_delvport(struct bfa_fcs_fabric_s *fabric,
40 struct bfa_fcs_vport_s *vport);
41int bfa_fcs_fabric_is_online(struct bfa_fcs_fabric_s *fabric);
42struct bfa_fcs_vport_s *bfa_fcs_fabric_vport_lookup(
43 struct bfa_fcs_fabric_s *fabric, wwn_t pwwn);
44void bfa_fcs_fabric_modstart(struct bfa_fcs_s *fcs);
45void bfa_fcs_fabric_uf_recv(struct bfa_fcs_fabric_s *fabric,
46 struct fchs_s *fchs, u16 len);
47u16 bfa_fcs_fabric_vport_count(struct bfa_fcs_fabric_s *fabric);
48bfa_boolean_t bfa_fcs_fabric_is_loopback(struct bfa_fcs_fabric_s *fabric);
49enum bfa_pport_type bfa_fcs_fabric_port_type(struct bfa_fcs_fabric_s *fabric);
50void bfa_fcs_fabric_psymb_init(struct bfa_fcs_fabric_s *fabric);
51void bfa_fcs_fabric_port_delete_comp(struct bfa_fcs_fabric_s *fabric);
52
53bfa_status_t bfa_fcs_fabric_addvf(struct bfa_fcs_fabric_s *vf,
54 struct bfa_fcs_s *fcs, struct bfa_port_cfg_s *port_cfg,
55 struct bfad_vf_s *vf_drv);
56void bfa_fcs_auth_finished(struct bfa_fcs_fabric_s *fabric,
57 enum auth_status status);
58
59void bfa_fcs_fabric_set_fabric_name(struct bfa_fcs_fabric_s *fabric,
60 wwn_t fabric_name);
61#endif /* __FCS_FABRIC_H__ */
diff --git a/drivers/scsi/bfa/fcs_fcpim.h b/drivers/scsi/bfa/fcs_fcpim.h
new file mode 100644
index 000000000000..61e9e2687de3
--- /dev/null
+++ b/drivers/scsi/bfa/fcs_fcpim.h
@@ -0,0 +1,44 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17#ifndef __FCS_FCPIM_H__
18#define __FCS_FCPIM_H__
19
20#include <defs/bfa_defs_port.h>
21#include <fcs/bfa_fcs_lport.h>
22#include <fcs/bfa_fcs_rport.h>
23
24/*
25 * Following routines are from FCPIM and will be called by rport.
26 */
27struct bfa_fcs_itnim_s *bfa_fcs_itnim_create(struct bfa_fcs_rport_s *rport);
28void bfa_fcs_itnim_delete(struct bfa_fcs_itnim_s *itnim);
29void bfa_fcs_itnim_rport_offline(struct bfa_fcs_itnim_s *itnim);
30void bfa_fcs_itnim_rport_online(struct bfa_fcs_itnim_s *itnim);
31bfa_status_t bfa_fcs_itnim_get_online_state(struct bfa_fcs_itnim_s *itnim);
32
33void bfa_fcs_itnim_is_initiator(struct bfa_fcs_itnim_s *itnim);
34void bfa_fcs_itnim_pause(struct bfa_fcs_itnim_s *itnim);
35void bfa_fcs_itnim_resume(struct bfa_fcs_itnim_s *itnim);
36
37/*
38 * Modudle init/cleanup routines.
39 */
40void bfa_fcs_fcpim_modinit(struct bfa_fcs_s *fcs);
41void bfa_fcs_fcpim_modexit(struct bfa_fcs_s *fcs);
42void bfa_fcs_fcpim_uf_recv(struct bfa_fcs_itnim_s *itnim, struct fchs_s *fchs,
43 u16 len);
44#endif /* __FCS_FCPIM_H__ */
diff --git a/drivers/scsi/bfa/fcs_fcptm.h b/drivers/scsi/bfa/fcs_fcptm.h
new file mode 100644
index 000000000000..ffff0829fd31
--- /dev/null
+++ b/drivers/scsi/bfa/fcs_fcptm.h
@@ -0,0 +1,45 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __FCS_FCPTM_H__
19#define __FCS_FCPTM_H__
20
21#include <defs/bfa_defs_port.h>
22#include <fcs/bfa_fcs_lport.h>
23#include <fcs/bfa_fcs_rport.h>
24
25/*
26 * Following routines are from FCPTM and will be called by rport.
27 */
28struct bfa_fcs_tin_s *bfa_fcs_tin_create(struct bfa_fcs_rport_s *rport);
29void bfa_fcs_tin_rport_offline(struct bfa_fcs_tin_s *tin);
30void bfa_fcs_tin_rport_online(struct bfa_fcs_tin_s *tin);
31void bfa_fcs_tin_delete(struct bfa_fcs_tin_s *tin);
32void bfa_fcs_tin_rx_prli(struct bfa_fcs_tin_s *tin, struct fchs_s *fchs,
33 u16 len);
34void bfa_fcs_tin_pause(struct bfa_fcs_tin_s *tin);
35void bfa_fcs_tin_resume(struct bfa_fcs_tin_s *tin);
36
37/*
38 * Modudle init/cleanup routines.
39 */
40void bfa_fcs_fcptm_modinit(struct bfa_fcs_s *fcs);
41void bfa_fcs_fcptm_modexit(struct bfa_fcs_s *fcs);
42void bfa_fcs_fcptm_uf_recv(struct bfa_fcs_tin_s *tin, struct fchs_s *fchs,
43 u16 len);
44
45#endif /* __FCS_FCPTM_H__ */
diff --git a/drivers/scsi/bfa/fcs_fcxp.h b/drivers/scsi/bfa/fcs_fcxp.h
new file mode 100644
index 000000000000..8277fe9c2b70
--- /dev/null
+++ b/drivers/scsi/bfa/fcs_fcxp.h
@@ -0,0 +1,29 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * fcs_fcxp.h FCXP helper macros for FCS
20 */
21
22
23#ifndef __FCS_FCXP_H__
24#define __FCS_FCXP_H__
25
26#define bfa_fcs_fcxp_alloc(__fcs) \
27 bfa_fcxp_alloc(NULL, (__fcs)->bfa, 0, 0, NULL, NULL, NULL, NULL)
28
29#endif /* __FCS_FCXP_H__ */
diff --git a/drivers/scsi/bfa/fcs_lport.h b/drivers/scsi/bfa/fcs_lport.h
new file mode 100644
index 000000000000..ae744ba35671
--- /dev/null
+++ b/drivers/scsi/bfa/fcs_lport.h
@@ -0,0 +1,117 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * fcs_lport.h FCS logical port interfaces
20 */
21
22#ifndef __FCS_LPORT_H__
23#define __FCS_LPORT_H__
24
25#define __VPORT_H__
26#include <defs/bfa_defs_port.h>
27#include <bfa_svc.h>
28#include <fcs/bfa_fcs_lport.h>
29#include <fcs/bfa_fcs_rport.h>
30#include <fcs/bfa_fcs_vport.h>
31#include <fcs_fabric.h>
32#include <fcs_ms.h>
33#include <cs/bfa_q.h>
34#include <fcbuild.h>
35
36/*
37 * PID used in P2P/N2N ( In Big Endian)
38 */
39#define N2N_LOCAL_PID 0x010000
40#define N2N_REMOTE_PID 0x020000
41
42/*
43 * Misc Timeouts
44 */
45/*
46 * To be used when spawning a timer before retrying a failed command. Milli
47 * Secs.
48 */
49#define BFA_FCS_RETRY_TIMEOUT 2000
50
51/*
52 * Check for Port/Vport Mode/Role
53 */
54#define BFA_FCS_VPORT_IS_INITIATOR_MODE(port) \
55 (port->port_cfg.roles & BFA_PORT_ROLE_FCP_IM)
56
57#define BFA_FCS_VPORT_IS_TARGET_MODE(port) \
58 (port->port_cfg.roles & BFA_PORT_ROLE_FCP_TM)
59
60#define BFA_FCS_VPORT_IS_IPFC_MODE(port) \
61 (port->port_cfg.roles & BFA_PORT_ROLE_FCP_IPFC)
62
63/*
64 * Is this a Well Known Address
65 */
66#define BFA_FCS_PID_IS_WKA(pid) ((bfa_os_ntoh3b(pid) > 0xFFF000) ? 1 : 0)
67
68/*
69 * Pointer to elements within Port
70 */
71#define BFA_FCS_GET_HAL_FROM_PORT(port) (port->fcs->bfa)
72#define BFA_FCS_GET_NS_FROM_PORT(port) (&port->port_topo.pfab.ns)
73#define BFA_FCS_GET_SCN_FROM_PORT(port) (&port->port_topo.pfab.scn)
74#define BFA_FCS_GET_MS_FROM_PORT(port) (&port->port_topo.pfab.ms)
75#define BFA_FCS_GET_FDMI_FROM_PORT(port) (&port->port_topo.pfab.ms.fdmi)
76
77/*
78 * handler for unsolicied frames
79 */
80void bfa_fcs_port_uf_recv(struct bfa_fcs_port_s *lport, struct fchs_s *fchs,
81 u16 len);
82
83/*
84 * Following routines will be called by Fabric to indicate port
85 * online/offline to vport.
86 */
87void bfa_fcs_lport_init(struct bfa_fcs_port_s *lport, struct bfa_fcs_s *fcs,
88 u16 vf_id, struct bfa_port_cfg_s *port_cfg,
89 struct bfa_fcs_vport_s *vport);
90void bfa_fcs_port_online(struct bfa_fcs_port_s *port);
91void bfa_fcs_port_offline(struct bfa_fcs_port_s *port);
92void bfa_fcs_port_delete(struct bfa_fcs_port_s *port);
93bfa_boolean_t bfa_fcs_port_is_online(struct bfa_fcs_port_s *port);
94
95/*
96 * Lookup rport based on PID
97 */
98struct bfa_fcs_rport_s *bfa_fcs_port_get_rport_by_pid(
99 struct bfa_fcs_port_s *port, u32 pid);
100
101/*
102 * Lookup rport based on PWWN
103 */
104struct bfa_fcs_rport_s *bfa_fcs_port_get_rport_by_pwwn(
105 struct bfa_fcs_port_s *port, wwn_t pwwn);
106struct bfa_fcs_rport_s *bfa_fcs_port_get_rport_by_nwwn(
107 struct bfa_fcs_port_s *port, wwn_t nwwn);
108void bfa_fcs_port_add_rport(struct bfa_fcs_port_s *port,
109 struct bfa_fcs_rport_s *rport);
110void bfa_fcs_port_del_rport(struct bfa_fcs_port_s *port,
111 struct bfa_fcs_rport_s *rport);
112
113void bfa_fcs_port_modinit(struct bfa_fcs_s *fcs);
114void bfa_fcs_port_modexit(struct bfa_fcs_s *fcs);
115void bfa_fcs_port_lip(struct bfa_fcs_port_s *port);
116
117#endif /* __FCS_LPORT_H__ */
diff --git a/drivers/scsi/bfa/fcs_ms.h b/drivers/scsi/bfa/fcs_ms.h
new file mode 100644
index 000000000000..b6a8c12876f4
--- /dev/null
+++ b/drivers/scsi/bfa/fcs_ms.h
@@ -0,0 +1,35 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * fcs_ms.h FCS ms interfaces
20 */
21#ifndef __FCS_MS_H__
22#define __FCS_MS_H__
23
24/* MS FCS routines */
25void bfa_fcs_port_ms_init(struct bfa_fcs_port_s *port);
26void bfa_fcs_port_ms_offline(struct bfa_fcs_port_s *port);
27void bfa_fcs_port_ms_online(struct bfa_fcs_port_s *port);
28void bfa_fcs_port_ms_fabric_rscn(struct bfa_fcs_port_s *port);
29
30/* FDMI FCS routines */
31void bfa_fcs_port_fdmi_init(struct bfa_fcs_port_ms_s *ms);
32void bfa_fcs_port_fdmi_offline(struct bfa_fcs_port_ms_s *ms);
33void bfa_fcs_port_fdmi_online(struct bfa_fcs_port_ms_s *ms);
34
35#endif
diff --git a/drivers/scsi/bfa/fcs_port.h b/drivers/scsi/bfa/fcs_port.h
new file mode 100644
index 000000000000..abb65191dd27
--- /dev/null
+++ b/drivers/scsi/bfa/fcs_port.h
@@ -0,0 +1,32 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * fcs_pport.h FCS physical port interfaces
20 */
21
22
23#ifndef __FCS_PPORT_H__
24#define __FCS_PPORT_H__
25
26/*
27 * fcs friend functions: only between fcs modules
28 */
29void bfa_fcs_pport_modinit(struct bfa_fcs_s *fcs);
30void bfa_fcs_pport_modexit(struct bfa_fcs_s *fcs);
31
32#endif /* __FCS_PPORT_H__ */
diff --git a/drivers/scsi/bfa/fcs_rport.h b/drivers/scsi/bfa/fcs_rport.h
new file mode 100644
index 000000000000..f601e9d74236
--- /dev/null
+++ b/drivers/scsi/bfa/fcs_rport.h
@@ -0,0 +1,61 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * fcs_rport.h FCS rport interfaces and defines
20 */
21
22#ifndef __FCS_RPORT_H__
23#define __FCS_RPORT_H__
24
25#include <fcs/bfa_fcs_rport.h>
26
27void bfa_fcs_rport_modinit(struct bfa_fcs_s *fcs);
28void bfa_fcs_rport_modexit(struct bfa_fcs_s *fcs);
29
30void bfa_fcs_rport_uf_recv(struct bfa_fcs_rport_s *rport, struct fchs_s *fchs,
31 u16 len);
32void bfa_fcs_rport_scn(struct bfa_fcs_rport_s *rport);
33
34struct bfa_fcs_rport_s *bfa_fcs_rport_create(struct bfa_fcs_port_s *port,
35 u32 pid);
36void bfa_fcs_rport_delete(struct bfa_fcs_rport_s *rport);
37void bfa_fcs_rport_online(struct bfa_fcs_rport_s *rport);
38void bfa_fcs_rport_offline(struct bfa_fcs_rport_s *rport);
39void bfa_fcs_rport_start(struct bfa_fcs_port_s *port, struct fchs_s *rx_fchs,
40 struct fc_logi_s *plogi_rsp);
41void bfa_fcs_rport_plogi_create(struct bfa_fcs_port_s *port,
42 struct fchs_s *rx_fchs,
43 struct fc_logi_s *plogi);
44void bfa_fcs_rport_plogi(struct bfa_fcs_rport_s *rport, struct fchs_s *fchs,
45 struct fc_logi_s *plogi);
46void bfa_fcs_rport_logo_imp(struct bfa_fcs_rport_s *rport);
47void bfa_fcs_rport_itnim_ack(struct bfa_fcs_rport_s *rport);
48void bfa_fcs_rport_itntm_ack(struct bfa_fcs_rport_s *rport);
49void bfa_fcs_rport_tin_ack(struct bfa_fcs_rport_s *rport);
50void bfa_fcs_rport_fcptm_offline_done(struct bfa_fcs_rport_s *rport);
51int bfa_fcs_rport_get_state(struct bfa_fcs_rport_s *rport);
52struct bfa_fcs_rport_s *bfa_fcs_rport_create_by_wwn(struct bfa_fcs_port_s *port,
53 wwn_t wwn);
54
55
56/* Rport Features */
57void bfa_fcs_rpf_init(struct bfa_fcs_rport_s *rport);
58void bfa_fcs_rpf_rport_online(struct bfa_fcs_rport_s *rport);
59void bfa_fcs_rpf_rport_offline(struct bfa_fcs_rport_s *rport);
60
61#endif /* __FCS_RPORT_H__ */
diff --git a/drivers/scsi/bfa/fcs_trcmod.h b/drivers/scsi/bfa/fcs_trcmod.h
new file mode 100644
index 000000000000..41b5ae8d7644
--- /dev/null
+++ b/drivers/scsi/bfa/fcs_trcmod.h
@@ -0,0 +1,56 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * fcs_trcmod.h BFA FCS trace modules
20 */
21
22#ifndef __FCS_TRCMOD_H__
23#define __FCS_TRCMOD_H__
24
25#include <cs/bfa_trc.h>
26
27/*
28 * !!! Only append to the enums defined here to avoid any versioning
29 * !!! needed between trace utility and driver version
30 */
31enum {
32 BFA_TRC_FCS_FABRIC = 1,
33 BFA_TRC_FCS_VFAPI = 2,
34 BFA_TRC_FCS_PORT = 3,
35 BFA_TRC_FCS_VPORT = 4,
36 BFA_TRC_FCS_VP_API = 5,
37 BFA_TRC_FCS_VPS = 6,
38 BFA_TRC_FCS_RPORT = 7,
39 BFA_TRC_FCS_FCPIM = 8,
40 BFA_TRC_FCS_FCPTM = 9,
41 BFA_TRC_FCS_NS = 10,
42 BFA_TRC_FCS_SCN = 11,
43 BFA_TRC_FCS_LOOP = 12,
44 BFA_TRC_FCS_UF = 13,
45 BFA_TRC_FCS_PPORT = 14,
46 BFA_TRC_FCS_FCPIP = 15,
47 BFA_TRC_FCS_PORT_API = 16,
48 BFA_TRC_FCS_RPORT_API = 17,
49 BFA_TRC_FCS_AUTH = 18,
50 BFA_TRC_FCS_N2N = 19,
51 BFA_TRC_FCS_MS = 20,
52 BFA_TRC_FCS_FDMI = 21,
53 BFA_TRC_FCS_RPORT_FTRS = 22,
54};
55
56#endif /* __FCS_TRCMOD_H__ */
diff --git a/drivers/scsi/bfa/fcs_uf.h b/drivers/scsi/bfa/fcs_uf.h
new file mode 100644
index 000000000000..96f1bdcb31ed
--- /dev/null
+++ b/drivers/scsi/bfa/fcs_uf.h
@@ -0,0 +1,32 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * fcs_uf.h FCS unsolicited frame receive
20 */
21
22
23#ifndef __FCS_UF_H__
24#define __FCS_UF_H__
25
26/*
27 * fcs friend functions: only between fcs modules
28 */
29void bfa_fcs_uf_modinit(struct bfa_fcs_s *fcs);
30void bfa_fcs_uf_modexit(struct bfa_fcs_s *fcs);
31
32#endif /* __FCS_UF_H__ */
diff --git a/drivers/scsi/bfa/fcs_vport.h b/drivers/scsi/bfa/fcs_vport.h
new file mode 100644
index 000000000000..9e80b6a97b7f
--- /dev/null
+++ b/drivers/scsi/bfa/fcs_vport.h
@@ -0,0 +1,39 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __FCS_VPORT_H__
19#define __FCS_VPORT_H__
20
21#include <fcs/bfa_fcs_lport.h>
22#include <fcs/bfa_fcs_vport.h>
23#include <defs/bfa_defs_pci.h>
24
25/*
26 * Modudle init/cleanup routines.
27 */
28
29void bfa_fcs_vport_modinit(struct bfa_fcs_s *fcs);
30void bfa_fcs_vport_modexit(struct bfa_fcs_s *fcs);
31
32void bfa_fcs_vport_cleanup(struct bfa_fcs_vport_s *vport);
33void bfa_fcs_vport_online(struct bfa_fcs_vport_s *vport);
34void bfa_fcs_vport_offline(struct bfa_fcs_vport_s *vport);
35void bfa_fcs_vport_delete_comp(struct bfa_fcs_vport_s *vport);
36u32 bfa_fcs_vport_get_max(struct bfa_fcs_s *fcs);
37
38#endif /* __FCS_VPORT_H__ */
39
diff --git a/drivers/scsi/bfa/fdmi.c b/drivers/scsi/bfa/fdmi.c
new file mode 100644
index 000000000000..b845eb272c78
--- /dev/null
+++ b/drivers/scsi/bfa/fdmi.c
@@ -0,0 +1,1223 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * port_api.c BFA FCS port
20 */
21
22
23#include <bfa.h>
24#include <bfa_svc.h>
25#include "fcs_lport.h"
26#include "fcs_rport.h"
27#include "lport_priv.h"
28#include "fcs_trcmod.h"
29#include "fcs_fcxp.h"
30#include <fcs/bfa_fcs_fdmi.h>
31
32BFA_TRC_FILE(FCS, FDMI);
33
34#define BFA_FCS_FDMI_CMD_MAX_RETRIES 2
35
36/*
37 * forward declarations
38 */
39static void bfa_fcs_port_fdmi_send_rhba(void *fdmi_cbarg,
40 struct bfa_fcxp_s *fcxp_alloced);
41static void bfa_fcs_port_fdmi_send_rprt(void *fdmi_cbarg,
42 struct bfa_fcxp_s *fcxp_alloced);
43static void bfa_fcs_port_fdmi_send_rpa(void *fdmi_cbarg,
44 struct bfa_fcxp_s *fcxp_alloced);
45static void bfa_fcs_port_fdmi_rhba_response(void *fcsarg,
46 struct bfa_fcxp_s *fcxp,
47 void *cbarg,
48 bfa_status_t req_status,
49 u32 rsp_len,
50 u32 resid_len,
51 struct fchs_s *rsp_fchs);
52static void bfa_fcs_port_fdmi_rprt_response(void *fcsarg,
53 struct bfa_fcxp_s *fcxp,
54 void *cbarg,
55 bfa_status_t req_status,
56 u32 rsp_len,
57 u32 resid_len,
58 struct fchs_s *rsp_fchs);
59static void bfa_fcs_port_fdmi_rpa_response(void *fcsarg,
60 struct bfa_fcxp_s *fcxp,
61 void *cbarg,
62 bfa_status_t req_status,
63 u32 rsp_len,
64 u32 resid_len,
65 struct fchs_s *rsp_fchs);
66static void bfa_fcs_port_fdmi_timeout(void *arg);
67static u16 bfa_fcs_port_fdmi_build_rhba_pyld(
68 struct bfa_fcs_port_fdmi_s *fdmi, u8 *pyld);
69static u16 bfa_fcs_port_fdmi_build_rprt_pyld(
70 struct bfa_fcs_port_fdmi_s *fdmi, u8 *pyld);
71static u16 bfa_fcs_port_fdmi_build_rpa_pyld(
72 struct bfa_fcs_port_fdmi_s *fdmi, u8 *pyld);
73static u16 bfa_fcs_port_fdmi_build_portattr_block(
74 struct bfa_fcs_port_fdmi_s *fdmi, u8 *pyld);
75void bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_port_fdmi_s *fdmi,
76 struct bfa_fcs_fdmi_hba_attr_s *hba_attr);
77void bfa_fcs_fdmi_get_portattr(struct bfa_fcs_port_fdmi_s *fdmi,
78 struct bfa_fcs_fdmi_port_attr_s *port_attr);
79/**
80 * fcs_fdmi_sm FCS FDMI state machine
81 */
82
83/**
84 * FDMI State Machine events
85 */
86enum port_fdmi_event {
87 FDMISM_EVENT_PORT_ONLINE = 1,
88 FDMISM_EVENT_PORT_OFFLINE = 2,
89 FDMISM_EVENT_RSP_OK = 4,
90 FDMISM_EVENT_RSP_ERROR = 5,
91 FDMISM_EVENT_TIMEOUT = 6,
92 FDMISM_EVENT_RHBA_SENT = 7,
93 FDMISM_EVENT_RPRT_SENT = 8,
94 FDMISM_EVENT_RPA_SENT = 9,
95};
96
97static void bfa_fcs_port_fdmi_sm_offline(struct bfa_fcs_port_fdmi_s *fdmi,
98 enum port_fdmi_event event);
99static void bfa_fcs_port_fdmi_sm_sending_rhba(struct bfa_fcs_port_fdmi_s *fdmi,
100 enum port_fdmi_event event);
101static void bfa_fcs_port_fdmi_sm_rhba(struct bfa_fcs_port_fdmi_s *fdmi,
102 enum port_fdmi_event event);
103static void bfa_fcs_port_fdmi_sm_rhba_retry(struct bfa_fcs_port_fdmi_s *fdmi,
104 enum port_fdmi_event event);
105static void bfa_fcs_port_fdmi_sm_sending_rprt(struct bfa_fcs_port_fdmi_s *fdmi,
106 enum port_fdmi_event event);
107static void bfa_fcs_port_fdmi_sm_rprt(struct bfa_fcs_port_fdmi_s *fdmi,
108 enum port_fdmi_event event);
109static void bfa_fcs_port_fdmi_sm_rprt_retry(struct bfa_fcs_port_fdmi_s *fdmi,
110 enum port_fdmi_event event);
111static void bfa_fcs_port_fdmi_sm_sending_rpa(struct bfa_fcs_port_fdmi_s *fdmi,
112 enum port_fdmi_event event);
113static void bfa_fcs_port_fdmi_sm_rpa(struct bfa_fcs_port_fdmi_s *fdmi,
114 enum port_fdmi_event event);
115static void bfa_fcs_port_fdmi_sm_rpa_retry(struct bfa_fcs_port_fdmi_s *fdmi,
116 enum port_fdmi_event event);
117static void bfa_fcs_port_fdmi_sm_online(struct bfa_fcs_port_fdmi_s *fdmi,
118 enum port_fdmi_event event);
119/**
120 * Start in offline state - awaiting MS to send start.
121 */
122static void
123bfa_fcs_port_fdmi_sm_offline(struct bfa_fcs_port_fdmi_s *fdmi,
124 enum port_fdmi_event event)
125{
126 struct bfa_fcs_port_s *port = fdmi->ms->port;
127
128 bfa_trc(port->fcs, port->port_cfg.pwwn);
129 bfa_trc(port->fcs, event);
130
131 fdmi->retry_cnt = 0;
132
133 switch (event) {
134 case FDMISM_EVENT_PORT_ONLINE:
135 if (port->vport) {
136 /*
137 * For Vports, register a new port.
138 */
139 bfa_sm_set_state(fdmi,
140 bfa_fcs_port_fdmi_sm_sending_rprt);
141 bfa_fcs_port_fdmi_send_rprt(fdmi, NULL);
142 } else {
143 /*
144 * For a base port, we should first register the HBA
145 * atribute. The HBA attribute also contains the base
146 * port registration.
147 */
148 bfa_sm_set_state(fdmi,
149 bfa_fcs_port_fdmi_sm_sending_rhba);
150 bfa_fcs_port_fdmi_send_rhba(fdmi, NULL);
151 }
152 break;
153
154 case FDMISM_EVENT_PORT_OFFLINE:
155 break;
156
157 default:
158 bfa_assert(0);
159 }
160}
161
162static void
163bfa_fcs_port_fdmi_sm_sending_rhba(struct bfa_fcs_port_fdmi_s *fdmi,
164 enum port_fdmi_event event)
165{
166 struct bfa_fcs_port_s *port = fdmi->ms->port;
167
168 bfa_trc(port->fcs, port->port_cfg.pwwn);
169 bfa_trc(port->fcs, event);
170
171 switch (event) {
172 case FDMISM_EVENT_RHBA_SENT:
173 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_rhba);
174 break;
175
176 case FDMISM_EVENT_PORT_OFFLINE:
177 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
178 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port),
179 &fdmi->fcxp_wqe);
180 break;
181
182 default:
183 bfa_assert(0);
184 }
185}
186
187static void
188bfa_fcs_port_fdmi_sm_rhba(struct bfa_fcs_port_fdmi_s *fdmi,
189 enum port_fdmi_event event)
190{
191 struct bfa_fcs_port_s *port = fdmi->ms->port;
192
193 bfa_trc(port->fcs, port->port_cfg.pwwn);
194 bfa_trc(port->fcs, event);
195
196 switch (event) {
197 case FDMISM_EVENT_RSP_ERROR:
198 /*
199 * if max retries have not been reached, start timer for a
200 * delayed retry
201 */
202 if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) {
203 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_rhba_retry);
204 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port),
205 &fdmi->timer, bfa_fcs_port_fdmi_timeout,
206 fdmi, BFA_FCS_RETRY_TIMEOUT);
207 } else {
208 /*
209 * set state to offline
210 */
211 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
212 }
213 break;
214
215 case FDMISM_EVENT_RSP_OK:
216 /*
217 * Initiate Register Port Attributes
218 */
219 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_sending_rpa);
220 fdmi->retry_cnt = 0;
221 bfa_fcs_port_fdmi_send_rpa(fdmi, NULL);
222 break;
223
224 case FDMISM_EVENT_PORT_OFFLINE:
225 bfa_fcxp_discard(fdmi->fcxp);
226 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
227 break;
228
229 default:
230 bfa_assert(0);
231 }
232}
233
234static void
235bfa_fcs_port_fdmi_sm_rhba_retry(struct bfa_fcs_port_fdmi_s *fdmi,
236 enum port_fdmi_event event)
237{
238 struct bfa_fcs_port_s *port = fdmi->ms->port;
239
240 bfa_trc(port->fcs, port->port_cfg.pwwn);
241 bfa_trc(port->fcs, event);
242
243 switch (event) {
244 case FDMISM_EVENT_TIMEOUT:
245 /*
246 * Retry Timer Expired. Re-send
247 */
248 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_sending_rhba);
249 bfa_fcs_port_fdmi_send_rhba(fdmi, NULL);
250 break;
251
252 case FDMISM_EVENT_PORT_OFFLINE:
253 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
254 bfa_timer_stop(&fdmi->timer);
255 break;
256
257 default:
258 bfa_assert(0);
259 }
260}
261
262/*
263* RPRT : Register Port
264 */
265static void
266bfa_fcs_port_fdmi_sm_sending_rprt(struct bfa_fcs_port_fdmi_s *fdmi,
267 enum port_fdmi_event event)
268{
269 struct bfa_fcs_port_s *port = fdmi->ms->port;
270
271 bfa_trc(port->fcs, port->port_cfg.pwwn);
272 bfa_trc(port->fcs, event);
273
274 switch (event) {
275 case FDMISM_EVENT_RPRT_SENT:
276 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_rprt);
277 break;
278
279 case FDMISM_EVENT_PORT_OFFLINE:
280 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
281 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port),
282 &fdmi->fcxp_wqe);
283 break;
284
285 default:
286 bfa_assert(0);
287 }
288}
289
290static void
291bfa_fcs_port_fdmi_sm_rprt(struct bfa_fcs_port_fdmi_s *fdmi,
292 enum port_fdmi_event event)
293{
294 struct bfa_fcs_port_s *port = fdmi->ms->port;
295
296 bfa_trc(port->fcs, port->port_cfg.pwwn);
297 bfa_trc(port->fcs, event);
298
299 switch (event) {
300 case FDMISM_EVENT_RSP_ERROR:
301 /*
302 * if max retries have not been reached, start timer for a
303 * delayed retry
304 */
305 if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) {
306 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_rprt_retry);
307 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port),
308 &fdmi->timer, bfa_fcs_port_fdmi_timeout,
309 fdmi, BFA_FCS_RETRY_TIMEOUT);
310
311 } else {
312 /*
313 * set state to offline
314 */
315 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
316 fdmi->retry_cnt = 0;
317 }
318 break;
319
320 case FDMISM_EVENT_RSP_OK:
321 fdmi->retry_cnt = 0;
322 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_online);
323 break;
324
325 case FDMISM_EVENT_PORT_OFFLINE:
326 bfa_fcxp_discard(fdmi->fcxp);
327 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
328 break;
329
330 default:
331 bfa_assert(0);
332 }
333}
334
335static void
336bfa_fcs_port_fdmi_sm_rprt_retry(struct bfa_fcs_port_fdmi_s *fdmi,
337 enum port_fdmi_event event)
338{
339 struct bfa_fcs_port_s *port = fdmi->ms->port;
340
341 bfa_trc(port->fcs, port->port_cfg.pwwn);
342 bfa_trc(port->fcs, event);
343
344 switch (event) {
345 case FDMISM_EVENT_TIMEOUT:
346 /*
347 * Retry Timer Expired. Re-send
348 */
349 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_sending_rprt);
350 bfa_fcs_port_fdmi_send_rprt(fdmi, NULL);
351 break;
352
353 case FDMISM_EVENT_PORT_OFFLINE:
354 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
355 bfa_timer_stop(&fdmi->timer);
356 break;
357
358 default:
359 bfa_assert(0);
360 }
361}
362
363/*
364 * Register Port Attributes
365 */
366static void
367bfa_fcs_port_fdmi_sm_sending_rpa(struct bfa_fcs_port_fdmi_s *fdmi,
368 enum port_fdmi_event event)
369{
370 struct bfa_fcs_port_s *port = fdmi->ms->port;
371
372 bfa_trc(port->fcs, port->port_cfg.pwwn);
373 bfa_trc(port->fcs, event);
374
375 switch (event) {
376 case FDMISM_EVENT_RPA_SENT:
377 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_rpa);
378 break;
379
380 case FDMISM_EVENT_PORT_OFFLINE:
381 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
382 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(port),
383 &fdmi->fcxp_wqe);
384 break;
385
386 default:
387 bfa_assert(0);
388 }
389}
390
391static void
392bfa_fcs_port_fdmi_sm_rpa(struct bfa_fcs_port_fdmi_s *fdmi,
393 enum port_fdmi_event event)
394{
395 struct bfa_fcs_port_s *port = fdmi->ms->port;
396
397 bfa_trc(port->fcs, port->port_cfg.pwwn);
398 bfa_trc(port->fcs, event);
399
400 switch (event) {
401 case FDMISM_EVENT_RSP_ERROR:
402 /*
403 * if max retries have not been reached, start timer for a
404 * delayed retry
405 */
406 if (fdmi->retry_cnt++ < BFA_FCS_FDMI_CMD_MAX_RETRIES) {
407 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_rpa_retry);
408 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(port),
409 &fdmi->timer, bfa_fcs_port_fdmi_timeout,
410 fdmi, BFA_FCS_RETRY_TIMEOUT);
411 } else {
412 /*
413 * set state to offline
414 */
415 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
416 fdmi->retry_cnt = 0;
417 }
418 break;
419
420 case FDMISM_EVENT_RSP_OK:
421 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_online);
422 fdmi->retry_cnt = 0;
423 break;
424
425 case FDMISM_EVENT_PORT_OFFLINE:
426 bfa_fcxp_discard(fdmi->fcxp);
427 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
428 break;
429
430 default:
431 bfa_assert(0);
432 }
433}
434
435static void
436bfa_fcs_port_fdmi_sm_rpa_retry(struct bfa_fcs_port_fdmi_s *fdmi,
437 enum port_fdmi_event event)
438{
439 struct bfa_fcs_port_s *port = fdmi->ms->port;
440
441 bfa_trc(port->fcs, port->port_cfg.pwwn);
442 bfa_trc(port->fcs, event);
443
444 switch (event) {
445 case FDMISM_EVENT_TIMEOUT:
446 /*
447 * Retry Timer Expired. Re-send
448 */
449 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_sending_rpa);
450 bfa_fcs_port_fdmi_send_rpa(fdmi, NULL);
451 break;
452
453 case FDMISM_EVENT_PORT_OFFLINE:
454 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
455 bfa_timer_stop(&fdmi->timer);
456 break;
457
458 default:
459 bfa_assert(0);
460 }
461}
462
463static void
464bfa_fcs_port_fdmi_sm_online(struct bfa_fcs_port_fdmi_s *fdmi,
465 enum port_fdmi_event event)
466{
467 struct bfa_fcs_port_s *port = fdmi->ms->port;
468
469 bfa_trc(port->fcs, port->port_cfg.pwwn);
470 bfa_trc(port->fcs, event);
471
472 switch (event) {
473 case FDMISM_EVENT_PORT_OFFLINE:
474 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
475 break;
476
477 default:
478 bfa_assert(0);
479 }
480}
481
482
483/**
484* RHBA : Register HBA Attributes.
485 */
486static void
487bfa_fcs_port_fdmi_send_rhba(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced)
488{
489 struct bfa_fcs_port_fdmi_s *fdmi = fdmi_cbarg;
490 struct bfa_fcs_port_s *port = fdmi->ms->port;
491 struct fchs_s fchs;
492 int len, attr_len;
493 struct bfa_fcxp_s *fcxp;
494 u8 *pyld;
495
496 bfa_trc(port->fcs, port->port_cfg.pwwn);
497
498 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
499 if (!fcxp) {
500 bfa_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe,
501 bfa_fcs_port_fdmi_send_rhba, fdmi);
502 return;
503 }
504 fdmi->fcxp = fcxp;
505
506 pyld = bfa_fcxp_get_reqbuf(fcxp);
507 bfa_os_memset(pyld, 0, FC_MAX_PDUSZ);
508
509 len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_port_get_fcid(port),
510 FDMI_RHBA);
511
512 attr_len = bfa_fcs_port_fdmi_build_rhba_pyld(fdmi,
513 (u8 *) ((struct ct_hdr_s *) pyld + 1));
514
515 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
516 FC_CLASS_3, (len + attr_len), &fchs,
517 bfa_fcs_port_fdmi_rhba_response, (void *)fdmi,
518 FC_MAX_PDUSZ, FC_RA_TOV);
519
520 bfa_sm_send_event(fdmi, FDMISM_EVENT_RHBA_SENT);
521}
522
523static u16
524bfa_fcs_port_fdmi_build_rhba_pyld(struct bfa_fcs_port_fdmi_s *fdmi,
525 u8 *pyld)
526{
527 struct bfa_fcs_port_s *port = fdmi->ms->port;
528 struct bfa_fcs_fdmi_hba_attr_s hba_attr; /* @todo */
529 struct bfa_fcs_fdmi_hba_attr_s *fcs_hba_attr = &hba_attr; /* @todo */
530 struct fdmi_rhba_s *rhba = (struct fdmi_rhba_s *) pyld;
531 struct fdmi_attr_s *attr;
532 u8 *curr_ptr;
533 u16 len, count;
534
535 /*
536 * get hba attributes
537 */
538 bfa_fcs_fdmi_get_hbaattr(fdmi, fcs_hba_attr);
539
540 rhba->hba_id = bfa_fcs_port_get_pwwn(port);
541 rhba->port_list.num_ports = bfa_os_htonl(1);
542 rhba->port_list.port_entry = bfa_fcs_port_get_pwwn(port);
543
544 len = sizeof(rhba->hba_id) + sizeof(rhba->port_list);
545
546 count = 0;
547 len += sizeof(rhba->hba_attr_blk.attr_count);
548
549 /*
550 * fill out the invididual entries of the HBA attrib Block
551 */
552 curr_ptr = (u8 *) &rhba->hba_attr_blk.hba_attr;
553
554 /*
555 * Node Name
556 */
557 attr = (struct fdmi_attr_s *) curr_ptr;
558 attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_NODENAME);
559 attr->len = sizeof(wwn_t);
560 memcpy(attr->value, &bfa_fcs_port_get_nwwn(port), attr->len);
561 curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
562 len += attr->len;
563 count++;
564 attr->len =
565 bfa_os_htons(attr->len + sizeof(attr->type) +
566 sizeof(attr->len));
567
568 /*
569 * Manufacturer
570 */
571 attr = (struct fdmi_attr_s *) curr_ptr;
572 attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_MANUFACTURER);
573 attr->len = (u16) strlen(fcs_hba_attr->manufacturer);
574 memcpy(attr->value, fcs_hba_attr->manufacturer, attr->len);
575 /* variable fields need to be 4 byte aligned */
576 attr->len = fc_roundup(attr->len, sizeof(u32));
577 curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
578 len += attr->len;
579 count++;
580 attr->len =
581 bfa_os_htons(attr->len + sizeof(attr->type) +
582 sizeof(attr->len));
583
584 /*
585 * Serial Number
586 */
587 attr = (struct fdmi_attr_s *) curr_ptr;
588 attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_SERIALNUM);
589 attr->len = (u16) strlen(fcs_hba_attr->serial_num);
590 memcpy(attr->value, fcs_hba_attr->serial_num, attr->len);
591 /* variable fields need to be 4 byte aligned */
592 attr->len = fc_roundup(attr->len, sizeof(u32));
593 curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
594 len += attr->len;
595 count++;
596 attr->len =
597 bfa_os_htons(attr->len + sizeof(attr->type) +
598 sizeof(attr->len));
599
600 /*
601 * Model
602 */
603 attr = (struct fdmi_attr_s *) curr_ptr;
604 attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_MODEL);
605 attr->len = (u16) strlen(fcs_hba_attr->model);
606 memcpy(attr->value, fcs_hba_attr->model, attr->len);
607 /* variable fields need to be 4 byte aligned */
608 attr->len = fc_roundup(attr->len, sizeof(u32));
609 curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
610 len += attr->len;
611 count++;
612 attr->len =
613 bfa_os_htons(attr->len + sizeof(attr->type) +
614 sizeof(attr->len));
615
616 /*
617 * Model Desc
618 */
619 attr = (struct fdmi_attr_s *) curr_ptr;
620 attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_MODEL_DESC);
621 attr->len = (u16) strlen(fcs_hba_attr->model_desc);
622 memcpy(attr->value, fcs_hba_attr->model_desc, attr->len);
623 /* variable fields need to be 4 byte aligned */
624 attr->len = fc_roundup(attr->len, sizeof(u32));
625 curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
626 len += attr->len;
627 count++;
628 attr->len =
629 bfa_os_htons(attr->len + sizeof(attr->type) +
630 sizeof(attr->len));
631
632 /*
633 * H/W Version
634 */
635 if (fcs_hba_attr->hw_version[0] != '\0') {
636 attr = (struct fdmi_attr_s *) curr_ptr;
637 attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_HW_VERSION);
638 attr->len = (u16) strlen(fcs_hba_attr->hw_version);
639 memcpy(attr->value, fcs_hba_attr->hw_version, attr->len);
640 /* variable fields need to be 4 byte aligned */
641 attr->len = fc_roundup(attr->len, sizeof(u32));
642 curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
643 len += attr->len;
644 count++;
645 attr->len =
646 bfa_os_htons(attr->len + sizeof(attr->type) +
647 sizeof(attr->len));
648 }
649
650 /*
651 * Driver Version
652 */
653 attr = (struct fdmi_attr_s *) curr_ptr;
654 attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_DRIVER_VERSION);
655 attr->len = (u16) strlen(fcs_hba_attr->driver_version);
656 memcpy(attr->value, fcs_hba_attr->driver_version, attr->len);
657 /* variable fields need to be 4 byte aligned */
658 attr->len = fc_roundup(attr->len, sizeof(u32));
659 curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
660 len += attr->len;;
661 count++;
662 attr->len =
663 bfa_os_htons(attr->len + sizeof(attr->type) +
664 sizeof(attr->len));
665
666 /*
667 * Option Rom Version
668 */
669 if (fcs_hba_attr->option_rom_ver[0] != '\0') {
670 attr = (struct fdmi_attr_s *) curr_ptr;
671 attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_ROM_VERSION);
672 attr->len = (u16) strlen(fcs_hba_attr->option_rom_ver);
673 memcpy(attr->value, fcs_hba_attr->option_rom_ver, attr->len);
674 /* variable fields need to be 4 byte aligned */
675 attr->len = fc_roundup(attr->len, sizeof(u32));
676 curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
677 len += attr->len;
678 count++;
679 attr->len =
680 bfa_os_htons(attr->len + sizeof(attr->type) +
681 sizeof(attr->len));
682 }
683
684 /*
685 * f/w Version = driver version
686 */
687 attr = (struct fdmi_attr_s *) curr_ptr;
688 attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_FW_VERSION);
689 attr->len = (u16) strlen(fcs_hba_attr->driver_version);
690 memcpy(attr->value, fcs_hba_attr->driver_version, attr->len);
691 /* variable fields need to be 4 byte aligned */
692 attr->len = fc_roundup(attr->len, sizeof(u32));
693 curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
694 len += attr->len;
695 count++;
696 attr->len =
697 bfa_os_htons(attr->len + sizeof(attr->type) +
698 sizeof(attr->len));
699
700 /*
701 * OS Name
702 */
703 if (fcs_hba_attr->os_name[0] != '\0') {
704 attr = (struct fdmi_attr_s *) curr_ptr;
705 attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_OS_NAME);
706 attr->len = (u16) strlen(fcs_hba_attr->os_name);
707 memcpy(attr->value, fcs_hba_attr->os_name, attr->len);
708 /* variable fields need to be 4 byte aligned */
709 attr->len = fc_roundup(attr->len, sizeof(u32));
710 curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
711 len += attr->len;
712 count++;
713 attr->len =
714 bfa_os_htons(attr->len + sizeof(attr->type) +
715 sizeof(attr->len));
716 }
717
718 /*
719 * MAX_CT_PAYLOAD
720 */
721 attr = (struct fdmi_attr_s *) curr_ptr;
722 attr->type = bfa_os_htons(FDMI_HBA_ATTRIB_MAX_CT);
723 attr->len = sizeof(fcs_hba_attr->max_ct_pyld);
724 memcpy(attr->value, &fcs_hba_attr->max_ct_pyld, attr->len);
725 len += attr->len;
726 count++;
727 attr->len =
728 bfa_os_htons(attr->len + sizeof(attr->type) +
729 sizeof(attr->len));
730
731 /*
732 * Update size of payload
733 */
734 len += ((sizeof(attr->type) + sizeof(attr->len)) * count);
735
736 rhba->hba_attr_blk.attr_count = bfa_os_htonl(count);
737 return len;
738}
739
740static void
741bfa_fcs_port_fdmi_rhba_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
742 void *cbarg, bfa_status_t req_status,
743 u32 rsp_len, u32 resid_len,
744 struct fchs_s *rsp_fchs)
745{
746 struct bfa_fcs_port_fdmi_s *fdmi = (struct bfa_fcs_port_fdmi_s *)cbarg;
747 struct bfa_fcs_port_s *port = fdmi->ms->port;
748 struct ct_hdr_s *cthdr = NULL;
749
750 bfa_trc(port->fcs, port->port_cfg.pwwn);
751
752 /*
753 * Sanity Checks
754 */
755 if (req_status != BFA_STATUS_OK) {
756 bfa_trc(port->fcs, req_status);
757 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
758 return;
759 }
760
761 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
762 cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
763
764 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
765 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK);
766 return;
767 }
768
769 bfa_trc(port->fcs, cthdr->reason_code);
770 bfa_trc(port->fcs, cthdr->exp_code);
771 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
772}
773
774/**
775* RPRT : Register Port
776 */
777static void
778bfa_fcs_port_fdmi_send_rprt(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced)
779{
780 struct bfa_fcs_port_fdmi_s *fdmi = fdmi_cbarg;
781 struct bfa_fcs_port_s *port = fdmi->ms->port;
782 struct fchs_s fchs;
783 u16 len, attr_len;
784 struct bfa_fcxp_s *fcxp;
785 u8 *pyld;
786
787 bfa_trc(port->fcs, port->port_cfg.pwwn);
788
789 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
790 if (!fcxp) {
791 bfa_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe,
792 bfa_fcs_port_fdmi_send_rprt, fdmi);
793 return;
794 }
795 fdmi->fcxp = fcxp;
796
797 pyld = bfa_fcxp_get_reqbuf(fcxp);
798 bfa_os_memset(pyld, 0, FC_MAX_PDUSZ);
799
800 len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_port_get_fcid(port),
801 FDMI_RPRT);
802
803 attr_len = bfa_fcs_port_fdmi_build_rprt_pyld(fdmi,
804 (u8 *) ((struct ct_hdr_s *) pyld + 1));
805
806 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
807 FC_CLASS_3, len + attr_len, &fchs,
808 bfa_fcs_port_fdmi_rprt_response, (void *)fdmi,
809 FC_MAX_PDUSZ, FC_RA_TOV);
810
811 bfa_sm_send_event(fdmi, FDMISM_EVENT_RPRT_SENT);
812}
813
814/**
815 * This routine builds Port Attribute Block that used in RPA, RPRT commands.
816 */
817static u16
818bfa_fcs_port_fdmi_build_portattr_block(struct bfa_fcs_port_fdmi_s *fdmi,
819 u8 *pyld)
820{
821 struct bfa_fcs_fdmi_port_attr_s fcs_port_attr;
822 struct fdmi_port_attr_s *port_attrib = (struct fdmi_port_attr_s *) pyld;
823 struct fdmi_attr_s *attr;
824 u8 *curr_ptr;
825 u16 len;
826 u8 count = 0;
827
828 /*
829 * get port attributes
830 */
831 bfa_fcs_fdmi_get_portattr(fdmi, &fcs_port_attr);
832
833 len = sizeof(port_attrib->attr_count);
834
835 /*
836 * fill out the invididual entries
837 */
838 curr_ptr = (u8 *) &port_attrib->port_attr;
839
840 /*
841 * FC4 Types
842 */
843 attr = (struct fdmi_attr_s *) curr_ptr;
844 attr->type = bfa_os_htons(FDMI_PORT_ATTRIB_FC4_TYPES);
845 attr->len = sizeof(fcs_port_attr.supp_fc4_types);
846 memcpy(attr->value, fcs_port_attr.supp_fc4_types, attr->len);
847 curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
848 len += attr->len;
849 ++count;
850 attr->len =
851 bfa_os_htons(attr->len + sizeof(attr->type) +
852 sizeof(attr->len));
853
854 /*
855 * Supported Speed
856 */
857 attr = (struct fdmi_attr_s *) curr_ptr;
858 attr->type = bfa_os_htons(FDMI_PORT_ATTRIB_SUPP_SPEED);
859 attr->len = sizeof(fcs_port_attr.supp_speed);
860 memcpy(attr->value, &fcs_port_attr.supp_speed, attr->len);
861 curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
862 len += attr->len;
863 ++count;
864 attr->len =
865 bfa_os_htons(attr->len + sizeof(attr->type) +
866 sizeof(attr->len));
867
868 /*
869 * current Port Speed
870 */
871 attr = (struct fdmi_attr_s *) curr_ptr;
872 attr->type = bfa_os_htons(FDMI_PORT_ATTRIB_PORT_SPEED);
873 attr->len = sizeof(fcs_port_attr.curr_speed);
874 memcpy(attr->value, &fcs_port_attr.curr_speed, attr->len);
875 curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
876 len += attr->len;
877 ++count;
878 attr->len =
879 bfa_os_htons(attr->len + sizeof(attr->type) +
880 sizeof(attr->len));
881
882 /*
883 * max frame size
884 */
885 attr = (struct fdmi_attr_s *) curr_ptr;
886 attr->type = bfa_os_htons(FDMI_PORT_ATTRIB_FRAME_SIZE);
887 attr->len = sizeof(fcs_port_attr.max_frm_size);
888 memcpy(attr->value, &fcs_port_attr.max_frm_size, attr->len);
889 curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
890 len += attr->len;
891 ++count;
892 attr->len =
893 bfa_os_htons(attr->len + sizeof(attr->type) +
894 sizeof(attr->len));
895
896 /*
897 * OS Device Name
898 */
899 if (fcs_port_attr.os_device_name[0] != '\0') {
900 attr = (struct fdmi_attr_s *) curr_ptr;
901 attr->type = bfa_os_htons(FDMI_PORT_ATTRIB_DEV_NAME);
902 attr->len = (u16) strlen(fcs_port_attr.os_device_name);
903 memcpy(attr->value, fcs_port_attr.os_device_name, attr->len);
904 /* variable fields need to be 4 byte aligned */
905 attr->len = fc_roundup(attr->len, sizeof(u32));
906 curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
907 len += attr->len;
908 ++count;
909 attr->len =
910 bfa_os_htons(attr->len + sizeof(attr->type) +
911 sizeof(attr->len));
912
913 }
914 /*
915 * Host Name
916 */
917 if (fcs_port_attr.host_name[0] != '\0') {
918 attr = (struct fdmi_attr_s *) curr_ptr;
919 attr->type = bfa_os_htons(FDMI_PORT_ATTRIB_HOST_NAME);
920 attr->len = (u16) strlen(fcs_port_attr.host_name);
921 memcpy(attr->value, fcs_port_attr.host_name, attr->len);
922 /* variable fields need to be 4 byte aligned */
923 attr->len = fc_roundup(attr->len, sizeof(u32));
924 curr_ptr += sizeof(attr->type) + sizeof(attr->len) + attr->len;
925 len += attr->len;
926 ++count;
927 attr->len =
928 bfa_os_htons(attr->len + sizeof(attr->type) +
929 sizeof(attr->len));
930
931 }
932
933 /*
934 * Update size of payload
935 */
936 port_attrib->attr_count = bfa_os_htonl(count);
937 len += ((sizeof(attr->type) + sizeof(attr->len)) * count);
938 return len;
939}
940
941static u16
942bfa_fcs_port_fdmi_build_rprt_pyld(struct bfa_fcs_port_fdmi_s *fdmi,
943 u8 *pyld)
944{
945 struct bfa_fcs_port_s *port = fdmi->ms->port;
946 struct fdmi_rprt_s *rprt = (struct fdmi_rprt_s *) pyld;
947 u16 len;
948
949 rprt->hba_id = bfa_fcs_port_get_pwwn(bfa_fcs_get_base_port(port->fcs));
950 rprt->port_name = bfa_fcs_port_get_pwwn(port);
951
952 len = bfa_fcs_port_fdmi_build_portattr_block(fdmi,
953 (u8 *) &rprt->port_attr_blk);
954
955 len += sizeof(rprt->hba_id) + sizeof(rprt->port_name);
956
957 return len;
958}
959
960static void
961bfa_fcs_port_fdmi_rprt_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
962 void *cbarg, bfa_status_t req_status,
963 u32 rsp_len, u32 resid_len,
964 struct fchs_s *rsp_fchs)
965{
966 struct bfa_fcs_port_fdmi_s *fdmi = (struct bfa_fcs_port_fdmi_s *)cbarg;
967 struct bfa_fcs_port_s *port = fdmi->ms->port;
968 struct ct_hdr_s *cthdr = NULL;
969
970 bfa_trc(port->fcs, port->port_cfg.pwwn);
971
972 /*
973 * Sanity Checks
974 */
975 if (req_status != BFA_STATUS_OK) {
976 bfa_trc(port->fcs, req_status);
977 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
978 return;
979 }
980
981 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
982 cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
983
984 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
985 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK);
986 return;
987 }
988
989 bfa_trc(port->fcs, cthdr->reason_code);
990 bfa_trc(port->fcs, cthdr->exp_code);
991 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
992}
993
994/**
995* RPA : Register Port Attributes.
996 */
997static void
998bfa_fcs_port_fdmi_send_rpa(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced)
999{
1000 struct bfa_fcs_port_fdmi_s *fdmi = fdmi_cbarg;
1001 struct bfa_fcs_port_s *port = fdmi->ms->port;
1002 struct fchs_s fchs;
1003 u16 len, attr_len;
1004 struct bfa_fcxp_s *fcxp;
1005 u8 *pyld;
1006
1007 bfa_trc(port->fcs, port->port_cfg.pwwn);
1008
1009 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
1010 if (!fcxp) {
1011 bfa_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe,
1012 bfa_fcs_port_fdmi_send_rpa, fdmi);
1013 return;
1014 }
1015 fdmi->fcxp = fcxp;
1016
1017 pyld = bfa_fcxp_get_reqbuf(fcxp);
1018 bfa_os_memset(pyld, 0, FC_MAX_PDUSZ);
1019
1020 len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_port_get_fcid(port),
1021 FDMI_RPA);
1022
1023 attr_len = bfa_fcs_port_fdmi_build_rpa_pyld(fdmi,
1024 (u8 *) ((struct ct_hdr_s *) pyld + 1));
1025
1026 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1027 FC_CLASS_3, len + attr_len, &fchs,
1028 bfa_fcs_port_fdmi_rpa_response, (void *)fdmi,
1029 FC_MAX_PDUSZ, FC_RA_TOV);
1030
1031 bfa_sm_send_event(fdmi, FDMISM_EVENT_RPA_SENT);
1032}
1033
1034static u16
1035bfa_fcs_port_fdmi_build_rpa_pyld(struct bfa_fcs_port_fdmi_s *fdmi,
1036 u8 *pyld)
1037{
1038 struct bfa_fcs_port_s *port = fdmi->ms->port;
1039 struct fdmi_rpa_s *rpa = (struct fdmi_rpa_s *) pyld;
1040 u16 len;
1041
1042 rpa->port_name = bfa_fcs_port_get_pwwn(port);
1043
1044 len = bfa_fcs_port_fdmi_build_portattr_block(fdmi,
1045 (u8 *) &rpa->port_attr_blk);
1046
1047 len += sizeof(rpa->port_name);
1048
1049 return len;
1050}
1051
1052static void
1053bfa_fcs_port_fdmi_rpa_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
1054 void *cbarg, bfa_status_t req_status,
1055 u32 rsp_len, u32 resid_len,
1056 struct fchs_s *rsp_fchs)
1057{
1058 struct bfa_fcs_port_fdmi_s *fdmi = (struct bfa_fcs_port_fdmi_s *)cbarg;
1059 struct bfa_fcs_port_s *port = fdmi->ms->port;
1060 struct ct_hdr_s *cthdr = NULL;
1061
1062 bfa_trc(port->fcs, port->port_cfg.pwwn);
1063
1064 /*
1065 * Sanity Checks
1066 */
1067 if (req_status != BFA_STATUS_OK) {
1068 bfa_trc(port->fcs, req_status);
1069 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
1070 return;
1071 }
1072
1073 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
1074 cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
1075
1076 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
1077 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK);
1078 return;
1079 }
1080
1081 bfa_trc(port->fcs, cthdr->reason_code);
1082 bfa_trc(port->fcs, cthdr->exp_code);
1083 bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR);
1084}
1085
1086static void
1087bfa_fcs_port_fdmi_timeout(void *arg)
1088{
1089 struct bfa_fcs_port_fdmi_s *fdmi = (struct bfa_fcs_port_fdmi_s *)arg;
1090
1091 bfa_sm_send_event(fdmi, FDMISM_EVENT_TIMEOUT);
1092}
1093
1094void
1095bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_port_fdmi_s *fdmi,
1096 struct bfa_fcs_fdmi_hba_attr_s *hba_attr)
1097{
1098 struct bfa_fcs_port_s *port = fdmi->ms->port;
1099 struct bfa_fcs_driver_info_s *driver_info = &port->fcs->driver_info;
1100 struct bfa_adapter_attr_s adapter_attr;
1101
1102 bfa_os_memset(hba_attr, 0, sizeof(struct bfa_fcs_fdmi_hba_attr_s));
1103 bfa_os_memset(&adapter_attr, 0, sizeof(struct bfa_adapter_attr_s));
1104
1105 bfa_ioc_get_adapter_attr(&port->fcs->bfa->ioc, &adapter_attr);
1106
1107 strncpy(hba_attr->manufacturer, adapter_attr.manufacturer,
1108 sizeof(adapter_attr.manufacturer));
1109
1110 strncpy(hba_attr->serial_num, adapter_attr.serial_num,
1111 sizeof(adapter_attr.serial_num));
1112
1113 strncpy(hba_attr->model, adapter_attr.model, sizeof(hba_attr->model));
1114
1115 strncpy(hba_attr->model_desc, adapter_attr.model_descr,
1116 sizeof(hba_attr->model_desc));
1117
1118 strncpy(hba_attr->hw_version, adapter_attr.hw_ver,
1119 sizeof(hba_attr->hw_version));
1120
1121 strncpy(hba_attr->driver_version, (char *)driver_info->version,
1122 sizeof(hba_attr->driver_version));
1123
1124 strncpy(hba_attr->option_rom_ver, adapter_attr.optrom_ver,
1125 sizeof(hba_attr->option_rom_ver));
1126
1127 strncpy(hba_attr->fw_version, adapter_attr.fw_ver,
1128 sizeof(hba_attr->fw_version));
1129
1130 strncpy(hba_attr->os_name, driver_info->host_os_name,
1131 sizeof(hba_attr->os_name));
1132
1133 /*
1134 * If there is a patch level, append it to the os name along with a
1135 * separator
1136 */
1137 if (driver_info->host_os_patch[0] != '\0') {
1138 strncat(hba_attr->os_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR,
1139 sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR));
1140 strncat(hba_attr->os_name, driver_info->host_os_patch,
1141 sizeof(driver_info->host_os_patch));
1142 }
1143
1144 hba_attr->max_ct_pyld = bfa_os_htonl(FC_MAX_PDUSZ);
1145
1146}
1147
1148void
1149bfa_fcs_fdmi_get_portattr(struct bfa_fcs_port_fdmi_s *fdmi,
1150 struct bfa_fcs_fdmi_port_attr_s *port_attr)
1151{
1152 struct bfa_fcs_port_s *port = fdmi->ms->port;
1153 struct bfa_fcs_driver_info_s *driver_info = &port->fcs->driver_info;
1154 struct bfa_pport_attr_s pport_attr;
1155
1156 bfa_os_memset(port_attr, 0, sizeof(struct bfa_fcs_fdmi_port_attr_s));
1157
1158 /*
1159 * get pport attributes from hal
1160 */
1161 bfa_pport_get_attr(port->fcs->bfa, &pport_attr);
1162
1163 /*
1164 * get FC4 type Bitmask
1165 */
1166 fc_get_fc4type_bitmask(FC_TYPE_FCP, port_attr->supp_fc4_types);
1167
1168 /*
1169 * Supported Speeds
1170 */
1171 port_attr->supp_speed = bfa_os_htonl(BFA_FCS_FDMI_SUPORTED_SPEEDS);
1172
1173 /*
1174 * Current Speed
1175 */
1176 port_attr->curr_speed = bfa_os_htonl(pport_attr.speed);
1177
1178 /*
1179 * Max PDU Size.
1180 */
1181 port_attr->max_frm_size = bfa_os_htonl(FC_MAX_PDUSZ);
1182
1183 /*
1184 * OS device Name
1185 */
1186 strncpy(port_attr->os_device_name, (char *)driver_info->os_device_name,
1187 sizeof(port_attr->os_device_name));
1188
1189 /*
1190 * Host name
1191 */
1192 strncpy(port_attr->host_name, (char *)driver_info->host_machine_name,
1193 sizeof(port_attr->host_name));
1194
1195}
1196
1197
1198void
1199bfa_fcs_port_fdmi_init(struct bfa_fcs_port_ms_s *ms)
1200{
1201 struct bfa_fcs_port_fdmi_s *fdmi = &ms->fdmi;
1202
1203 fdmi->ms = ms;
1204 bfa_sm_set_state(fdmi, bfa_fcs_port_fdmi_sm_offline);
1205}
1206
1207void
1208bfa_fcs_port_fdmi_offline(struct bfa_fcs_port_ms_s *ms)
1209{
1210 struct bfa_fcs_port_fdmi_s *fdmi = &ms->fdmi;
1211
1212 fdmi->ms = ms;
1213 bfa_sm_send_event(fdmi, FDMISM_EVENT_PORT_OFFLINE);
1214}
1215
1216void
1217bfa_fcs_port_fdmi_online(struct bfa_fcs_port_ms_s *ms)
1218{
1219 struct bfa_fcs_port_fdmi_s *fdmi = &ms->fdmi;
1220
1221 fdmi->ms = ms;
1222 bfa_sm_send_event(fdmi, FDMISM_EVENT_PORT_ONLINE);
1223}
diff --git a/drivers/scsi/bfa/include/aen/bfa_aen.h b/drivers/scsi/bfa/include/aen/bfa_aen.h
new file mode 100644
index 000000000000..da8cac093d3d
--- /dev/null
+++ b/drivers/scsi/bfa/include/aen/bfa_aen.h
@@ -0,0 +1,92 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17#ifndef __BFA_AEN_H__
18#define __BFA_AEN_H__
19
20#include "defs/bfa_defs_aen.h"
21
22#define BFA_AEN_MAX_ENTRY 512
23
24extern s32 bfa_aen_max_cfg_entry;
25struct bfa_aen_s {
26 void *bfad;
27 s32 max_entry;
28 s32 write_index;
29 s32 read_index;
30 u32 bfad_num;
31 u32 seq_num;
32 void (*aen_cb_notify)(void *bfad);
33 void (*gettimeofday)(struct bfa_timeval_s *tv);
34 struct bfa_trc_mod_s *trcmod;
35 struct bfa_aen_entry_s list[BFA_AEN_MAX_ENTRY]; /* Must be the last */
36};
37
38
39/**
40 * Public APIs
41 */
42static inline void
43bfa_aen_set_max_cfg_entry(int max_entry)
44{
45 bfa_aen_max_cfg_entry = max_entry;
46}
47
48static inline s32
49bfa_aen_get_max_cfg_entry(void)
50{
51 return bfa_aen_max_cfg_entry;
52}
53
54static inline s32
55bfa_aen_get_meminfo(void)
56{
57 return (sizeof(struct bfa_aen_entry_s) * bfa_aen_get_max_cfg_entry());
58}
59
60static inline s32
61bfa_aen_get_wi(struct bfa_aen_s *aen)
62{
63 return aen->write_index;
64}
65
66static inline s32
67bfa_aen_get_ri(struct bfa_aen_s *aen)
68{
69 return aen->read_index;
70}
71
72static inline s32
73bfa_aen_fetch_count(struct bfa_aen_s *aen, s32 read_index)
74{
75 return ((aen->write_index + aen->max_entry) - read_index)
76 % aen->max_entry;
77}
78
79s32 bfa_aen_init(struct bfa_aen_s *aen, struct bfa_trc_mod_s *trcmod,
80 void *bfad, u32 inst_id, void (*aen_cb_notify)(void *),
81 void (*gettimeofday)(struct bfa_timeval_s *));
82
83s32 bfa_aen_post(struct bfa_aen_s *aen, enum bfa_aen_category aen_category,
84 int aen_type, union bfa_aen_data_u *aen_data);
85
86s32 bfa_aen_fetch(struct bfa_aen_s *aen, struct bfa_aen_entry_s *aen_entry,
87 s32 entry_space, s32 rii, s32 *ri_arr,
88 s32 ri_arr_cnt);
89
90s32 bfa_aen_get_inst(struct bfa_aen_s *aen);
91
92#endif /* __BFA_AEN_H__ */
diff --git a/drivers/scsi/bfa/include/aen/bfa_aen_adapter.h b/drivers/scsi/bfa/include/aen/bfa_aen_adapter.h
new file mode 100644
index 000000000000..260d3ea1cab3
--- /dev/null
+++ b/drivers/scsi/bfa/include/aen/bfa_aen_adapter.h
@@ -0,0 +1,31 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/* messages define for BFA_AEN_CAT_ADAPTER Module */
19#ifndef __bfa_aen_adapter_h__
20#define __bfa_aen_adapter_h__
21
22#include <cs/bfa_log.h>
23#include <defs/bfa_defs_aen.h>
24
25#define BFA_AEN_ADAPTER_ADD \
26 BFA_LOG_CREATE_ID(BFA_AEN_CAT_ADAPTER, BFA_ADAPTER_AEN_ADD)
27#define BFA_AEN_ADAPTER_REMOVE \
28 BFA_LOG_CREATE_ID(BFA_AEN_CAT_ADAPTER, BFA_ADAPTER_AEN_REMOVE)
29
30#endif
31
diff --git a/drivers/scsi/bfa/include/aen/bfa_aen_audit.h b/drivers/scsi/bfa/include/aen/bfa_aen_audit.h
new file mode 100644
index 000000000000..12cd7aab5d53
--- /dev/null
+++ b/drivers/scsi/bfa/include/aen/bfa_aen_audit.h
@@ -0,0 +1,31 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/* messages define for BFA_AEN_CAT_AUDIT Module */
19#ifndef __bfa_aen_audit_h__
20#define __bfa_aen_audit_h__
21
22#include <cs/bfa_log.h>
23#include <defs/bfa_defs_aen.h>
24
25#define BFA_AEN_AUDIT_AUTH_ENABLE \
26 BFA_LOG_CREATE_ID(BFA_AEN_CAT_AUDIT, BFA_AUDIT_AEN_AUTH_ENABLE)
27#define BFA_AEN_AUDIT_AUTH_DISABLE \
28 BFA_LOG_CREATE_ID(BFA_AEN_CAT_AUDIT, BFA_AUDIT_AEN_AUTH_DISABLE)
29
30#endif
31
diff --git a/drivers/scsi/bfa/include/aen/bfa_aen_ethport.h b/drivers/scsi/bfa/include/aen/bfa_aen_ethport.h
new file mode 100644
index 000000000000..507d0b58d149
--- /dev/null
+++ b/drivers/scsi/bfa/include/aen/bfa_aen_ethport.h
@@ -0,0 +1,35 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/* messages define for BFA_AEN_CAT_ETHPORT Module */
19#ifndef __bfa_aen_ethport_h__
20#define __bfa_aen_ethport_h__
21
22#include <cs/bfa_log.h>
23#include <defs/bfa_defs_aen.h>
24
25#define BFA_AEN_ETHPORT_LINKUP \
26 BFA_LOG_CREATE_ID(BFA_AEN_CAT_ETHPORT, BFA_ETHPORT_AEN_LINKUP)
27#define BFA_AEN_ETHPORT_LINKDOWN \
28 BFA_LOG_CREATE_ID(BFA_AEN_CAT_ETHPORT, BFA_ETHPORT_AEN_LINKDOWN)
29#define BFA_AEN_ETHPORT_ENABLE \
30 BFA_LOG_CREATE_ID(BFA_AEN_CAT_ETHPORT, BFA_ETHPORT_AEN_ENABLE)
31#define BFA_AEN_ETHPORT_DISABLE \
32 BFA_LOG_CREATE_ID(BFA_AEN_CAT_ETHPORT, BFA_ETHPORT_AEN_DISABLE)
33
34#endif
35
diff --git a/drivers/scsi/bfa/include/aen/bfa_aen_ioc.h b/drivers/scsi/bfa/include/aen/bfa_aen_ioc.h
new file mode 100644
index 000000000000..71378b446b69
--- /dev/null
+++ b/drivers/scsi/bfa/include/aen/bfa_aen_ioc.h
@@ -0,0 +1,37 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/* messages define for BFA_AEN_CAT_IOC Module */
19#ifndef __bfa_aen_ioc_h__
20#define __bfa_aen_ioc_h__
21
22#include <cs/bfa_log.h>
23#include <defs/bfa_defs_aen.h>
24
25#define BFA_AEN_IOC_HBGOOD \
26 BFA_LOG_CREATE_ID(BFA_AEN_CAT_IOC, BFA_IOC_AEN_HBGOOD)
27#define BFA_AEN_IOC_HBFAIL \
28 BFA_LOG_CREATE_ID(BFA_AEN_CAT_IOC, BFA_IOC_AEN_HBFAIL)
29#define BFA_AEN_IOC_ENABLE \
30 BFA_LOG_CREATE_ID(BFA_AEN_CAT_IOC, BFA_IOC_AEN_ENABLE)
31#define BFA_AEN_IOC_DISABLE \
32 BFA_LOG_CREATE_ID(BFA_AEN_CAT_IOC, BFA_IOC_AEN_DISABLE)
33#define BFA_AEN_IOC_FWMISMATCH \
34 BFA_LOG_CREATE_ID(BFA_AEN_CAT_IOC, BFA_IOC_AEN_FWMISMATCH)
35
36#endif
37
diff --git a/drivers/scsi/bfa/include/aen/bfa_aen_itnim.h b/drivers/scsi/bfa/include/aen/bfa_aen_itnim.h
new file mode 100644
index 000000000000..a7d8ddcfef99
--- /dev/null
+++ b/drivers/scsi/bfa/include/aen/bfa_aen_itnim.h
@@ -0,0 +1,33 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/* messages define for BFA_AEN_CAT_ITNIM Module */
19#ifndef __bfa_aen_itnim_h__
20#define __bfa_aen_itnim_h__
21
22#include <cs/bfa_log.h>
23#include <defs/bfa_defs_aen.h>
24
25#define BFA_AEN_ITNIM_ONLINE \
26 BFA_LOG_CREATE_ID(BFA_AEN_CAT_ITNIM, BFA_ITNIM_AEN_ONLINE)
27#define BFA_AEN_ITNIM_OFFLINE \
28 BFA_LOG_CREATE_ID(BFA_AEN_CAT_ITNIM, BFA_ITNIM_AEN_OFFLINE)
29#define BFA_AEN_ITNIM_DISCONNECT \
30 BFA_LOG_CREATE_ID(BFA_AEN_CAT_ITNIM, BFA_ITNIM_AEN_DISCONNECT)
31
32#endif
33
diff --git a/drivers/scsi/bfa/include/aen/bfa_aen_lport.h b/drivers/scsi/bfa/include/aen/bfa_aen_lport.h
new file mode 100644
index 000000000000..5a8ebb65193f
--- /dev/null
+++ b/drivers/scsi/bfa/include/aen/bfa_aen_lport.h
@@ -0,0 +1,51 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/* messages define for BFA_AEN_CAT_LPORT Module */
19#ifndef __bfa_aen_lport_h__
20#define __bfa_aen_lport_h__
21
22#include <cs/bfa_log.h>
23#include <defs/bfa_defs_aen.h>
24
25#define BFA_AEN_LPORT_NEW \
26 BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, BFA_LPORT_AEN_NEW)
27#define BFA_AEN_LPORT_DELETE \
28 BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, BFA_LPORT_AEN_DELETE)
29#define BFA_AEN_LPORT_ONLINE \
30 BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, BFA_LPORT_AEN_ONLINE)
31#define BFA_AEN_LPORT_OFFLINE \
32 BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, BFA_LPORT_AEN_OFFLINE)
33#define BFA_AEN_LPORT_DISCONNECT \
34 BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, BFA_LPORT_AEN_DISCONNECT)
35#define BFA_AEN_LPORT_NEW_PROP \
36 BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, BFA_LPORT_AEN_NEW_PROP)
37#define BFA_AEN_LPORT_DELETE_PROP \
38 BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, BFA_LPORT_AEN_DELETE_PROP)
39#define BFA_AEN_LPORT_NEW_STANDARD \
40 BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, BFA_LPORT_AEN_NEW_STANDARD)
41#define BFA_AEN_LPORT_DELETE_STANDARD \
42 BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, BFA_LPORT_AEN_DELETE_STANDARD)
43#define BFA_AEN_LPORT_NPIV_DUP_WWN \
44 BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, BFA_LPORT_AEN_NPIV_DUP_WWN)
45#define BFA_AEN_LPORT_NPIV_FABRIC_MAX \
46 BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, BFA_LPORT_AEN_NPIV_FABRIC_MAX)
47#define BFA_AEN_LPORT_NPIV_UNKNOWN \
48 BFA_LOG_CREATE_ID(BFA_AEN_CAT_LPORT, BFA_LPORT_AEN_NPIV_UNKNOWN)
49
50#endif
51
diff --git a/drivers/scsi/bfa/include/aen/bfa_aen_port.h b/drivers/scsi/bfa/include/aen/bfa_aen_port.h
new file mode 100644
index 000000000000..9add905a622d
--- /dev/null
+++ b/drivers/scsi/bfa/include/aen/bfa_aen_port.h
@@ -0,0 +1,57 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/* messages define for BFA_AEN_CAT_PORT Module */
19#ifndef __bfa_aen_port_h__
20#define __bfa_aen_port_h__
21
22#include <cs/bfa_log.h>
23#include <defs/bfa_defs_aen.h>
24
25#define BFA_AEN_PORT_ONLINE \
26 BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, BFA_PORT_AEN_ONLINE)
27#define BFA_AEN_PORT_OFFLINE \
28 BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, BFA_PORT_AEN_OFFLINE)
29#define BFA_AEN_PORT_RLIR \
30 BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, BFA_PORT_AEN_RLIR)
31#define BFA_AEN_PORT_SFP_INSERT \
32 BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, BFA_PORT_AEN_SFP_INSERT)
33#define BFA_AEN_PORT_SFP_REMOVE \
34 BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, BFA_PORT_AEN_SFP_REMOVE)
35#define BFA_AEN_PORT_SFP_POM \
36 BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, BFA_PORT_AEN_SFP_POM)
37#define BFA_AEN_PORT_ENABLE \
38 BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, BFA_PORT_AEN_ENABLE)
39#define BFA_AEN_PORT_DISABLE \
40 BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, BFA_PORT_AEN_DISABLE)
41#define BFA_AEN_PORT_AUTH_ON \
42 BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, BFA_PORT_AEN_AUTH_ON)
43#define BFA_AEN_PORT_AUTH_OFF \
44 BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, BFA_PORT_AEN_AUTH_OFF)
45#define BFA_AEN_PORT_DISCONNECT \
46 BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, BFA_PORT_AEN_DISCONNECT)
47#define BFA_AEN_PORT_QOS_NEG \
48 BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, BFA_PORT_AEN_QOS_NEG)
49#define BFA_AEN_PORT_FABRIC_NAME_CHANGE \
50 BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, BFA_PORT_AEN_FABRIC_NAME_CHANGE)
51#define BFA_AEN_PORT_SFP_ACCESS_ERROR \
52 BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, BFA_PORT_AEN_SFP_ACCESS_ERROR)
53#define BFA_AEN_PORT_SFP_UNSUPPORT \
54 BFA_LOG_CREATE_ID(BFA_AEN_CAT_PORT, BFA_PORT_AEN_SFP_UNSUPPORT)
55
56#endif
57
diff --git a/drivers/scsi/bfa/include/aen/bfa_aen_rport.h b/drivers/scsi/bfa/include/aen/bfa_aen_rport.h
new file mode 100644
index 000000000000..7e4be1fd5e15
--- /dev/null
+++ b/drivers/scsi/bfa/include/aen/bfa_aen_rport.h
@@ -0,0 +1,37 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/* messages define for BFA_AEN_CAT_RPORT Module */
19#ifndef __bfa_aen_rport_h__
20#define __bfa_aen_rport_h__
21
22#include <cs/bfa_log.h>
23#include <defs/bfa_defs_aen.h>
24
25#define BFA_AEN_RPORT_ONLINE \
26 BFA_LOG_CREATE_ID(BFA_AEN_CAT_RPORT, BFA_RPORT_AEN_ONLINE)
27#define BFA_AEN_RPORT_OFFLINE \
28 BFA_LOG_CREATE_ID(BFA_AEN_CAT_RPORT, BFA_RPORT_AEN_OFFLINE)
29#define BFA_AEN_RPORT_DISCONNECT \
30 BFA_LOG_CREATE_ID(BFA_AEN_CAT_RPORT, BFA_RPORT_AEN_DISCONNECT)
31#define BFA_AEN_RPORT_QOS_PRIO \
32 BFA_LOG_CREATE_ID(BFA_AEN_CAT_RPORT, BFA_RPORT_AEN_QOS_PRIO)
33#define BFA_AEN_RPORT_QOS_FLOWID \
34 BFA_LOG_CREATE_ID(BFA_AEN_CAT_RPORT, BFA_RPORT_AEN_QOS_FLOWID)
35
36#endif
37
diff --git a/drivers/scsi/bfa/include/bfa.h b/drivers/scsi/bfa/include/bfa.h
new file mode 100644
index 000000000000..64c1412c5703
--- /dev/null
+++ b/drivers/scsi/bfa/include/bfa.h
@@ -0,0 +1,177 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17#ifndef __BFA_H__
18#define __BFA_H__
19
20#include <bfa_os_inc.h>
21#include <cs/bfa_debug.h>
22#include <cs/bfa_q.h>
23#include <cs/bfa_trc.h>
24#include <cs/bfa_log.h>
25#include <cs/bfa_plog.h>
26#include <defs/bfa_defs_status.h>
27#include <defs/bfa_defs_ioc.h>
28#include <defs/bfa_defs_iocfc.h>
29#include <aen/bfa_aen.h>
30#include <bfi/bfi.h>
31
32struct bfa_s;
33#include <bfa_intr_priv.h>
34
35struct bfa_pcidev_s;
36
37/**
38 * PCI devices supported by the current BFA
39 */
40struct bfa_pciid_s {
41 u16 device_id;
42 u16 vendor_id;
43};
44
45extern char bfa_version[];
46
47/**
48 * BFA Power Mgmt Commands
49 */
50enum bfa_pm_cmd {
51 BFA_PM_CTL_D0 = 0,
52 BFA_PM_CTL_D1 = 1,
53 BFA_PM_CTL_D2 = 2,
54 BFA_PM_CTL_D3 = 3,
55};
56
57/**
58 * BFA memory resources
59 */
60enum bfa_mem_type {
61 BFA_MEM_TYPE_KVA = 1, /*! Kernel Virtual Memory *(non-dma-able) */
62 BFA_MEM_TYPE_DMA = 2, /*! DMA-able memory */
63 BFA_MEM_TYPE_MAX = BFA_MEM_TYPE_DMA,
64};
65
66struct bfa_mem_elem_s {
67 enum bfa_mem_type mem_type; /* see enum bfa_mem_type */
68 u32 mem_len; /* Total Length in Bytes */
69 u8 *kva; /* kernel virtual address */
70 u64 dma; /* dma address if DMA memory */
71 u8 *kva_curp; /* kva allocation cursor */
72 u64 dma_curp; /* dma allocation cursor */
73};
74
75struct bfa_meminfo_s {
76 struct bfa_mem_elem_s meminfo[BFA_MEM_TYPE_MAX];
77};
78#define bfa_meminfo_kva(_m) \
79 (_m)->meminfo[BFA_MEM_TYPE_KVA - 1].kva_curp
80#define bfa_meminfo_dma_virt(_m) \
81 (_m)->meminfo[BFA_MEM_TYPE_DMA - 1].kva_curp
82#define bfa_meminfo_dma_phys(_m) \
83 (_m)->meminfo[BFA_MEM_TYPE_DMA - 1].dma_curp
84
85/**
86 * Generic Scatter Gather Element used by driver
87 */
88struct bfa_sge_s {
89 u32 sg_len;
90 void *sg_addr;
91};
92
93#define bfa_sge_to_be(__sge) do { \
94 ((u32 *)(__sge))[0] = bfa_os_htonl(((u32 *)(__sge))[0]); \
95 ((u32 *)(__sge))[1] = bfa_os_htonl(((u32 *)(__sge))[1]); \
96 ((u32 *)(__sge))[2] = bfa_os_htonl(((u32 *)(__sge))[2]); \
97} while (0)
98
99
100/*
101 * bfa stats interfaces
102 */
103#define bfa_stats(_mod, _stats) (_mod)->stats._stats ++
104
105#define bfa_ioc_get_stats(__bfa, __ioc_stats) \
106 bfa_ioc_fetch_stats(&(__bfa)->ioc, __ioc_stats)
107#define bfa_ioc_clear_stats(__bfa) \
108 bfa_ioc_clr_stats(&(__bfa)->ioc)
109
110/*
111 * bfa API functions
112 */
113void bfa_get_pciids(struct bfa_pciid_s **pciids, int *npciids);
114void bfa_cfg_get_default(struct bfa_iocfc_cfg_s *cfg);
115void bfa_cfg_get_min(struct bfa_iocfc_cfg_s *cfg);
116void bfa_cfg_get_meminfo(struct bfa_iocfc_cfg_s *cfg,
117 struct bfa_meminfo_s *meminfo);
118void bfa_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
119 struct bfa_meminfo_s *meminfo,
120 struct bfa_pcidev_s *pcidev);
121void bfa_init_trc(struct bfa_s *bfa, struct bfa_trc_mod_s *trcmod);
122void bfa_init_log(struct bfa_s *bfa, struct bfa_log_mod_s *logmod);
123void bfa_init_aen(struct bfa_s *bfa, struct bfa_aen_s *aen);
124void bfa_init_plog(struct bfa_s *bfa, struct bfa_plog_s *plog);
125void bfa_detach(struct bfa_s *bfa);
126void bfa_init(struct bfa_s *bfa);
127void bfa_start(struct bfa_s *bfa);
128void bfa_stop(struct bfa_s *bfa);
129void bfa_attach_fcs(struct bfa_s *bfa);
130void bfa_cb_init(void *bfad, bfa_status_t status);
131void bfa_cb_stop(void *bfad, bfa_status_t status);
132void bfa_cb_updateq(void *bfad, bfa_status_t status);
133
134bfa_boolean_t bfa_intx(struct bfa_s *bfa);
135void bfa_isr_enable(struct bfa_s *bfa);
136void bfa_isr_disable(struct bfa_s *bfa);
137void bfa_msix_getvecs(struct bfa_s *bfa, u32 *msix_vecs_bmap,
138 u32 *num_vecs, u32 *max_vec_bit);
139#define bfa_msix(__bfa, __vec) (__bfa)->msix.handler[__vec](__bfa, __vec)
140
141void bfa_comp_deq(struct bfa_s *bfa, struct list_head *comp_q);
142void bfa_comp_process(struct bfa_s *bfa, struct list_head *comp_q);
143void bfa_comp_free(struct bfa_s *bfa, struct list_head *comp_q);
144
145typedef void (*bfa_cb_ioc_t) (void *cbarg, enum bfa_status status);
146void bfa_iocfc_get_attr(struct bfa_s *bfa, struct bfa_iocfc_attr_s *attr);
147bfa_status_t bfa_iocfc_get_stats(struct bfa_s *bfa,
148 struct bfa_iocfc_stats_s *stats,
149 bfa_cb_ioc_t cbfn, void *cbarg);
150bfa_status_t bfa_iocfc_clear_stats(struct bfa_s *bfa,
151 bfa_cb_ioc_t cbfn, void *cbarg);
152void bfa_get_attr(struct bfa_s *bfa, struct bfa_ioc_attr_s *ioc_attr);
153
154void bfa_adapter_get_attr(struct bfa_s *bfa,
155 struct bfa_adapter_attr_s *ad_attr);
156u64 bfa_adapter_get_id(struct bfa_s *bfa);
157
158bfa_status_t bfa_iocfc_israttr_set(struct bfa_s *bfa,
159 struct bfa_iocfc_intr_attr_s *attr);
160
161void bfa_iocfc_enable(struct bfa_s *bfa);
162void bfa_iocfc_disable(struct bfa_s *bfa);
163void bfa_ioc_auto_recover(bfa_boolean_t auto_recover);
164void bfa_cb_ioc_disable(void *bfad);
165void bfa_timer_tick(struct bfa_s *bfa);
166#define bfa_timer_start(_bfa, _timer, _timercb, _arg, _timeout) \
167 bfa_timer_begin(&(_bfa)->timer_mod, _timer, _timercb, _arg, _timeout)
168
169/*
170 * BFA debug API functions
171 */
172bfa_status_t bfa_debug_fwtrc(struct bfa_s *bfa, void *trcdata, int *trclen);
173bfa_status_t bfa_debug_fwsave(struct bfa_s *bfa, void *trcdata, int *trclen);
174
175#include "bfa_priv.h"
176
177#endif /* __BFA_H__ */
diff --git a/drivers/scsi/bfa/include/bfa_fcpim.h b/drivers/scsi/bfa/include/bfa_fcpim.h
new file mode 100644
index 000000000000..04789795fa53
--- /dev/null
+++ b/drivers/scsi/bfa/include/bfa_fcpim.h
@@ -0,0 +1,159 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFA_FCPIM_H__
19#define __BFA_FCPIM_H__
20
21#include <bfa.h>
22#include <bfa_svc.h>
23#include <bfi/bfi_fcpim.h>
24#include <defs/bfa_defs_fcpim.h>
25
26/*
27 * forward declarations
28 */
29struct bfa_itnim_s;
30struct bfa_ioim_s;
31struct bfa_tskim_s;
32struct bfad_ioim_s;
33struct bfad_tskim_s;
34
35/*
36 * bfa fcpim module API functions
37 */
38void bfa_fcpim_path_tov_set(struct bfa_s *bfa, u16 path_tov);
39u16 bfa_fcpim_path_tov_get(struct bfa_s *bfa);
40void bfa_fcpim_qdepth_set(struct bfa_s *bfa, u16 q_depth);
41u16 bfa_fcpim_qdepth_get(struct bfa_s *bfa);
42bfa_status_t bfa_fcpim_get_modstats(struct bfa_s *bfa,
43 struct bfa_fcpim_stats_s *modstats);
44bfa_status_t bfa_fcpim_clr_modstats(struct bfa_s *bfa);
45
46/*
47 * bfa itnim API functions
48 */
49struct bfa_itnim_s *bfa_itnim_create(struct bfa_s *bfa,
50 struct bfa_rport_s *rport, void *itnim);
51void bfa_itnim_delete(struct bfa_itnim_s *itnim);
52void bfa_itnim_online(struct bfa_itnim_s *itnim,
53 bfa_boolean_t seq_rec);
54void bfa_itnim_offline(struct bfa_itnim_s *itnim);
55void bfa_itnim_get_stats(struct bfa_itnim_s *itnim,
56 struct bfa_itnim_hal_stats_s *stats);
57void bfa_itnim_clear_stats(struct bfa_itnim_s *itnim);
58
59
60/**
61 * BFA completion callback for bfa_itnim_online().
62 *
63 * @param[in] itnim FCS or driver itnim instance
64 *
65 * return None
66 */
67void bfa_cb_itnim_online(void *itnim);
68
69/**
70 * BFA completion callback for bfa_itnim_offline().
71 *
72 * @param[in] itnim FCS or driver itnim instance
73 *
74 * return None
75 */
76void bfa_cb_itnim_offline(void *itnim);
77void bfa_cb_itnim_tov_begin(void *itnim);
78void bfa_cb_itnim_tov(void *itnim);
79
80/**
81 * BFA notification to FCS/driver for second level error recovery.
82 *
83 * Atleast one I/O request has timedout and target is unresponsive to
84 * repeated abort requests. Second level error recovery should be initiated
85 * by starting implicit logout and recovery procedures.
86 *
87 * @param[in] itnim FCS or driver itnim instance
88 *
89 * return None
90 */
91void bfa_cb_itnim_sler(void *itnim);
92
93/*
94 * bfa ioim API functions
95 */
96struct bfa_ioim_s *bfa_ioim_alloc(struct bfa_s *bfa,
97 struct bfad_ioim_s *dio,
98 struct bfa_itnim_s *itnim,
99 u16 nsgles);
100
101void bfa_ioim_free(struct bfa_ioim_s *ioim);
102void bfa_ioim_start(struct bfa_ioim_s *ioim);
103void bfa_ioim_abort(struct bfa_ioim_s *ioim);
104void bfa_ioim_delayed_comp(struct bfa_ioim_s *ioim,
105 bfa_boolean_t iotov);
106
107
108/**
109 * I/O completion notification.
110 *
111 * @param[in] dio driver IO structure
112 * @param[in] io_status IO completion status
113 * @param[in] scsi_status SCSI status returned by target
114 * @param[in] sns_len SCSI sense length, 0 if none
115 * @param[in] sns_info SCSI sense data, if any
116 * @param[in] residue Residual length
117 *
118 * @return None
119 */
120void bfa_cb_ioim_done(void *bfad, struct bfad_ioim_s *dio,
121 enum bfi_ioim_status io_status,
122 u8 scsi_status, int sns_len,
123 u8 *sns_info, s32 residue);
124
125/**
126 * I/O good completion notification.
127 *
128 * @param[in] dio driver IO structure
129 *
130 * @return None
131 */
132void bfa_cb_ioim_good_comp(void *bfad, struct bfad_ioim_s *dio);
133
134/**
135 * I/O abort completion notification
136 *
137 * @param[in] dio driver IO that was aborted
138 *
139 * @return None
140 */
141void bfa_cb_ioim_abort(void *bfad, struct bfad_ioim_s *dio);
142void bfa_cb_ioim_resfree(void *hcb_bfad);
143
144void bfa_cb_ioim_resfree(void *hcb_bfad);
145
146/*
147 * bfa tskim API functions
148 */
149struct bfa_tskim_s *bfa_tskim_alloc(struct bfa_s *bfa,
150 struct bfad_tskim_s *dtsk);
151void bfa_tskim_free(struct bfa_tskim_s *tskim);
152void bfa_tskim_start(struct bfa_tskim_s *tskim,
153 struct bfa_itnim_s *itnim, lun_t lun,
154 enum fcp_tm_cmnd tm, u8 t_secs);
155void bfa_cb_tskim_done(void *bfad, struct bfad_tskim_s *dtsk,
156 enum bfi_tskim_status tsk_status);
157
158#endif /* __BFA_FCPIM_H__ */
159
diff --git a/drivers/scsi/bfa/include/bfa_fcptm.h b/drivers/scsi/bfa/include/bfa_fcptm.h
new file mode 100644
index 000000000000..5f5ffe0bb1bb
--- /dev/null
+++ b/drivers/scsi/bfa/include/bfa_fcptm.h
@@ -0,0 +1,47 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFA_FCPTM_H__
19#define __BFA_FCPTM_H__
20
21#include <bfa.h>
22#include <bfa_svc.h>
23#include <bfi/bfi_fcptm.h>
24
25/*
26 * forward declarations
27 */
28struct bfa_tin_s;
29struct bfa_iotm_s;
30struct bfa_tsktm_s;
31
32/*
33 * bfa fcptm module API functions
34 */
35void bfa_fcptm_path_tov_set(struct bfa_s *bfa, u16 path_tov);
36u16 bfa_fcptm_path_tov_get(struct bfa_s *bfa);
37void bfa_fcptm_qdepth_set(struct bfa_s *bfa, u16 q_depth);
38u16 bfa_fcptm_qdepth_get(struct bfa_s *bfa);
39
40/*
41 * bfa tin API functions
42 */
43void bfa_tin_get_stats(struct bfa_tin_s *tin, struct bfa_tin_stats_s *stats);
44void bfa_tin_clear_stats(struct bfa_tin_s *tin);
45
46#endif /* __BFA_FCPTM_H__ */
47
diff --git a/drivers/scsi/bfa/include/bfa_svc.h b/drivers/scsi/bfa/include/bfa_svc.h
new file mode 100644
index 000000000000..0c80b74f72ef
--- /dev/null
+++ b/drivers/scsi/bfa/include/bfa_svc.h
@@ -0,0 +1,324 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17#ifndef __BFA_SVC_H__
18#define __BFA_SVC_H__
19
20/*
21 * forward declarations
22 */
23struct bfa_fcxp_s;
24
25#include <defs/bfa_defs_status.h>
26#include <defs/bfa_defs_pport.h>
27#include <defs/bfa_defs_rport.h>
28#include <defs/bfa_defs_qos.h>
29#include <cs/bfa_sm.h>
30#include <bfa.h>
31
32/**
33 * BFA rport information.
34 */
35struct bfa_rport_info_s {
36 u16 max_frmsz; /* max rcv pdu size */
37 u32 pid : 24, /* remote port ID */
38 lp_tag : 8;
39 u32 local_pid : 24, /* local port ID */
40 cisc : 8; /* CIRO supported */
41 u8 fc_class; /* supported FC classes. enum fc_cos */
42 u8 vf_en; /* virtual fabric enable */
43 u16 vf_id; /* virtual fabric ID */
44 enum bfa_pport_speed speed; /* Rport's current speed */
45};
46
47/**
48 * BFA rport data structure
49 */
50struct bfa_rport_s {
51 struct list_head qe; /* queue element */
52 bfa_sm_t sm; /* state machine */
53 struct bfa_s *bfa; /* backpointer to BFA */
54 void *rport_drv; /* fcs/driver rport object */
55 u16 fw_handle; /* firmware rport handle */
56 u16 rport_tag; /* BFA rport tag */
57 struct bfa_rport_info_s rport_info; /* rport info from *fcs/driver */
58 struct bfa_reqq_wait_s reqq_wait; /* to wait for room in reqq */
59 struct bfa_cb_qe_s hcb_qe; /* BFA callback qelem */
60 struct bfa_rport_hal_stats_s stats; /* BFA rport statistics */
61 struct bfa_rport_qos_attr_s qos_attr;
62 union a {
63 bfa_status_t status; /* f/w status */
64 void *fw_msg; /* QoS scn event */
65 } event_arg;
66};
67#define BFA_RPORT_FC_COS(_rport) ((_rport)->rport_info.fc_class)
68
69/**
70 * Send completion callback.
71 */
72typedef void (*bfa_cb_fcxp_send_t) (void *bfad_fcxp, struct bfa_fcxp_s *fcxp,
73 void *cbarg, enum bfa_status req_status,
74 u32 rsp_len, u32 resid_len,
75 struct fchs_s *rsp_fchs);
76
77/**
78 * BFA fcxp allocation (asynchronous)
79 */
80typedef void (*bfa_fcxp_alloc_cbfn_t) (void *cbarg, struct bfa_fcxp_s *fcxp);
81
82struct bfa_fcxp_wqe_s {
83 struct list_head qe;
84 bfa_fcxp_alloc_cbfn_t alloc_cbfn;
85 void *alloc_cbarg;
86};
87
88typedef u64 (*bfa_fcxp_get_sgaddr_t) (void *bfad_fcxp, int sgeid);
89typedef u32 (*bfa_fcxp_get_sglen_t) (void *bfad_fcxp, int sgeid);
90
91#define BFA_UF_BUFSZ (2 * 1024 + 256)
92
93/**
94 * @todo private
95 */
96struct bfa_uf_buf_s {
97 u8 d[BFA_UF_BUFSZ];
98};
99
100
101struct bfa_uf_s {
102 struct list_head qe; /* queue element */
103 struct bfa_s *bfa; /* bfa instance */
104 u16 uf_tag; /* identifying tag f/w messages */
105 u16 vf_id;
106 u16 src_rport_handle;
107 u16 rsvd;
108 u8 *data_ptr;
109 u16 data_len; /* actual receive length */
110 u16 pb_len; /* posted buffer length */
111 void *buf_kva; /* buffer virtual address */
112 u64 buf_pa; /* buffer physical address */
113 struct bfa_cb_qe_s hcb_qe; /* comp: BFA comp qelem */
114 struct bfa_sge_s sges[BFI_SGE_INLINE_MAX];
115};
116
117typedef void (*bfa_cb_pport_t) (void *cbarg, enum bfa_status status);
118
119/**
120 * bfa lport login/logout service interface
121 */
122struct bfa_lps_s {
123 struct list_head qe; /* queue element */
124 struct bfa_s *bfa; /* parent bfa instance */
125 bfa_sm_t sm; /* finite state machine */
126 u8 lp_tag; /* lport tag */
127 u8 reqq; /* lport request queue */
128 u8 alpa; /* ALPA for loop topologies */
129 u32 lp_pid; /* lport port ID */
130 bfa_boolean_t fdisc; /* send FDISC instead of FLOGI*/
131 bfa_boolean_t auth_en; /* enable authentication */
132 bfa_boolean_t auth_req; /* authentication required */
133 bfa_boolean_t npiv_en; /* NPIV is allowed by peer */
134 bfa_boolean_t fport; /* attached peer is F_PORT */
135 bfa_boolean_t brcd_switch;/* attached peer is brcd switch */
136 bfa_status_t status; /* login status */
137 u16 pdusz; /* max receive PDU size */
138 u16 pr_bbcred; /* BB_CREDIT from peer */
139 u8 lsrjt_rsn; /* LSRJT reason */
140 u8 lsrjt_expl; /* LSRJT explanation */
141 wwn_t pwwn; /* port wwn of lport */
142 wwn_t nwwn; /* node wwn of lport */
143 wwn_t pr_pwwn; /* port wwn of lport peer */
144 wwn_t pr_nwwn; /* node wwn of lport peer */
145 mac_t lp_mac; /* fpma/spma MAC for lport */
146 mac_t fcf_mac; /* FCF MAC of lport */
147 struct bfa_reqq_wait_s wqe; /* request wait queue element */
148 void *uarg; /* user callback arg */
149 struct bfa_cb_qe_s hcb_qe; /* comp: callback qelem */
150 struct bfi_lps_login_rsp_s *loginrsp;
151 bfa_eproto_status_t ext_status;
152};
153
154/*
155 * bfa pport API functions
156 */
157bfa_status_t bfa_pport_enable(struct bfa_s *bfa);
158bfa_status_t bfa_pport_disable(struct bfa_s *bfa);
159bfa_status_t bfa_pport_cfg_speed(struct bfa_s *bfa,
160 enum bfa_pport_speed speed);
161enum bfa_pport_speed bfa_pport_get_speed(struct bfa_s *bfa);
162bfa_status_t bfa_pport_cfg_topology(struct bfa_s *bfa,
163 enum bfa_pport_topology topo);
164enum bfa_pport_topology bfa_pport_get_topology(struct bfa_s *bfa);
165bfa_status_t bfa_pport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa);
166bfa_boolean_t bfa_pport_get_hardalpa(struct bfa_s *bfa, u8 *alpa);
167u8 bfa_pport_get_myalpa(struct bfa_s *bfa);
168bfa_status_t bfa_pport_clr_hardalpa(struct bfa_s *bfa);
169bfa_status_t bfa_pport_cfg_maxfrsize(struct bfa_s *bfa, u16 maxsize);
170u16 bfa_pport_get_maxfrsize(struct bfa_s *bfa);
171u32 bfa_pport_mypid(struct bfa_s *bfa);
172u8 bfa_pport_get_rx_bbcredit(struct bfa_s *bfa);
173bfa_status_t bfa_pport_trunk_enable(struct bfa_s *bfa, u8 bitmap);
174bfa_status_t bfa_pport_trunk_disable(struct bfa_s *bfa);
175bfa_boolean_t bfa_pport_trunk_query(struct bfa_s *bfa, u32 *bitmap);
176void bfa_pport_get_attr(struct bfa_s *bfa, struct bfa_pport_attr_s *attr);
177wwn_t bfa_pport_get_wwn(struct bfa_s *bfa, bfa_boolean_t node);
178bfa_status_t bfa_pport_get_stats(struct bfa_s *bfa,
179 union bfa_pport_stats_u *stats,
180 bfa_cb_pport_t cbfn, void *cbarg);
181bfa_status_t bfa_pport_clear_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn,
182 void *cbarg);
183void bfa_pport_event_register(struct bfa_s *bfa,
184 void (*event_cbfn) (void *cbarg,
185 bfa_pport_event_t event), void *event_cbarg);
186bfa_boolean_t bfa_pport_is_disabled(struct bfa_s *bfa);
187void bfa_pport_cfg_qos(struct bfa_s *bfa, bfa_boolean_t on_off);
188void bfa_pport_cfg_ratelim(struct bfa_s *bfa, bfa_boolean_t on_off);
189bfa_status_t bfa_pport_cfg_ratelim_speed(struct bfa_s *bfa,
190 enum bfa_pport_speed speed);
191enum bfa_pport_speed bfa_pport_get_ratelim_speed(struct bfa_s *bfa);
192
193void bfa_pport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit);
194void bfa_pport_busy(struct bfa_s *bfa, bfa_boolean_t status);
195void bfa_pport_beacon(struct bfa_s *bfa, bfa_boolean_t beacon,
196 bfa_boolean_t link_e2e_beacon);
197void bfa_cb_pport_event(void *cbarg, bfa_pport_event_t event);
198void bfa_pport_qos_get_attr(struct bfa_s *bfa, struct bfa_qos_attr_s *qos_attr);
199void bfa_pport_qos_get_vc_attr(struct bfa_s *bfa,
200 struct bfa_qos_vc_attr_s *qos_vc_attr);
201bfa_status_t bfa_pport_get_qos_stats(struct bfa_s *bfa,
202 union bfa_pport_stats_u *stats,
203 bfa_cb_pport_t cbfn, void *cbarg);
204bfa_status_t bfa_pport_clear_qos_stats(struct bfa_s *bfa, bfa_cb_pport_t cbfn,
205 void *cbarg);
206bfa_boolean_t bfa_pport_is_ratelim(struct bfa_s *bfa);
207bfa_boolean_t bfa_pport_is_linkup(struct bfa_s *bfa);
208
209/*
210 * bfa rport API functions
211 */
212struct bfa_rport_s *bfa_rport_create(struct bfa_s *bfa, void *rport_drv);
213void bfa_rport_delete(struct bfa_rport_s *rport);
214void bfa_rport_online(struct bfa_rport_s *rport,
215 struct bfa_rport_info_s *rport_info);
216void bfa_rport_offline(struct bfa_rport_s *rport);
217void bfa_rport_speed(struct bfa_rport_s *rport, enum bfa_pport_speed speed);
218void bfa_rport_get_stats(struct bfa_rport_s *rport,
219 struct bfa_rport_hal_stats_s *stats);
220void bfa_rport_clear_stats(struct bfa_rport_s *rport);
221void bfa_cb_rport_online(void *rport);
222void bfa_cb_rport_offline(void *rport);
223void bfa_cb_rport_qos_scn_flowid(void *rport,
224 struct bfa_rport_qos_attr_s old_qos_attr,
225 struct bfa_rport_qos_attr_s new_qos_attr);
226void bfa_cb_rport_qos_scn_prio(void *rport,
227 struct bfa_rport_qos_attr_s old_qos_attr,
228 struct bfa_rport_qos_attr_s new_qos_attr);
229void bfa_rport_get_qos_attr(struct bfa_rport_s *rport,
230 struct bfa_rport_qos_attr_s *qos_attr);
231
232/*
233 * bfa fcxp API functions
234 */
235struct bfa_fcxp_s *bfa_fcxp_alloc(void *bfad_fcxp, struct bfa_s *bfa,
236 int nreq_sgles, int nrsp_sgles,
237 bfa_fcxp_get_sgaddr_t get_req_sga,
238 bfa_fcxp_get_sglen_t get_req_sglen,
239 bfa_fcxp_get_sgaddr_t get_rsp_sga,
240 bfa_fcxp_get_sglen_t get_rsp_sglen);
241void bfa_fcxp_alloc_wait(struct bfa_s *bfa, struct bfa_fcxp_wqe_s *wqe,
242 bfa_fcxp_alloc_cbfn_t alloc_cbfn, void *cbarg);
243void bfa_fcxp_walloc_cancel(struct bfa_s *bfa,
244 struct bfa_fcxp_wqe_s *wqe);
245void bfa_fcxp_discard(struct bfa_fcxp_s *fcxp);
246
247void *bfa_fcxp_get_reqbuf(struct bfa_fcxp_s *fcxp);
248void *bfa_fcxp_get_rspbuf(struct bfa_fcxp_s *fcxp);
249
250void bfa_fcxp_free(struct bfa_fcxp_s *fcxp);
251
252void bfa_fcxp_send(struct bfa_fcxp_s *fcxp,
253 struct bfa_rport_s *rport, u16 vf_id, u8 lp_tag,
254 bfa_boolean_t cts, enum fc_cos cos,
255 u32 reqlen, struct fchs_s *fchs,
256 bfa_cb_fcxp_send_t cbfn,
257 void *cbarg,
258 u32 rsp_maxlen, u8 rsp_timeout);
259bfa_status_t bfa_fcxp_abort(struct bfa_fcxp_s *fcxp);
260u32 bfa_fcxp_get_reqbufsz(struct bfa_fcxp_s *fcxp);
261u32 bfa_fcxp_get_maxrsp(struct bfa_s *bfa);
262
263static inline void *
264bfa_uf_get_frmbuf(struct bfa_uf_s *uf)
265{
266 return uf->data_ptr;
267}
268
269static inline u16
270bfa_uf_get_frmlen(struct bfa_uf_s *uf)
271{
272 return uf->data_len;
273}
274
275/**
276 * Callback prototype for unsolicited frame receive handler.
277 *
278 * @param[in] cbarg callback arg for receive handler
279 * @param[in] uf unsolicited frame descriptor
280 *
281 * @return None
282 */
283typedef void (*bfa_cb_uf_recv_t) (void *cbarg, struct bfa_uf_s *uf);
284
285/*
286 * bfa uf API functions
287 */
288void bfa_uf_recv_register(struct bfa_s *bfa, bfa_cb_uf_recv_t ufrecv,
289 void *cbarg);
290void bfa_uf_free(struct bfa_uf_s *uf);
291
292/**
293 * bfa lport service api
294 */
295
296struct bfa_lps_s *bfa_lps_alloc(struct bfa_s *bfa);
297void bfa_lps_delete(struct bfa_lps_s *lps);
298void bfa_lps_discard(struct bfa_lps_s *lps);
299void bfa_lps_flogi(struct bfa_lps_s *lps, void *uarg, u8 alpa, u16 pdusz,
300 wwn_t pwwn, wwn_t nwwn, bfa_boolean_t auth_en);
301void bfa_lps_fdisc(struct bfa_lps_s *lps, void *uarg, u16 pdusz, wwn_t pwwn,
302 wwn_t nwwn);
303void bfa_lps_flogo(struct bfa_lps_s *lps);
304void bfa_lps_fdisclogo(struct bfa_lps_s *lps);
305u8 bfa_lps_get_tag(struct bfa_lps_s *lps);
306bfa_boolean_t bfa_lps_is_npiv_en(struct bfa_lps_s *lps);
307bfa_boolean_t bfa_lps_is_fport(struct bfa_lps_s *lps);
308bfa_boolean_t bfa_lps_is_brcd_fabric(struct bfa_lps_s *lps);
309bfa_boolean_t bfa_lps_is_authreq(struct bfa_lps_s *lps);
310bfa_eproto_status_t bfa_lps_get_extstatus(struct bfa_lps_s *lps);
311u32 bfa_lps_get_pid(struct bfa_lps_s *lps);
312u8 bfa_lps_get_tag_from_pid(struct bfa_s *bfa, u32 pid);
313u16 bfa_lps_get_peer_bbcredit(struct bfa_lps_s *lps);
314wwn_t bfa_lps_get_peer_pwwn(struct bfa_lps_s *lps);
315wwn_t bfa_lps_get_peer_nwwn(struct bfa_lps_s *lps);
316u8 bfa_lps_get_lsrjt_rsn(struct bfa_lps_s *lps);
317u8 bfa_lps_get_lsrjt_expl(struct bfa_lps_s *lps);
318void bfa_cb_lps_flogi_comp(void *bfad, void *uarg, bfa_status_t status);
319void bfa_cb_lps_flogo_comp(void *bfad, void *uarg);
320void bfa_cb_lps_fdisc_comp(void *bfad, void *uarg, bfa_status_t status);
321void bfa_cb_lps_fdisclogo_comp(void *bfad, void *uarg);
322
323#endif /* __BFA_SVC_H__ */
324
diff --git a/drivers/scsi/bfa/include/bfa_timer.h b/drivers/scsi/bfa/include/bfa_timer.h
new file mode 100644
index 000000000000..e407103fa565
--- /dev/null
+++ b/drivers/scsi/bfa/include/bfa_timer.h
@@ -0,0 +1,53 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17#ifndef __BFA_TIMER_H__
18#define __BFA_TIMER_H__
19
20#include <bfa_os_inc.h>
21#include <cs/bfa_q.h>
22
23struct bfa_s;
24
25typedef void (*bfa_timer_cbfn_t)(void *);
26
27/**
28 * BFA timer data structure
29 */
30struct bfa_timer_s {
31 struct list_head qe;
32 bfa_timer_cbfn_t timercb;
33 void *arg;
34 int timeout; /**< in millisecs. */
35};
36
37/**
38 * Timer module structure
39 */
40struct bfa_timer_mod_s {
41 struct list_head timer_q;
42};
43
44#define BFA_TIMER_FREQ 500 /**< specified in millisecs */
45
46void bfa_timer_beat(struct bfa_timer_mod_s *mod);
47void bfa_timer_init(struct bfa_timer_mod_s *mod);
48void bfa_timer_begin(struct bfa_timer_mod_s *mod, struct bfa_timer_s *timer,
49 bfa_timer_cbfn_t timercb, void *arg,
50 unsigned int timeout);
51void bfa_timer_stop(struct bfa_timer_s *timer);
52
53#endif /* __BFA_TIMER_H__ */
diff --git a/drivers/scsi/bfa/include/bfi/bfi.h b/drivers/scsi/bfa/include/bfi/bfi.h
new file mode 100644
index 000000000000..6cadfe0d4ba1
--- /dev/null
+++ b/drivers/scsi/bfa/include/bfi/bfi.h
@@ -0,0 +1,174 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFI_H__
19#define __BFI_H__
20
21#include <bfa_os_inc.h>
22#include <defs/bfa_defs_status.h>
23
24#pragma pack(1)
25
26/**
27 * Msg header common to all msgs
28 */
29struct bfi_mhdr_s {
30 u8 msg_class; /* @ref bfi_mclass_t */
31 u8 msg_id; /* msg opcode with in the class */
32 union {
33 struct {
34 u8 rsvd;
35 u8 lpu_id; /* msg destination */
36 } h2i;
37 u16 i2htok; /* token in msgs to host */
38 } mtag;
39};
40
41#define bfi_h2i_set(_mh, _mc, _op, _lpuid) do { \
42 (_mh).msg_class = (_mc); \
43 (_mh).msg_id = (_op); \
44 (_mh).mtag.h2i.lpu_id = (_lpuid); \
45} while (0)
46
47#define bfi_i2h_set(_mh, _mc, _op, _i2htok) do { \
48 (_mh).msg_class = (_mc); \
49 (_mh).msg_id = (_op); \
50 (_mh).mtag.i2htok = (_i2htok); \
51} while (0)
52
53/*
54 * Message opcodes: 0-127 to firmware, 128-255 to host
55 */
56#define BFI_I2H_OPCODE_BASE 128
57#define BFA_I2HM(_x) ((_x) + BFI_I2H_OPCODE_BASE)
58
59/**
60 ****************************************************************************
61 *
62 * Scatter Gather Element and Page definition
63 *
64 ****************************************************************************
65 */
66
67#define BFI_SGE_INLINE 1
68#define BFI_SGE_INLINE_MAX (BFI_SGE_INLINE + 1)
69
70/**
71 * SG Flags
72 */
73enum {
74 BFI_SGE_DATA = 0, /* data address, not last */
75 BFI_SGE_DATA_CPL = 1, /* data addr, last in current page */
76 BFI_SGE_DATA_LAST = 3, /* data address, last */
77 BFI_SGE_LINK = 2, /* link address */
78 BFI_SGE_PGDLEN = 2, /* cumulative data length for page */
79};
80
81/**
82 * DMA addresses
83 */
84union bfi_addr_u {
85 struct {
86 u32 addr_lo;
87 u32 addr_hi;
88 } a32;
89};
90
91/**
92 * Scatter Gather Element
93 */
94struct bfi_sge_s {
95#ifdef __BIGENDIAN
96 u32 flags : 2,
97 rsvd : 2,
98 sg_len : 28;
99#else
100 u32 sg_len : 28,
101 rsvd : 2,
102 flags : 2;
103#endif
104 union bfi_addr_u sga;
105};
106
107/**
108 * Scatter Gather Page
109 */
110#define BFI_SGPG_DATA_SGES 7
111#define BFI_SGPG_SGES_MAX (BFI_SGPG_DATA_SGES + 1)
112#define BFI_SGPG_RSVD_WD_LEN 8
113struct bfi_sgpg_s {
114 struct bfi_sge_s sges[BFI_SGPG_SGES_MAX];
115 u32 rsvd[BFI_SGPG_RSVD_WD_LEN];
116};
117
118/*
119 * Large Message structure - 128 Bytes size Msgs
120 */
121#define BFI_LMSG_SZ 128
122#define BFI_LMSG_PL_WSZ \
123 ((BFI_LMSG_SZ - sizeof(struct bfi_mhdr_s)) / 4)
124
125struct bfi_msg_s {
126 struct bfi_mhdr_s mhdr;
127 u32 pl[BFI_LMSG_PL_WSZ];
128};
129
130/**
131 * Mailbox message structure
132 */
133#define BFI_MBMSG_SZ 7
134struct bfi_mbmsg_s {
135 struct bfi_mhdr_s mh;
136 u32 pl[BFI_MBMSG_SZ];
137};
138
139/**
140 * Message Classes
141 */
142enum bfi_mclass {
143 BFI_MC_IOC = 1, /* IO Controller (IOC) */
144 BFI_MC_DIAG = 2, /* Diagnostic Msgs */
145 BFI_MC_FLASH = 3, /* Flash message class */
146 BFI_MC_CEE = 4,
147 BFI_MC_FC_PORT = 5, /* FC port */
148 BFI_MC_IOCFC = 6, /* FC - IO Controller (IOC) */
149 BFI_MC_LL = 7, /* Link Layer */
150 BFI_MC_UF = 8, /* Unsolicited frame receive */
151 BFI_MC_FCXP = 9, /* FC Transport */
152 BFI_MC_LPS = 10, /* lport fc login services */
153 BFI_MC_RPORT = 11, /* Remote port */
154 BFI_MC_ITNIM = 12, /* I-T nexus (Initiator mode) */
155 BFI_MC_IOIM_READ = 13, /* read IO (Initiator mode) */
156 BFI_MC_IOIM_WRITE = 14, /* write IO (Initiator mode) */
157 BFI_MC_IOIM_IO = 15, /* IO (Initiator mode) */
158 BFI_MC_IOIM = 16, /* IO (Initiator mode) */
159 BFI_MC_IOIM_IOCOM = 17, /* good IO completion */
160 BFI_MC_TSKIM = 18, /* Initiator Task management */
161 BFI_MC_SBOOT = 19, /* SAN boot services */
162 BFI_MC_IPFC = 20, /* IP over FC Msgs */
163 BFI_MC_PORT = 21, /* Physical port */
164 BFI_MC_MAX = 32
165};
166
167#define BFI_IOC_MAX_CQS 4
168#define BFI_IOC_MAX_CQS_ASIC 8
169#define BFI_IOC_MSGLEN_MAX 32 /* 32 bytes */
170
171#pragma pack()
172
173#endif /* __BFI_H__ */
174
diff --git a/drivers/scsi/bfa/include/bfi/bfi_boot.h b/drivers/scsi/bfa/include/bfi/bfi_boot.h
new file mode 100644
index 000000000000..5955afe7d108
--- /dev/null
+++ b/drivers/scsi/bfa/include/bfi/bfi_boot.h
@@ -0,0 +1,34 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17/*
18 * bfi_boot.h
19 */
20
21#ifndef __BFI_BOOT_H__
22#define __BFI_BOOT_H__
23
24#define BFI_BOOT_TYPE_OFF 8
25#define BFI_BOOT_PARAM_OFF 12
26
27#define BFI_BOOT_TYPE_NORMAL 0 /* param is device id */
28#define BFI_BOOT_TYPE_FLASH 1
29#define BFI_BOOT_TYPE_MEMTEST 2
30
31#define BFI_BOOT_MEMTEST_RES_ADDR 0x900
32#define BFI_BOOT_MEMTEST_RES_SIG 0xA0A1A2A3
33
34#endif
diff --git a/drivers/scsi/bfa/include/bfi/bfi_cbreg.h b/drivers/scsi/bfa/include/bfi/bfi_cbreg.h
new file mode 100644
index 000000000000..b3bb52b565b1
--- /dev/null
+++ b/drivers/scsi/bfa/include/bfi/bfi_cbreg.h
@@ -0,0 +1,305 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/*
19 * bfi_cbreg.h crossbow host block register definitions
20 *
21 * !!! Do not edit. Auto generated. !!!
22 */
23
24#ifndef __BFI_CBREG_H__
25#define __BFI_CBREG_H__
26
27
28#define HOSTFN0_INT_STATUS 0x00014000
29#define __HOSTFN0_INT_STATUS_LVL_MK 0x00f00000
30#define __HOSTFN0_INT_STATUS_LVL_SH 20
31#define __HOSTFN0_INT_STATUS_LVL(_v) ((_v) << __HOSTFN0_INT_STATUS_LVL_SH)
32#define __HOSTFN0_INT_STATUS_P 0x000fffff
33#define HOSTFN0_INT_MSK 0x00014004
34#define HOST_PAGE_NUM_FN0 0x00014008
35#define __HOST_PAGE_NUM_FN 0x000001ff
36#define HOSTFN1_INT_STATUS 0x00014100
37#define __HOSTFN1_INT_STAT_LVL_MK 0x00f00000
38#define __HOSTFN1_INT_STAT_LVL_SH 20
39#define __HOSTFN1_INT_STAT_LVL(_v) ((_v) << __HOSTFN1_INT_STAT_LVL_SH)
40#define __HOSTFN1_INT_STAT_P 0x000fffff
41#define HOSTFN1_INT_MSK 0x00014104
42#define HOST_PAGE_NUM_FN1 0x00014108
43#define APP_PLL_400_CTL_REG 0x00014204
44#define __P_400_PLL_LOCK 0x80000000
45#define __APP_PLL_400_SRAM_USE_100MHZ 0x00100000
46#define __APP_PLL_400_RESET_TIMER_MK 0x000e0000
47#define __APP_PLL_400_RESET_TIMER_SH 17
48#define __APP_PLL_400_RESET_TIMER(_v) ((_v) << __APP_PLL_400_RESET_TIMER_SH)
49#define __APP_PLL_400_LOGIC_SOFT_RESET 0x00010000
50#define __APP_PLL_400_CNTLMT0_1_MK 0x0000c000
51#define __APP_PLL_400_CNTLMT0_1_SH 14
52#define __APP_PLL_400_CNTLMT0_1(_v) ((_v) << __APP_PLL_400_CNTLMT0_1_SH)
53#define __APP_PLL_400_JITLMT0_1_MK 0x00003000
54#define __APP_PLL_400_JITLMT0_1_SH 12
55#define __APP_PLL_400_JITLMT0_1(_v) ((_v) << __APP_PLL_400_JITLMT0_1_SH)
56#define __APP_PLL_400_HREF 0x00000800
57#define __APP_PLL_400_HDIV 0x00000400
58#define __APP_PLL_400_P0_1_MK 0x00000300
59#define __APP_PLL_400_P0_1_SH 8
60#define __APP_PLL_400_P0_1(_v) ((_v) << __APP_PLL_400_P0_1_SH)
61#define __APP_PLL_400_Z0_2_MK 0x000000e0
62#define __APP_PLL_400_Z0_2_SH 5
63#define __APP_PLL_400_Z0_2(_v) ((_v) << __APP_PLL_400_Z0_2_SH)
64#define __APP_PLL_400_RSEL200500 0x00000010
65#define __APP_PLL_400_ENARST 0x00000008
66#define __APP_PLL_400_BYPASS 0x00000004
67#define __APP_PLL_400_LRESETN 0x00000002
68#define __APP_PLL_400_ENABLE 0x00000001
69#define APP_PLL_212_CTL_REG 0x00014208
70#define __P_212_PLL_LOCK 0x80000000
71#define __APP_PLL_212_RESET_TIMER_MK 0x000e0000
72#define __APP_PLL_212_RESET_TIMER_SH 17
73#define __APP_PLL_212_RESET_TIMER(_v) ((_v) << __APP_PLL_212_RESET_TIMER_SH)
74#define __APP_PLL_212_LOGIC_SOFT_RESET 0x00010000
75#define __APP_PLL_212_CNTLMT0_1_MK 0x0000c000
76#define __APP_PLL_212_CNTLMT0_1_SH 14
77#define __APP_PLL_212_CNTLMT0_1(_v) ((_v) << __APP_PLL_212_CNTLMT0_1_SH)
78#define __APP_PLL_212_JITLMT0_1_MK 0x00003000
79#define __APP_PLL_212_JITLMT0_1_SH 12
80#define __APP_PLL_212_JITLMT0_1(_v) ((_v) << __APP_PLL_212_JITLMT0_1_SH)
81#define __APP_PLL_212_HREF 0x00000800
82#define __APP_PLL_212_HDIV 0x00000400
83#define __APP_PLL_212_P0_1_MK 0x00000300
84#define __APP_PLL_212_P0_1_SH 8
85#define __APP_PLL_212_P0_1(_v) ((_v) << __APP_PLL_212_P0_1_SH)
86#define __APP_PLL_212_Z0_2_MK 0x000000e0
87#define __APP_PLL_212_Z0_2_SH 5
88#define __APP_PLL_212_Z0_2(_v) ((_v) << __APP_PLL_212_Z0_2_SH)
89#define __APP_PLL_212_RSEL200500 0x00000010
90#define __APP_PLL_212_ENARST 0x00000008
91#define __APP_PLL_212_BYPASS 0x00000004
92#define __APP_PLL_212_LRESETN 0x00000002
93#define __APP_PLL_212_ENABLE 0x00000001
94#define HOST_SEM0_REG 0x00014230
95#define __HOST_SEMAPHORE 0x00000001
96#define HOST_SEM1_REG 0x00014234
97#define HOST_SEM2_REG 0x00014238
98#define HOST_SEM3_REG 0x0001423c
99#define HOST_SEM0_INFO_REG 0x00014240
100#define HOST_SEM1_INFO_REG 0x00014244
101#define HOST_SEM2_INFO_REG 0x00014248
102#define HOST_SEM3_INFO_REG 0x0001424c
103#define HOSTFN0_LPU0_CMD_STAT 0x00019000
104#define __HOSTFN0_LPU0_MBOX_INFO_MK 0xfffffffe
105#define __HOSTFN0_LPU0_MBOX_INFO_SH 1
106#define __HOSTFN0_LPU0_MBOX_INFO(_v) ((_v) << __HOSTFN0_LPU0_MBOX_INFO_SH)
107#define __HOSTFN0_LPU0_MBOX_CMD_STATUS 0x00000001
108#define LPU0_HOSTFN0_CMD_STAT 0x00019008
109#define __LPU0_HOSTFN0_MBOX_INFO_MK 0xfffffffe
110#define __LPU0_HOSTFN0_MBOX_INFO_SH 1
111#define __LPU0_HOSTFN0_MBOX_INFO(_v) ((_v) << __LPU0_HOSTFN0_MBOX_INFO_SH)
112#define __LPU0_HOSTFN0_MBOX_CMD_STATUS 0x00000001
113#define HOSTFN1_LPU1_CMD_STAT 0x00019014
114#define __HOSTFN1_LPU1_MBOX_INFO_MK 0xfffffffe
115#define __HOSTFN1_LPU1_MBOX_INFO_SH 1
116#define __HOSTFN1_LPU1_MBOX_INFO(_v) ((_v) << __HOSTFN1_LPU1_MBOX_INFO_SH)
117#define __HOSTFN1_LPU1_MBOX_CMD_STATUS 0x00000001
118#define LPU1_HOSTFN1_CMD_STAT 0x0001901c
119#define __LPU1_HOSTFN1_MBOX_INFO_MK 0xfffffffe
120#define __LPU1_HOSTFN1_MBOX_INFO_SH 1
121#define __LPU1_HOSTFN1_MBOX_INFO(_v) ((_v) << __LPU1_HOSTFN1_MBOX_INFO_SH)
122#define __LPU1_HOSTFN1_MBOX_CMD_STATUS 0x00000001
123#define CPE_Q0_DEPTH 0x00010014
124#define CPE_Q0_PI 0x0001001c
125#define CPE_Q0_CI 0x00010020
126#define CPE_Q1_DEPTH 0x00010034
127#define CPE_Q1_PI 0x0001003c
128#define CPE_Q1_CI 0x00010040
129#define CPE_Q2_DEPTH 0x00010054
130#define CPE_Q2_PI 0x0001005c
131#define CPE_Q2_CI 0x00010060
132#define CPE_Q3_DEPTH 0x00010074
133#define CPE_Q3_PI 0x0001007c
134#define CPE_Q3_CI 0x00010080
135#define CPE_Q4_DEPTH 0x00010094
136#define CPE_Q4_PI 0x0001009c
137#define CPE_Q4_CI 0x000100a0
138#define CPE_Q5_DEPTH 0x000100b4
139#define CPE_Q5_PI 0x000100bc
140#define CPE_Q5_CI 0x000100c0
141#define CPE_Q6_DEPTH 0x000100d4
142#define CPE_Q6_PI 0x000100dc
143#define CPE_Q6_CI 0x000100e0
144#define CPE_Q7_DEPTH 0x000100f4
145#define CPE_Q7_PI 0x000100fc
146#define CPE_Q7_CI 0x00010100
147#define RME_Q0_DEPTH 0x00011014
148#define RME_Q0_PI 0x0001101c
149#define RME_Q0_CI 0x00011020
150#define RME_Q1_DEPTH 0x00011034
151#define RME_Q1_PI 0x0001103c
152#define RME_Q1_CI 0x00011040
153#define RME_Q2_DEPTH 0x00011054
154#define RME_Q2_PI 0x0001105c
155#define RME_Q2_CI 0x00011060
156#define RME_Q3_DEPTH 0x00011074
157#define RME_Q3_PI 0x0001107c
158#define RME_Q3_CI 0x00011080
159#define RME_Q4_DEPTH 0x00011094
160#define RME_Q4_PI 0x0001109c
161#define RME_Q4_CI 0x000110a0
162#define RME_Q5_DEPTH 0x000110b4
163#define RME_Q5_PI 0x000110bc
164#define RME_Q5_CI 0x000110c0
165#define RME_Q6_DEPTH 0x000110d4
166#define RME_Q6_PI 0x000110dc
167#define RME_Q6_CI 0x000110e0
168#define RME_Q7_DEPTH 0x000110f4
169#define RME_Q7_PI 0x000110fc
170#define RME_Q7_CI 0x00011100
171#define PSS_CTL_REG 0x00018800
172#define __PSS_I2C_CLK_DIV_MK 0x00030000
173#define __PSS_I2C_CLK_DIV_SH 16
174#define __PSS_I2C_CLK_DIV(_v) ((_v) << __PSS_I2C_CLK_DIV_SH)
175#define __PSS_LMEM_INIT_DONE 0x00001000
176#define __PSS_LMEM_RESET 0x00000200
177#define __PSS_LMEM_INIT_EN 0x00000100
178#define __PSS_LPU1_RESET 0x00000002
179#define __PSS_LPU0_RESET 0x00000001
180
181
182/*
183 * These definitions are either in error/missing in spec. Its auto-generated
184 * from hard coded values in regparse.pl.
185 */
186#define __EMPHPOST_AT_4G_MK_FIX 0x0000001c
187#define __EMPHPOST_AT_4G_SH_FIX 0x00000002
188#define __EMPHPRE_AT_4G_FIX 0x00000003
189#define __SFP_TXRATE_EN_FIX 0x00000100
190#define __SFP_RXRATE_EN_FIX 0x00000080
191
192
193/*
194 * These register definitions are auto-generated from hard coded values
195 * in regparse.pl.
196 */
197#define HOSTFN0_LPU_MBOX0_0 0x00019200
198#define HOSTFN1_LPU_MBOX0_8 0x00019260
199#define LPU_HOSTFN0_MBOX0_0 0x00019280
200#define LPU_HOSTFN1_MBOX0_8 0x000192e0
201
202
203/*
204 * These register mapping definitions are auto-generated from mapping tables
205 * in regparse.pl.
206 */
207#define BFA_IOC0_HBEAT_REG HOST_SEM0_INFO_REG
208#define BFA_IOC0_STATE_REG HOST_SEM1_INFO_REG
209#define BFA_IOC1_HBEAT_REG HOST_SEM2_INFO_REG
210#define BFA_IOC1_STATE_REG HOST_SEM3_INFO_REG
211#define BFA_FW_USE_COUNT HOST_SEM4_INFO_REG
212
213#define CPE_Q_DEPTH(__n) \
214 (CPE_Q0_DEPTH + (__n) * (CPE_Q1_DEPTH - CPE_Q0_DEPTH))
215#define CPE_Q_PI(__n) \
216 (CPE_Q0_PI + (__n) * (CPE_Q1_PI - CPE_Q0_PI))
217#define CPE_Q_CI(__n) \
218 (CPE_Q0_CI + (__n) * (CPE_Q1_CI - CPE_Q0_CI))
219#define RME_Q_DEPTH(__n) \
220 (RME_Q0_DEPTH + (__n) * (RME_Q1_DEPTH - RME_Q0_DEPTH))
221#define RME_Q_PI(__n) \
222 (RME_Q0_PI + (__n) * (RME_Q1_PI - RME_Q0_PI))
223#define RME_Q_CI(__n) \
224 (RME_Q0_CI + (__n) * (RME_Q1_CI - RME_Q0_CI))
225
226#define CPE_Q_NUM(__fn, __q) (((__fn) << 2) + (__q))
227#define RME_Q_NUM(__fn, __q) (((__fn) << 2) + (__q))
228#define CPE_Q_MASK(__q) ((__q) & 0x3)
229#define RME_Q_MASK(__q) ((__q) & 0x3)
230
231
232/*
233 * PCI MSI-X vector defines
234 */
235enum {
236 BFA_MSIX_CPE_Q0 = 0,
237 BFA_MSIX_CPE_Q1 = 1,
238 BFA_MSIX_CPE_Q2 = 2,
239 BFA_MSIX_CPE_Q3 = 3,
240 BFA_MSIX_CPE_Q4 = 4,
241 BFA_MSIX_CPE_Q5 = 5,
242 BFA_MSIX_CPE_Q6 = 6,
243 BFA_MSIX_CPE_Q7 = 7,
244 BFA_MSIX_RME_Q0 = 8,
245 BFA_MSIX_RME_Q1 = 9,
246 BFA_MSIX_RME_Q2 = 10,
247 BFA_MSIX_RME_Q3 = 11,
248 BFA_MSIX_RME_Q4 = 12,
249 BFA_MSIX_RME_Q5 = 13,
250 BFA_MSIX_RME_Q6 = 14,
251 BFA_MSIX_RME_Q7 = 15,
252 BFA_MSIX_ERR_EMC = 16,
253 BFA_MSIX_ERR_LPU0 = 17,
254 BFA_MSIX_ERR_LPU1 = 18,
255 BFA_MSIX_ERR_PSS = 19,
256 BFA_MSIX_MBOX_LPU0 = 20,
257 BFA_MSIX_MBOX_LPU1 = 21,
258 BFA_MSIX_CB_MAX = 22,
259};
260
261/*
262 * And corresponding host interrupt status bit field defines
263 */
264#define __HFN_INT_CPE_Q0 0x00000001U
265#define __HFN_INT_CPE_Q1 0x00000002U
266#define __HFN_INT_CPE_Q2 0x00000004U
267#define __HFN_INT_CPE_Q3 0x00000008U
268#define __HFN_INT_CPE_Q4 0x00000010U
269#define __HFN_INT_CPE_Q5 0x00000020U
270#define __HFN_INT_CPE_Q6 0x00000040U
271#define __HFN_INT_CPE_Q7 0x00000080U
272#define __HFN_INT_RME_Q0 0x00000100U
273#define __HFN_INT_RME_Q1 0x00000200U
274#define __HFN_INT_RME_Q2 0x00000400U
275#define __HFN_INT_RME_Q3 0x00000800U
276#define __HFN_INT_RME_Q4 0x00001000U
277#define __HFN_INT_RME_Q5 0x00002000U
278#define __HFN_INT_RME_Q6 0x00004000U
279#define __HFN_INT_RME_Q7 0x00008000U
280#define __HFN_INT_ERR_EMC 0x00010000U
281#define __HFN_INT_ERR_LPU0 0x00020000U
282#define __HFN_INT_ERR_LPU1 0x00040000U
283#define __HFN_INT_ERR_PSS 0x00080000U
284#define __HFN_INT_MBOX_LPU0 0x00100000U
285#define __HFN_INT_MBOX_LPU1 0x00200000U
286#define __HFN_INT_MBOX1_LPU0 0x00400000U
287#define __HFN_INT_MBOX1_LPU1 0x00800000U
288#define __HFN_INT_CPE_MASK 0x000000ffU
289#define __HFN_INT_RME_MASK 0x0000ff00U
290
291
292/*
293 * crossbow memory map.
294 */
295#define PSS_SMEM_PAGE_START 0x8000
296#define PSS_SMEM_PGNUM(_pg0, _ma) ((_pg0) + ((_ma) >> 15))
297#define PSS_SMEM_PGOFF(_ma) ((_ma) & 0x7fff)
298
299/*
300 * End of crossbow memory map
301 */
302
303
304#endif /* __BFI_CBREG_H__ */
305
diff --git a/drivers/scsi/bfa/include/bfi/bfi_cee.h b/drivers/scsi/bfa/include/bfi/bfi_cee.h
new file mode 100644
index 000000000000..0970596583ea
--- /dev/null
+++ b/drivers/scsi/bfa/include/bfi/bfi_cee.h
@@ -0,0 +1,119 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17/**
18 * Copyright (c) 2006-2009 Brocade Communications Systems, Inc.
19 * All rights reserved.
20 *
21 * bfi_dcbx.h BFI Interface (Mailbox commands and related structures)
22 * between host driver and DCBX/LLDP firmware module.
23 *
24**/
25
26#ifndef __BFI_CEE_H__
27#define __BFI_CEE_H__
28
29#include <bfi/bfi.h>
30
31#pragma pack(1)
32
33
34enum bfi_cee_h2i_msgs_e {
35 BFI_CEE_H2I_GET_CFG_REQ = 1,
36 BFI_CEE_H2I_RESET_STATS = 2,
37 BFI_CEE_H2I_GET_STATS_REQ = 3,
38};
39
40
41enum bfi_cee_i2h_msgs_e {
42 BFI_CEE_I2H_GET_CFG_RSP = BFA_I2HM(1),
43 BFI_CEE_I2H_RESET_STATS_RSP = BFA_I2HM(2),
44 BFI_CEE_I2H_GET_STATS_RSP = BFA_I2HM(3),
45};
46
47
48/* Data structures */
49
50/*
51 * BFI_CEE_H2I_RESET_STATS
52 */
53struct bfi_lldp_reset_stats_s {
54 struct bfi_mhdr_s mh;
55};
56
57/*
58 * BFI_CEE_H2I_RESET_STATS
59 */
60struct bfi_cee_reset_stats_s {
61 struct bfi_mhdr_s mh;
62};
63
64/*
65 * BFI_CEE_H2I_GET_CFG_REQ
66 */
67struct bfi_cee_get_req_s {
68 struct bfi_mhdr_s mh;
69 union bfi_addr_u dma_addr;
70};
71
72
73/*
74 * BFI_CEE_I2H_GET_CFG_RSP
75 */
76struct bfi_cee_get_rsp_s {
77 struct bfi_mhdr_s mh;
78 u8 cmd_status;
79 u8 rsvd[3];
80};
81
82/*
83 * BFI_CEE_H2I_GET_STATS_REQ
84 */
85struct bfi_cee_stats_req_s {
86 struct bfi_mhdr_s mh;
87 union bfi_addr_u dma_addr;
88};
89
90
91/*
92 * BFI_CEE_I2H_GET_STATS_RSP
93 */
94struct bfi_cee_stats_rsp_s {
95 struct bfi_mhdr_s mh;
96 u8 cmd_status;
97 u8 rsvd[3];
98};
99
100
101
102union bfi_cee_h2i_msg_u {
103 struct bfi_mhdr_s mh;
104 struct bfi_cee_get_req_s get_req;
105 struct bfi_cee_stats_req_s stats_req;
106};
107
108
109union bfi_cee_i2h_msg_u {
110 struct bfi_mhdr_s mh;
111 struct bfi_cee_get_rsp_s get_rsp;
112 struct bfi_cee_stats_rsp_s stats_rsp;
113};
114
115#pragma pack()
116
117
118#endif /* __BFI_CEE_H__ */
119
diff --git a/drivers/scsi/bfa/include/bfi/bfi_ctreg.h b/drivers/scsi/bfa/include/bfi/bfi_ctreg.h
new file mode 100644
index 000000000000..d3caa58c0a0a
--- /dev/null
+++ b/drivers/scsi/bfa/include/bfi/bfi_ctreg.h
@@ -0,0 +1,611 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/*
19 * bfi_ctreg.h catapult host block register definitions
20 *
21 * !!! Do not edit. Auto generated. !!!
22 */
23
24#ifndef __BFI_CTREG_H__
25#define __BFI_CTREG_H__
26
27
28#define HOSTFN0_LPU_MBOX0_0 0x00019200
29#define HOSTFN1_LPU_MBOX0_8 0x00019260
30#define LPU_HOSTFN0_MBOX0_0 0x00019280
31#define LPU_HOSTFN1_MBOX0_8 0x000192e0
32#define HOSTFN2_LPU_MBOX0_0 0x00019400
33#define HOSTFN3_LPU_MBOX0_8 0x00019460
34#define LPU_HOSTFN2_MBOX0_0 0x00019480
35#define LPU_HOSTFN3_MBOX0_8 0x000194e0
36#define HOSTFN0_INT_STATUS 0x00014000
37#define __HOSTFN0_HALT_OCCURRED 0x01000000
38#define __HOSTFN0_INT_STATUS_LVL_MK 0x00f00000
39#define __HOSTFN0_INT_STATUS_LVL_SH 20
40#define __HOSTFN0_INT_STATUS_LVL(_v) ((_v) << __HOSTFN0_INT_STATUS_LVL_SH)
41#define __HOSTFN0_INT_STATUS_P_MK 0x000f0000
42#define __HOSTFN0_INT_STATUS_P_SH 16
43#define __HOSTFN0_INT_STATUS_P(_v) ((_v) << __HOSTFN0_INT_STATUS_P_SH)
44#define __HOSTFN0_INT_STATUS_F 0x0000ffff
45#define HOSTFN0_INT_MSK 0x00014004
46#define HOST_PAGE_NUM_FN0 0x00014008
47#define __HOST_PAGE_NUM_FN 0x000001ff
48#define HOST_MSIX_ERR_INDEX_FN0 0x0001400c
49#define __MSIX_ERR_INDEX_FN 0x000001ff
50#define HOSTFN1_INT_STATUS 0x00014100
51#define __HOSTFN1_HALT_OCCURRED 0x01000000
52#define __HOSTFN1_INT_STATUS_LVL_MK 0x00f00000
53#define __HOSTFN1_INT_STATUS_LVL_SH 20
54#define __HOSTFN1_INT_STATUS_LVL(_v) ((_v) << __HOSTFN1_INT_STATUS_LVL_SH)
55#define __HOSTFN1_INT_STATUS_P_MK 0x000f0000
56#define __HOSTFN1_INT_STATUS_P_SH 16
57#define __HOSTFN1_INT_STATUS_P(_v) ((_v) << __HOSTFN1_INT_STATUS_P_SH)
58#define __HOSTFN1_INT_STATUS_F 0x0000ffff
59#define HOSTFN1_INT_MSK 0x00014104
60#define HOST_PAGE_NUM_FN1 0x00014108
61#define HOST_MSIX_ERR_INDEX_FN1 0x0001410c
62#define APP_PLL_425_CTL_REG 0x00014204
63#define __P_425_PLL_LOCK 0x80000000
64#define __APP_PLL_425_SRAM_USE_100MHZ 0x00100000
65#define __APP_PLL_425_RESET_TIMER_MK 0x000e0000
66#define __APP_PLL_425_RESET_TIMER_SH 17
67#define __APP_PLL_425_RESET_TIMER(_v) ((_v) << __APP_PLL_425_RESET_TIMER_SH)
68#define __APP_PLL_425_LOGIC_SOFT_RESET 0x00010000
69#define __APP_PLL_425_CNTLMT0_1_MK 0x0000c000
70#define __APP_PLL_425_CNTLMT0_1_SH 14
71#define __APP_PLL_425_CNTLMT0_1(_v) ((_v) << __APP_PLL_425_CNTLMT0_1_SH)
72#define __APP_PLL_425_JITLMT0_1_MK 0x00003000
73#define __APP_PLL_425_JITLMT0_1_SH 12
74#define __APP_PLL_425_JITLMT0_1(_v) ((_v) << __APP_PLL_425_JITLMT0_1_SH)
75#define __APP_PLL_425_HREF 0x00000800
76#define __APP_PLL_425_HDIV 0x00000400
77#define __APP_PLL_425_P0_1_MK 0x00000300
78#define __APP_PLL_425_P0_1_SH 8
79#define __APP_PLL_425_P0_1(_v) ((_v) << __APP_PLL_425_P0_1_SH)
80#define __APP_PLL_425_Z0_2_MK 0x000000e0
81#define __APP_PLL_425_Z0_2_SH 5
82#define __APP_PLL_425_Z0_2(_v) ((_v) << __APP_PLL_425_Z0_2_SH)
83#define __APP_PLL_425_RSEL200500 0x00000010
84#define __APP_PLL_425_ENARST 0x00000008
85#define __APP_PLL_425_BYPASS 0x00000004
86#define __APP_PLL_425_LRESETN 0x00000002
87#define __APP_PLL_425_ENABLE 0x00000001
88#define APP_PLL_312_CTL_REG 0x00014208
89#define __P_312_PLL_LOCK 0x80000000
90#define __ENABLE_MAC_AHB_1 0x00800000
91#define __ENABLE_MAC_AHB_0 0x00400000
92#define __ENABLE_MAC_1 0x00200000
93#define __ENABLE_MAC_0 0x00100000
94#define __APP_PLL_312_RESET_TIMER_MK 0x000e0000
95#define __APP_PLL_312_RESET_TIMER_SH 17
96#define __APP_PLL_312_RESET_TIMER(_v) ((_v) << __APP_PLL_312_RESET_TIMER_SH)
97#define __APP_PLL_312_LOGIC_SOFT_RESET 0x00010000
98#define __APP_PLL_312_CNTLMT0_1_MK 0x0000c000
99#define __APP_PLL_312_CNTLMT0_1_SH 14
100#define __APP_PLL_312_CNTLMT0_1(_v) ((_v) << __APP_PLL_312_CNTLMT0_1_SH)
101#define __APP_PLL_312_JITLMT0_1_MK 0x00003000
102#define __APP_PLL_312_JITLMT0_1_SH 12
103#define __APP_PLL_312_JITLMT0_1(_v) ((_v) << __APP_PLL_312_JITLMT0_1_SH)
104#define __APP_PLL_312_HREF 0x00000800
105#define __APP_PLL_312_HDIV 0x00000400
106#define __APP_PLL_312_P0_1_MK 0x00000300
107#define __APP_PLL_312_P0_1_SH 8
108#define __APP_PLL_312_P0_1(_v) ((_v) << __APP_PLL_312_P0_1_SH)
109#define __APP_PLL_312_Z0_2_MK 0x000000e0
110#define __APP_PLL_312_Z0_2_SH 5
111#define __APP_PLL_312_Z0_2(_v) ((_v) << __APP_PLL_312_Z0_2_SH)
112#define __APP_PLL_312_RSEL200500 0x00000010
113#define __APP_PLL_312_ENARST 0x00000008
114#define __APP_PLL_312_BYPASS 0x00000004
115#define __APP_PLL_312_LRESETN 0x00000002
116#define __APP_PLL_312_ENABLE 0x00000001
117#define MBIST_CTL_REG 0x00014220
118#define __EDRAM_BISTR_START 0x00000004
119#define __MBIST_RESET 0x00000002
120#define __MBIST_START 0x00000001
121#define MBIST_STAT_REG 0x00014224
122#define __EDRAM_BISTR_STATUS 0x00000008
123#define __EDRAM_BISTR_DONE 0x00000004
124#define __MEM_BIT_STATUS 0x00000002
125#define __MBIST_DONE 0x00000001
126#define HOST_SEM0_REG 0x00014230
127#define __HOST_SEMAPHORE 0x00000001
128#define HOST_SEM1_REG 0x00014234
129#define HOST_SEM2_REG 0x00014238
130#define HOST_SEM3_REG 0x0001423c
131#define HOST_SEM0_INFO_REG 0x00014240
132#define HOST_SEM1_INFO_REG 0x00014244
133#define HOST_SEM2_INFO_REG 0x00014248
134#define HOST_SEM3_INFO_REG 0x0001424c
135#define ETH_MAC_SER_REG 0x00014288
136#define __APP_EMS_CKBUFAMPIN 0x00000020
137#define __APP_EMS_REFCLKSEL 0x00000010
138#define __APP_EMS_CMLCKSEL 0x00000008
139#define __APP_EMS_REFCKBUFEN2 0x00000004
140#define __APP_EMS_REFCKBUFEN1 0x00000002
141#define __APP_EMS_CHANNEL_SEL 0x00000001
142#define HOSTFN2_INT_STATUS 0x00014300
143#define __HOSTFN2_HALT_OCCURRED 0x01000000
144#define __HOSTFN2_INT_STATUS_LVL_MK 0x00f00000
145#define __HOSTFN2_INT_STATUS_LVL_SH 20
146#define __HOSTFN2_INT_STATUS_LVL(_v) ((_v) << __HOSTFN2_INT_STATUS_LVL_SH)
147#define __HOSTFN2_INT_STATUS_P_MK 0x000f0000
148#define __HOSTFN2_INT_STATUS_P_SH 16
149#define __HOSTFN2_INT_STATUS_P(_v) ((_v) << __HOSTFN2_INT_STATUS_P_SH)
150#define __HOSTFN2_INT_STATUS_F 0x0000ffff
151#define HOSTFN2_INT_MSK 0x00014304
152#define HOST_PAGE_NUM_FN2 0x00014308
153#define HOST_MSIX_ERR_INDEX_FN2 0x0001430c
154#define HOSTFN3_INT_STATUS 0x00014400
155#define __HALT_OCCURRED 0x01000000
156#define __HOSTFN3_INT_STATUS_LVL_MK 0x00f00000
157#define __HOSTFN3_INT_STATUS_LVL_SH 20
158#define __HOSTFN3_INT_STATUS_LVL(_v) ((_v) << __HOSTFN3_INT_STATUS_LVL_SH)
159#define __HOSTFN3_INT_STATUS_P_MK 0x000f0000
160#define __HOSTFN3_INT_STATUS_P_SH 16
161#define __HOSTFN3_INT_STATUS_P(_v) ((_v) << __HOSTFN3_INT_STATUS_P_SH)
162#define __HOSTFN3_INT_STATUS_F 0x0000ffff
163#define HOSTFN3_INT_MSK 0x00014404
164#define HOST_PAGE_NUM_FN3 0x00014408
165#define HOST_MSIX_ERR_INDEX_FN3 0x0001440c
166#define FNC_ID_REG 0x00014600
167#define __FUNCTION_NUMBER 0x00000007
168#define FNC_PERS_REG 0x00014604
169#define __F3_FUNCTION_ACTIVE 0x80000000
170#define __F3_FUNCTION_MODE 0x40000000
171#define __F3_PORT_MAP_MK 0x30000000
172#define __F3_PORT_MAP_SH 28
173#define __F3_PORT_MAP(_v) ((_v) << __F3_PORT_MAP_SH)
174#define __F3_VM_MODE 0x08000000
175#define __F3_INTX_STATUS_MK 0x07000000
176#define __F3_INTX_STATUS_SH 24
177#define __F3_INTX_STATUS(_v) ((_v) << __F3_INTX_STATUS_SH)
178#define __F2_FUNCTION_ACTIVE 0x00800000
179#define __F2_FUNCTION_MODE 0x00400000
180#define __F2_PORT_MAP_MK 0x00300000
181#define __F2_PORT_MAP_SH 20
182#define __F2_PORT_MAP(_v) ((_v) << __F2_PORT_MAP_SH)
183#define __F2_VM_MODE 0x00080000
184#define __F2_INTX_STATUS_MK 0x00070000
185#define __F2_INTX_STATUS_SH 16
186#define __F2_INTX_STATUS(_v) ((_v) << __F2_INTX_STATUS_SH)
187#define __F1_FUNCTION_ACTIVE 0x00008000
188#define __F1_FUNCTION_MODE 0x00004000
189#define __F1_PORT_MAP_MK 0x00003000
190#define __F1_PORT_MAP_SH 12
191#define __F1_PORT_MAP(_v) ((_v) << __F1_PORT_MAP_SH)
192#define __F1_VM_MODE 0x00000800
193#define __F1_INTX_STATUS_MK 0x00000700
194#define __F1_INTX_STATUS_SH 8
195#define __F1_INTX_STATUS(_v) ((_v) << __F1_INTX_STATUS_SH)
196#define __F0_FUNCTION_ACTIVE 0x00000080
197#define __F0_FUNCTION_MODE 0x00000040
198#define __F0_PORT_MAP_MK 0x00000030
199#define __F0_PORT_MAP_SH 4
200#define __F0_PORT_MAP(_v) ((_v) << __F0_PORT_MAP_SH)
201#define __F0_VM_MODE 0x00000008
202#define __F0_INTX_STATUS 0x00000007
203enum {
204 __F0_INTX_STATUS_MSIX = 0x0,
205 __F0_INTX_STATUS_INTA = 0x1,
206 __F0_INTX_STATUS_INTB = 0x2,
207 __F0_INTX_STATUS_INTC = 0x3,
208 __F0_INTX_STATUS_INTD = 0x4,
209};
210#define OP_MODE 0x0001460c
211#define __APP_ETH_CLK_LOWSPEED 0x00000004
212#define __GLOBAL_CORECLK_HALFSPEED 0x00000002
213#define __GLOBAL_FCOE_MODE 0x00000001
214#define HOST_SEM4_REG 0x00014610
215#define HOST_SEM5_REG 0x00014614
216#define HOST_SEM6_REG 0x00014618
217#define HOST_SEM7_REG 0x0001461c
218#define HOST_SEM4_INFO_REG 0x00014620
219#define HOST_SEM5_INFO_REG 0x00014624
220#define HOST_SEM6_INFO_REG 0x00014628
221#define HOST_SEM7_INFO_REG 0x0001462c
222#define HOSTFN0_LPU0_MBOX0_CMD_STAT 0x00019000
223#define __HOSTFN0_LPU0_MBOX0_INFO_MK 0xfffffffe
224#define __HOSTFN0_LPU0_MBOX0_INFO_SH 1
225#define __HOSTFN0_LPU0_MBOX0_INFO(_v) ((_v) << __HOSTFN0_LPU0_MBOX0_INFO_SH)
226#define __HOSTFN0_LPU0_MBOX0_CMD_STATUS 0x00000001
227#define HOSTFN0_LPU1_MBOX0_CMD_STAT 0x00019004
228#define __HOSTFN0_LPU1_MBOX0_INFO_MK 0xfffffffe
229#define __HOSTFN0_LPU1_MBOX0_INFO_SH 1
230#define __HOSTFN0_LPU1_MBOX0_INFO(_v) ((_v) << __HOSTFN0_LPU1_MBOX0_INFO_SH)
231#define __HOSTFN0_LPU1_MBOX0_CMD_STATUS 0x00000001
232#define LPU0_HOSTFN0_MBOX0_CMD_STAT 0x00019008
233#define __LPU0_HOSTFN0_MBOX0_INFO_MK 0xfffffffe
234#define __LPU0_HOSTFN0_MBOX0_INFO_SH 1
235#define __LPU0_HOSTFN0_MBOX0_INFO(_v) ((_v) << __LPU0_HOSTFN0_MBOX0_INFO_SH)
236#define __LPU0_HOSTFN0_MBOX0_CMD_STATUS 0x00000001
237#define LPU1_HOSTFN0_MBOX0_CMD_STAT 0x0001900c
238#define __LPU1_HOSTFN0_MBOX0_INFO_MK 0xfffffffe
239#define __LPU1_HOSTFN0_MBOX0_INFO_SH 1
240#define __LPU1_HOSTFN0_MBOX0_INFO(_v) ((_v) << __LPU1_HOSTFN0_MBOX0_INFO_SH)
241#define __LPU1_HOSTFN0_MBOX0_CMD_STATUS 0x00000001
242#define HOSTFN1_LPU0_MBOX0_CMD_STAT 0x00019010
243#define __HOSTFN1_LPU0_MBOX0_INFO_MK 0xfffffffe
244#define __HOSTFN1_LPU0_MBOX0_INFO_SH 1
245#define __HOSTFN1_LPU0_MBOX0_INFO(_v) ((_v) << __HOSTFN1_LPU0_MBOX0_INFO_SH)
246#define __HOSTFN1_LPU0_MBOX0_CMD_STATUS 0x00000001
247#define HOSTFN1_LPU1_MBOX0_CMD_STAT 0x00019014
248#define __HOSTFN1_LPU1_MBOX0_INFO_MK 0xfffffffe
249#define __HOSTFN1_LPU1_MBOX0_INFO_SH 1
250#define __HOSTFN1_LPU1_MBOX0_INFO(_v) ((_v) << __HOSTFN1_LPU1_MBOX0_INFO_SH)
251#define __HOSTFN1_LPU1_MBOX0_CMD_STATUS 0x00000001
252#define LPU0_HOSTFN1_MBOX0_CMD_STAT 0x00019018
253#define __LPU0_HOSTFN1_MBOX0_INFO_MK 0xfffffffe
254#define __LPU0_HOSTFN1_MBOX0_INFO_SH 1
255#define __LPU0_HOSTFN1_MBOX0_INFO(_v) ((_v) << __LPU0_HOSTFN1_MBOX0_INFO_SH)
256#define __LPU0_HOSTFN1_MBOX0_CMD_STATUS 0x00000001
257#define LPU1_HOSTFN1_MBOX0_CMD_STAT 0x0001901c
258#define __LPU1_HOSTFN1_MBOX0_INFO_MK 0xfffffffe
259#define __LPU1_HOSTFN1_MBOX0_INFO_SH 1
260#define __LPU1_HOSTFN1_MBOX0_INFO(_v) ((_v) << __LPU1_HOSTFN1_MBOX0_INFO_SH)
261#define __LPU1_HOSTFN1_MBOX0_CMD_STATUS 0x00000001
262#define HOSTFN2_LPU0_MBOX0_CMD_STAT 0x00019150
263#define __HOSTFN2_LPU0_MBOX0_INFO_MK 0xfffffffe
264#define __HOSTFN2_LPU0_MBOX0_INFO_SH 1
265#define __HOSTFN2_LPU0_MBOX0_INFO(_v) ((_v) << __HOSTFN2_LPU0_MBOX0_INFO_SH)
266#define __HOSTFN2_LPU0_MBOX0_CMD_STATUS 0x00000001
267#define HOSTFN2_LPU1_MBOX0_CMD_STAT 0x00019154
268#define __HOSTFN2_LPU1_MBOX0_INFO_MK 0xfffffffe
269#define __HOSTFN2_LPU1_MBOX0_INFO_SH 1
270#define __HOSTFN2_LPU1_MBOX0_INFO(_v) ((_v) << __HOSTFN2_LPU1_MBOX0_INFO_SH)
271#define __HOSTFN2_LPU1_MBOX0BOX0_CMD_STATUS 0x00000001
272#define LPU0_HOSTFN2_MBOX0_CMD_STAT 0x00019158
273#define __LPU0_HOSTFN2_MBOX0_INFO_MK 0xfffffffe
274#define __LPU0_HOSTFN2_MBOX0_INFO_SH 1
275#define __LPU0_HOSTFN2_MBOX0_INFO(_v) ((_v) << __LPU0_HOSTFN2_MBOX0_INFO_SH)
276#define __LPU0_HOSTFN2_MBOX0_CMD_STATUS 0x00000001
277#define LPU1_HOSTFN2_MBOX0_CMD_STAT 0x0001915c
278#define __LPU1_HOSTFN2_MBOX0_INFO_MK 0xfffffffe
279#define __LPU1_HOSTFN2_MBOX0_INFO_SH 1
280#define __LPU1_HOSTFN2_MBOX0_INFO(_v) ((_v) << __LPU1_HOSTFN2_MBOX0_INFO_SH)
281#define __LPU1_HOSTFN2_MBOX0_CMD_STATUS 0x00000001
282#define HOSTFN3_LPU0_MBOX0_CMD_STAT 0x00019160
283#define __HOSTFN3_LPU0_MBOX0_INFO_MK 0xfffffffe
284#define __HOSTFN3_LPU0_MBOX0_INFO_SH 1
285#define __HOSTFN3_LPU0_MBOX0_INFO(_v) ((_v) << __HOSTFN3_LPU0_MBOX0_INFO_SH)
286#define __HOSTFN3_LPU0_MBOX0_CMD_STATUS 0x00000001
287#define HOSTFN3_LPU1_MBOX0_CMD_STAT 0x00019164
288#define __HOSTFN3_LPU1_MBOX0_INFO_MK 0xfffffffe
289#define __HOSTFN3_LPU1_MBOX0_INFO_SH 1
290#define __HOSTFN3_LPU1_MBOX0_INFO(_v) ((_v) << __HOSTFN3_LPU1_MBOX0_INFO_SH)
291#define __HOSTFN3_LPU1_MBOX0_CMD_STATUS 0x00000001
292#define LPU0_HOSTFN3_MBOX0_CMD_STAT 0x00019168
293#define __LPU0_HOSTFN3_MBOX0_INFO_MK 0xfffffffe
294#define __LPU0_HOSTFN3_MBOX0_INFO_SH 1
295#define __LPU0_HOSTFN3_MBOX0_INFO(_v) ((_v) << __LPU0_HOSTFN3_MBOX0_INFO_SH)
296#define __LPU0_HOSTFN3_MBOX0_CMD_STATUS 0x00000001
297#define LPU1_HOSTFN3_MBOX0_CMD_STAT 0x0001916c
298#define __LPU1_HOSTFN3_MBOX0_INFO_MK 0xfffffffe
299#define __LPU1_HOSTFN3_MBOX0_INFO_SH 1
300#define __LPU1_HOSTFN3_MBOX0_INFO(_v) ((_v) << __LPU1_HOSTFN3_MBOX0_INFO_SH)
301#define __LPU1_HOSTFN3_MBOX0_CMD_STATUS 0x00000001
302#define FW_INIT_HALT_P0 0x000191ac
303#define __FW_INIT_HALT_P 0x00000001
304#define FW_INIT_HALT_P1 0x000191bc
305#define CPE_PI_PTR_Q0 0x00038000
306#define __CPE_PI_UNUSED_MK 0xffff0000
307#define __CPE_PI_UNUSED_SH 16
308#define __CPE_PI_UNUSED(_v) ((_v) << __CPE_PI_UNUSED_SH)
309#define __CPE_PI_PTR 0x0000ffff
310#define CPE_PI_PTR_Q1 0x00038040
311#define CPE_CI_PTR_Q0 0x00038004
312#define __CPE_CI_UNUSED_MK 0xffff0000
313#define __CPE_CI_UNUSED_SH 16
314#define __CPE_CI_UNUSED(_v) ((_v) << __CPE_CI_UNUSED_SH)
315#define __CPE_CI_PTR 0x0000ffff
316#define CPE_CI_PTR_Q1 0x00038044
317#define CPE_DEPTH_Q0 0x00038008
318#define __CPE_DEPTH_UNUSED_MK 0xf8000000
319#define __CPE_DEPTH_UNUSED_SH 27
320#define __CPE_DEPTH_UNUSED(_v) ((_v) << __CPE_DEPTH_UNUSED_SH)
321#define __CPE_MSIX_VEC_INDEX_MK 0x07ff0000
322#define __CPE_MSIX_VEC_INDEX_SH 16
323#define __CPE_MSIX_VEC_INDEX(_v) ((_v) << __CPE_MSIX_VEC_INDEX_SH)
324#define __CPE_DEPTH 0x0000ffff
325#define CPE_DEPTH_Q1 0x00038048
326#define CPE_QCTRL_Q0 0x0003800c
327#define __CPE_CTRL_UNUSED30_MK 0xfc000000
328#define __CPE_CTRL_UNUSED30_SH 26
329#define __CPE_CTRL_UNUSED30(_v) ((_v) << __CPE_CTRL_UNUSED30_SH)
330#define __CPE_FUNC_INT_CTRL_MK 0x03000000
331#define __CPE_FUNC_INT_CTRL_SH 24
332#define __CPE_FUNC_INT_CTRL(_v) ((_v) << __CPE_FUNC_INT_CTRL_SH)
333enum {
334 __CPE_FUNC_INT_CTRL_DISABLE = 0x0,
335 __CPE_FUNC_INT_CTRL_F2NF = 0x1,
336 __CPE_FUNC_INT_CTRL_3QUART = 0x2,
337 __CPE_FUNC_INT_CTRL_HALF = 0x3,
338};
339#define __CPE_CTRL_UNUSED20_MK 0x00f00000
340#define __CPE_CTRL_UNUSED20_SH 20
341#define __CPE_CTRL_UNUSED20(_v) ((_v) << __CPE_CTRL_UNUSED20_SH)
342#define __CPE_SCI_TH_MK 0x000f0000
343#define __CPE_SCI_TH_SH 16
344#define __CPE_SCI_TH(_v) ((_v) << __CPE_SCI_TH_SH)
345#define __CPE_CTRL_UNUSED10_MK 0x0000c000
346#define __CPE_CTRL_UNUSED10_SH 14
347#define __CPE_CTRL_UNUSED10(_v) ((_v) << __CPE_CTRL_UNUSED10_SH)
348#define __CPE_ACK_PENDING 0x00002000
349#define __CPE_CTRL_UNUSED40_MK 0x00001c00
350#define __CPE_CTRL_UNUSED40_SH 10
351#define __CPE_CTRL_UNUSED40(_v) ((_v) << __CPE_CTRL_UNUSED40_SH)
352#define __CPE_PCIEID_MK 0x00000300
353#define __CPE_PCIEID_SH 8
354#define __CPE_PCIEID(_v) ((_v) << __CPE_PCIEID_SH)
355#define __CPE_CTRL_UNUSED00_MK 0x000000fe
356#define __CPE_CTRL_UNUSED00_SH 1
357#define __CPE_CTRL_UNUSED00(_v) ((_v) << __CPE_CTRL_UNUSED00_SH)
358#define __CPE_ESIZE 0x00000001
359#define CPE_QCTRL_Q1 0x0003804c
360#define __CPE_CTRL_UNUSED31_MK 0xfc000000
361#define __CPE_CTRL_UNUSED31_SH 26
362#define __CPE_CTRL_UNUSED31(_v) ((_v) << __CPE_CTRL_UNUSED31_SH)
363#define __CPE_CTRL_UNUSED21_MK 0x00f00000
364#define __CPE_CTRL_UNUSED21_SH 20
365#define __CPE_CTRL_UNUSED21(_v) ((_v) << __CPE_CTRL_UNUSED21_SH)
366#define __CPE_CTRL_UNUSED11_MK 0x0000c000
367#define __CPE_CTRL_UNUSED11_SH 14
368#define __CPE_CTRL_UNUSED11(_v) ((_v) << __CPE_CTRL_UNUSED11_SH)
369#define __CPE_CTRL_UNUSED41_MK 0x00001c00
370#define __CPE_CTRL_UNUSED41_SH 10
371#define __CPE_CTRL_UNUSED41(_v) ((_v) << __CPE_CTRL_UNUSED41_SH)
372#define __CPE_CTRL_UNUSED01_MK 0x000000fe
373#define __CPE_CTRL_UNUSED01_SH 1
374#define __CPE_CTRL_UNUSED01(_v) ((_v) << __CPE_CTRL_UNUSED01_SH)
375#define RME_PI_PTR_Q0 0x00038020
376#define __LATENCY_TIME_STAMP_MK 0xffff0000
377#define __LATENCY_TIME_STAMP_SH 16
378#define __LATENCY_TIME_STAMP(_v) ((_v) << __LATENCY_TIME_STAMP_SH)
379#define __RME_PI_PTR 0x0000ffff
380#define RME_PI_PTR_Q1 0x00038060
381#define RME_CI_PTR_Q0 0x00038024
382#define __DELAY_TIME_STAMP_MK 0xffff0000
383#define __DELAY_TIME_STAMP_SH 16
384#define __DELAY_TIME_STAMP(_v) ((_v) << __DELAY_TIME_STAMP_SH)
385#define __RME_CI_PTR 0x0000ffff
386#define RME_CI_PTR_Q1 0x00038064
387#define RME_DEPTH_Q0 0x00038028
388#define __RME_DEPTH_UNUSED_MK 0xf8000000
389#define __RME_DEPTH_UNUSED_SH 27
390#define __RME_DEPTH_UNUSED(_v) ((_v) << __RME_DEPTH_UNUSED_SH)
391#define __RME_MSIX_VEC_INDEX_MK 0x07ff0000
392#define __RME_MSIX_VEC_INDEX_SH 16
393#define __RME_MSIX_VEC_INDEX(_v) ((_v) << __RME_MSIX_VEC_INDEX_SH)
394#define __RME_DEPTH 0x0000ffff
395#define RME_DEPTH_Q1 0x00038068
396#define RME_QCTRL_Q0 0x0003802c
397#define __RME_INT_LATENCY_TIMER_MK 0xff000000
398#define __RME_INT_LATENCY_TIMER_SH 24
399#define __RME_INT_LATENCY_TIMER(_v) ((_v) << __RME_INT_LATENCY_TIMER_SH)
400#define __RME_INT_DELAY_TIMER_MK 0x00ff0000
401#define __RME_INT_DELAY_TIMER_SH 16
402#define __RME_INT_DELAY_TIMER(_v) ((_v) << __RME_INT_DELAY_TIMER_SH)
403#define __RME_INT_DELAY_DISABLE 0x00008000
404#define __RME_DLY_DELAY_DISABLE 0x00004000
405#define __RME_ACK_PENDING 0x00002000
406#define __RME_FULL_INTERRUPT_DISABLE 0x00001000
407#define __RME_CTRL_UNUSED10_MK 0x00000c00
408#define __RME_CTRL_UNUSED10_SH 10
409#define __RME_CTRL_UNUSED10(_v) ((_v) << __RME_CTRL_UNUSED10_SH)
410#define __RME_PCIEID_MK 0x00000300
411#define __RME_PCIEID_SH 8
412#define __RME_PCIEID(_v) ((_v) << __RME_PCIEID_SH)
413#define __RME_CTRL_UNUSED00_MK 0x000000fe
414#define __RME_CTRL_UNUSED00_SH 1
415#define __RME_CTRL_UNUSED00(_v) ((_v) << __RME_CTRL_UNUSED00_SH)
416#define __RME_ESIZE 0x00000001
417#define RME_QCTRL_Q1 0x0003806c
418#define __RME_CTRL_UNUSED11_MK 0x00000c00
419#define __RME_CTRL_UNUSED11_SH 10
420#define __RME_CTRL_UNUSED11(_v) ((_v) << __RME_CTRL_UNUSED11_SH)
421#define __RME_CTRL_UNUSED01_MK 0x000000fe
422#define __RME_CTRL_UNUSED01_SH 1
423#define __RME_CTRL_UNUSED01(_v) ((_v) << __RME_CTRL_UNUSED01_SH)
424#define PSS_CTL_REG 0x00018800
425#define __PSS_I2C_CLK_DIV_MK 0x007f0000
426#define __PSS_I2C_CLK_DIV_SH 16
427#define __PSS_I2C_CLK_DIV(_v) ((_v) << __PSS_I2C_CLK_DIV_SH)
428#define __PSS_LMEM_INIT_DONE 0x00001000
429#define __PSS_LMEM_RESET 0x00000200
430#define __PSS_LMEM_INIT_EN 0x00000100
431#define __PSS_LPU1_RESET 0x00000002
432#define __PSS_LPU0_RESET 0x00000001
433#define HQM_QSET0_RXQ_DRBL_P0 0x00038000
434#define __RXQ0_ADD_VECTORS_P 0x80000000
435#define __RXQ0_STOP_P 0x40000000
436#define __RXQ0_PRD_PTR_P 0x0000ffff
437#define HQM_QSET1_RXQ_DRBL_P0 0x00038080
438#define __RXQ1_ADD_VECTORS_P 0x80000000
439#define __RXQ1_STOP_P 0x40000000
440#define __RXQ1_PRD_PTR_P 0x0000ffff
441#define HQM_QSET0_RXQ_DRBL_P1 0x0003c000
442#define HQM_QSET1_RXQ_DRBL_P1 0x0003c080
443#define HQM_QSET0_TXQ_DRBL_P0 0x00038020
444#define __TXQ0_ADD_VECTORS_P 0x80000000
445#define __TXQ0_STOP_P 0x40000000
446#define __TXQ0_PRD_PTR_P 0x0000ffff
447#define HQM_QSET1_TXQ_DRBL_P0 0x000380a0
448#define __TXQ1_ADD_VECTORS_P 0x80000000
449#define __TXQ1_STOP_P 0x40000000
450#define __TXQ1_PRD_PTR_P 0x0000ffff
451#define HQM_QSET0_TXQ_DRBL_P1 0x0003c020
452#define HQM_QSET1_TXQ_DRBL_P1 0x0003c0a0
453#define HQM_QSET0_IB_DRBL_1_P0 0x00038040
454#define __IB1_0_ACK_P 0x80000000
455#define __IB1_0_DISABLE_P 0x40000000
456#define __IB1_0_NUM_OF_ACKED_EVENTS_P 0x0000ffff
457#define HQM_QSET1_IB_DRBL_1_P0 0x000380c0
458#define __IB1_1_ACK_P 0x80000000
459#define __IB1_1_DISABLE_P 0x40000000
460#define __IB1_1_NUM_OF_ACKED_EVENTS_P 0x0000ffff
461#define HQM_QSET0_IB_DRBL_1_P1 0x0003c040
462#define HQM_QSET1_IB_DRBL_1_P1 0x0003c0c0
463#define HQM_QSET0_IB_DRBL_2_P0 0x00038060
464#define __IB2_0_ACK_P 0x80000000
465#define __IB2_0_DISABLE_P 0x40000000
466#define __IB2_0_NUM_OF_ACKED_EVENTS_P 0x0000ffff
467#define HQM_QSET1_IB_DRBL_2_P0 0x000380e0
468#define __IB2_1_ACK_P 0x80000000
469#define __IB2_1_DISABLE_P 0x40000000
470#define __IB2_1_NUM_OF_ACKED_EVENTS_P 0x0000ffff
471#define HQM_QSET0_IB_DRBL_2_P1 0x0003c060
472#define HQM_QSET1_IB_DRBL_2_P1 0x0003c0e0
473
474
475/*
476 * These definitions are either in error/missing in spec. Its auto-generated
477 * from hard coded values in regparse.pl.
478 */
479#define __EMPHPOST_AT_4G_MK_FIX 0x0000001c
480#define __EMPHPOST_AT_4G_SH_FIX 0x00000002
481#define __EMPHPRE_AT_4G_FIX 0x00000003
482#define __SFP_TXRATE_EN_FIX 0x00000100
483#define __SFP_RXRATE_EN_FIX 0x00000080
484
485
486/*
487 * These register definitions are auto-generated from hard coded values
488 * in regparse.pl.
489 */
490
491
492/*
493 * These register mapping definitions are auto-generated from mapping tables
494 * in regparse.pl.
495 */
496#define BFA_IOC0_HBEAT_REG HOST_SEM0_INFO_REG
497#define BFA_IOC0_STATE_REG HOST_SEM1_INFO_REG
498#define BFA_IOC1_HBEAT_REG HOST_SEM2_INFO_REG
499#define BFA_IOC1_STATE_REG HOST_SEM3_INFO_REG
500#define BFA_FW_USE_COUNT HOST_SEM4_INFO_REG
501
502#define CPE_DEPTH_Q(__n) \
503 (CPE_DEPTH_Q0 + (__n) * (CPE_DEPTH_Q1 - CPE_DEPTH_Q0))
504#define CPE_QCTRL_Q(__n) \
505 (CPE_QCTRL_Q0 + (__n) * (CPE_QCTRL_Q1 - CPE_QCTRL_Q0))
506#define CPE_PI_PTR_Q(__n) \
507 (CPE_PI_PTR_Q0 + (__n) * (CPE_PI_PTR_Q1 - CPE_PI_PTR_Q0))
508#define CPE_CI_PTR_Q(__n) \
509 (CPE_CI_PTR_Q0 + (__n) * (CPE_CI_PTR_Q1 - CPE_CI_PTR_Q0))
510#define RME_DEPTH_Q(__n) \
511 (RME_DEPTH_Q0 + (__n) * (RME_DEPTH_Q1 - RME_DEPTH_Q0))
512#define RME_QCTRL_Q(__n) \
513 (RME_QCTRL_Q0 + (__n) * (RME_QCTRL_Q1 - RME_QCTRL_Q0))
514#define RME_PI_PTR_Q(__n) \
515 (RME_PI_PTR_Q0 + (__n) * (RME_PI_PTR_Q1 - RME_PI_PTR_Q0))
516#define RME_CI_PTR_Q(__n) \
517 (RME_CI_PTR_Q0 + (__n) * (RME_CI_PTR_Q1 - RME_CI_PTR_Q0))
518#define HQM_QSET_RXQ_DRBL_P0(__n) \
519 (HQM_QSET0_RXQ_DRBL_P0 + (__n) * (HQM_QSET1_RXQ_DRBL_P0 - \
520 HQM_QSET0_RXQ_DRBL_P0))
521#define HQM_QSET_TXQ_DRBL_P0(__n) \
522 (HQM_QSET0_TXQ_DRBL_P0 + (__n) * (HQM_QSET1_TXQ_DRBL_P0 - \
523 HQM_QSET0_TXQ_DRBL_P0))
524#define HQM_QSET_IB_DRBL_1_P0(__n) \
525 (HQM_QSET0_IB_DRBL_1_P0 + (__n) * (HQM_QSET1_IB_DRBL_1_P0 - \
526 HQM_QSET0_IB_DRBL_1_P0))
527#define HQM_QSET_IB_DRBL_2_P0(__n) \
528 (HQM_QSET0_IB_DRBL_2_P0 + (__n) * (HQM_QSET1_IB_DRBL_2_P0 - \
529 HQM_QSET0_IB_DRBL_2_P0))
530#define HQM_QSET_RXQ_DRBL_P1(__n) \
531 (HQM_QSET0_RXQ_DRBL_P1 + (__n) * (HQM_QSET1_RXQ_DRBL_P1 - \
532 HQM_QSET0_RXQ_DRBL_P1))
533#define HQM_QSET_TXQ_DRBL_P1(__n) \
534 (HQM_QSET0_TXQ_DRBL_P1 + (__n) * (HQM_QSET1_TXQ_DRBL_P1 - \
535 HQM_QSET0_TXQ_DRBL_P1))
536#define HQM_QSET_IB_DRBL_1_P1(__n) \
537 (HQM_QSET0_IB_DRBL_1_P1 + (__n) * (HQM_QSET1_IB_DRBL_1_P1 - \
538 HQM_QSET0_IB_DRBL_1_P1))
539#define HQM_QSET_IB_DRBL_2_P1(__n) \
540 (HQM_QSET0_IB_DRBL_2_P1 + (__n) * (HQM_QSET1_IB_DRBL_2_P1 - \
541 HQM_QSET0_IB_DRBL_2_P1))
542
543#define CPE_Q_NUM(__fn, __q) (((__fn) << 2) + (__q))
544#define RME_Q_NUM(__fn, __q) (((__fn) << 2) + (__q))
545#define CPE_Q_MASK(__q) ((__q) & 0x3)
546#define RME_Q_MASK(__q) ((__q) & 0x3)
547
548
549/*
550 * PCI MSI-X vector defines
551 */
552enum {
553 BFA_MSIX_CPE_Q0 = 0,
554 BFA_MSIX_CPE_Q1 = 1,
555 BFA_MSIX_CPE_Q2 = 2,
556 BFA_MSIX_CPE_Q3 = 3,
557 BFA_MSIX_RME_Q0 = 4,
558 BFA_MSIX_RME_Q1 = 5,
559 BFA_MSIX_RME_Q2 = 6,
560 BFA_MSIX_RME_Q3 = 7,
561 BFA_MSIX_LPU_ERR = 8,
562 BFA_MSIX_CT_MAX = 9,
563};
564
565/*
566 * And corresponding host interrupt status bit field defines
567 */
568#define __HFN_INT_CPE_Q0 0x00000001U
569#define __HFN_INT_CPE_Q1 0x00000002U
570#define __HFN_INT_CPE_Q2 0x00000004U
571#define __HFN_INT_CPE_Q3 0x00000008U
572#define __HFN_INT_CPE_Q4 0x00000010U
573#define __HFN_INT_CPE_Q5 0x00000020U
574#define __HFN_INT_CPE_Q6 0x00000040U
575#define __HFN_INT_CPE_Q7 0x00000080U
576#define __HFN_INT_RME_Q0 0x00000100U
577#define __HFN_INT_RME_Q1 0x00000200U
578#define __HFN_INT_RME_Q2 0x00000400U
579#define __HFN_INT_RME_Q3 0x00000800U
580#define __HFN_INT_RME_Q4 0x00001000U
581#define __HFN_INT_RME_Q5 0x00002000U
582#define __HFN_INT_RME_Q6 0x00004000U
583#define __HFN_INT_RME_Q7 0x00008000U
584#define __HFN_INT_ERR_EMC 0x00010000U
585#define __HFN_INT_ERR_LPU0 0x00020000U
586#define __HFN_INT_ERR_LPU1 0x00040000U
587#define __HFN_INT_ERR_PSS 0x00080000U
588#define __HFN_INT_MBOX_LPU0 0x00100000U
589#define __HFN_INT_MBOX_LPU1 0x00200000U
590#define __HFN_INT_MBOX1_LPU0 0x00400000U
591#define __HFN_INT_MBOX1_LPU1 0x00800000U
592#define __HFN_INT_CPE_MASK 0x000000ffU
593#define __HFN_INT_RME_MASK 0x0000ff00U
594
595
596/*
597 * catapult memory map.
598 */
599#define LL_PGN_HQM0 0x0096
600#define LL_PGN_HQM1 0x0097
601#define PSS_SMEM_PAGE_START 0x8000
602#define PSS_SMEM_PGNUM(_pg0, _ma) ((_pg0) + ((_ma) >> 15))
603#define PSS_SMEM_PGOFF(_ma) ((_ma) & 0x7fff)
604
605/*
606 * End of catapult memory map
607 */
608
609
610#endif /* __BFI_CTREG_H__ */
611
diff --git a/drivers/scsi/bfa/include/bfi/bfi_fabric.h b/drivers/scsi/bfa/include/bfi/bfi_fabric.h
new file mode 100644
index 000000000000..c0669ed41078
--- /dev/null
+++ b/drivers/scsi/bfa/include/bfi/bfi_fabric.h
@@ -0,0 +1,92 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFI_FABRIC_H__
19#define __BFI_FABRIC_H__
20
21#include <bfi/bfi.h>
22
23#pragma pack(1)
24
25enum bfi_fabric_h2i_msgs {
26 BFI_FABRIC_H2I_CREATE_REQ = 1,
27 BFI_FABRIC_H2I_DELETE_REQ = 2,
28 BFI_FABRIC_H2I_SETAUTH = 3,
29};
30
31enum bfi_fabric_i2h_msgs {
32 BFI_FABRIC_I2H_CREATE_RSP = BFA_I2HM(1),
33 BFI_FABRIC_I2H_DELETE_RSP = BFA_I2HM(2),
34 BFI_FABRIC_I2H_SETAUTH_RSP = BFA_I2HM(3),
35 BFI_FABRIC_I2H_ONLINE = BFA_I2HM(4),
36 BFI_FABRIC_I2H_OFFLINE = BFA_I2HM(5),
37};
38
39struct bfi_fabric_create_req_s {
40 bfi_mhdr_t mh; /* common msg header */
41 u8 vf_en; /* virtual fabric enable */
42 u8 rsvd;
43 u16 vf_id; /* virtual fabric ID */
44 wwn_t pwwn; /* port name */
45 wwn_t nwwn; /* node name */
46};
47
48struct bfi_fabric_create_rsp_s {
49 bfi_mhdr_t mh; /* common msg header */
50 u16 bfa_handle; /* host fabric handle */
51 u8 status; /* fabric create status */
52 u8 rsvd;
53};
54
55struct bfi_fabric_delete_req_s {
56 bfi_mhdr_t mh; /* common msg header */
57 u16 fw_handle; /* firmware fabric handle */
58 u16 rsvd;
59};
60
61struct bfi_fabric_delete_rsp_s {
62 bfi_mhdr_t mh; /* common msg header */
63 u16 bfa_handle; /* host fabric handle */
64 u8 status; /* fabric deletion status */
65 u8 rsvd;
66};
67
68#define BFI_FABRIC_AUTHSECRET_LEN 64
69struct bfi_fabric_setauth_req_s {
70 bfi_mhdr_t mh; /* common msg header */
71 u16 fw_handle; /* f/w handle of fabric */
72 u8 algorithm;
73 u8 group;
74 u8 secret[BFI_FABRIC_AUTHSECRET_LEN];
75};
76
77union bfi_fabric_h2i_msg_u {
78 bfi_msg_t *msg;
79 struct bfi_fabric_create_req_s *create_req;
80 struct bfi_fabric_delete_req_s *delete_req;
81};
82
83union bfi_fabric_i2h_msg_u {
84 bfi_msg_t *msg;
85 struct bfi_fabric_create_rsp_s *create_rsp;
86 struct bfi_fabric_delete_rsp_s *delete_rsp;
87};
88
89#pragma pack()
90
91#endif /* __BFI_FABRIC_H__ */
92
diff --git a/drivers/scsi/bfa/include/bfi/bfi_fcpim.h b/drivers/scsi/bfa/include/bfi/bfi_fcpim.h
new file mode 100644
index 000000000000..52c059fb4c3a
--- /dev/null
+++ b/drivers/scsi/bfa/include/bfi/bfi_fcpim.h
@@ -0,0 +1,301 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFI_FCPIM_H__
19#define __BFI_FCPIM_H__
20
21#include "bfi.h"
22#include <protocol/fcp.h>
23
24#pragma pack(1)
25
26/*
27 * Initiator mode I-T nexus interface defines.
28 */
29
30enum bfi_itnim_h2i {
31 BFI_ITNIM_H2I_CREATE_REQ = 1, /* i-t nexus creation */
32 BFI_ITNIM_H2I_DELETE_REQ = 2, /* i-t nexus deletion */
33};
34
35enum bfi_itnim_i2h {
36 BFI_ITNIM_I2H_CREATE_RSP = BFA_I2HM(1),
37 BFI_ITNIM_I2H_DELETE_RSP = BFA_I2HM(2),
38 BFI_ITNIM_I2H_SLER_EVENT = BFA_I2HM(3),
39};
40
41struct bfi_itnim_create_req_s {
42 struct bfi_mhdr_s mh; /* common msg header */
43 u16 fw_handle; /* f/w handle for itnim */
44 u8 class; /* FC class for IO */
45 u8 seq_rec; /* sequence recovery support */
46 u8 msg_no; /* seq id of the msg */
47};
48
49struct bfi_itnim_create_rsp_s {
50 struct bfi_mhdr_s mh; /* common msg header */
51 u16 bfa_handle; /* bfa handle for itnim */
52 u8 status; /* fcp request status */
53 u8 seq_id; /* seq id of the msg */
54};
55
56struct bfi_itnim_delete_req_s {
57 struct bfi_mhdr_s mh; /* common msg header */
58 u16 fw_handle; /* f/w itnim handle */
59 u8 seq_id; /* seq id of the msg */
60 u8 rsvd;
61};
62
63struct bfi_itnim_delete_rsp_s {
64 struct bfi_mhdr_s mh; /* common msg header */
65 u16 bfa_handle; /* bfa handle for itnim */
66 u8 status; /* fcp request status */
67 u8 seq_id; /* seq id of the msg */
68};
69
70struct bfi_itnim_sler_event_s {
71 struct bfi_mhdr_s mh; /* common msg header */
72 u16 bfa_handle; /* bfa handle for itnim */
73 u16 rsvd;
74};
75
76union bfi_itnim_h2i_msg_u {
77 struct bfi_itnim_create_req_s *create_req;
78 struct bfi_itnim_delete_req_s *delete_req;
79 struct bfi_msg_s *msg;
80};
81
82union bfi_itnim_i2h_msg_u {
83 struct bfi_itnim_create_rsp_s *create_rsp;
84 struct bfi_itnim_delete_rsp_s *delete_rsp;
85 struct bfi_itnim_sler_event_s *sler_event;
86 struct bfi_msg_s *msg;
87};
88
89/*
90 * Initiator mode IO interface defines.
91 */
92
93enum bfi_ioim_h2i {
94 BFI_IOIM_H2I_IOABORT_REQ = 1, /* IO abort request */
95 BFI_IOIM_H2I_IOCLEANUP_REQ = 2, /* IO cleanup request */
96};
97
98enum bfi_ioim_i2h {
99 BFI_IOIM_I2H_IO_RSP = BFA_I2HM(1), /* non-fp IO response */
100 BFI_IOIM_I2H_IOABORT_RSP = BFA_I2HM(2),/* ABORT rsp */
101};
102
103/**
104 * IO command DIF info
105 */
106struct bfi_ioim_dif_s {
107 u32 dif_info[4];
108};
109
110/**
111 * FCP IO messages overview
112 *
113 * @note
114 * - Max CDB length supported is 64 bytes.
115 * - SCSI Linked commands and SCSI bi-directional Commands not
116 * supported.
117 *
118 */
119struct bfi_ioim_req_s {
120 struct bfi_mhdr_s mh; /* Common msg header */
121 u16 io_tag; /* I/O tag */
122 u16 rport_hdl; /* itnim/rport firmware handle */
123 struct fcp_cmnd_s cmnd; /* IO request info */
124
125 /**
126 * SG elements array within the IO request must be double word
127 * aligned. This aligment is required to optimize SGM setup for the IO.
128 */
129 struct bfi_sge_s sges[BFI_SGE_INLINE_MAX];
130 u8 io_timeout;
131 u8 dif_en;
132 u8 rsvd_a[2];
133 struct bfi_ioim_dif_s dif;
134};
135
136/**
137 * This table shows various IO status codes from firmware and their
138 * meaning. Host driver can use these status codes to further process
139 * IO completions.
140 *
141 * BFI_IOIM_STS_OK : IO completed with error free SCSI &
142 * transport status.
143 * - io-tag can be reused.
144 *
145 * BFA_IOIM_STS_SCSI_ERR : IO completed with scsi error.
146 * - io-tag can be reused.
147 *
148 * BFI_IOIM_STS_HOST_ABORTED : IO was aborted successfully due to
149 * host request.
150 * - io-tag cannot be reused yet.
151 *
152 * BFI_IOIM_STS_ABORTED : IO was aborted successfully
153 * internally by f/w.
154 * - io-tag cannot be reused yet.
155 *
156 * BFI_IOIM_STS_TIMEDOUT : IO timedout and ABTS/RRQ is happening
157 * in the firmware and
158 * - io-tag cannot be reused yet.
159 *
160 * BFI_IOIM_STS_SQER_NEEDED : Firmware could not recover the IO
161 * with sequence level error
162 * logic and hence host needs to retry
163 * this IO with a different IO tag
164 * - io-tag cannot be used yet.
165 *
166 * BFI_IOIM_STS_NEXUS_ABORT : Second Level Error Recovery from host
167 * is required because 2 consecutive ABTS
168 * timedout and host needs logout and
169 * re-login with the target
170 * - io-tag cannot be used yet.
171 *
172 * BFI_IOIM_STS_UNDERRUN : IO completed with SCSI status good,
173 * but the data tranferred is less than
174 * the fcp data length in the command.
175 * ex. SCSI INQUIRY where transferred
176 * data length and residue count in FCP
177 * response accounts for total fcp-dl
178 * - io-tag can be reused.
179 *
180 * BFI_IOIM_STS_OVERRUN : IO completed with SCSI status good,
181 * but the data transerred is more than
182 * fcp data length in the command. ex.
183 * TAPE IOs where blocks can of unequal
184 * lengths.
185 * - io-tag can be reused.
186 *
187 * BFI_IOIM_STS_RES_FREE : Firmware has completed using io-tag
188 * during abort process
189 * - io-tag can be reused.
190 *
191 * BFI_IOIM_STS_PROTO_ERR : Firmware detected a protocol error.
192 * ex target sent more data than
193 * requested, or there was data frame
194 * loss and other reasons
195 * - io-tag cannot be used yet.
196 *
197 * BFI_IOIM_STS_DIF_ERR : Firwmare detected DIF error. ex: DIF
198 * CRC err or Ref Tag err or App tag err.
199 * - io-tag can be reused.
200 *
201 * BFA_IOIM_STS_TSK_MGT_ABORT : IO was aborted because of Task
202 * Management command from the host
203 * - io-tag can be reused.
204 *
205 * BFI_IOIM_STS_UTAG : Firmware does not know about this
206 * io_tag.
207 * - io-tag can be reused.
208 */
209enum bfi_ioim_status {
210 BFI_IOIM_STS_OK = 0,
211 BFI_IOIM_STS_HOST_ABORTED = 1,
212 BFI_IOIM_STS_ABORTED = 2,
213 BFI_IOIM_STS_TIMEDOUT = 3,
214 BFI_IOIM_STS_RES_FREE = 4,
215 BFI_IOIM_STS_SQER_NEEDED = 5,
216 BFI_IOIM_STS_PROTO_ERR = 6,
217 BFI_IOIM_STS_UTAG = 7,
218 BFI_IOIM_STS_PATHTOV = 8,
219};
220
221#define BFI_IOIM_SNSLEN (256)
222/**
223 * I/O response message
224 */
225struct bfi_ioim_rsp_s {
226 struct bfi_mhdr_s mh; /* common msg header */
227 u16 io_tag; /* completed IO tag */
228 u16 bfa_rport_hndl; /* releated rport handle */
229 u8 io_status; /* IO completion status */
230 u8 reuse_io_tag; /* IO tag can be reused */
231 u16 abort_tag; /* host abort request tag */
232 u8 scsi_status; /* scsi status from target */
233 u8 sns_len; /* scsi sense length */
234 u8 resid_flags; /* IO residue flags */
235 u8 rsvd_a;
236 u32 residue; /* IO residual length in bytes */
237 u32 rsvd_b[3];
238};
239
240struct bfi_ioim_abort_req_s {
241 struct bfi_mhdr_s mh; /* Common msg header */
242 u16 io_tag; /* I/O tag */
243 u16 abort_tag; /* unique request tag */
244};
245
246/*
247 * Initiator mode task management command interface defines.
248 */
249
250enum bfi_tskim_h2i {
251 BFI_TSKIM_H2I_TM_REQ = 1, /* task-mgmt command */
252 BFI_TSKIM_H2I_ABORT_REQ = 2, /* task-mgmt command */
253};
254
255enum bfi_tskim_i2h {
256 BFI_TSKIM_I2H_TM_RSP = BFA_I2HM(1),
257};
258
259struct bfi_tskim_req_s {
260 struct bfi_mhdr_s mh; /* Common msg header */
261 u16 tsk_tag; /* task management tag */
262 u16 itn_fhdl; /* itn firmware handle */
263 lun_t lun; /* LU number */
264 u8 tm_flags; /* see fcp_tm_cmnd_t */
265 u8 t_secs; /* Timeout value in seconds */
266 u8 rsvd[2];
267};
268
269struct bfi_tskim_abortreq_s {
270 struct bfi_mhdr_s mh; /* Common msg header */
271 u16 tsk_tag; /* task management tag */
272 u16 rsvd;
273};
274
275enum bfi_tskim_status {
276 /*
277 * Following are FCP-4 spec defined status codes,
278 * **DO NOT CHANGE THEM **
279 */
280 BFI_TSKIM_STS_OK = 0,
281 BFI_TSKIM_STS_NOT_SUPP = 4,
282 BFI_TSKIM_STS_FAILED = 5,
283
284 /**
285 * Defined by BFA
286 */
287 BFI_TSKIM_STS_TIMEOUT = 10, /* TM request timedout */
288 BFI_TSKIM_STS_ABORTED = 11, /* Aborted on host request */
289};
290
291struct bfi_tskim_rsp_s {
292 struct bfi_mhdr_s mh; /* Common msg header */
293 u16 tsk_tag; /* task mgmt cmnd tag */
294 u8 tsk_status; /* @ref bfi_tskim_status */
295 u8 rsvd;
296};
297
298#pragma pack()
299
300#endif /* __BFI_FCPIM_H__ */
301
diff --git a/drivers/scsi/bfa/include/bfi/bfi_fcxp.h b/drivers/scsi/bfa/include/bfi/bfi_fcxp.h
new file mode 100644
index 000000000000..e0e995a32828
--- /dev/null
+++ b/drivers/scsi/bfa/include/bfi/bfi_fcxp.h
@@ -0,0 +1,71 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFI_FCXP_H__
19#define __BFI_FCXP_H__
20
21#include "bfi.h"
22
23#pragma pack(1)
24
25enum bfi_fcxp_h2i {
26 BFI_FCXP_H2I_SEND_REQ = 1,
27};
28
29enum bfi_fcxp_i2h {
30 BFI_FCXP_I2H_SEND_RSP = BFA_I2HM(1),
31};
32
33#define BFA_FCXP_MAX_SGES 2
34
35/**
36 * FCXP send request structure
37 */
38struct bfi_fcxp_send_req_s {
39 struct bfi_mhdr_s mh; /* Common msg header */
40 u16 fcxp_tag; /* driver request tag */
41 u16 max_frmsz; /* max send frame size */
42 u16 vf_id; /* vsan tag if applicable */
43 u16 rport_fw_hndl; /* FW Handle for the remote port */
44 u8 class; /* FC class used for req/rsp */
45 u8 rsp_timeout; /* timeout in secs, 0-no response */
46 u8 cts; /* continue sequence */
47 u8 lp_tag; /* lport tag */
48 struct fchs_s fchs; /* request FC header structure */
49 u32 req_len; /* request payload length */
50 u32 rsp_maxlen; /* max response length expected */
51 struct bfi_sge_s req_sge[BFA_FCXP_MAX_SGES]; /* request buf */
52 struct bfi_sge_s rsp_sge[BFA_FCXP_MAX_SGES]; /* response buf */
53};
54
55/**
56 * FCXP send response structure
57 */
58struct bfi_fcxp_send_rsp_s {
59 struct bfi_mhdr_s mh; /* Common msg header */
60 u16 fcxp_tag; /* send request tag */
61 u8 req_status; /* request status */
62 u8 rsvd;
63 u32 rsp_len; /* actual response length */
64 u32 residue_len; /* residual response length */
65 struct fchs_s fchs; /* response FC header structure */
66};
67
68#pragma pack()
69
70#endif /* __BFI_FCXP_H__ */
71
diff --git a/drivers/scsi/bfa/include/bfi/bfi_ioc.h b/drivers/scsi/bfa/include/bfi/bfi_ioc.h
new file mode 100644
index 000000000000..026e9c06ae97
--- /dev/null
+++ b/drivers/scsi/bfa/include/bfi/bfi_ioc.h
@@ -0,0 +1,202 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFI_IOC_H__
19#define __BFI_IOC_H__
20
21#include "bfi.h"
22#include <defs/bfa_defs_ioc.h>
23
24#pragma pack(1)
25
26enum bfi_ioc_h2i_msgs {
27 BFI_IOC_H2I_ENABLE_REQ = 1,
28 BFI_IOC_H2I_DISABLE_REQ = 2,
29 BFI_IOC_H2I_GETATTR_REQ = 3,
30 BFI_IOC_H2I_DBG_SYNC = 4,
31 BFI_IOC_H2I_DBG_DUMP = 5,
32};
33
34enum bfi_ioc_i2h_msgs {
35 BFI_IOC_I2H_ENABLE_REPLY = BFA_I2HM(1),
36 BFI_IOC_I2H_DISABLE_REPLY = BFA_I2HM(2),
37 BFI_IOC_I2H_GETATTR_REPLY = BFA_I2HM(3),
38 BFI_IOC_I2H_READY_EVENT = BFA_I2HM(4),
39 BFI_IOC_I2H_HBEAT = BFA_I2HM(5),
40};
41
42/**
43 * BFI_IOC_H2I_GETATTR_REQ message
44 */
45struct bfi_ioc_getattr_req_s {
46 struct bfi_mhdr_s mh;
47 union bfi_addr_u attr_addr;
48};
49
50struct bfi_ioc_attr_s {
51 wwn_t mfg_wwn;
52 mac_t mfg_mac;
53 u16 rsvd_a;
54 char brcd_serialnum[STRSZ(BFA_MFG_SERIALNUM_SIZE)];
55 u8 pcie_gen;
56 u8 pcie_lanes_orig;
57 u8 pcie_lanes;
58 u8 rx_bbcredit; /* receive buffer credits */
59 u32 adapter_prop; /* adapter properties */
60 u16 maxfrsize; /* max receive frame size */
61 char asic_rev;
62 u8 rsvd_b;
63 char fw_version[BFA_VERSION_LEN];
64 char optrom_version[BFA_VERSION_LEN];
65 struct bfa_mfg_vpd_s vpd;
66};
67
68/**
69 * BFI_IOC_I2H_GETATTR_REPLY message
70 */
71struct bfi_ioc_getattr_reply_s {
72 struct bfi_mhdr_s mh; /* Common msg header */
73 u8 status; /* cfg reply status */
74 u8 rsvd[3];
75};
76
77/**
78 * Firmware memory page offsets
79 */
80#define BFI_IOC_SMEM_PG0_CB (0x40)
81#define BFI_IOC_SMEM_PG0_CT (0x180)
82
83/**
84 * Firmware trace offset
85 */
86#define BFI_IOC_TRC_OFF (0x4b00)
87#define BFI_IOC_TRC_ENTS 256
88
89#define BFI_IOC_FW_SIGNATURE (0xbfadbfad)
90#define BFI_IOC_MD5SUM_SZ 4
91struct bfi_ioc_image_hdr_s {
92 u32 signature; /* constant signature */
93 u32 rsvd_a;
94 u32 exec; /* exec vector */
95 u32 param; /* parameters */
96 u32 rsvd_b[4];
97 u32 md5sum[BFI_IOC_MD5SUM_SZ];
98};
99
100/**
101 * BFI_IOC_I2H_READY_EVENT message
102 */
103struct bfi_ioc_rdy_event_s {
104 struct bfi_mhdr_s mh; /* common msg header */
105 u8 init_status; /* init event status */
106 u8 rsvd[3];
107};
108
109struct bfi_ioc_hbeat_s {
110 struct bfi_mhdr_s mh; /* common msg header */
111 u32 hb_count; /* current heart beat count */
112};
113
114/**
115 * IOC hardware/firmware state
116 */
117enum bfi_ioc_state {
118 BFI_IOC_UNINIT = 0, /* not initialized */
119 BFI_IOC_INITING = 1, /* h/w is being initialized */
120 BFI_IOC_HWINIT = 2, /* h/w is initialized */
121 BFI_IOC_CFG = 3, /* IOC configuration in progress */
122 BFI_IOC_OP = 4, /* IOC is operational */
123 BFI_IOC_DISABLING = 5, /* IOC is being disabled */
124 BFI_IOC_DISABLED = 6, /* IOC is disabled */
125 BFI_IOC_CFG_DISABLED = 7, /* IOC is being disabled;transient */
126 BFI_IOC_HBFAIL = 8, /* IOC heart-beat failure */
127 BFI_IOC_MEMTEST = 9, /* IOC is doing memtest */
128};
129
130#define BFI_IOC_ENDIAN_SIG 0x12345678
131
132enum {
133 BFI_ADAPTER_TYPE_FC = 0x01, /* FC adapters */
134 BFI_ADAPTER_TYPE_MK = 0x0f0000, /* adapter type mask */
135 BFI_ADAPTER_TYPE_SH = 16, /* adapter type shift */
136 BFI_ADAPTER_NPORTS_MK = 0xff00, /* number of ports mask */
137 BFI_ADAPTER_NPORTS_SH = 8, /* number of ports shift */
138 BFI_ADAPTER_SPEED_MK = 0xff, /* adapter speed mask */
139 BFI_ADAPTER_SPEED_SH = 0, /* adapter speed shift */
140 BFI_ADAPTER_PROTO = 0x100000, /* prototype adapaters */
141 BFI_ADAPTER_TTV = 0x200000, /* TTV debug capable */
142 BFI_ADAPTER_UNSUPP = 0x400000, /* unknown adapter type */
143};
144
145#define BFI_ADAPTER_GETP(__prop,__adap_prop) \
146 (((__adap_prop) & BFI_ADAPTER_ ## __prop ## _MK) >> \
147 BFI_ADAPTER_ ## __prop ## _SH)
148#define BFI_ADAPTER_SETP(__prop, __val) \
149 ((__val) << BFI_ADAPTER_ ## __prop ## _SH)
150#define BFI_ADAPTER_IS_PROTO(__adap_type) \
151 ((__adap_type) & BFI_ADAPTER_PROTO)
152#define BFI_ADAPTER_IS_TTV(__adap_type) \
153 ((__adap_type) & BFI_ADAPTER_TTV)
154#define BFI_ADAPTER_IS_UNSUPP(__adap_type) \
155 ((__adap_type) & BFI_ADAPTER_UNSUPP)
156#define BFI_ADAPTER_IS_SPECIAL(__adap_type) \
157 ((__adap_type) & (BFI_ADAPTER_TTV | BFI_ADAPTER_PROTO | \
158 BFI_ADAPTER_UNSUPP))
159
160/**
161 * BFI_IOC_H2I_ENABLE_REQ & BFI_IOC_H2I_DISABLE_REQ messages
162 */
163struct bfi_ioc_ctrl_req_s {
164 struct bfi_mhdr_s mh;
165 u8 ioc_class;
166 u8 rsvd[3];
167};
168
169/**
170 * BFI_IOC_I2H_ENABLE_REPLY & BFI_IOC_I2H_DISABLE_REPLY messages
171 */
172struct bfi_ioc_ctrl_reply_s {
173 struct bfi_mhdr_s mh; /* Common msg header */
174 u8 status; /* enable/disable status */
175 u8 rsvd[3];
176};
177
178#define BFI_IOC_MSGSZ 8
179/**
180 * H2I Messages
181 */
182union bfi_ioc_h2i_msg_u {
183 struct bfi_mhdr_s mh;
184 struct bfi_ioc_ctrl_req_s enable_req;
185 struct bfi_ioc_ctrl_req_s disable_req;
186 struct bfi_ioc_getattr_req_s getattr_req;
187 u32 mboxmsg[BFI_IOC_MSGSZ];
188};
189
190/**
191 * I2H Messages
192 */
193union bfi_ioc_i2h_msg_u {
194 struct bfi_mhdr_s mh;
195 struct bfi_ioc_rdy_event_s rdy_event;
196 u32 mboxmsg[BFI_IOC_MSGSZ];
197};
198
199#pragma pack()
200
201#endif /* __BFI_IOC_H__ */
202
diff --git a/drivers/scsi/bfa/include/bfi/bfi_iocfc.h b/drivers/scsi/bfa/include/bfi/bfi_iocfc.h
new file mode 100644
index 000000000000..c3760df72575
--- /dev/null
+++ b/drivers/scsi/bfa/include/bfi/bfi_iocfc.h
@@ -0,0 +1,177 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFI_IOCFC_H__
19#define __BFI_IOCFC_H__
20
21#include "bfi.h"
22#include <defs/bfa_defs_ioc.h>
23#include <defs/bfa_defs_iocfc.h>
24#include <defs/bfa_defs_boot.h>
25
26#pragma pack(1)
27
28enum bfi_iocfc_h2i_msgs {
29 BFI_IOCFC_H2I_CFG_REQ = 1,
30 BFI_IOCFC_H2I_GET_STATS_REQ = 2,
31 BFI_IOCFC_H2I_CLEAR_STATS_REQ = 3,
32 BFI_IOCFC_H2I_SET_INTR_REQ = 4,
33 BFI_IOCFC_H2I_UPDATEQ_REQ = 5,
34};
35
36enum bfi_iocfc_i2h_msgs {
37 BFI_IOCFC_I2H_CFG_REPLY = BFA_I2HM(1),
38 BFI_IOCFC_I2H_GET_STATS_RSP = BFA_I2HM(2),
39 BFI_IOCFC_I2H_CLEAR_STATS_RSP = BFA_I2HM(3),
40 BFI_IOCFC_I2H_UPDATEQ_RSP = BFA_I2HM(5),
41};
42
43struct bfi_iocfc_cfg_s {
44 u8 num_cqs; /* Number of CQs to be used */
45 u8 sense_buf_len; /* SCSI sense length */
46 u8 trunk_enabled; /* port trunking enabled */
47 u8 trunk_ports; /* trunk ports bit map */
48 u32 endian_sig; /* endian signature of host */
49
50 /**
51 * Request and response circular queue base addresses, size and
52 * shadow index pointers.
53 */
54 union bfi_addr_u req_cq_ba[BFI_IOC_MAX_CQS];
55 union bfi_addr_u req_shadow_ci[BFI_IOC_MAX_CQS];
56 u16 req_cq_elems[BFI_IOC_MAX_CQS];
57 union bfi_addr_u rsp_cq_ba[BFI_IOC_MAX_CQS];
58 union bfi_addr_u rsp_shadow_pi[BFI_IOC_MAX_CQS];
59 u16 rsp_cq_elems[BFI_IOC_MAX_CQS];
60
61 union bfi_addr_u stats_addr; /* DMA-able address for stats */
62 union bfi_addr_u cfgrsp_addr; /* config response dma address */
63 union bfi_addr_u ioim_snsbase; /* IO sense buffer base address */
64 struct bfa_iocfc_intr_attr_s intr_attr; /* IOC interrupt attributes */
65};
66
67/**
68 * Boot target wwn information for this port. This contains either the stored
69 * or discovered boot target port wwns for the port.
70 */
71struct bfi_iocfc_bootwwns {
72 wwn_t wwn[BFA_BOOT_BOOTLUN_MAX];
73 u8 nwwns;
74 u8 rsvd[7];
75};
76
77struct bfi_iocfc_cfgrsp_s {
78 struct bfa_iocfc_fwcfg_s fwcfg;
79 struct bfa_iocfc_intr_attr_s intr_attr;
80 struct bfi_iocfc_bootwwns bootwwns;
81};
82
83/**
84 * BFI_IOCFC_H2I_CFG_REQ message
85 */
86struct bfi_iocfc_cfg_req_s {
87 struct bfi_mhdr_s mh;
88 union bfi_addr_u ioc_cfg_dma_addr;
89};
90
91/**
92 * BFI_IOCFC_I2H_CFG_REPLY message
93 */
94struct bfi_iocfc_cfg_reply_s {
95 struct bfi_mhdr_s mh; /* Common msg header */
96 u8 cfg_success; /* cfg reply status */
97 u8 lpu_bm; /* LPUs assigned for this IOC */
98 u8 rsvd[2];
99};
100
101/**
102 * BFI_IOCFC_H2I_GET_STATS_REQ & BFI_IOCFC_H2I_CLEAR_STATS_REQ messages
103 */
104struct bfi_iocfc_stats_req_s {
105 struct bfi_mhdr_s mh; /* msg header */
106 u32 msgtag; /* msgtag for reply */
107};
108
109/**
110 * BFI_IOCFC_I2H_GET_STATS_RSP & BFI_IOCFC_I2H_CLEAR_STATS_RSP messages
111 */
112struct bfi_iocfc_stats_rsp_s {
113 struct bfi_mhdr_s mh; /* common msg header */
114 u8 status; /* reply status */
115 u8 rsvd[3];
116 u32 msgtag; /* msgtag for reply */
117};
118
119/**
120 * BFI_IOCFC_H2I_SET_INTR_REQ message
121 */
122struct bfi_iocfc_set_intr_req_s {
123 struct bfi_mhdr_s mh; /* common msg header */
124 u8 coalesce; /* enable intr coalescing*/
125 u8 rsvd[3];
126 u16 delay; /* delay timer 0..1125us */
127 u16 latency; /* latency timer 0..225us */
128};
129
130/**
131 * BFI_IOCFC_H2I_UPDATEQ_REQ message
132 */
133struct bfi_iocfc_updateq_req_s {
134 struct bfi_mhdr_s mh; /* common msg header */
135 u32 reqq_ba; /* reqq base addr */
136 u32 rspq_ba; /* rspq base addr */
137 u32 reqq_sci; /* reqq shadow ci */
138 u32 rspq_spi; /* rspq shadow pi */
139};
140
141/**
142 * BFI_IOCFC_I2H_UPDATEQ_RSP message
143 */
144struct bfi_iocfc_updateq_rsp_s {
145 struct bfi_mhdr_s mh; /* common msg header */
146 u8 status; /* updateq status */
147 u8 rsvd[3];
148};
149
150/**
151 * H2I Messages
152 */
153union bfi_iocfc_h2i_msg_u {
154 struct bfi_mhdr_s mh;
155 struct bfi_iocfc_cfg_req_s cfg_req;
156 struct bfi_iocfc_stats_req_s stats_get;
157 struct bfi_iocfc_stats_req_s stats_clr;
158 struct bfi_iocfc_updateq_req_s updateq_req;
159 u32 mboxmsg[BFI_IOC_MSGSZ];
160};
161
162/**
163 * I2H Messages
164 */
165union bfi_iocfc_i2h_msg_u {
166 struct bfi_mhdr_s mh;
167 struct bfi_iocfc_cfg_reply_s cfg_reply;
168 struct bfi_iocfc_stats_rsp_s stats_get_rsp;
169 struct bfi_iocfc_stats_rsp_s stats_clr_rsp;
170 struct bfi_iocfc_updateq_rsp_s updateq_rsp;
171 u32 mboxmsg[BFI_IOC_MSGSZ];
172};
173
174#pragma pack()
175
176#endif /* __BFI_IOCFC_H__ */
177
diff --git a/drivers/scsi/bfa/include/bfi/bfi_lport.h b/drivers/scsi/bfa/include/bfi/bfi_lport.h
new file mode 100644
index 000000000000..29010614bac9
--- /dev/null
+++ b/drivers/scsi/bfa/include/bfi/bfi_lport.h
@@ -0,0 +1,89 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFI_LPORT_H__
19#define __BFI_LPORT_H__
20
21#include <bfi/bfi.h>
22
23#pragma pack(1)
24
25enum bfi_lport_h2i_msgs {
26 BFI_LPORT_H2I_CREATE_REQ = 1,
27 BFI_LPORT_H2I_DELETE_REQ = 2,
28};
29
30enum bfi_lport_i2h_msgs {
31 BFI_LPORT_I2H_CREATE_RSP = BFA_I2HM(1),
32 BFI_LPORT_I2H_DELETE_RSP = BFA_I2HM(2),
33 BFI_LPORT_I2H_ONLINE = BFA_I2HM(3),
34 BFI_LPORT_I2H_OFFLINE = BFA_I2HM(4),
35};
36
37#define BFI_LPORT_MAX_SYNNAME 64
38
39enum bfi_lport_role_e {
40 BFI_LPORT_ROLE_FCPIM = 1,
41 BFI_LPORT_ROLE_FCPTM = 2,
42 BFI_LPORT_ROLE_IPFC = 4,
43};
44
45struct bfi_lport_create_req_s {
46 bfi_mhdr_t mh; /* common msg header */
47 u16 fabric_fwhdl; /* parent fabric instance */
48 u8 roles; /* lport FC-4 roles */
49 u8 rsvd;
50 wwn_t pwwn; /* port name */
51 wwn_t nwwn; /* node name */
52 u8 symname[BFI_LPORT_MAX_SYNNAME];
53};
54
55struct bfi_lport_create_rsp_s {
56 bfi_mhdr_t mh; /* common msg header */
57 u8 status; /* lport creation status */
58 u8 rsvd[3];
59};
60
61struct bfi_lport_delete_req_s {
62 bfi_mhdr_t mh; /* common msg header */
63 u16 fw_handle; /* firmware lport handle */
64 u16 rsvd;
65};
66
67struct bfi_lport_delete_rsp_s {
68 bfi_mhdr_t mh; /* common msg header */
69 u16 bfa_handle; /* host lport handle */
70 u8 status; /* lport deletion status */
71 u8 rsvd;
72};
73
74union bfi_lport_h2i_msg_u {
75 bfi_msg_t *msg;
76 struct bfi_lport_create_req_s *create_req;
77 struct bfi_lport_delete_req_s *delete_req;
78};
79
80union bfi_lport_i2h_msg_u {
81 bfi_msg_t *msg;
82 struct bfi_lport_create_rsp_s *create_rsp;
83 struct bfi_lport_delete_rsp_s *delete_rsp;
84};
85
86#pragma pack()
87
88#endif /* __BFI_LPORT_H__ */
89
diff --git a/drivers/scsi/bfa/include/bfi/bfi_lps.h b/drivers/scsi/bfa/include/bfi/bfi_lps.h
new file mode 100644
index 000000000000..414b0e30f6ef
--- /dev/null
+++ b/drivers/scsi/bfa/include/bfi/bfi_lps.h
@@ -0,0 +1,96 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFI_LPS_H__
19#define __BFI_LPS_H__
20
21#include <bfi/bfi.h>
22
23#pragma pack(1)
24
25enum bfi_lps_h2i_msgs {
26 BFI_LPS_H2I_LOGIN_REQ = 1,
27 BFI_LPS_H2I_LOGOUT_REQ = 2,
28};
29
30enum bfi_lps_i2h_msgs {
31 BFI_LPS_H2I_LOGIN_RSP = BFA_I2HM(1),
32 BFI_LPS_H2I_LOGOUT_RSP = BFA_I2HM(2),
33};
34
35struct bfi_lps_login_req_s {
36 struct bfi_mhdr_s mh; /* common msg header */
37 u8 lp_tag;
38 u8 alpa;
39 u16 pdu_size;
40 wwn_t pwwn;
41 wwn_t nwwn;
42 u8 fdisc;
43 u8 auth_en;
44 u8 rsvd[2];
45};
46
47struct bfi_lps_login_rsp_s {
48 struct bfi_mhdr_s mh; /* common msg header */
49 u8 lp_tag;
50 u8 status;
51 u8 lsrjt_rsn;
52 u8 lsrjt_expl;
53 wwn_t port_name;
54 wwn_t node_name;
55 u16 bb_credit;
56 u8 f_port;
57 u8 npiv_en;
58 u32 lp_pid : 24;
59 u32 auth_req : 8;
60 mac_t lp_mac;
61 mac_t fcf_mac;
62 u8 ext_status;
63 u8 brcd_switch;/* attached peer is brcd switch */
64};
65
66struct bfi_lps_logout_req_s {
67 struct bfi_mhdr_s mh; /* common msg header */
68 u8 lp_tag;
69 u8 rsvd[3];
70 wwn_t port_name;
71};
72
73struct bfi_lps_logout_rsp_s {
74 struct bfi_mhdr_s mh; /* common msg header */
75 u8 lp_tag;
76 u8 status;
77 u8 rsvd[2];
78};
79
80union bfi_lps_h2i_msg_u {
81 struct bfi_mhdr_s *msg;
82 struct bfi_lps_login_req_s *login_req;
83 struct bfi_lps_logout_req_s *logout_req;
84};
85
86union bfi_lps_i2h_msg_u {
87 struct bfi_msg_s *msg;
88 struct bfi_lps_login_rsp_s *login_rsp;
89 struct bfi_lps_logout_rsp_s *logout_rsp;
90};
91
92#pragma pack()
93
94#endif /* __BFI_LPS_H__ */
95
96
diff --git a/drivers/scsi/bfa/include/bfi/bfi_port.h b/drivers/scsi/bfa/include/bfi/bfi_port.h
new file mode 100644
index 000000000000..3ec3bea110ba
--- /dev/null
+++ b/drivers/scsi/bfa/include/bfi/bfi_port.h
@@ -0,0 +1,115 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17#ifndef __BFI_PORT_H__
18#define __BFI_PORT_H__
19
20#include <bfi/bfi.h>
21#include <defs/bfa_defs_pport.h>
22
23#pragma pack(1)
24
25enum bfi_port_h2i {
26 BFI_PORT_H2I_ENABLE_REQ = (1),
27 BFI_PORT_H2I_DISABLE_REQ = (2),
28 BFI_PORT_H2I_GET_STATS_REQ = (3),
29 BFI_PORT_H2I_CLEAR_STATS_REQ = (4),
30};
31
32enum bfi_port_i2h {
33 BFI_PORT_I2H_ENABLE_RSP = BFA_I2HM(1),
34 BFI_PORT_I2H_DISABLE_RSP = BFA_I2HM(2),
35 BFI_PORT_I2H_GET_STATS_RSP = BFA_I2HM(3),
36 BFI_PORT_I2H_CLEAR_STATS_RSP = BFA_I2HM(4),
37};
38
39/**
40 * Generic REQ type
41 */
42struct bfi_port_generic_req_s {
43 struct bfi_mhdr_s mh; /* msg header */
44 u32 msgtag; /* msgtag for reply */
45 u32 rsvd;
46};
47
48/**
49 * Generic RSP type
50 */
51struct bfi_port_generic_rsp_s {
52 struct bfi_mhdr_s mh; /* common msg header */
53 u8 status; /* port enable status */
54 u8 rsvd[3];
55 u32 msgtag; /* msgtag for reply */
56};
57
58/**
59 * @todo
60 * BFI_PORT_H2I_ENABLE_REQ
61 */
62
63/**
64 * @todo
65 * BFI_PORT_I2H_ENABLE_RSP
66 */
67
68/**
69 * BFI_PORT_H2I_DISABLE_REQ
70 */
71
72/**
73 * BFI_PORT_I2H_DISABLE_RSP
74 */
75
76/**
77 * BFI_PORT_H2I_GET_STATS_REQ
78 */
79struct bfi_port_get_stats_req_s {
80 struct bfi_mhdr_s mh; /* common msg header */
81 union bfi_addr_u dma_addr;
82};
83
84/**
85 * BFI_PORT_I2H_GET_STATS_RSP
86 */
87
88/**
89 * BFI_PORT_H2I_CLEAR_STATS_REQ
90 */
91
92/**
93 * BFI_PORT_I2H_CLEAR_STATS_RSP
94 */
95
96union bfi_port_h2i_msg_u {
97 struct bfi_mhdr_s mh;
98 struct bfi_port_generic_req_s enable_req;
99 struct bfi_port_generic_req_s disable_req;
100 struct bfi_port_get_stats_req_s getstats_req;
101 struct bfi_port_generic_req_s clearstats_req;
102};
103
104union bfi_port_i2h_msg_u {
105 struct bfi_mhdr_s mh;
106 struct bfi_port_generic_rsp_s enable_rsp;
107 struct bfi_port_generic_rsp_s disable_rsp;
108 struct bfi_port_generic_rsp_s getstats_rsp;
109 struct bfi_port_generic_rsp_s clearstats_rsp;
110};
111
112#pragma pack()
113
114#endif /* __BFI_PORT_H__ */
115
diff --git a/drivers/scsi/bfa/include/bfi/bfi_pport.h b/drivers/scsi/bfa/include/bfi/bfi_pport.h
new file mode 100644
index 000000000000..c96d246851af
--- /dev/null
+++ b/drivers/scsi/bfa/include/bfi/bfi_pport.h
@@ -0,0 +1,184 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17#ifndef __BFI_PPORT_H__
18#define __BFI_PPORT_H__
19
20#include <bfi/bfi.h>
21#include <defs/bfa_defs_pport.h>
22
23#pragma pack(1)
24
25enum bfi_pport_h2i {
26 BFI_PPORT_H2I_ENABLE_REQ = (1),
27 BFI_PPORT_H2I_DISABLE_REQ = (2),
28 BFI_PPORT_H2I_GET_STATS_REQ = (3),
29 BFI_PPORT_H2I_CLEAR_STATS_REQ = (4),
30 BFI_PPORT_H2I_SET_SVC_PARAMS_REQ = (5),
31 BFI_PPORT_H2I_ENABLE_RX_VF_TAG_REQ = (6),
32 BFI_PPORT_H2I_ENABLE_TX_VF_TAG_REQ = (7),
33 BFI_PPORT_H2I_GET_QOS_STATS_REQ = (8),
34 BFI_PPORT_H2I_CLEAR_QOS_STATS_REQ = (9),
35};
36
37enum bfi_pport_i2h {
38 BFI_PPORT_I2H_ENABLE_RSP = BFA_I2HM(1),
39 BFI_PPORT_I2H_DISABLE_RSP = BFA_I2HM(2),
40 BFI_PPORT_I2H_GET_STATS_RSP = BFA_I2HM(3),
41 BFI_PPORT_I2H_CLEAR_STATS_RSP = BFA_I2HM(4),
42 BFI_PPORT_I2H_SET_SVC_PARAMS_RSP = BFA_I2HM(5),
43 BFI_PPORT_I2H_ENABLE_RX_VF_TAG_RSP = BFA_I2HM(6),
44 BFI_PPORT_I2H_ENABLE_TX_VF_TAG_RSP = BFA_I2HM(7),
45 BFI_PPORT_I2H_EVENT = BFA_I2HM(8),
46 BFI_PPORT_I2H_GET_QOS_STATS_RSP = BFA_I2HM(9),
47 BFI_PPORT_I2H_CLEAR_QOS_STATS_RSP = BFA_I2HM(10),
48};
49
50/**
51 * Generic REQ type
52 */
53struct bfi_pport_generic_req_s {
54 struct bfi_mhdr_s mh; /* msg header */
55 u32 msgtag; /* msgtag for reply */
56};
57
58/**
59 * Generic RSP type
60 */
61struct bfi_pport_generic_rsp_s {
62 struct bfi_mhdr_s mh; /* common msg header */
63 u8 status; /* port enable status */
64 u8 rsvd[3];
65 u32 msgtag; /* msgtag for reply */
66};
67
68/**
69 * BFI_PPORT_H2I_ENABLE_REQ
70 */
71struct bfi_pport_enable_req_s {
72 struct bfi_mhdr_s mh; /* msg header */
73 u32 rsvd1;
74 wwn_t nwwn; /* node wwn of physical port */
75 wwn_t pwwn; /* port wwn of physical port */
76 struct bfa_pport_cfg_s port_cfg; /* port configuration */
77 union bfi_addr_u stats_dma_addr; /* DMA address for stats */
78 u32 msgtag; /* msgtag for reply */
79 u32 rsvd2;
80};
81
82/**
83 * BFI_PPORT_I2H_ENABLE_RSP
84 */
85#define bfi_pport_enable_rsp_t struct bfi_pport_generic_rsp_s
86
87/**
88 * BFI_PPORT_H2I_DISABLE_REQ
89 */
90#define bfi_pport_disable_req_t struct bfi_pport_generic_req_s
91
92/**
93 * BFI_PPORT_I2H_DISABLE_RSP
94 */
95#define bfi_pport_disable_rsp_t struct bfi_pport_generic_rsp_s
96
97/**
98 * BFI_PPORT_H2I_GET_STATS_REQ
99 */
100#define bfi_pport_get_stats_req_t struct bfi_pport_generic_req_s
101
102/**
103 * BFI_PPORT_I2H_GET_STATS_RSP
104 */
105#define bfi_pport_get_stats_rsp_t struct bfi_pport_generic_rsp_s
106
107/**
108 * BFI_PPORT_H2I_CLEAR_STATS_REQ
109 */
110#define bfi_pport_clear_stats_req_t struct bfi_pport_generic_req_s
111
112/**
113 * BFI_PPORT_I2H_CLEAR_STATS_RSP
114 */
115#define bfi_pport_clear_stats_rsp_t struct bfi_pport_generic_rsp_s
116
117/**
118 * BFI_PPORT_H2I_GET_QOS_STATS_REQ
119 */
120#define bfi_pport_get_qos_stats_req_t struct bfi_pport_generic_req_s
121
122/**
123 * BFI_PPORT_H2I_GET_QOS_STATS_RSP
124 */
125#define bfi_pport_get_qos_stats_rsp_t struct bfi_pport_generic_rsp_s
126
127/**
128 * BFI_PPORT_H2I_CLEAR_QOS_STATS_REQ
129 */
130#define bfi_pport_clear_qos_stats_req_t struct bfi_pport_generic_req_s
131
132/**
133 * BFI_PPORT_H2I_CLEAR_QOS_STATS_RSP
134 */
135#define bfi_pport_clear_qos_stats_rsp_t struct bfi_pport_generic_rsp_s
136
137/**
138 * BFI_PPORT_H2I_SET_SVC_PARAMS_REQ
139 */
140struct bfi_pport_set_svc_params_req_s {
141 struct bfi_mhdr_s mh; /* msg header */
142 u16 tx_bbcredit; /* Tx credits */
143 u16 rsvd;
144};
145
146/**
147 * BFI_PPORT_I2H_SET_SVC_PARAMS_RSP
148 */
149
150/**
151 * BFI_PPORT_I2H_EVENT
152 */
153struct bfi_pport_event_s {
154 struct bfi_mhdr_s mh; /* common msg header */
155 struct bfa_pport_link_s link_state;
156};
157
158union bfi_pport_h2i_msg_u {
159 struct bfi_mhdr_s *mhdr;
160 struct bfi_pport_enable_req_s *penable;
161 struct bfi_pport_generic_req_s *pdisable;
162 struct bfi_pport_generic_req_s *pgetstats;
163 struct bfi_pport_generic_req_s *pclearstats;
164 struct bfi_pport_set_svc_params_req_s *psetsvcparams;
165 struct bfi_pport_get_qos_stats_req_s *pgetqosstats;
166 struct bfi_pport_generic_req_s *pclearqosstats;
167};
168
169union bfi_pport_i2h_msg_u {
170 struct bfi_msg_s *msg;
171 struct bfi_pport_generic_rsp_s *enable_rsp;
172 struct bfi_pport_disable_rsp_s *disable_rsp;
173 struct bfi_pport_generic_rsp_s *getstats_rsp;
174 struct bfi_pport_clear_stats_rsp_s *clearstats_rsp;
175 struct bfi_pport_set_svc_params_rsp_s *setsvcparasm_rsp;
176 struct bfi_pport_get_qos_stats_rsp_s *getqosstats_rsp;
177 struct bfi_pport_clear_qos_stats_rsp_s *clearqosstats_rsp;
178 struct bfi_pport_event_s *event;
179};
180
181#pragma pack()
182
183#endif /* __BFI_PPORT_H__ */
184
diff --git a/drivers/scsi/bfa/include/bfi/bfi_rport.h b/drivers/scsi/bfa/include/bfi/bfi_rport.h
new file mode 100644
index 000000000000..3520f55f09d7
--- /dev/null
+++ b/drivers/scsi/bfa/include/bfi/bfi_rport.h
@@ -0,0 +1,104 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFI_RPORT_H__
19#define __BFI_RPORT_H__
20
21#include <bfi/bfi.h>
22
23#pragma pack(1)
24
25enum bfi_rport_h2i_msgs {
26 BFI_RPORT_H2I_CREATE_REQ = 1,
27 BFI_RPORT_H2I_DELETE_REQ = 2,
28 BFI_RPORT_H2I_SET_SPEED_REQ = 3,
29};
30
31enum bfi_rport_i2h_msgs {
32 BFI_RPORT_I2H_CREATE_RSP = BFA_I2HM(1),
33 BFI_RPORT_I2H_DELETE_RSP = BFA_I2HM(2),
34 BFI_RPORT_I2H_QOS_SCN = BFA_I2HM(3),
35};
36
37struct bfi_rport_create_req_s {
38 struct bfi_mhdr_s mh; /* common msg header */
39 u16 bfa_handle; /* host rport handle */
40 u16 max_frmsz; /* max rcv pdu size */
41 u32 pid : 24, /* remote port ID */
42 lp_tag : 8; /* local port tag */
43 u32 local_pid : 24, /* local port ID */
44 cisc : 8;
45 u8 fc_class; /* supported FC classes */
46 u8 vf_en; /* virtual fabric enable */
47 u16 vf_id; /* virtual fabric ID */
48};
49
50struct bfi_rport_create_rsp_s {
51 struct bfi_mhdr_s mh; /* common msg header */
52 u8 status; /* rport creation status */
53 u8 rsvd[3];
54 u16 bfa_handle; /* host rport handle */
55 u16 fw_handle; /* firmware rport handle */
56 struct bfa_rport_qos_attr_s qos_attr; /* QoS Attributes */
57};
58
59struct bfa_rport_speed_req_s {
60 struct bfi_mhdr_s mh; /* common msg header */
61 u16 fw_handle; /* firmware rport handle */
62 u8 speed; /*! rport's speed via RPSC */
63 u8 rsvd;
64};
65
66struct bfi_rport_delete_req_s {
67 struct bfi_mhdr_s mh; /* common msg header */
68 u16 fw_handle; /* firmware rport handle */
69 u16 rsvd;
70};
71
72struct bfi_rport_delete_rsp_s {
73 struct bfi_mhdr_s mh; /* common msg header */
74 u16 bfa_handle; /* host rport handle */
75 u8 status; /* rport deletion status */
76 u8 rsvd;
77};
78
79struct bfi_rport_qos_scn_s {
80 struct bfi_mhdr_s mh; /* common msg header */
81 u16 bfa_handle; /* host rport handle */
82 u16 rsvd;
83 struct bfa_rport_qos_attr_s old_qos_attr; /* Old QoS Attributes */
84 struct bfa_rport_qos_attr_s new_qos_attr; /* New QoS Attributes */
85};
86
87union bfi_rport_h2i_msg_u {
88 struct bfi_msg_s *msg;
89 struct bfi_rport_create_req_s *create_req;
90 struct bfi_rport_delete_req_s *delete_req;
91 struct bfi_rport_speed_req_s *speed_req;
92};
93
94union bfi_rport_i2h_msg_u {
95 struct bfi_msg_s *msg;
96 struct bfi_rport_create_rsp_s *create_rsp;
97 struct bfi_rport_delete_rsp_s *delete_rsp;
98 struct bfi_rport_qos_scn_s *qos_scn_evt;
99};
100
101#pragma pack()
102
103#endif /* __BFI_RPORT_H__ */
104
diff --git a/drivers/scsi/bfa/include/bfi/bfi_uf.h b/drivers/scsi/bfa/include/bfi/bfi_uf.h
new file mode 100644
index 000000000000..f328a9e7e622
--- /dev/null
+++ b/drivers/scsi/bfa/include/bfi/bfi_uf.h
@@ -0,0 +1,52 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFI_UF_H__
19#define __BFI_UF_H__
20
21#include "bfi.h"
22
23#pragma pack(1)
24
25enum bfi_uf_h2i {
26 BFI_UF_H2I_BUF_POST = 1,
27};
28
29enum bfi_uf_i2h {
30 BFI_UF_I2H_FRM_RCVD = BFA_I2HM(1),
31};
32
33#define BFA_UF_MAX_SGES 2
34
35struct bfi_uf_buf_post_s {
36 struct bfi_mhdr_s mh; /* Common msg header */
37 u16 buf_tag; /* buffer tag */
38 u16 buf_len; /* total buffer length */
39 struct bfi_sge_s sge[BFA_UF_MAX_SGES]; /* buffer DMA SGEs */
40};
41
42struct bfi_uf_frm_rcvd_s {
43 struct bfi_mhdr_s mh; /* Common msg header */
44 u16 buf_tag; /* buffer tag */
45 u16 rsvd;
46 u16 frm_len; /* received frame length */
47 u16 xfr_len; /* tranferred length */
48};
49
50#pragma pack()
51
52#endif /* __BFI_UF_H__ */
diff --git a/drivers/scsi/bfa/include/cna/bfa_cna_trcmod.h b/drivers/scsi/bfa/include/cna/bfa_cna_trcmod.h
new file mode 100644
index 000000000000..43ba7064e81a
--- /dev/null
+++ b/drivers/scsi/bfa/include/cna/bfa_cna_trcmod.h
@@ -0,0 +1,36 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * bfa_cna_trcmod.h CNA trace modules
20 */
21
22#ifndef __BFA_CNA_TRCMOD_H__
23#define __BFA_CNA_TRCMOD_H__
24
25#include <cs/bfa_trc.h>
26
27/*
28 * !!! Only append to the enums defined here to avoid any versioning
29 * !!! needed between trace utility and driver version
30 */
31enum {
32 BFA_TRC_CNA_CEE = 1,
33 BFA_TRC_CNA_PORT = 2,
34};
35
36#endif /* __BFA_CNA_TRCMOD_H__ */
diff --git a/drivers/scsi/bfa/include/cna/cee/bfa_cee.h b/drivers/scsi/bfa/include/cna/cee/bfa_cee.h
new file mode 100644
index 000000000000..77f297f68046
--- /dev/null
+++ b/drivers/scsi/bfa/include/cna/cee/bfa_cee.h
@@ -0,0 +1,77 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFA_CEE_H__
19#define __BFA_CEE_H__
20
21#include <defs/bfa_defs_cee.h>
22#include <bfa_ioc.h>
23#include <cs/bfa_trc.h>
24#include <cs/bfa_log.h>
25
26typedef void (*bfa_cee_get_attr_cbfn_t) (void *dev, bfa_status_t status);
27typedef void (*bfa_cee_get_stats_cbfn_t) (void *dev, bfa_status_t status);
28typedef void (*bfa_cee_reset_stats_cbfn_t) (void *dev, bfa_status_t status);
29typedef void (*bfa_cee_hbfail_cbfn_t) (void *dev, bfa_status_t status);
30
31struct bfa_cee_cbfn_s {
32 bfa_cee_get_attr_cbfn_t get_attr_cbfn;
33 void *get_attr_cbarg;
34 bfa_cee_get_stats_cbfn_t get_stats_cbfn;
35 void *get_stats_cbarg;
36 bfa_cee_reset_stats_cbfn_t reset_stats_cbfn;
37 void *reset_stats_cbarg;
38};
39
40struct bfa_cee_s {
41 void *dev;
42 bfa_boolean_t get_attr_pending;
43 bfa_boolean_t get_stats_pending;
44 bfa_boolean_t reset_stats_pending;
45 bfa_status_t get_attr_status;
46 bfa_status_t get_stats_status;
47 bfa_status_t reset_stats_status;
48 struct bfa_cee_cbfn_s cbfn;
49 struct bfa_ioc_hbfail_notify_s hbfail;
50 struct bfa_trc_mod_s *trcmod;
51 struct bfa_log_mod_s *logmod;
52 struct bfa_cee_attr_s *attr;
53 struct bfa_cee_stats_s *stats;
54 struct bfa_dma_s attr_dma;
55 struct bfa_dma_s stats_dma;
56 struct bfa_ioc_s *ioc;
57 struct bfa_mbox_cmd_s get_cfg_mb;
58 struct bfa_mbox_cmd_s get_stats_mb;
59 struct bfa_mbox_cmd_s reset_stats_mb;
60};
61
62u32 bfa_cee_meminfo(void);
63void bfa_cee_mem_claim(struct bfa_cee_s *cee, u8 *dma_kva,
64 u64 dma_pa);
65void bfa_cee_attach(struct bfa_cee_s *cee, struct bfa_ioc_s *ioc, void *dev,
66 struct bfa_trc_mod_s *trcmod,
67 struct bfa_log_mod_s *logmod);
68void bfa_cee_detach(struct bfa_cee_s *cee);
69bfa_status_t bfa_cee_get_attr(struct bfa_cee_s *cee,
70 struct bfa_cee_attr_s *attr,
71 bfa_cee_get_attr_cbfn_t cbfn, void *cbarg);
72bfa_status_t bfa_cee_get_stats(struct bfa_cee_s *cee,
73 struct bfa_cee_stats_s *stats,
74 bfa_cee_get_stats_cbfn_t cbfn, void *cbarg);
75bfa_status_t bfa_cee_reset_stats(struct bfa_cee_s *cee,
76 bfa_cee_reset_stats_cbfn_t cbfn, void *cbarg);
77#endif /* __BFA_CEE_H__ */
diff --git a/drivers/scsi/bfa/include/cna/port/bfa_port.h b/drivers/scsi/bfa/include/cna/port/bfa_port.h
new file mode 100644
index 000000000000..7cbf17d3141b
--- /dev/null
+++ b/drivers/scsi/bfa/include/cna/port/bfa_port.h
@@ -0,0 +1,69 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFA_PORT_H__
19#define __BFA_PORT_H__
20
21#include <defs/bfa_defs_port.h>
22#include <bfa_ioc.h>
23#include <cs/bfa_trc.h>
24#include <cs/bfa_log.h>
25
26typedef void (*bfa_port_stats_cbfn_t) (void *dev, bfa_status_t status);
27typedef void (*bfa_port_endis_cbfn_t) (void *dev, bfa_status_t status);
28
29struct bfa_port_s {
30 void *dev;
31 struct bfa_ioc_s *ioc;
32 struct bfa_trc_mod_s *trcmod;
33 struct bfa_log_mod_s *logmod;
34 u32 msgtag;
35 bfa_boolean_t stats_busy;
36 struct bfa_mbox_cmd_s stats_mb;
37 bfa_port_stats_cbfn_t stats_cbfn;
38 void *stats_cbarg;
39 bfa_status_t stats_status;
40 union bfa_pport_stats_u *stats;
41 struct bfa_dma_s stats_dma;
42 bfa_boolean_t endis_pending;
43 struct bfa_mbox_cmd_s endis_mb;
44 bfa_port_endis_cbfn_t endis_cbfn;
45 void *endis_cbarg;
46 bfa_status_t endis_status;
47 struct bfa_ioc_hbfail_notify_s hbfail;
48};
49
50void bfa_port_attach(struct bfa_port_s *port, struct bfa_ioc_s *ioc,
51 void *dev, struct bfa_trc_mod_s *trcmod,
52 struct bfa_log_mod_s *logmod);
53void bfa_port_detach(struct bfa_port_s *port);
54void bfa_port_hbfail(void *arg);
55
56bfa_status_t bfa_port_get_stats(struct bfa_port_s *port,
57 union bfa_pport_stats_u *stats,
58 bfa_port_stats_cbfn_t cbfn, void *cbarg);
59bfa_status_t bfa_port_clear_stats(struct bfa_port_s *port,
60 bfa_port_stats_cbfn_t cbfn, void *cbarg);
61bfa_status_t bfa_port_enable(struct bfa_port_s *port,
62 bfa_port_endis_cbfn_t cbfn, void *cbarg);
63bfa_status_t bfa_port_disable(struct bfa_port_s *port,
64 bfa_port_endis_cbfn_t cbfn, void *cbarg);
65u32 bfa_port_meminfo(void);
66void bfa_port_mem_claim(struct bfa_port_s *port, u8 *dma_kva,
67 u64 dma_pa);
68
69#endif /* __BFA_PORT_H__ */
diff --git a/drivers/scsi/bfa/include/cna/pstats/ethport_defs.h b/drivers/scsi/bfa/include/cna/pstats/ethport_defs.h
new file mode 100644
index 000000000000..1563ee512218
--- /dev/null
+++ b/drivers/scsi/bfa/include/cna/pstats/ethport_defs.h
@@ -0,0 +1,36 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved.
4 *
5 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License (GPL) Version 2 as
9 * published by the Free Software Foundation
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 */
16
17#ifndef __ETHPORT_DEFS_H__
18#define __ETHPORT_DEFS_H__
19
20struct bnad_drv_stats {
21 u64 netif_queue_stop;
22 u64 netif_queue_wakeup;
23 u64 tso4;
24 u64 tso6;
25 u64 tso_err;
26 u64 tcpcsum_offload;
27 u64 udpcsum_offload;
28 u64 csum_help;
29 u64 csum_help_err;
30
31 u64 hw_stats_updates;
32 u64 netif_rx_schedule;
33 u64 netif_rx_complete;
34 u64 netif_rx_dropped;
35};
36#endif
diff --git a/drivers/scsi/bfa/include/cna/pstats/phyport_defs.h b/drivers/scsi/bfa/include/cna/pstats/phyport_defs.h
new file mode 100644
index 000000000000..eb7548030d0f
--- /dev/null
+++ b/drivers/scsi/bfa/include/cna/pstats/phyport_defs.h
@@ -0,0 +1,218 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved.
4 *
5 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License (GPL) Version 2 as
9 * published by the Free Software Foundation
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 */
16
17#ifndef __PHYPORT_DEFS_H__
18#define __PHYPORT_DEFS_H__
19
20#define BNA_TXF_ID_MAX 64
21#define BNA_RXF_ID_MAX 64
22
23/*
24 * Statistics
25 */
26
27/*
28 * TxF Frame Statistics
29 */
30struct bna_stats_txf {
31 u64 ucast_octets;
32 u64 ucast;
33 u64 ucast_vlan;
34
35 u64 mcast_octets;
36 u64 mcast;
37 u64 mcast_vlan;
38
39 u64 bcast_octets;
40 u64 bcast;
41 u64 bcast_vlan;
42
43 u64 errors;
44 u64 filter_vlan; /* frames filtered due to VLAN */
45 u64 filter_mac_sa; /* frames filtered due to SA check */
46};
47
48/*
49 * RxF Frame Statistics
50 */
51struct bna_stats_rxf {
52 u64 ucast_octets;
53 u64 ucast;
54 u64 ucast_vlan;
55
56 u64 mcast_octets;
57 u64 mcast;
58 u64 mcast_vlan;
59
60 u64 bcast_octets;
61 u64 bcast;
62 u64 bcast_vlan;
63 u64 frame_drops;
64};
65
66/*
67 * FC Tx Frame Statistics
68 */
69struct bna_stats_fc_tx {
70 u64 txf_ucast_octets;
71 u64 txf_ucast;
72 u64 txf_ucast_vlan;
73
74 u64 txf_mcast_octets;
75 u64 txf_mcast;
76 u64 txf_mcast_vlan;
77
78 u64 txf_bcast_octets;
79 u64 txf_bcast;
80 u64 txf_bcast_vlan;
81
82 u64 txf_parity_errors;
83 u64 txf_timeout;
84 u64 txf_fid_parity_errors;
85};
86
87/*
88 * FC Rx Frame Statistics
89 */
90struct bna_stats_fc_rx {
91 u64 rxf_ucast_octets;
92 u64 rxf_ucast;
93 u64 rxf_ucast_vlan;
94
95 u64 rxf_mcast_octets;
96 u64 rxf_mcast;
97 u64 rxf_mcast_vlan;
98
99 u64 rxf_bcast_octets;
100 u64 rxf_bcast;
101 u64 rxf_bcast_vlan;
102};
103
104/*
105 * RAD Frame Statistics
106 */
107struct cna_stats_rad {
108 u64 rx_frames;
109 u64 rx_octets;
110 u64 rx_vlan_frames;
111
112 u64 rx_ucast;
113 u64 rx_ucast_octets;
114 u64 rx_ucast_vlan;
115
116 u64 rx_mcast;
117 u64 rx_mcast_octets;
118 u64 rx_mcast_vlan;
119
120 u64 rx_bcast;
121 u64 rx_bcast_octets;
122 u64 rx_bcast_vlan;
123
124 u64 rx_drops;
125};
126
127/*
128 * BPC Tx Registers
129 */
130struct cna_stats_bpc_tx {
131 u64 tx_pause[8];
132 u64 tx_zero_pause[8]; /* Pause cancellation */
133 u64 tx_first_pause[8]; /* Pause initiation rather
134 *than retention */
135};
136
137/*
138 * BPC Rx Registers
139 */
140struct cna_stats_bpc_rx {
141 u64 rx_pause[8];
142 u64 rx_zero_pause[8]; /* Pause cancellation */
143 u64 rx_first_pause[8]; /* Pause initiation rather
144 *than retention */
145};
146
147/*
148 * MAC Rx Statistics
149 */
150struct cna_stats_mac_rx {
151 u64 frame_64; /* both rx and tx counter */
152 u64 frame_65_127; /* both rx and tx counter */
153 u64 frame_128_255; /* both rx and tx counter */
154 u64 frame_256_511; /* both rx and tx counter */
155 u64 frame_512_1023; /* both rx and tx counter */
156 u64 frame_1024_1518; /* both rx and tx counter */
157 u64 frame_1518_1522; /* both rx and tx counter */
158 u64 rx_bytes;
159 u64 rx_packets;
160 u64 rx_fcs_error;
161 u64 rx_multicast;
162 u64 rx_broadcast;
163 u64 rx_control_frames;
164 u64 rx_pause;
165 u64 rx_unknown_opcode;
166 u64 rx_alignment_error;
167 u64 rx_frame_length_error;
168 u64 rx_code_error;
169 u64 rx_carrier_sense_error;
170 u64 rx_undersize;
171 u64 rx_oversize;
172 u64 rx_fragments;
173 u64 rx_jabber;
174 u64 rx_drop;
175};
176
177/*
178 * MAC Tx Statistics
179 */
180struct cna_stats_mac_tx {
181 u64 tx_bytes;
182 u64 tx_packets;
183 u64 tx_multicast;
184 u64 tx_broadcast;
185 u64 tx_pause;
186 u64 tx_deferral;
187 u64 tx_excessive_deferral;
188 u64 tx_single_collision;
189 u64 tx_muliple_collision;
190 u64 tx_late_collision;
191 u64 tx_excessive_collision;
192 u64 tx_total_collision;
193 u64 tx_pause_honored;
194 u64 tx_drop;
195 u64 tx_jabber;
196 u64 tx_fcs_error;
197 u64 tx_control_frame;
198 u64 tx_oversize;
199 u64 tx_undersize;
200 u64 tx_fragments;
201};
202
203/*
204 * Complete statistics
205 */
206struct bna_stats {
207 struct cna_stats_mac_rx mac_rx_stats;
208 struct cna_stats_bpc_rx bpc_rx_stats;
209 struct cna_stats_rad rad_stats;
210 struct bna_stats_fc_rx fc_rx_stats;
211 struct cna_stats_mac_tx mac_tx_stats;
212 struct cna_stats_bpc_tx bpc_tx_stats;
213 struct bna_stats_fc_tx fc_tx_stats;
214 struct bna_stats_rxf rxf_stats[BNA_TXF_ID_MAX];
215 struct bna_stats_txf txf_stats[BNA_RXF_ID_MAX];
216};
217
218#endif
diff --git a/drivers/scsi/bfa/include/cs/bfa_checksum.h b/drivers/scsi/bfa/include/cs/bfa_checksum.h
new file mode 100644
index 000000000000..af8c1d533ba8
--- /dev/null
+++ b/drivers/scsi/bfa/include/cs/bfa_checksum.h
@@ -0,0 +1,60 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * bfa_checksum.h BFA checksum utilities
20 */
21
22#ifndef __BFA_CHECKSUM_H__
23#define __BFA_CHECKSUM_H__
24
25static inline u32
26bfa_checksum_u32(u32 *buf, int sz)
27{
28 int i, m = sz >> 2;
29 u32 sum = 0;
30
31 for (i = 0; i < m; i++)
32 sum ^= buf[i];
33
34 return (sum);
35}
36
37static inline u16
38bfa_checksum_u16(u16 *buf, int sz)
39{
40 int i, m = sz >> 1;
41 u16 sum = 0;
42
43 for (i = 0; i < m; i++)
44 sum ^= buf[i];
45
46 return (sum);
47}
48
49static inline u8
50bfa_checksum_u8(u8 *buf, int sz)
51{
52 int i;
53 u8 sum = 0;
54
55 for (i = 0; i < sz; i++)
56 sum ^= buf[i];
57
58 return (sum);
59}
60#endif
diff --git a/drivers/scsi/bfa/include/cs/bfa_debug.h b/drivers/scsi/bfa/include/cs/bfa_debug.h
new file mode 100644
index 000000000000..441be86b1b0f
--- /dev/null
+++ b/drivers/scsi/bfa/include/cs/bfa_debug.h
@@ -0,0 +1,44 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * bfa_debug.h BFA debug interfaces
20 */
21
22#ifndef __BFA_DEBUG_H__
23#define __BFA_DEBUG_H__
24
25#define bfa_assert(__cond) do { \
26 if (!(__cond)) \
27 bfa_panic(__LINE__, __FILE__, #__cond); \
28} while (0)
29
30#define bfa_sm_fault(__mod, __event) do { \
31 bfa_sm_panic((__mod)->logm, __LINE__, __FILE__, __event); \
32} while (0)
33
34#ifndef BFA_PERF_BUILD
35#define bfa_assert_fp(__cond) bfa_assert(__cond)
36#else
37#define bfa_assert_fp(__cond)
38#endif
39
40struct bfa_log_mod_s;
41void bfa_panic(int line, char *file, char *panicstr);
42void bfa_sm_panic(struct bfa_log_mod_s *logm, int line, char *file, int event);
43
44#endif /* __BFA_DEBUG_H__ */
diff --git a/drivers/scsi/bfa/include/cs/bfa_log.h b/drivers/scsi/bfa/include/cs/bfa_log.h
new file mode 100644
index 000000000000..761cbe22130a
--- /dev/null
+++ b/drivers/scsi/bfa/include/cs/bfa_log.h
@@ -0,0 +1,184 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * bfa_log.h BFA log library data structure and function definition
20 */
21
22#ifndef __BFA_LOG_H__
23#define __BFA_LOG_H__
24
25#include <bfa_os_inc.h>
26#include <defs/bfa_defs_status.h>
27#include <defs/bfa_defs_aen.h>
28
29/*
30 * BFA log module definition
31 *
32 * To create a new module id:
33 * Add a #define at the end of the list below. Select a value for your
34 * definition so that it is one (1) greater than the previous
35 * definition. Modify the definition of BFA_LOG_MODULE_ID_MAX to become
36 * your new definition.
37 * Should have no gaps in between the values because this is used in arrays.
38 * IMPORTANT: AEN_IDs must be at the begining, otherwise update bfa_defs_aen.h
39 */
40
41enum bfa_log_module_id {
42 BFA_LOG_UNUSED_ID = 0,
43
44 /* AEN defs begin */
45 BFA_LOG_AEN_MIN = BFA_LOG_UNUSED_ID,
46
47 BFA_LOG_AEN_ID_ADAPTER = BFA_LOG_AEN_MIN + BFA_AEN_CAT_ADAPTER,/* 1 */
48 BFA_LOG_AEN_ID_PORT = BFA_LOG_AEN_MIN + BFA_AEN_CAT_PORT, /* 2 */
49 BFA_LOG_AEN_ID_LPORT = BFA_LOG_AEN_MIN + BFA_AEN_CAT_LPORT, /* 3 */
50 BFA_LOG_AEN_ID_RPORT = BFA_LOG_AEN_MIN + BFA_AEN_CAT_RPORT, /* 4 */
51 BFA_LOG_AEN_ID_ITNIM = BFA_LOG_AEN_MIN + BFA_AEN_CAT_ITNIM, /* 5 */
52 BFA_LOG_AEN_ID_TIN = BFA_LOG_AEN_MIN + BFA_AEN_CAT_TIN, /* 6 */
53 BFA_LOG_AEN_ID_IPFC = BFA_LOG_AEN_MIN + BFA_AEN_CAT_IPFC, /* 7 */
54 BFA_LOG_AEN_ID_AUDIT = BFA_LOG_AEN_MIN + BFA_AEN_CAT_AUDIT, /* 8 */
55 BFA_LOG_AEN_ID_IOC = BFA_LOG_AEN_MIN + BFA_AEN_CAT_IOC, /* 9 */
56 BFA_LOG_AEN_ID_ETHPORT = BFA_LOG_AEN_MIN + BFA_AEN_CAT_ETHPORT,/* 10 */
57
58 BFA_LOG_AEN_MAX = BFA_LOG_AEN_ID_ETHPORT,
59 /* AEN defs end */
60
61 BFA_LOG_MODULE_ID_MIN = BFA_LOG_AEN_MAX,
62
63 BFA_LOG_FW_ID = BFA_LOG_MODULE_ID_MIN + 1,
64 BFA_LOG_HAL_ID = BFA_LOG_MODULE_ID_MIN + 2,
65 BFA_LOG_FCS_ID = BFA_LOG_MODULE_ID_MIN + 3,
66 BFA_LOG_WDRV_ID = BFA_LOG_MODULE_ID_MIN + 4,
67 BFA_LOG_LINUX_ID = BFA_LOG_MODULE_ID_MIN + 5,
68 BFA_LOG_SOLARIS_ID = BFA_LOG_MODULE_ID_MIN + 6,
69
70 BFA_LOG_MODULE_ID_MAX = BFA_LOG_SOLARIS_ID,
71
72 /* Not part of any arrays */
73 BFA_LOG_MODULE_ID_ALL = BFA_LOG_MODULE_ID_MAX + 1,
74 BFA_LOG_AEN_ALL = BFA_LOG_MODULE_ID_MAX + 2,
75 BFA_LOG_DRV_ALL = BFA_LOG_MODULE_ID_MAX + 3,
76};
77
78/*
79 * BFA log catalog name
80 */
81#define BFA_LOG_CAT_NAME "BFA"
82
83/*
84 * bfa log severity values
85 */
86enum bfa_log_severity {
87 BFA_LOG_INVALID = 0,
88 BFA_LOG_CRITICAL = 1,
89 BFA_LOG_ERROR = 2,
90 BFA_LOG_WARNING = 3,
91 BFA_LOG_INFO = 4,
92 BFA_LOG_NONE = 5,
93 BFA_LOG_LEVEL_MAX = BFA_LOG_NONE
94};
95
96#define BFA_LOG_MODID_OFFSET 16
97
98
99struct bfa_log_msgdef_s {
100 u32 msg_id; /* message id */
101 int attributes; /* attributes */
102 int severity; /* severity level */
103 char *msg_value;
104 /* msg string */
105 char *message;
106 /* msg format string */
107 int arg_type; /* argument type */
108 int arg_num; /* number of argument */
109};
110
111/*
112 * supported argument type
113 */
114enum bfa_log_arg_type {
115 BFA_LOG_S = 0, /* string */
116 BFA_LOG_D, /* decimal */
117 BFA_LOG_I, /* integer */
118 BFA_LOG_O, /* oct number */
119 BFA_LOG_U, /* unsigned integer */
120 BFA_LOG_X, /* hex number */
121 BFA_LOG_F, /* floating */
122 BFA_LOG_C, /* character */
123 BFA_LOG_L, /* double */
124 BFA_LOG_P /* pointer */
125};
126
127#define BFA_LOG_ARG_TYPE 2
128#define BFA_LOG_ARG0 (0 * BFA_LOG_ARG_TYPE)
129#define BFA_LOG_ARG1 (1 * BFA_LOG_ARG_TYPE)
130#define BFA_LOG_ARG2 (2 * BFA_LOG_ARG_TYPE)
131#define BFA_LOG_ARG3 (3 * BFA_LOG_ARG_TYPE)
132
133#define BFA_LOG_GET_MOD_ID(msgid) ((msgid >> BFA_LOG_MODID_OFFSET) & 0xff)
134#define BFA_LOG_GET_MSG_IDX(msgid) (msgid & 0xffff)
135#define BFA_LOG_GET_MSG_ID(msgdef) ((msgdef)->msg_id)
136#define BFA_LOG_GET_MSG_FMT_STRING(msgdef) ((msgdef)->message)
137#define BFA_LOG_GET_SEVERITY(msgdef) ((msgdef)->severity)
138
139/*
140 * Event attributes
141 */
142#define BFA_LOG_ATTR_NONE 0
143#define BFA_LOG_ATTR_AUDIT 1
144#define BFA_LOG_ATTR_LOG 2
145#define BFA_LOG_ATTR_FFDC 4
146
147#define BFA_LOG_CREATE_ID(msw, lsw) \
148 (((u32)msw << BFA_LOG_MODID_OFFSET) | lsw)
149
150struct bfa_log_mod_s;
151
152/**
153 * callback function
154 */
155typedef void (*bfa_log_cb_t)(struct bfa_log_mod_s *log_mod, u32 msg_id,
156 const char *format, ...);
157
158
159struct bfa_log_mod_s {
160 char instance_info[16]; /* instance info */
161 int log_level[BFA_LOG_MODULE_ID_MAX + 1];
162 /* log level for modules */
163 bfa_log_cb_t cbfn; /* callback function */
164};
165
166extern int bfa_log_init(struct bfa_log_mod_s *log_mod,
167 char *instance_name, bfa_log_cb_t cbfn);
168extern int bfa_log(struct bfa_log_mod_s *log_mod, u32 msg_id, ...);
169extern bfa_status_t bfa_log_set_level(struct bfa_log_mod_s *log_mod,
170 int mod_id, enum bfa_log_severity log_level);
171extern bfa_status_t bfa_log_set_level_all(struct bfa_log_mod_s *log_mod,
172 enum bfa_log_severity log_level);
173extern bfa_status_t bfa_log_set_level_aen(struct bfa_log_mod_s *log_mod,
174 enum bfa_log_severity log_level);
175extern enum bfa_log_severity bfa_log_get_level(struct bfa_log_mod_s *log_mod,
176 int mod_id);
177extern enum bfa_log_severity bfa_log_get_msg_level(
178 struct bfa_log_mod_s *log_mod, u32 msg_id);
179/*
180 * array of messages generated from xml files
181 */
182extern struct bfa_log_msgdef_s bfa_log_msg_array[];
183
184#endif
diff --git a/drivers/scsi/bfa/include/cs/bfa_perf.h b/drivers/scsi/bfa/include/cs/bfa_perf.h
new file mode 100644
index 000000000000..45aa5f978ff5
--- /dev/null
+++ b/drivers/scsi/bfa/include/cs/bfa_perf.h
@@ -0,0 +1,34 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17#ifndef __BFAD_PERF_H__
18#define __BFAD_PERF_H__
19
20#ifdef BFAD_PERF_BUILD
21
22#undef bfa_trc
23#undef bfa_trc32
24#undef bfa_assert
25#undef BFA_TRC_FILE
26
27#define bfa_trc(_trcp, _data)
28#define bfa_trc32(_trcp, _data)
29#define bfa_assert(__cond)
30#define BFA_TRC_FILE(__mod, __submod)
31
32#endif
33
34#endif /* __BFAD_PERF_H__ */
diff --git a/drivers/scsi/bfa/include/cs/bfa_plog.h b/drivers/scsi/bfa/include/cs/bfa_plog.h
new file mode 100644
index 000000000000..670f86e5fc6e
--- /dev/null
+++ b/drivers/scsi/bfa/include/cs/bfa_plog.h
@@ -0,0 +1,162 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17#ifndef __BFA_PORTLOG_H__
18#define __BFA_PORTLOG_H__
19
20#include "protocol/fc.h"
21#include <defs/bfa_defs_types.h>
22
23#define BFA_PL_NLOG_ENTS 256
24#define BFA_PL_LOG_REC_INCR(_x) ((_x)++, (_x) %= BFA_PL_NLOG_ENTS)
25
26#define BFA_PL_STRING_LOG_SZ 32 /* number of chars in string log */
27#define BFA_PL_INT_LOG_SZ 8 /* number of integers in the integer log */
28
29enum bfa_plog_log_type {
30 BFA_PL_LOG_TYPE_INVALID = 0,
31 BFA_PL_LOG_TYPE_INT = 1,
32 BFA_PL_LOG_TYPE_STRING = 2,
33};
34
35/*
36 * the (fixed size) record format for each entry in the portlog
37 */
38struct bfa_plog_rec_s {
39 u32 tv; /* Filled by the portlog driver when the *
40 * entry is added to the circular log. */
41 u8 port; /* Source port that logged this entry. CM
42 * entities will use 0xFF */
43 u8 mid; /* Integer value to be used by all entities *
44 * while logging. The module id to string *
45 * conversion will be done by BFAL. See
46 * enum bfa_plog_mid */
47 u8 eid; /* indicates Rx, Tx, IOCTL, etc. See
48 * enum bfa_plog_eid */
49 u8 log_type; /* indicates string log or integer log.
50 * see bfa_plog_log_type_t */
51 u8 log_num_ints;
52 /*
53 * interpreted only if log_type is INT_LOG. indicates number of
54 * integers in the int_log[] (0-PL_INT_LOG_SZ).
55 */
56 u8 rsvd;
57 u16 misc; /* can be used to indicate fc frame length,
58 *etc.. */
59 union {
60 char string_log[BFA_PL_STRING_LOG_SZ];
61 u32 int_log[BFA_PL_INT_LOG_SZ];
62 } log_entry;
63
64};
65
66/*
67 * the following #defines will be used by the logging entities to indicate
68 * their module id. BFAL will convert the integer value to string format
69 *
70* process to be used while changing the following #defines:
71 * - Always add new entries at the end
72 * - define corresponding string in BFAL
73 * - Do not remove any entry or rearrange the order.
74 */
75enum bfa_plog_mid {
76 BFA_PL_MID_INVALID = 0,
77 BFA_PL_MID_DEBUG = 1,
78 BFA_PL_MID_DRVR = 2,
79 BFA_PL_MID_HAL = 3,
80 BFA_PL_MID_HAL_FCXP = 4,
81 BFA_PL_MID_HAL_UF = 5,
82 BFA_PL_MID_FCS = 6,
83 BFA_PL_MID_MAX = 7
84};
85
86#define BFA_PL_MID_STRLEN 8
87struct bfa_plog_mid_strings_s {
88 char m_str[BFA_PL_MID_STRLEN];
89};
90
91/*
92 * the following #defines will be used by the logging entities to indicate
93 * their event type. BFAL will convert the integer value to string format
94 *
95* process to be used while changing the following #defines:
96 * - Always add new entries at the end
97 * - define corresponding string in BFAL
98 * - Do not remove any entry or rearrange the order.
99 */
100enum bfa_plog_eid {
101 BFA_PL_EID_INVALID = 0,
102 BFA_PL_EID_IOC_DISABLE = 1,
103 BFA_PL_EID_IOC_ENABLE = 2,
104 BFA_PL_EID_PORT_DISABLE = 3,
105 BFA_PL_EID_PORT_ENABLE = 4,
106 BFA_PL_EID_PORT_ST_CHANGE = 5,
107 BFA_PL_EID_TX = 6,
108 BFA_PL_EID_TX_ACK1 = 7,
109 BFA_PL_EID_TX_RJT = 8,
110 BFA_PL_EID_TX_BSY = 9,
111 BFA_PL_EID_RX = 10,
112 BFA_PL_EID_RX_ACK1 = 11,
113 BFA_PL_EID_RX_RJT = 12,
114 BFA_PL_EID_RX_BSY = 13,
115 BFA_PL_EID_CT_IN = 14,
116 BFA_PL_EID_CT_OUT = 15,
117 BFA_PL_EID_DRIVER_START = 16,
118 BFA_PL_EID_RSCN = 17,
119 BFA_PL_EID_DEBUG = 18,
120 BFA_PL_EID_MISC = 19,
121 BFA_PL_EID_MAX = 20
122};
123
124#define BFA_PL_ENAME_STRLEN 8
125struct bfa_plog_eid_strings_s {
126 char e_str[BFA_PL_ENAME_STRLEN];
127};
128
129#define BFA_PL_SIG_LEN 8
130#define BFA_PL_SIG_STR "12pl123"
131
132/*
133 * per port circular log buffer
134 */
135struct bfa_plog_s {
136 char plog_sig[BFA_PL_SIG_LEN]; /* Start signature */
137 u8 plog_enabled;
138 u8 rsvd[7];
139 u32 ticks;
140 u16 head;
141 u16 tail;
142 struct bfa_plog_rec_s plog_recs[BFA_PL_NLOG_ENTS];
143};
144
145void bfa_plog_init(struct bfa_plog_s *plog);
146void bfa_plog_str(struct bfa_plog_s *plog, enum bfa_plog_mid mid,
147 enum bfa_plog_eid event, u16 misc, char *log_str);
148void bfa_plog_intarr(struct bfa_plog_s *plog, enum bfa_plog_mid mid,
149 enum bfa_plog_eid event, u16 misc,
150 u32 *intarr, u32 num_ints);
151void bfa_plog_fchdr(struct bfa_plog_s *plog, enum bfa_plog_mid mid,
152 enum bfa_plog_eid event, u16 misc,
153 struct fchs_s *fchdr);
154void bfa_plog_fchdr_and_pl(struct bfa_plog_s *plog, enum bfa_plog_mid mid,
155 enum bfa_plog_eid event, u16 misc,
156 struct fchs_s *fchdr, u32 pld_w0);
157void bfa_plog_clear(struct bfa_plog_s *plog);
158void bfa_plog_enable(struct bfa_plog_s *plog);
159void bfa_plog_disable(struct bfa_plog_s *plog);
160bfa_boolean_t bfa_plog_get_setting(struct bfa_plog_s *plog);
161
162#endif /* __BFA_PORTLOG_H__ */
diff --git a/drivers/scsi/bfa/include/cs/bfa_q.h b/drivers/scsi/bfa/include/cs/bfa_q.h
new file mode 100644
index 000000000000..ea895facedbc
--- /dev/null
+++ b/drivers/scsi/bfa/include/cs/bfa_q.h
@@ -0,0 +1,81 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * bfa_q.h Circular queue definitions.
20 */
21
22#ifndef __BFA_Q_H__
23#define __BFA_Q_H__
24
25#define bfa_q_first(_q) ((void *)(((struct list_head *) (_q))->next))
26#define bfa_q_next(_qe) (((struct list_head *) (_qe))->next)
27#define bfa_q_prev(_qe) (((struct list_head *) (_qe))->prev)
28
29/*
30 * bfa_q_qe_init - to initialize a queue element
31 */
32#define bfa_q_qe_init(_qe) { \
33 bfa_q_next(_qe) = (struct list_head *) NULL; \
34 bfa_q_prev(_qe) = (struct list_head *) NULL; \
35}
36
37/*
38 * bfa_q_deq - dequeue an element from head of the queue
39 */
40#define bfa_q_deq(_q, _qe) { \
41 if (!list_empty(_q)) { \
42 (*((struct list_head **) (_qe))) = bfa_q_next(_q); \
43 bfa_q_prev(bfa_q_next(*((struct list_head **) _qe))) = \
44 (struct list_head *) (_q); \
45 bfa_q_next(_q) = bfa_q_next(*((struct list_head **) _qe)); \
46 BFA_Q_DBG_INIT(*((struct list_head **) _qe)); \
47 } else { \
48 *((struct list_head **) (_qe)) = (struct list_head *) NULL; \
49 } \
50}
51
52/*
53 * bfa_q_deq_tail - dequeue an element from tail of the queue
54 */
55#define bfa_q_deq_tail(_q, _qe) { \
56 if (!list_empty(_q)) { \
57 *((struct list_head **) (_qe)) = bfa_q_prev(_q); \
58 bfa_q_next(bfa_q_prev(*((struct list_head **) _qe))) = \
59 (struct list_head *) (_q); \
60 bfa_q_prev(_q) = bfa_q_prev(*(struct list_head **) _qe); \
61 BFA_Q_DBG_INIT(*((struct list_head **) _qe)); \
62 } else { \
63 *((struct list_head **) (_qe)) = (struct list_head *) NULL; \
64 } \
65}
66
67/*
68 * #ifdef BFA_DEBUG (Using bfa_assert to check for debug_build is not
69 * consistent across modules)
70 */
71#ifndef BFA_PERF_BUILD
72#define BFA_Q_DBG_INIT(_qe) bfa_q_qe_init(_qe)
73#else
74#define BFA_Q_DBG_INIT(_qe)
75#endif
76
77#define bfa_q_is_on_q(_q, _qe) \
78 bfa_q_is_on_q_func(_q, (struct list_head *)(_qe))
79extern int bfa_q_is_on_q_func(struct list_head *q, struct list_head *qe);
80
81#endif
diff --git a/drivers/scsi/bfa/include/cs/bfa_sm.h b/drivers/scsi/bfa/include/cs/bfa_sm.h
new file mode 100644
index 000000000000..9877066680a6
--- /dev/null
+++ b/drivers/scsi/bfa/include/cs/bfa_sm.h
@@ -0,0 +1,69 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * bfasm.h State machine defines
20 */
21
22#ifndef __BFA_SM_H__
23#define __BFA_SM_H__
24
25typedef void (*bfa_sm_t)(void *sm, int event);
26
27#define bfa_sm_set_state(_sm, _state) (_sm)->sm = (bfa_sm_t)(_state)
28#define bfa_sm_send_event(_sm, _event) (_sm)->sm((_sm), (_event))
29#define bfa_sm_get_state(_sm) ((_sm)->sm)
30#define bfa_sm_cmp_state(_sm, _state) ((_sm)->sm == (bfa_sm_t)(_state))
31
32/**
33 * For converting from state machine function to state encoding.
34 */
35struct bfa_sm_table_s {
36 bfa_sm_t sm; /* state machine function */
37 int state; /* state machine encoding */
38 char *name; /* state name for display */
39};
40#define BFA_SM(_sm) ((bfa_sm_t)(_sm))
41
42int bfa_sm_to_state(struct bfa_sm_table_s *smt, bfa_sm_t sm);
43
44/**
45 * State machine with entry actions.
46 */
47typedef void (*bfa_fsm_t)(void *fsm, int event);
48
49/**
50 * oc - object class eg. bfa_ioc
51 * st - state, eg. reset
52 * otype - object type, eg. struct bfa_ioc_s
53 * etype - object type, eg. enum ioc_event
54 */
55#define bfa_fsm_state_decl(oc, st, otype, etype) \
56 static void oc ## _sm_ ## st(otype * fsm, etype event); \
57 static void oc ## _sm_ ## st ## _entry(otype * fsm)
58
59#define bfa_fsm_set_state(_fsm, _state) do { \
60 (_fsm)->fsm = (bfa_fsm_t)(_state); \
61 _state ## _entry(_fsm); \
62} while (0)
63
64#define bfa_fsm_send_event(_fsm, _event) \
65 (_fsm)->fsm((_fsm), (_event))
66#define bfa_fsm_cmp_state(_fsm, _state) \
67 ((_fsm)->fsm == (bfa_fsm_t)(_state))
68
69#endif
diff --git a/drivers/scsi/bfa/include/cs/bfa_trc.h b/drivers/scsi/bfa/include/cs/bfa_trc.h
new file mode 100644
index 000000000000..3e743928c74c
--- /dev/null
+++ b/drivers/scsi/bfa/include/cs/bfa_trc.h
@@ -0,0 +1,176 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17#ifndef __BFA_TRC_H__
18#define __BFA_TRC_H__
19
20#include <bfa_os_inc.h>
21
22#ifndef BFA_TRC_MAX
23#define BFA_TRC_MAX (4 * 1024)
24#endif
25
26#ifndef BFA_TRC_TS
27#define BFA_TRC_TS(_trcm) ((_trcm)->ticks ++)
28#endif
29
30struct bfa_trc_s {
31#ifdef __BIGENDIAN
32 u16 fileno;
33 u16 line;
34#else
35 u16 line;
36 u16 fileno;
37#endif
38 u32 timestamp;
39 union {
40 struct {
41 u32 rsvd;
42 u32 u32;
43 } u32;
44 u64 u64;
45 } data;
46};
47
48
49struct bfa_trc_mod_s {
50 u32 head;
51 u32 tail;
52 u32 ntrc;
53 u32 stopped;
54 u32 ticks;
55 u32 rsvd[3];
56 struct bfa_trc_s trc[BFA_TRC_MAX];
57};
58
59
60enum {
61 BFA_TRC_FW = 1, /* firmware modules */
62 BFA_TRC_HAL = 2, /* BFA modules */
63 BFA_TRC_FCS = 3, /* BFA FCS modules */
64 BFA_TRC_LDRV = 4, /* Linux driver modules */
65 BFA_TRC_SDRV = 5, /* Solaris driver modules */
66 BFA_TRC_VDRV = 6, /* vmware driver modules */
67 BFA_TRC_WDRV = 7, /* windows driver modules */
68 BFA_TRC_AEN = 8, /* AEN module */
69 BFA_TRC_BIOS = 9, /* bios driver modules */
70 BFA_TRC_EFI = 10, /* EFI driver modules */
71 BNA_TRC_WDRV = 11, /* BNA windows driver modules */
72 BNA_TRC_VDRV = 12, /* BNA vmware driver modules */
73 BNA_TRC_SDRV = 13, /* BNA Solaris driver modules */
74 BNA_TRC_LDRV = 14, /* BNA Linux driver modules */
75 BNA_TRC_HAL = 15, /* BNA modules */
76 BFA_TRC_CNA = 16, /* Common modules */
77 BNA_TRC_IMDRV = 17 /* BNA windows intermediate driver modules */
78};
79#define BFA_TRC_MOD_SH 10
80#define BFA_TRC_MOD(__mod) ((BFA_TRC_ ## __mod) << BFA_TRC_MOD_SH)
81
82/**
83 * Define a new tracing file (module). Module should match one defined above.
84 */
85#define BFA_TRC_FILE(__mod, __submod) \
86 static int __trc_fileno = ((BFA_TRC_ ## __mod ## _ ## __submod) | \
87 BFA_TRC_MOD(__mod))
88
89
90#define bfa_trc32(_trcp, _data) \
91 __bfa_trc((_trcp)->trcmod, __trc_fileno, __LINE__, (u32)_data)
92
93
94#ifndef BFA_BOOT_BUILD
95#define bfa_trc(_trcp, _data) \
96 __bfa_trc((_trcp)->trcmod, __trc_fileno, __LINE__, (u64)_data)
97#else
98void bfa_boot_trc(struct bfa_trc_mod_s *trcmod, u16 fileno,
99 u16 line, u32 data);
100#define bfa_trc(_trcp, _data) \
101 bfa_boot_trc((_trcp)->trcmod, __trc_fileno, __LINE__, (u32)_data)
102#endif
103
104
105static inline void
106bfa_trc_init(struct bfa_trc_mod_s *trcm)
107{
108 trcm->head = trcm->tail = trcm->stopped = 0;
109 trcm->ntrc = BFA_TRC_MAX;
110}
111
112
113static inline void
114bfa_trc_stop(struct bfa_trc_mod_s *trcm)
115{
116 trcm->stopped = 1;
117}
118
119#ifdef FWTRC
120extern void dc_flush(void *data);
121#else
122#define dc_flush(data)
123#endif
124
125
126static inline void
127__bfa_trc(struct bfa_trc_mod_s *trcm, int fileno, int line, u64 data)
128{
129 int tail = trcm->tail;
130 struct bfa_trc_s *trc = &trcm->trc[tail];
131
132 if (trcm->stopped)
133 return;
134
135 trc->fileno = (u16) fileno;
136 trc->line = (u16) line;
137 trc->data.u64 = data;
138 trc->timestamp = BFA_TRC_TS(trcm);
139 dc_flush(trc);
140
141 trcm->tail = (trcm->tail + 1) & (BFA_TRC_MAX - 1);
142 if (trcm->tail == trcm->head)
143 trcm->head = (trcm->head + 1) & (BFA_TRC_MAX - 1);
144 dc_flush(trcm);
145}
146
147
148static inline void
149__bfa_trc32(struct bfa_trc_mod_s *trcm, int fileno, int line, u32 data)
150{
151 int tail = trcm->tail;
152 struct bfa_trc_s *trc = &trcm->trc[tail];
153
154 if (trcm->stopped)
155 return;
156
157 trc->fileno = (u16) fileno;
158 trc->line = (u16) line;
159 trc->data.u32.u32 = data;
160 trc->timestamp = BFA_TRC_TS(trcm);
161 dc_flush(trc);
162
163 trcm->tail = (trcm->tail + 1) & (BFA_TRC_MAX - 1);
164 if (trcm->tail == trcm->head)
165 trcm->head = (trcm->head + 1) & (BFA_TRC_MAX - 1);
166 dc_flush(trcm);
167}
168
169#ifndef BFA_PERF_BUILD
170#define bfa_trc_fp(_trcp, _data) bfa_trc(_trcp, _data)
171#else
172#define bfa_trc_fp(_trcp, _data)
173#endif
174
175#endif /* __BFA_TRC_H__ */
176
diff --git a/drivers/scsi/bfa/include/cs/bfa_wc.h b/drivers/scsi/bfa/include/cs/bfa_wc.h
new file mode 100644
index 000000000000..0460bd4fc7c4
--- /dev/null
+++ b/drivers/scsi/bfa/include/cs/bfa_wc.h
@@ -0,0 +1,68 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * bfa_wc.h Generic wait counter.
20 */
21
22#ifndef __BFA_WC_H__
23#define __BFA_WC_H__
24
25typedef void (*bfa_wc_resume_t) (void *cbarg);
26
27struct bfa_wc_s {
28 bfa_wc_resume_t wc_resume;
29 void *wc_cbarg;
30 int wc_count;
31};
32
33static inline void
34bfa_wc_up(struct bfa_wc_s *wc)
35{
36 wc->wc_count++;
37}
38
39static inline void
40bfa_wc_down(struct bfa_wc_s *wc)
41{
42 wc->wc_count--;
43 if (wc->wc_count == 0)
44 wc->wc_resume(wc->wc_cbarg);
45}
46
47/**
48 * Initialize a waiting counter.
49 */
50static inline void
51bfa_wc_init(struct bfa_wc_s *wc, bfa_wc_resume_t wc_resume, void *wc_cbarg)
52{
53 wc->wc_resume = wc_resume;
54 wc->wc_cbarg = wc_cbarg;
55 wc->wc_count = 0;
56 bfa_wc_up(wc);
57}
58
59/**
60 * Wait for counter to reach zero
61 */
62static inline void
63bfa_wc_wait(struct bfa_wc_s *wc)
64{
65 bfa_wc_down(wc);
66}
67
68#endif
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_adapter.h b/drivers/scsi/bfa/include/defs/bfa_defs_adapter.h
new file mode 100644
index 000000000000..8c208fc8e329
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_adapter.h
@@ -0,0 +1,82 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17#ifndef __BFA_DEFS_ADAPTER_H__
18#define __BFA_DEFS_ADAPTER_H__
19
20#include <protocol/types.h>
21#include <defs/bfa_defs_version.h>
22#include <defs/bfa_defs_mfg.h>
23
24/**
25 * BFA adapter level attributes.
26 */
27enum {
28 BFA_ADAPTER_SERIAL_NUM_LEN = STRSZ(BFA_MFG_SERIALNUM_SIZE),
29 /*
30 *!< adapter serial num length
31 */
32 BFA_ADAPTER_MODEL_NAME_LEN = 16, /* model name length */
33 BFA_ADAPTER_MODEL_DESCR_LEN = 128, /* model description length */
34 BFA_ADAPTER_MFG_NAME_LEN = 8, /* manufacturer name length */
35 BFA_ADAPTER_SYM_NAME_LEN = 64, /* adapter symbolic name length */
36 BFA_ADAPTER_OS_TYPE_LEN = 64, /* adapter os type length */
37};
38
39struct bfa_adapter_attr_s {
40 char manufacturer[BFA_ADAPTER_MFG_NAME_LEN];
41 char serial_num[BFA_ADAPTER_SERIAL_NUM_LEN];
42 u32 rsvd1;
43 char model[BFA_ADAPTER_MODEL_NAME_LEN];
44 char model_descr[BFA_ADAPTER_MODEL_DESCR_LEN];
45 wwn_t pwwn;
46 char node_symname[FC_SYMNAME_MAX];
47 char hw_ver[BFA_VERSION_LEN];
48 char fw_ver[BFA_VERSION_LEN];
49 char optrom_ver[BFA_VERSION_LEN];
50 char os_type[BFA_ADAPTER_OS_TYPE_LEN];
51 struct bfa_mfg_vpd_s vpd;
52 struct mac_s mac;
53
54 u8 nports;
55 u8 max_speed;
56 u8 prototype;
57 char asic_rev;
58
59 u8 pcie_gen;
60 u8 pcie_lanes_orig;
61 u8 pcie_lanes;
62 u8 cna_capable;
63};
64
65/**
66 * BFA adapter level events
67 * Arguments below are in BFAL context from Mgmt
68 * BFA_PORT_AEN_ADD: [in]: None [out]: serial_num, pwwn, nports
69 * BFA_PORT_AEN_REMOVE: [in]: pwwn [out]: serial_num, pwwn, nports
70 */
71enum bfa_adapter_aen_event {
72 BFA_ADAPTER_AEN_ADD = 1, /* New Adapter found event */
73 BFA_ADAPTER_AEN_REMOVE = 2, /* Adapter removed event */
74};
75
76struct bfa_adapter_aen_data_s {
77 char serial_num[BFA_ADAPTER_SERIAL_NUM_LEN];
78 u32 nports; /* Number of NPorts */
79 wwn_t pwwn; /* WWN of one of its physical port */
80};
81
82#endif /* __BFA_DEFS_ADAPTER_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_aen.h b/drivers/scsi/bfa/include/defs/bfa_defs_aen.h
new file mode 100644
index 000000000000..4c81a613db3d
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_aen.h
@@ -0,0 +1,73 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFA_DEFS_AEN_H__
19#define __BFA_DEFS_AEN_H__
20
21#include <defs/bfa_defs_types.h>
22#include <defs/bfa_defs_ioc.h>
23#include <defs/bfa_defs_adapter.h>
24#include <defs/bfa_defs_port.h>
25#include <defs/bfa_defs_lport.h>
26#include <defs/bfa_defs_rport.h>
27#include <defs/bfa_defs_itnim.h>
28#include <defs/bfa_defs_tin.h>
29#include <defs/bfa_defs_ipfc.h>
30#include <defs/bfa_defs_audit.h>
31#include <defs/bfa_defs_ethport.h>
32
33enum bfa_aen_category {
34 BFA_AEN_CAT_ADAPTER = 1,
35 BFA_AEN_CAT_PORT = 2,
36 BFA_AEN_CAT_LPORT = 3,
37 BFA_AEN_CAT_RPORT = 4,
38 BFA_AEN_CAT_ITNIM = 5,
39 BFA_AEN_CAT_TIN = 6,
40 BFA_AEN_CAT_IPFC = 7,
41 BFA_AEN_CAT_AUDIT = 8,
42 BFA_AEN_CAT_IOC = 9,
43 BFA_AEN_CAT_ETHPORT = 10,
44 BFA_AEN_MAX_CAT = 10
45};
46
47#pragma pack(1)
48union bfa_aen_data_u {
49 struct bfa_adapter_aen_data_s adapter;
50 struct bfa_port_aen_data_s port;
51 struct bfa_lport_aen_data_s lport;
52 struct bfa_rport_aen_data_s rport;
53 struct bfa_itnim_aen_data_s itnim;
54 struct bfa_audit_aen_data_s audit;
55 struct bfa_ioc_aen_data_s ioc;
56 struct bfa_ethport_aen_data_s ethport;
57};
58
59struct bfa_aen_entry_s {
60 enum bfa_aen_category aen_category;
61 int aen_type;
62 union bfa_aen_data_u aen_data;
63 struct bfa_timeval_s aen_tv;
64 s32 seq_num;
65 s32 bfad_num;
66 s32 rsvd[1];
67};
68
69#pragma pack()
70
71#define bfa_aen_event_t int
72
73#endif /* __BFA_DEFS_AEN_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_audit.h b/drivers/scsi/bfa/include/defs/bfa_defs_audit.h
new file mode 100644
index 000000000000..8e3a962bf20c
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_audit.h
@@ -0,0 +1,38 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFA_DEFS_AUDIT_H__
19#define __BFA_DEFS_AUDIT_H__
20
21#include <bfa_os_inc.h>
22
23/**
24 * BFA audit events
25 */
26enum bfa_audit_aen_event {
27 BFA_AUDIT_AEN_AUTH_ENABLE = 1,
28 BFA_AUDIT_AEN_AUTH_DISABLE = 2,
29};
30
31/**
32 * audit event data
33 */
34struct bfa_audit_aen_data_s {
35 wwn_t pwwn;
36};
37
38#endif /* __BFA_DEFS_AUDIT_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_auth.h b/drivers/scsi/bfa/include/defs/bfa_defs_auth.h
new file mode 100644
index 000000000000..dd19c83aba58
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_auth.h
@@ -0,0 +1,112 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17#ifndef __BFA_DEFS_AUTH_H__
18#define __BFA_DEFS_AUTH_H__
19
20#include <defs/bfa_defs_types.h>
21
22#define PUBLIC_KEY 15409
23#define PRIVATE_KEY 19009
24#define KEY_LEN 32399
25#define BFA_AUTH_SECRET_STRING_LEN 256
26#define BFA_AUTH_FAIL_TIMEOUT 0xFF
27
28/**
29 * Authentication status
30 */
31enum bfa_auth_status {
32 BFA_AUTH_STATUS_NONE = 0, /* no authentication */
33 BFA_AUTH_UNINIT = 1, /* state - uninit */
34 BFA_AUTH_NEG_SEND = 2, /* state - negotiate send */
35 BFA_AUTH_CHAL_WAIT = 3, /* state - challenge wait */
36 BFA_AUTH_NEG_RETRY = 4, /* state - negotiate retry */
37 BFA_AUTH_REPLY_SEND = 5, /* state - reply send */
38 BFA_AUTH_STATUS_WAIT = 6, /* state - status wait */
39 BFA_AUTH_SUCCESS = 7, /* state - success */
40 BFA_AUTH_FAILED = 8, /* state - failed */
41 BFA_AUTH_STATUS_UNKNOWN = 9, /* authentication status unknown */
42};
43
44struct auth_proto_stats_s {
45 u32 auth_rjts;
46 u32 auth_negs;
47 u32 auth_dones;
48
49 u32 dhchap_challenges;
50 u32 dhchap_replies;
51 u32 dhchap_successes;
52};
53
54/**
55 * Authentication related statistics
56 */
57struct bfa_auth_stats_s {
58 u32 auth_failures; /* authentication failures */
59 u32 auth_successes; /* authentication successes*/
60 struct auth_proto_stats_s auth_rx_stats; /* Rx protocol stats */
61 struct auth_proto_stats_s auth_tx_stats; /* Tx protocol stats */
62};
63
64/**
65 * Authentication hash function algorithms
66 */
67enum bfa_auth_algo {
68 BFA_AUTH_ALGO_MD5 = 1, /* Message-Digest algorithm 5 */
69 BFA_AUTH_ALGO_SHA1 = 2, /* Secure Hash Algorithm 1 */
70 BFA_AUTH_ALGO_MS = 3, /* MD5, then SHA-1 */
71 BFA_AUTH_ALGO_SM = 4, /* SHA-1, then MD5 */
72};
73
74/**
75 * DH Groups
76 *
77 * Current value could be combination of one or more of the following values
78 */
79enum bfa_auth_group {
80 BFA_AUTH_GROUP_DHNULL = 0, /* DH NULL (value == 0) */
81 BFA_AUTH_GROUP_DH768 = 1, /* DH group 768 (value == 1) */
82 BFA_AUTH_GROUP_DH1024 = 2, /* DH group 1024 (value == 2) */
83 BFA_AUTH_GROUP_DH1280 = 4, /* DH group 1280 (value == 3) */
84 BFA_AUTH_GROUP_DH1536 = 8, /* DH group 1536 (value == 4) */
85
86 BFA_AUTH_GROUP_ALL = 256 /* Use default DH group order
87 * 0, 1, 2, 3, 4 */
88};
89
90/**
91 * Authentication secret sources
92 */
93enum bfa_auth_secretsource {
94 BFA_AUTH_SECSRC_LOCAL = 1, /* locally configured */
95 BFA_AUTH_SECSRC_RADIUS = 2, /* use radius server */
96 BFA_AUTH_SECSRC_TACACS = 3, /* TACACS server */
97};
98
99/**
100 * Authentication attributes
101 */
102struct bfa_auth_attr_s {
103 enum bfa_auth_status status;
104 enum bfa_auth_algo algo;
105 enum bfa_auth_group dh_grp;
106 u16 rjt_code;
107 u16 rjt_code_exp;
108 u8 secret_set;
109 u8 resv[7];
110};
111
112#endif /* __BFA_DEFS_AUTH_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_boot.h b/drivers/scsi/bfa/include/defs/bfa_defs_boot.h
new file mode 100644
index 000000000000..6f4aa5283545
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_boot.h
@@ -0,0 +1,71 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFA_DEFS_BOOT_H__
19#define __BFA_DEFS_BOOT_H__
20
21#include <protocol/types.h>
22#include <defs/bfa_defs_types.h>
23#include <defs/bfa_defs_pport.h>
24
25enum {
26 BFA_BOOT_BOOTLUN_MAX = 4, /* maximum boot lun per IOC */
27};
28
29#define BOOT_CFG_REV1 1
30
31/**
32 * Boot options setting. Boot options setting determines from where
33 * to get the boot lun information
34 */
35enum bfa_boot_bootopt {
36 BFA_BOOT_AUTO_DISCOVER = 0, /* Boot from blun provided by fabric */
37 BFA_BOOT_STORED_BLUN = 1, /* Boot from bluns stored in flash */
38 BFA_BOOT_FIRST_LUN = 2, /* Boot from first discovered blun */
39};
40
41/**
42 * Boot lun information.
43 */
44struct bfa_boot_bootlun_s {
45 wwn_t pwwn; /* port wwn of target */
46 lun_t lun; /* 64-bit lun */
47};
48
49/**
50 * BOOT boot configuraton
51 */
52struct bfa_boot_cfg_s {
53 u8 version;
54 u8 rsvd1;
55 u16 chksum;
56
57 u8 enable; /* enable/disable SAN boot */
58 u8 speed; /* boot speed settings */
59 u8 topology; /* boot topology setting */
60 u8 bootopt; /* bfa_boot_bootopt_t */
61
62 u32 nbluns; /* number of boot luns */
63
64 u32 rsvd2;
65
66 struct bfa_boot_bootlun_s blun[BFA_BOOT_BOOTLUN_MAX];
67 struct bfa_boot_bootlun_s blun_disc[BFA_BOOT_BOOTLUN_MAX];
68};
69
70
71#endif /* __BFA_DEFS_BOOT_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_cee.h b/drivers/scsi/bfa/include/defs/bfa_defs_cee.h
new file mode 100644
index 000000000000..520a22f52dd1
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_cee.h
@@ -0,0 +1,159 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * bfa_defs_cee.h Interface declarations between host based
7 * BFAL and DCBX/LLDP module in Firmware
8 *
9 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License (GPL) Version 2 as
13 * published by the Free Software Foundation
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 */
20#ifndef __BFA_DEFS_CEE_H__
21#define __BFA_DEFS_CEE_H__
22
23#include <defs/bfa_defs_types.h>
24#include <defs/bfa_defs_pport.h>
25#include <protocol/types.h>
26
27#pragma pack(1)
28
29#define BFA_CEE_LLDP_MAX_STRING_LEN (128)
30
31
32/* FIXME: this is coming from the protocol spec. Can the host & apps share the
33 protocol .h files ?
34 */
35#define BFA_CEE_LLDP_SYS_CAP_OTHER 0x0001
36#define BFA_CEE_LLDP_SYS_CAP_REPEATER 0x0002
37#define BFA_CEE_LLDP_SYS_CAP_MAC_BRIDGE 0x0004
38#define BFA_CEE_LLDP_SYS_CAP_WLAN_AP 0x0008
39#define BFA_CEE_LLDP_SYS_CAP_ROUTER 0x0010
40#define BFA_CEE_LLDP_SYS_CAP_TELEPHONE 0x0020
41#define BFA_CEE_LLDP_SYS_CAP_DOCSIS_CD 0x0040
42#define BFA_CEE_LLDP_SYS_CAP_STATION 0x0080
43#define BFA_CEE_LLDP_SYS_CAP_CVLAN 0x0100
44#define BFA_CEE_LLDP_SYS_CAP_SVLAN 0x0200
45#define BFA_CEE_LLDP_SYS_CAP_TPMR 0x0400
46
47
48/* LLDP string type */
49struct bfa_cee_lldp_str_s {
50 u8 sub_type;
51 u8 len;
52 u8 rsvd[2];
53 u8 value[BFA_CEE_LLDP_MAX_STRING_LEN];
54};
55
56
57/* LLDP paramters */
58struct bfa_cee_lldp_cfg_s {
59 struct bfa_cee_lldp_str_s chassis_id;
60 struct bfa_cee_lldp_str_s port_id;
61 struct bfa_cee_lldp_str_s port_desc;
62 struct bfa_cee_lldp_str_s sys_name;
63 struct bfa_cee_lldp_str_s sys_desc;
64 struct bfa_cee_lldp_str_s mgmt_addr;
65 u16 time_to_interval;
66 u16 enabled_system_cap;
67};
68
69enum bfa_cee_dcbx_version_e {
70 DCBX_PROTOCOL_PRECEE = 1,
71 DCBX_PROTOCOL_CEE = 2,
72};
73
74enum bfa_cee_lls_e {
75 CEE_LLS_DOWN_NO_TLV = 0, /* LLS is down because the TLV not sent by
76 * the peer */
77 CEE_LLS_DOWN = 1, /* LLS is down as advertised by the peer */
78 CEE_LLS_UP = 2,
79};
80
81/* CEE/DCBX parameters */
82struct bfa_cee_dcbx_cfg_s {
83 u8 pgid[8];
84 u8 pg_percentage[8];
85 u8 pfc_enabled; /* bitmap of priorties with PFC enabled */
86 u8 fcoe_user_priority; /* bitmap of priorities used for FcoE
87 * traffic */
88 u8 dcbx_version; /* operating version:CEE or preCEE */
89 u8 lls_fcoe; /* FCoE Logical Link Status */
90 u8 lls_lan; /* LAN Logical Link Status */
91 u8 rsvd[3];
92};
93
94/* CEE status */
95/* Making this to tri-state for the benefit of port list command */
96enum bfa_cee_status_e {
97 CEE_PHY_DOWN = 0,
98 CEE_PHY_UP = 1,
99 CEE_UP = 2,
100};
101
102/* CEE Query */
103struct bfa_cee_attr_s {
104 u8 cee_status;
105 u8 error_reason;
106 struct bfa_cee_lldp_cfg_s lldp_remote;
107 struct bfa_cee_dcbx_cfg_s dcbx_remote;
108 mac_t src_mac;
109 u8 link_speed;
110 u8 filler[3];
111};
112
113
114
115
116/* LLDP/DCBX/CEE Statistics */
117
118struct bfa_cee_lldp_stats_s {
119 u32 frames_transmitted;
120 u32 frames_aged_out;
121 u32 frames_discarded;
122 u32 frames_in_error;
123 u32 frames_rcvd;
124 u32 tlvs_discarded;
125 u32 tlvs_unrecognized;
126};
127
128struct bfa_cee_dcbx_stats_s {
129 u32 subtlvs_unrecognized;
130 u32 negotiation_failed;
131 u32 remote_cfg_changed;
132 u32 tlvs_received;
133 u32 tlvs_invalid;
134 u32 seqno;
135 u32 ackno;
136 u32 recvd_seqno;
137 u32 recvd_ackno;
138};
139
140struct bfa_cee_cfg_stats_s {
141 u32 cee_status_down;
142 u32 cee_status_up;
143 u32 cee_hw_cfg_changed;
144 u32 recvd_invalid_cfg;
145};
146
147
148struct bfa_cee_stats_s {
149 struct bfa_cee_lldp_stats_s lldp_stats;
150 struct bfa_cee_dcbx_stats_s dcbx_stats;
151 struct bfa_cee_cfg_stats_s cfg_stats;
152};
153
154#pragma pack()
155
156
157#endif /* __BFA_DEFS_CEE_H__ */
158
159
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_driver.h b/drivers/scsi/bfa/include/defs/bfa_defs_driver.h
new file mode 100644
index 000000000000..57049805762b
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_driver.h
@@ -0,0 +1,40 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFA_DEFS_DRIVER_H__
19#define __BFA_DEFS_DRIVER_H__
20
21/**
22 * Driver statistics
23 */
24 u16 tm_io_abort;
25 u16 tm_io_abort_comp;
26 u16 tm_lun_reset;
27 u16 tm_lun_reset_comp;
28 u16 tm_target_reset;
29 u16 tm_bus_reset;
30 u16 ioc_restart; /* IOC restart count */
31 u16 io_pending; /* outstanding io count per-IOC */
32 u64 control_req;
33 u64 input_req;
34 u64 output_req;
35 u64 input_words;
36 u64 output_words;
37} bfa_driver_stats_t;
38
39
40#endif /* __BFA_DEFS_DRIVER_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_ethport.h b/drivers/scsi/bfa/include/defs/bfa_defs_ethport.h
new file mode 100644
index 000000000000..79f9b3e146f7
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_ethport.h
@@ -0,0 +1,98 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFA_DEFS_ETHPORT_H__
19#define __BFA_DEFS_ETHPORT_H__
20
21#include <defs/bfa_defs_status.h>
22#include <protocol/types.h>
23#include <cna/pstats/phyport_defs.h>
24#include <cna/pstats/ethport_defs.h>
25
26struct bna_tx_info_s {
27 u32 miniport_state;
28 u32 adapter_state;
29 u64 tx_count;
30 u64 tx_wi;
31 u64 tx_sg;
32 u64 tx_tcp_chksum;
33 u64 tx_udp_chksum;
34 u64 tx_ip_chksum;
35 u64 tx_lsov1;
36 u64 tx_lsov2;
37 u64 tx_max_sg_len ;
38};
39
40struct bna_rx_queue_info_s {
41 u16 q_id ;
42 u16 buf_size ;
43 u16 buf_count ;
44 u16 rsvd ;
45 u64 rx_count ;
46 u64 rx_dropped ;
47 u64 rx_unsupported ;
48 u64 rx_internal_err ;
49 u64 rss_count ;
50 u64 vlan_count ;
51 u64 rx_tcp_chksum ;
52 u64 rx_udp_chksum ;
53 u64 rx_ip_chksum ;
54 u64 rx_hds ;
55};
56
57struct bna_rx_q_set_s {
58 u16 q_set_type;
59 u32 miniport_state;
60 u32 adapter_state;
61 struct bna_rx_queue_info_s rx_queue[2];
62};
63
64struct bna_port_stats_s {
65 struct bna_tx_info_s tx_stats;
66 u16 qset_count ;
67 struct bna_rx_q_set_s rx_qset[8];
68};
69
70struct bfa_ethport_stats_s {
71 struct bna_stats_txf txf_stats[1];
72 struct bna_stats_rxf rxf_stats[1];
73 struct bnad_drv_stats drv_stats;
74};
75
76/**
77 * Ethernet port events
78 * Arguments below are in BFAL context from Mgmt
79 * BFA_PORT_AEN_ETH_LINKUP: [in]: mac [out]: mac
80 * BFA_PORT_AEN_ETH_LINKDOWN: [in]: mac [out]: mac
81 * BFA_PORT_AEN_ETH_ENABLE: [in]: mac [out]: mac
82 * BFA_PORT_AEN_ETH_DISABLE: [in]: mac [out]: mac
83 *
84 */
85enum bfa_ethport_aen_event {
86 BFA_ETHPORT_AEN_LINKUP = 1, /* Base Port Ethernet link up event */
87 BFA_ETHPORT_AEN_LINKDOWN = 2, /* Base Port Ethernet link down event */
88 BFA_ETHPORT_AEN_ENABLE = 3, /* Base Port Ethernet link enable event */
89 BFA_ETHPORT_AEN_DISABLE = 4, /* Base Port Ethernet link disable
90 * event */
91};
92
93struct bfa_ethport_aen_data_s {
94 mac_t mac; /* MAC address of the physical port */
95};
96
97
98#endif /* __BFA_DEFS_ETHPORT_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_fcpim.h b/drivers/scsi/bfa/include/defs/bfa_defs_fcpim.h
new file mode 100644
index 000000000000..c08f4f5026ac
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_fcpim.h
@@ -0,0 +1,45 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17#ifndef __BFA_DEFS_FCPIM_H__
18#define __BFA_DEFS_FCPIM_H__
19
20struct bfa_fcpim_stats_s {
21 u32 total_ios; /* Total IO count */
22 u32 qresumes; /* IO waiting for CQ space */
23 u32 no_iotags; /* NO IO contexts */
24 u32 io_aborts; /* IO abort requests */
25 u32 no_tskims; /* NO task management contexts */
26 u32 iocomp_ok; /* IO completions with OK status */
27 u32 iocomp_underrun; /* IO underrun (good) */
28 u32 iocomp_overrun; /* IO overrun (good) */
29 u32 iocomp_aborted; /* Aborted IO requests */
30 u32 iocomp_timedout; /* IO timeouts */
31 u32 iocom_nexus_abort; /* IO selection timeouts */
32 u32 iocom_proto_err; /* IO protocol errors */
33 u32 iocom_dif_err; /* IO SBC-3 protection errors */
34 u32 iocom_tm_abort; /* IO aborted by TM requests */
35 u32 iocom_sqer_needed; /* IO retry for SQ error
36 *recovery */
37 u32 iocom_res_free; /* Delayed freeing of IO resources */
38 u32 iocomp_scsierr; /* IO with non-good SCSI status */
39 u32 iocom_hostabrts; /* Host IO abort requests */
40 u32 iocom_utags; /* IO comp with unknown tags */
41 u32 io_cleanups; /* IO implicitly aborted */
42 u32 io_tmaborts; /* IO aborted due to TM commands */
43 u32 rsvd;
44};
45#endif /*__BFA_DEFS_FCPIM_H__*/
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_im_common.h b/drivers/scsi/bfa/include/defs/bfa_defs_im_common.h
new file mode 100644
index 000000000000..9ccf53bef65a
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_im_common.h
@@ -0,0 +1,32 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFA_DEFS_IM_COMMON_H__
19#define __BFA_DEFS_IM_COMMON_H__
20
21#define BFA_ADAPTER_NAME_LEN 256
22#define BFA_ADAPTER_GUID_LEN 256
23#define RESERVED_VLAN_NAME L"PORT VLAN"
24#define PASSTHRU_VLAN_NAME L"PASSTHRU VLAN"
25
26 u64 tx_pkt_cnt;
27 u64 rx_pkt_cnt;
28 u32 duration;
29 u8 status;
30} bfa_im_stats_t, *pbfa_im_stats_t;
31
32#endif /* __BFA_DEFS_IM_COMMON_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_im_team.h b/drivers/scsi/bfa/include/defs/bfa_defs_im_team.h
new file mode 100644
index 000000000000..a486a7eb81d6
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_im_team.h
@@ -0,0 +1,72 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFA_DEFS_IM_TEAM_H__
19#define __BFA_DEFS_IM_TEAM_H__
20
21#include <protocol/types.h>
22
23#define BFA_TEAM_MAX_PORTS 8
24#define BFA_TEAM_NAME_LEN 256
25#define BFA_MAX_NUM_TEAMS 16
26#define BFA_TEAM_INVALID_DELAY -1
27
28 BFA_LACP_RATE_SLOW = 1,
29 BFA_LACP_RATE_FAST
30} bfa_im_lacp_rate_t;
31
32 BFA_TEAM_MODE_FAIL_OVER = 1,
33 BFA_TEAM_MODE_FAIL_BACK,
34 BFA_TEAM_MODE_LACP,
35 BFA_TEAM_MODE_NONE
36} bfa_im_team_mode_t;
37
38 BFA_XMIT_POLICY_L2 = 1,
39 BFA_XMIT_POLICY_L3_L4
40} bfa_im_xmit_policy_t;
41
42 bfa_im_team_mode_t team_mode;
43 bfa_im_lacp_rate_t lacp_rate;
44 bfa_im_xmit_policy_t xmit_policy;
45 int delay;
46 wchar_t primary[BFA_ADAPTER_NAME_LEN];
47 wchar_t preferred_primary[BFA_ADAPTER_NAME_LEN];
48 mac_t mac;
49 u16 num_ports;
50 u16 num_vlans;
51 u16 vlan_list[BFA_MAX_VLANS_PER_PORT];
52 wchar_t team_guid_list[BFA_TEAM_MAX_PORTS][BFA_ADAPTER_GUID_LEN];
53 wchar_t ioc_name_list[BFA_TEAM_MAX_PORTS][BFA_ADAPTER_NAME_LEN];
54} bfa_im_team_attr_t;
55
56 wchar_t team_name[BFA_TEAM_NAME_LEN];
57 bfa_im_xmit_policy_t xmit_policy;
58 int delay;
59 wchar_t primary[BFA_ADAPTER_NAME_LEN];
60 wchar_t preferred_primary[BFA_ADAPTER_NAME_LEN];
61} bfa_im_team_edit_t, *pbfa_im_team_edit_t;
62
63 wchar_t team_name[BFA_TEAM_NAME_LEN];
64 bfa_im_team_mode_t team_mode;
65 mac_t mac;
66} bfa_im_team_info_t;
67
68 bfa_im_team_info_t team_info[BFA_MAX_NUM_TEAMS];
69 u16 num_teams;
70} bfa_im_team_list_t, *pbfa_im_team_list_t;
71
72#endif /* __BFA_DEFS_IM_TEAM_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_ioc.h b/drivers/scsi/bfa/include/defs/bfa_defs_ioc.h
new file mode 100644
index 000000000000..b1d532da3a9d
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_ioc.h
@@ -0,0 +1,152 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFA_DEFS_IOC_H__
19#define __BFA_DEFS_IOC_H__
20
21#include <protocol/types.h>
22#include <defs/bfa_defs_types.h>
23#include <defs/bfa_defs_version.h>
24#include <defs/bfa_defs_adapter.h>
25#include <defs/bfa_defs_pm.h>
26
27enum {
28 BFA_IOC_DRIVER_LEN = 16,
29 BFA_IOC_CHIP_REV_LEN = 8,
30};
31
32/**
33 * Driver and firmware versions.
34 */
35struct bfa_ioc_driver_attr_s {
36 char driver[BFA_IOC_DRIVER_LEN]; /* driver name */
37 char driver_ver[BFA_VERSION_LEN]; /* driver version */
38 char fw_ver[BFA_VERSION_LEN]; /* firmware version*/
39 char bios_ver[BFA_VERSION_LEN]; /* bios version */
40 char efi_ver[BFA_VERSION_LEN]; /* EFI version */
41 char ob_ver[BFA_VERSION_LEN]; /* openboot version*/
42};
43
44/**
45 * IOC PCI device attributes
46 */
47struct bfa_ioc_pci_attr_s {
48 u16 vendor_id; /* PCI vendor ID */
49 u16 device_id; /* PCI device ID */
50 u16 ssid; /* subsystem ID */
51 u16 ssvid; /* subsystem vendor ID */
52 u32 pcifn; /* PCI device function */
53 u32 rsvd; /* padding */
54 u8 chip_rev[BFA_IOC_CHIP_REV_LEN]; /* chip revision */
55};
56
57/**
58 * IOC states
59 */
60enum bfa_ioc_state {
61 BFA_IOC_RESET = 1, /* IOC is in reset state */
62 BFA_IOC_SEMWAIT = 2, /* Waiting for IOC hardware semaphore */
63 BFA_IOC_HWINIT = 3, /* IOC hardware is being initialized */
64 BFA_IOC_GETATTR = 4, /* IOC is being configured */
65 BFA_IOC_OPERATIONAL = 5, /* IOC is operational */
66 BFA_IOC_INITFAIL = 6, /* IOC hardware failure */
67 BFA_IOC_HBFAIL = 7, /* IOC heart-beat failure */
68 BFA_IOC_DISABLING = 8, /* IOC is being disabled */
69 BFA_IOC_DISABLED = 9, /* IOC is disabled */
70 BFA_IOC_FWMISMATCH = 10, /* IOC firmware different from drivers */
71};
72
73/**
74 * IOC firmware stats
75 */
76struct bfa_fw_ioc_stats_s {
77 u32 hb_count;
78 u32 cfg_reqs;
79 u32 enable_reqs;
80 u32 disable_reqs;
81 u32 stats_reqs;
82 u32 clrstats_reqs;
83 u32 unknown_reqs;
84 u32 ic_reqs; /* interrupt coalesce reqs */
85};
86
87/**
88 * IOC driver stats
89 */
90struct bfa_ioc_drv_stats_s {
91 u32 ioc_isrs;
92 u32 ioc_enables;
93 u32 ioc_disables;
94 u32 ioc_hbfails;
95 u32 ioc_boots;
96 u32 stats_tmos;
97 u32 hb_count;
98 u32 disable_reqs;
99 u32 enable_reqs;
100 u32 disable_replies;
101 u32 enable_replies;
102};
103
104/**
105 * IOC statistics
106 */
107struct bfa_ioc_stats_s {
108 struct bfa_ioc_drv_stats_s drv_stats; /* driver IOC stats */
109 struct bfa_fw_ioc_stats_s fw_stats; /* firmware IOC stats */
110};
111
112
113enum bfa_ioc_type_e {
114 BFA_IOC_TYPE_FC = 1,
115 BFA_IOC_TYPE_FCoE = 2,
116 BFA_IOC_TYPE_LL = 3,
117};
118
119/**
120 * IOC attributes returned in queries
121 */
122struct bfa_ioc_attr_s {
123 enum bfa_ioc_type_e ioc_type;
124 enum bfa_ioc_state state; /* IOC state */
125 struct bfa_adapter_attr_s adapter_attr; /* HBA attributes */
126 struct bfa_ioc_driver_attr_s driver_attr; /* driver attr */
127 struct bfa_ioc_pci_attr_s pci_attr;
128 u8 port_id; /* port number */
129};
130
131/**
132 * BFA IOC level events
133 */
134enum bfa_ioc_aen_event {
135 BFA_IOC_AEN_HBGOOD = 1, /* Heart Beat restore event */
136 BFA_IOC_AEN_HBFAIL = 2, /* Heart Beat failure event */
137 BFA_IOC_AEN_ENABLE = 3, /* IOC enabled event */
138 BFA_IOC_AEN_DISABLE = 4, /* IOC disabled event */
139 BFA_IOC_AEN_FWMISMATCH = 5, /* IOC firmware mismatch */
140};
141
142/**
143 * BFA IOC level event data, now just a place holder
144 */
145struct bfa_ioc_aen_data_s {
146 enum bfa_ioc_type_e ioc_type;
147 wwn_t pwwn;
148 mac_t mac;
149};
150
151#endif /* __BFA_DEFS_IOC_H__ */
152
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_iocfc.h b/drivers/scsi/bfa/include/defs/bfa_defs_iocfc.h
new file mode 100644
index 000000000000..d76bcbd9820f
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_iocfc.h
@@ -0,0 +1,310 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFA_DEFS_IOCFC_H__
19#define __BFA_DEFS_IOCFC_H__
20
21#include <protocol/types.h>
22#include <defs/bfa_defs_types.h>
23#include <defs/bfa_defs_version.h>
24#include <defs/bfa_defs_adapter.h>
25#include <defs/bfa_defs_pm.h>
26
27#define BFA_IOCFC_INTR_DELAY 1125
28#define BFA_IOCFC_INTR_LATENCY 225
29
30/**
31 * Interrupt coalescing configuration.
32 */
33struct bfa_iocfc_intr_attr_s {
34 bfa_boolean_t coalesce; /* enable/disable coalescing */
35 u16 latency; /* latency in microseconds */
36 u16 delay; /* delay in microseconds */
37};
38
39/**
40 * IOC firmware configuraton
41 */
42struct bfa_iocfc_fwcfg_s {
43 u16 num_fabrics; /* number of fabrics */
44 u16 num_lports; /* number of local lports */
45 u16 num_rports; /* number of remote ports */
46 u16 num_ioim_reqs; /* number of IO reqs */
47 u16 num_tskim_reqs; /* task management requests */
48 u16 num_iotm_reqs; /* number of TM IO reqs */
49 u16 num_tsktm_reqs; /* TM task management requests*/
50 u16 num_fcxp_reqs; /* unassisted FC exchanges */
51 u16 num_uf_bufs; /* unsolicited recv buffers */
52 u8 num_cqs;
53 u8 rsvd;
54};
55
56struct bfa_iocfc_drvcfg_s {
57 u16 num_reqq_elems; /* number of req queue elements */
58 u16 num_rspq_elems; /* number of rsp queue elements */
59 u16 num_sgpgs; /* number of total SG pages */
60 u16 num_sboot_tgts; /* number of SAN boot targets */
61 u16 num_sboot_luns; /* number of SAN boot luns */
62 u16 ioc_recover; /* IOC recovery mode */
63 u16 min_cfg; /* minimum configuration */
64 u16 path_tov; /* device path timeout */
65 bfa_boolean_t delay_comp; /* delay completion of
66 failed inflight IOs */
67 u32 rsvd;
68};
69/**
70 * IOC configuration
71 */
72struct bfa_iocfc_cfg_s {
73 struct bfa_iocfc_fwcfg_s fwcfg; /* firmware side config */
74 struct bfa_iocfc_drvcfg_s drvcfg; /* driver side config */
75};
76
77/**
78 * IOC firmware IO stats
79 */
80struct bfa_fw_io_stats_s {
81 u32 host_abort; /* IO aborted by host driver*/
82 u32 host_cleanup; /* IO clean up by host driver */
83
84 u32 fw_io_timeout; /* IOs timedout */
85 u32 fw_frm_parse; /* frame parsed by f/w */
86 u32 fw_frm_data; /* fcp_data frame parsed by f/w */
87 u32 fw_frm_rsp; /* fcp_rsp frame parsed by f/w */
88 u32 fw_frm_xfer_rdy; /* xfer_rdy frame parsed by f/w */
89 u32 fw_frm_bls_acc; /* BLS ACC frame parsed by f/w */
90 u32 fw_frm_tgt_abort; /* target ABTS parsed by f/w */
91 u32 fw_frm_unknown; /* unknown parsed by f/w */
92 u32 fw_data_dma; /* f/w DMA'ed the data frame */
93 u32 fw_frm_drop; /* f/w drop the frame */
94
95 u32 rec_timeout; /* FW rec timed out */
96 u32 error_rec; /* FW sending rec on
97 * an error condition*/
98 u32 wait_for_si; /* FW wait for SI */
99 u32 rec_rsp_inval; /* REC rsp invalid */
100 u32 seqr_io_abort; /* target does not know cmd so abort */
101 u32 seqr_io_retry; /* SEQR failed so retry IO */
102
103 u32 itn_cisc_upd_rsp; /* ITN cisc updated on fcp_rsp */
104 u32 itn_cisc_upd_data; /* ITN cisc updated on fcp_data */
105 u32 itn_cisc_upd_xfer_rdy; /* ITN cisc updated on fcp_data */
106
107 u32 fcp_data_lost; /* fcp data lost */
108
109 u32 ro_set_in_xfer_rdy; /* Target set RO in Xfer_rdy frame */
110 u32 xfer_rdy_ooo_err; /* Out of order Xfer_rdy received */
111 u32 xfer_rdy_unknown_err; /* unknown error in xfer_rdy frame */
112
113 u32 io_abort_timeout; /* ABTS timedout */
114 u32 sler_initiated; /* SLER initiated */
115
116 u32 unexp_fcp_rsp; /* fcp response in wrong state */
117
118 u32 fcp_rsp_under_run; /* fcp rsp IO underrun */
119 u32 fcp_rsp_under_run_wr; /* fcp rsp IO underrun for write */
120 u32 fcp_rsp_under_run_err; /* fcp rsp IO underrun error */
121 u32 fcp_rsp_resid_inval; /* invalid residue */
122 u32 fcp_rsp_over_run; /* fcp rsp IO overrun */
123 u32 fcp_rsp_over_run_err; /* fcp rsp IO overrun error */
124 u32 fcp_rsp_proto_err; /* protocol error in fcp rsp */
125 u32 fcp_rsp_sense_err; /* error in sense info in fcp rsp */
126 u32 fcp_conf_req; /* FCP conf requested */
127
128 u32 tgt_aborted_io; /* target initiated abort */
129
130 u32 ioh_edtov_timeout_event;/* IOH edtov timer popped */
131 u32 ioh_fcp_rsp_excp_event; /* IOH FCP_RSP exception */
132 u32 ioh_fcp_conf_event; /* IOH FCP_CONF */
133 u32 ioh_mult_frm_rsp_event; /* IOH multi_frame FCP_RSP */
134 u32 ioh_hit_class2_event; /* IOH hit class2 */
135 u32 ioh_miss_other_event; /* IOH miss other */
136 u32 ioh_seq_cnt_err_event; /* IOH seq cnt error */
137 u32 ioh_len_err_event; /* IOH len error - fcp_dl !=
138 * bytes xfered */
139 u32 ioh_seq_len_err_event; /* IOH seq len error */
140 u32 ioh_data_oor_event; /* Data out of range */
141 u32 ioh_ro_ooo_event; /* Relative offset out of range */
142 u32 ioh_cpu_owned_event; /* IOH hit -iost owned by f/w */
143 u32 ioh_unexp_frame_event; /* unexpected frame recieved
144 * count */
145 u32 ioh_err_int; /* IOH error int during data-phase
146 * for scsi write
147 */
148};
149
150/**
151 * IOC port firmware stats
152 */
153
154struct bfa_fw_port_fpg_stats_s {
155 u32 intr_evt;
156 u32 intr;
157 u32 intr_excess;
158 u32 intr_cause0;
159 u32 intr_other;
160 u32 intr_other_ign;
161 u32 sig_lost;
162 u32 sig_regained;
163 u32 sync_lost;
164 u32 sync_to;
165 u32 sync_regained;
166 u32 div2_overflow;
167 u32 div2_underflow;
168 u32 efifo_overflow;
169 u32 efifo_underflow;
170 u32 idle_rx;
171 u32 lrr_rx;
172 u32 lr_rx;
173 u32 ols_rx;
174 u32 nos_rx;
175 u32 lip_rx;
176 u32 arbf0_rx;
177 u32 mrk_rx;
178 u32 const_mrk_rx;
179 u32 prim_unknown;
180 u32 rsvd;
181};
182
183
184struct bfa_fw_port_lksm_stats_s {
185 u32 hwsm_success; /* hwsm state machine success */
186 u32 hwsm_fails; /* hwsm fails */
187 u32 hwsm_wdtov; /* hwsm timed out */
188 u32 swsm_success; /* swsm success */
189 u32 swsm_fails; /* swsm fails */
190 u32 swsm_wdtov; /* swsm timed out */
191 u32 busybufs; /* link init failed due to busybuf */
192 u32 buf_waits; /* bufwait state entries */
193 u32 link_fails; /* link failures */
194 u32 psp_errors; /* primitive sequence protocol errors */
195 u32 lr_unexp; /* No. of times LR rx-ed unexpectedly */
196 u32 lrr_unexp; /* No. of times LRR rx-ed unexpectedly */
197 u32 lr_tx; /* No. of times LR tx started */
198 u32 lrr_tx; /* No. of times LRR tx started */
199 u32 ols_tx; /* No. of times OLS tx started */
200 u32 nos_tx; /* No. of times NOS tx started */
201};
202
203
204struct bfa_fw_port_snsm_stats_s {
205 u32 hwsm_success; /* Successful hwsm terminations */
206 u32 hwsm_fails; /* hwsm fail count */
207 u32 hwsm_wdtov; /* hwsm timed out */
208 u32 swsm_success; /* swsm success */
209 u32 swsm_wdtov; /* swsm timed out */
210 u32 error_resets; /* error resets initiated by upsm */
211 u32 sync_lost; /* Sync loss count */
212 u32 sig_lost; /* Signal loss count */
213};
214
215
216struct bfa_fw_port_physm_stats_s {
217 u32 module_inserts; /* Module insert count */
218 u32 module_xtracts; /* Module extracts count */
219 u32 module_invalids; /* Invalid module inserted count */
220 u32 module_read_ign; /* Module validation status ignored */
221 u32 laser_faults; /* Laser fault count */
222 u32 rsvd;
223};
224
225
226struct bfa_fw_fip_stats_s {
227 u32 disc_req; /* Discovery solicit requests */
228 u32 disc_rsp; /* Discovery solicit response */
229 u32 disc_err; /* Discovery advt. parse errors */
230 u32 disc_unsol; /* Discovery unsolicited */
231 u32 disc_timeouts; /* Discovery timeouts */
232 u32 linksvc_unsupp; /* Unsupported link service req */
233 u32 linksvc_err; /* Parse error in link service req */
234 u32 logo_req; /* Number of FIP logos received */
235 u32 clrvlink_req; /* Clear virtual link req */
236 u32 op_unsupp; /* Unsupported FIP operation */
237 u32 untagged; /* Untagged frames (ignored) */
238 u32 rsvd;
239};
240
241
242struct bfa_fw_lps_stats_s {
243 u32 mac_invalids; /* Invalid mac assigned */
244 u32 rsvd;
245};
246
247
248struct bfa_fw_fcoe_stats_s {
249 u32 cee_linkups; /* CEE link up count */
250 u32 cee_linkdns; /* CEE link down count */
251 u32 fip_linkups; /* FIP link up count */
252 u32 fip_linkdns; /* FIP link up count */
253 u32 fip_fails; /* FIP fail count */
254 u32 mac_invalids; /* Invalid mac assigned */
255};
256
257/**
258 * IOC firmware FCoE port stats
259 */
260struct bfa_fw_fcoe_port_stats_s {
261 struct bfa_fw_fcoe_stats_s fcoe_stats;
262 struct bfa_fw_fip_stats_s fip_stats;
263};
264
265/**
266 * IOC firmware FC port stats
267 */
268struct bfa_fw_fc_port_stats_s {
269 struct bfa_fw_port_fpg_stats_s fpg_stats;
270 struct bfa_fw_port_physm_stats_s physm_stats;
271 struct bfa_fw_port_snsm_stats_s snsm_stats;
272 struct bfa_fw_port_lksm_stats_s lksm_stats;
273};
274
275/**
276 * IOC firmware FC port stats
277 */
278union bfa_fw_port_stats_s {
279 struct bfa_fw_fc_port_stats_s fc_stats;
280 struct bfa_fw_fcoe_port_stats_s fcoe_stats;
281};
282
283/**
284 * IOC firmware stats
285 */
286struct bfa_fw_stats_s {
287 struct bfa_fw_ioc_stats_s ioc_stats;
288 struct bfa_fw_io_stats_s io_stats;
289 union bfa_fw_port_stats_s port_stats;
290};
291
292/**
293 * IOC statistics
294 */
295struct bfa_iocfc_stats_s {
296 struct bfa_fw_stats_s fw_stats; /* firmware IOC stats */
297};
298
299/**
300 * IOC attributes returned in queries
301 */
302struct bfa_iocfc_attr_s {
303 struct bfa_iocfc_cfg_s config; /* IOCFC config */
304 struct bfa_iocfc_intr_attr_s intr_attr; /* interrupt attr */
305};
306
307#define BFA_IOCFC_PATHTOV_MAX 60
308#define BFA_IOCFC_QDEPTH_MAX 2000
309
310#endif /* __BFA_DEFS_IOC_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_ipfc.h b/drivers/scsi/bfa/include/defs/bfa_defs_ipfc.h
new file mode 100644
index 000000000000..7cb63ea98f38
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_ipfc.h
@@ -0,0 +1,70 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17#ifndef __BFA_DEFS_IPFC_H__
18#define __BFA_DEFS_IPFC_H__
19
20#include <bfa_os_inc.h>
21#include <protocol/types.h>
22#include <defs/bfa_defs_types.h>
23
24/**
25 * FCS ip remote port states
26 */
27enum bfa_iprp_state {
28 BFA_IPRP_UNINIT = 0, /* PORT is not yet initialized */
29 BFA_IPRP_ONLINE = 1, /* process login is complete */
30 BFA_IPRP_OFFLINE = 2, /* iprp is offline */
31};
32
33/**
34 * FCS remote port statistics
35 */
36struct bfa_iprp_stats_s {
37 u32 offlines;
38 u32 onlines;
39 u32 rscns;
40 u32 plogis;
41 u32 logos;
42 u32 plogi_timeouts;
43 u32 plogi_rejects;
44};
45
46/**
47 * FCS iprp attribute returned in queries
48 */
49struct bfa_iprp_attr_s {
50 enum bfa_iprp_state state;
51};
52
53struct bfa_ipfc_stats_s {
54 u32 arp_sent;
55 u32 arp_recv;
56 u32 arp_reply_sent;
57 u32 arp_reply_recv;
58 u32 farp_sent;
59 u32 farp_recv;
60 u32 farp_reply_sent;
61 u32 farp_reply_recv;
62 u32 farp_reject_sent;
63 u32 farp_reject_recv;
64};
65
66struct bfa_ipfc_attr_s {
67 bfa_boolean_t enabled;
68};
69
70#endif /* __BFA_DEFS_IPFC_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_itnim.h b/drivers/scsi/bfa/include/defs/bfa_defs_itnim.h
new file mode 100644
index 000000000000..2ec769903d24
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_itnim.h
@@ -0,0 +1,126 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17#ifndef __BFA_DEFS_ITNIM_H__
18#define __BFA_DEFS_ITNIM_H__
19
20#include <bfa_os_inc.h>
21#include <protocol/types.h>
22
23/**
24 * FCS itnim states
25 */
26enum bfa_itnim_state {
27 BFA_ITNIM_OFFLINE = 0, /* offline */
28 BFA_ITNIM_PRLI_SEND = 1, /* prli send */
29 BFA_ITNIM_PRLI_SENT = 2, /* prli sent */
30 BFA_ITNIM_PRLI_RETRY = 3, /* prli retry */
31 BFA_ITNIM_HCB_ONLINE = 4, /* online callback */
32 BFA_ITNIM_ONLINE = 5, /* online */
33 BFA_ITNIM_HCB_OFFLINE = 6, /* offline callback */
34 BFA_ITNIM_INITIATIOR = 7, /* initiator */
35};
36
37struct bfa_itnim_hal_stats_s {
38 u32 onlines; /* ITN nexus onlines (PRLI done) */
39 u32 offlines; /* ITN Nexus offlines */
40 u32 creates; /* ITN create requests */
41 u32 deletes; /* ITN delete requests */
42 u32 create_comps; /* ITN create completions */
43 u32 delete_comps; /* ITN delete completions */
44 u32 sler_events; /* SLER (sequence level error
45 * recovery) events */
46 u32 ioc_disabled; /* Num IOC disables */
47 u32 cleanup_comps; /* ITN cleanup completions */
48 u32 tm_cmnds; /* task management(TM) cmnds sent */
49 u32 tm_fw_rsps; /* TM cmds firmware responses */
50 u32 tm_success; /* TM successes */
51 u32 tm_failures; /* TM failures */
52 u32 tm_io_comps; /* TM IO completions */
53 u32 tm_qresumes; /* TM queue resumes (after waiting
54 * for resources)
55 */
56 u32 tm_iocdowns; /* TM cmnds affected by IOC down */
57 u32 tm_cleanups; /* TM cleanups */
58 u32 tm_cleanup_comps;
59 /* TM cleanup completions */
60 u32 ios; /* IO requests */
61 u32 io_comps; /* IO completions */
62 u64 input_reqs; /* INPUT requests */
63 u64 output_reqs; /* OUTPUT requests */
64};
65
66/**
67 * FCS remote port statistics
68 */
69struct bfa_itnim_stats_s {
70 u32 onlines; /* num rport online */
71 u32 offlines; /* num rport offline */
72 u32 prli_sent; /* num prli sent out */
73 u32 fcxp_alloc_wait;/* num fcxp alloc waits */
74 u32 prli_rsp_err; /* num prli rsp errors */
75 u32 prli_rsp_acc; /* num prli rsp accepts */
76 u32 initiator; /* rport is an initiator */
77 u32 prli_rsp_parse_err; /* prli rsp parsing errors */
78 u32 prli_rsp_rjt; /* num prli rsp rejects */
79 u32 timeout; /* num timeouts detected */
80 u32 sler; /* num sler notification from BFA */
81 u32 rsvd;
82 struct bfa_itnim_hal_stats_s hal_stats;
83};
84
85/**
86 * FCS itnim attributes returned in queries
87 */
88struct bfa_itnim_attr_s {
89 enum bfa_itnim_state state; /* FCS itnim state */
90 u8 retry; /* data retransmision support */
91 u8 task_retry_id; /* task retry ident support */
92 u8 rec_support; /* REC supported */
93 u8 conf_comp; /* confirmed completion supp */
94};
95
96/**
97 * BFA ITNIM events.
98 * Arguments below are in BFAL context from Mgmt
99 * BFA_ITNIM_AEN_NEW: [in]: None [out]: vf_id, lpwwn
100 * BFA_ITNIM_AEN_DELETE: [in]: vf_id, lpwwn, rpwwn (0 = all fcp4 targets),
101 * [out]: vf_id, ppwwn, lpwwn, rpwwn
102 * BFA_ITNIM_AEN_ONLINE: [in]: vf_id, lpwwn, rpwwn (0 = all fcp4 targets),
103 * [out]: vf_id, ppwwn, lpwwn, rpwwn
104 * BFA_ITNIM_AEN_OFFLINE: [in]: vf_id, lpwwn, rpwwn (0 = all fcp4 targets),
105 * [out]: vf_id, ppwwn, lpwwn, rpwwn
106 * BFA_ITNIM_AEN_DISCONNECT:[in]: vf_id, lpwwn, rpwwn (0 = all fcp4 targets),
107 * [out]: vf_id, ppwwn, lpwwn, rpwwn
108 */
109enum bfa_itnim_aen_event {
110 BFA_ITNIM_AEN_ONLINE = 1, /* Target online */
111 BFA_ITNIM_AEN_OFFLINE = 2, /* Target offline */
112 BFA_ITNIM_AEN_DISCONNECT = 3, /* Target disconnected */
113};
114
115/**
116 * BFA ITNIM event data structure.
117 */
118struct bfa_itnim_aen_data_s {
119 u16 vf_id; /* vf_id of the IT nexus */
120 u16 rsvd[3];
121 wwn_t ppwwn; /* WWN of its physical port */
122 wwn_t lpwwn; /* WWN of logical port */
123 wwn_t rpwwn; /* WWN of remote(target) port */
124};
125
126#endif /* __BFA_DEFS_ITNIM_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_led.h b/drivers/scsi/bfa/include/defs/bfa_defs_led.h
new file mode 100644
index 000000000000..62039273264e
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_led.h
@@ -0,0 +1,35 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFA_DEFS_LED_H__
19#define __BFA_DEFS_LED_H__
20
21#define BFA_LED_MAX_NUM 3
22
23enum bfa_led_op {
24 BFA_LED_OFF = 0,
25 BFA_LED_ON = 1,
26 BFA_LED_FLICK = 2,
27 BFA_LED_BLINK = 3,
28};
29
30enum bfa_led_color {
31 BFA_LED_GREEN = 0,
32 BFA_LED_AMBER = 1,
33};
34
35#endif /* __BFA_DEFS_LED_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_lport.h b/drivers/scsi/bfa/include/defs/bfa_defs_lport.h
new file mode 100644
index 000000000000..7359f82aacfc
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_lport.h
@@ -0,0 +1,68 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFA_DEFS_LPORT_H__
19#define __BFA_DEFS_LPORT_H__
20
21#include <defs/bfa_defs_types.h>
22#include <defs/bfa_defs_port.h>
23
24/**
25 * BFA AEN logical port events.
26 * Arguments below are in BFAL context from Mgmt
27 * BFA_LPORT_AEN_NEW: [in]: None [out]: vf_id, ppwwn, lpwwn, roles
28 * BFA_LPORT_AEN_DELETE: [in]: lpwwn [out]: vf_id, ppwwn. lpwwn, roles
29 * BFA_LPORT_AEN_ONLINE: [in]: lpwwn [out]: vf_id, ppwwn. lpwwn, roles
30 * BFA_LPORT_AEN_OFFLINE: [in]: lpwwn [out]: vf_id, ppwwn. lpwwn, roles
31 * BFA_LPORT_AEN_DISCONNECT:[in]: lpwwn [out]: vf_id, ppwwn. lpwwn, roles
32 * BFA_LPORT_AEN_NEW_PROP: [in]: None [out]: vf_id, ppwwn. lpwwn, roles
33 * BFA_LPORT_AEN_DELETE_PROP: [in]: lpwwn [out]: vf_id, ppwwn. lpwwn, roles
34 * BFA_LPORT_AEN_NEW_STANDARD: [in]: None [out]: vf_id, ppwwn. lpwwn, roles
35 * BFA_LPORT_AEN_DELETE_STANDARD: [in]: lpwwn [out]: vf_id, ppwwn. lpwwn, roles
36 * BFA_LPORT_AEN_NPIV_DUP_WWN: [in]: lpwwn [out]: vf_id, ppwwn. lpwwn, roles
37 * BFA_LPORT_AEN_NPIV_FABRIC_MAX: [in]: lpwwn [out]: vf_id, ppwwn. lpwwn, roles
38 * BFA_LPORT_AEN_NPIV_UNKNOWN: [in]: lpwwn [out]: vf_id, ppwwn. lpwwn, roles
39 */
40enum bfa_lport_aen_event {
41 BFA_LPORT_AEN_NEW = 1, /* LPort created event */
42 BFA_LPORT_AEN_DELETE = 2, /* LPort deleted event */
43 BFA_LPORT_AEN_ONLINE = 3, /* LPort online event */
44 BFA_LPORT_AEN_OFFLINE = 4, /* LPort offline event */
45 BFA_LPORT_AEN_DISCONNECT = 5, /* LPort disconnect event */
46 BFA_LPORT_AEN_NEW_PROP = 6, /* VPort created event */
47 BFA_LPORT_AEN_DELETE_PROP = 7, /* VPort deleted event */
48 BFA_LPORT_AEN_NEW_STANDARD = 8, /* VPort created event */
49 BFA_LPORT_AEN_DELETE_STANDARD = 9, /* VPort deleted event */
50 BFA_LPORT_AEN_NPIV_DUP_WWN = 10, /* VPort configured with
51 * duplicate WWN event
52 */
53 BFA_LPORT_AEN_NPIV_FABRIC_MAX = 11, /* Max NPIV in fabric/fport */
54 BFA_LPORT_AEN_NPIV_UNKNOWN = 12, /* Unknown NPIV Error code event */
55};
56
57/**
58 * BFA AEN event data structure
59 */
60struct bfa_lport_aen_data_s {
61 u16 vf_id; /* vf_id of this logical port */
62 u16 rsvd;
63 enum bfa_port_role roles; /* Logical port mode,IM/TM/IP etc */
64 wwn_t ppwwn; /* WWN of its physical port */
65 wwn_t lpwwn; /* WWN of this logical port */
66};
67
68#endif /* __BFA_DEFS_LPORT_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_mfg.h b/drivers/scsi/bfa/include/defs/bfa_defs_mfg.h
new file mode 100644
index 000000000000..13fd4ab6aae2
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_mfg.h
@@ -0,0 +1,58 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17#ifndef __BFA_DEFS_MFG_H__
18#define __BFA_DEFS_MFG_H__
19
20#include <bfa_os_inc.h>
21
22/**
23 * Manufacturing block version
24 */
25#define BFA_MFG_VERSION 1
26
27/**
28 * Manufacturing block format
29 */
30#define BFA_MFG_SERIALNUM_SIZE 11
31#define BFA_MFG_PARTNUM_SIZE 14
32#define BFA_MFG_SUPPLIER_ID_SIZE 10
33#define BFA_MFG_SUPPLIER_PARTNUM_SIZE 20
34#define BFA_MFG_SUPPLIER_SERIALNUM_SIZE 20
35#define BFA_MFG_SUPPLIER_REVISION_SIZE 4
36#define STRSZ(_n) (((_n) + 4) & ~3)
37
38/**
39 * VPD data length
40 */
41#define BFA_MFG_VPD_LEN 256
42
43/**
44 * All numerical fields are in big-endian format.
45 */
46struct bfa_mfg_vpd_s {
47 u8 version; /* vpd data version */
48 u8 vpd_sig[3]; /* characters 'V', 'P', 'D' */
49 u8 chksum; /* u8 checksum */
50 u8 vendor; /* vendor */
51 u8 len; /* vpd data length excluding header */
52 u8 rsv;
53 u8 data[BFA_MFG_VPD_LEN]; /* vpd data */
54};
55
56#pragma pack(1)
57
58#endif /* __BFA_DEFS_MFG_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_pci.h b/drivers/scsi/bfa/include/defs/bfa_defs_pci.h
new file mode 100644
index 000000000000..c9b83321694b
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_pci.h
@@ -0,0 +1,41 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFA_DEFS_PCI_H__
19#define __BFA_DEFS_PCI_H__
20
21/**
22 * PCI device and vendor ID information
23 */
24enum {
25 BFA_PCI_VENDOR_ID_BROCADE = 0x1657,
26 BFA_PCI_DEVICE_ID_FC_8G2P = 0x13,
27 BFA_PCI_DEVICE_ID_FC_8G1P = 0x17,
28 BFA_PCI_DEVICE_ID_CT = 0x14,
29};
30
31/**
32 * PCI sub-system device and vendor ID information
33 */
34enum {
35 BFA_PCI_FCOE_SSDEVICE_ID = 0x14,
36};
37
38#define BFA_PCI_ACCESS_RANGES 1 /* Maximum number of device address ranges
39 * mapped through different BAR(s). */
40
41#endif /* __BFA_DEFS_PCI_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_pm.h b/drivers/scsi/bfa/include/defs/bfa_defs_pm.h
new file mode 100644
index 000000000000..e8d6d959006e
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_pm.h
@@ -0,0 +1,33 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFA_DEFS_PM_H__
19#define __BFA_DEFS_PM_H__
20
21#include <bfa_os_inc.h>
22
23/**
24 * BFA power management device states
25 */
26enum bfa_pm_ds {
27 BFA_PM_DS_D0 = 0, /* full power mode */
28 BFA_PM_DS_D1 = 1, /* power save state 1 */
29 BFA_PM_DS_D2 = 2, /* power save state 2 */
30 BFA_PM_DS_D3 = 3, /* power off state */
31};
32
33#endif /* __BFA_DEFS_PM_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_pom.h b/drivers/scsi/bfa/include/defs/bfa_defs_pom.h
new file mode 100644
index 000000000000..d9fa278472b7
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_pom.h
@@ -0,0 +1,56 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17#ifndef __BFA_DEFS_POM_H__
18#define __BFA_DEFS_POM_H__
19
20#include <bfa_os_inc.h>
21#include <defs/bfa_defs_types.h>
22
23/**
24 * POM health status levels for each attributes.
25 */
26enum bfa_pom_entry_health {
27 BFA_POM_HEALTH_NOINFO = 1, /* no information */
28 BFA_POM_HEALTH_NORMAL = 2, /* health is normal */
29 BFA_POM_HEALTH_WARNING = 3, /* warning level */
30 BFA_POM_HEALTH_ALARM = 4, /* alarming level */
31};
32
33/**
34 * Reading of temperature/voltage/current/power
35 */
36struct bfa_pom_entry_s {
37 enum bfa_pom_entry_health health; /* POM entry health */
38 u32 curr_value; /* current value */
39 u32 thr_warn_high; /* threshold warning high */
40 u32 thr_warn_low; /* threshold warning low */
41 u32 thr_alarm_low; /* threshold alaram low */
42 u32 thr_alarm_high; /* threshold alarm high */
43};
44
45/**
46 * POM attributes
47 */
48struct bfa_pom_attr_s {
49 struct bfa_pom_entry_s temperature; /* centigrade */
50 struct bfa_pom_entry_s voltage; /* volts */
51 struct bfa_pom_entry_s curr; /* milli amps */
52 struct bfa_pom_entry_s txpower; /* micro watts */
53 struct bfa_pom_entry_s rxpower; /* micro watts */
54};
55
56#endif /* __BFA_DEFS_POM_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_port.h b/drivers/scsi/bfa/include/defs/bfa_defs_port.h
new file mode 100644
index 000000000000..de0696c81bc4
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_port.h
@@ -0,0 +1,245 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFA_DEFS_PORT_H__
19#define __BFA_DEFS_PORT_H__
20
21#include <bfa_os_inc.h>
22#include <protocol/types.h>
23#include <defs/bfa_defs_pport.h>
24#include <defs/bfa_defs_ioc.h>
25
26#define BFA_FCS_FABRIC_IPADDR_SZ 16
27
28/**
29 * symbolic names for base port/virtual port
30 */
31#define BFA_SYMNAME_MAXLEN 128 /* vmware/windows uses 128 bytes */
32struct bfa_port_symname_s {
33 char symname[BFA_SYMNAME_MAXLEN];
34};
35
36/**
37* Roles of FCS port:
38 * - FCP IM and FCP TM roles cannot be enabled together for a FCS port
39 * - Create multiple ports if both IM and TM functions required.
40 * - Atleast one role must be specified.
41 */
42enum bfa_port_role {
43 BFA_PORT_ROLE_FCP_IM = 0x01, /* FCP initiator role */
44 BFA_PORT_ROLE_FCP_TM = 0x02, /* FCP target role */
45 BFA_PORT_ROLE_FCP_IPFC = 0x04, /* IP over FC role */
46 BFA_PORT_ROLE_FCP_MAX = BFA_PORT_ROLE_FCP_IPFC | BFA_PORT_ROLE_FCP_IM
47};
48
49/**
50 * FCS port configuration.
51 */
52struct bfa_port_cfg_s {
53 wwn_t pwwn; /* port wwn */
54 wwn_t nwwn; /* node wwn */
55 struct bfa_port_symname_s sym_name; /* vm port symbolic name */
56 enum bfa_port_role roles; /* FCS port roles */
57 u32 rsvd;
58 u8 tag[16]; /* opaque tag from application */
59};
60
61/**
62 * FCS port states
63 */
64enum bfa_port_state {
65 BFA_PORT_UNINIT = 0, /* PORT is not yet initialized */
66 BFA_PORT_FDISC = 1, /* FDISC is in progress */
67 BFA_PORT_ONLINE = 2, /* login to fabric is complete */
68 BFA_PORT_OFFLINE = 3, /* No login to fabric */
69};
70
71/**
72 * FCS port type. Required for VmWare.
73 */
74enum bfa_port_type {
75 BFA_PORT_TYPE_PHYSICAL = 0,
76 BFA_PORT_TYPE_VIRTUAL,
77};
78
79/**
80 * FCS port offline reason. Required for VmWare.
81 */
82enum bfa_port_offline_reason {
83 BFA_PORT_OFFLINE_UNKNOWN = 0,
84 BFA_PORT_OFFLINE_LINKDOWN,
85 BFA_PORT_OFFLINE_FAB_UNSUPPORTED, /* NPIV not supported by the
86 * fabric */
87 BFA_PORT_OFFLINE_FAB_NORESOURCES,
88 BFA_PORT_OFFLINE_FAB_LOGOUT,
89};
90
91/**
92 * FCS lport info. Required for VmWare.
93 */
94struct bfa_port_info_s {
95 u8 port_type; /* bfa_port_type_t : physical or
96 * virtual */
97 u8 port_state; /* one of bfa_port_state values */
98 u8 offline_reason; /* one of bfa_port_offline_reason_t
99 * values */
100 wwn_t port_wwn;
101 wwn_t node_wwn;
102
103 /*
104 * following 4 feilds are valid for Physical Ports only
105 */
106 u32 max_vports_supp; /* Max supported vports */
107 u32 num_vports_inuse; /* Num of in use vports */
108 u32 max_rports_supp; /* Max supported rports */
109 u32 num_rports_inuse; /* Num of doscovered rports */
110
111};
112
113/**
114 * FCS port statistics
115 */
116struct bfa_port_stats_s {
117 u32 ns_plogi_sent;
118 u32 ns_plogi_rsp_err;
119 u32 ns_plogi_acc_err;
120 u32 ns_plogi_accepts;
121 u32 ns_rejects; /* NS command rejects */
122 u32 ns_plogi_unknown_rsp;
123 u32 ns_plogi_alloc_wait;
124
125 u32 ns_retries; /* NS command retries */
126 u32 ns_timeouts; /* NS command timeouts */
127
128 u32 ns_rspnid_sent;
129 u32 ns_rspnid_accepts;
130 u32 ns_rspnid_rsp_err;
131 u32 ns_rspnid_rejects;
132 u32 ns_rspnid_alloc_wait;
133
134 u32 ns_rftid_sent;
135 u32 ns_rftid_accepts;
136 u32 ns_rftid_rsp_err;
137 u32 ns_rftid_rejects;
138 u32 ns_rftid_alloc_wait;
139
140 u32 ns_rffid_sent;
141 u32 ns_rffid_accepts;
142 u32 ns_rffid_rsp_err;
143 u32 ns_rffid_rejects;
144 u32 ns_rffid_alloc_wait;
145
146 u32 ns_gidft_sent;
147 u32 ns_gidft_accepts;
148 u32 ns_gidft_rsp_err;
149 u32 ns_gidft_rejects;
150 u32 ns_gidft_unknown_rsp;
151 u32 ns_gidft_alloc_wait;
152
153 /*
154 * Mgmt Server stats
155 */
156 u32 ms_retries; /* MS command retries */
157 u32 ms_timeouts; /* MS command timeouts */
158 u32 ms_plogi_sent;
159 u32 ms_plogi_rsp_err;
160 u32 ms_plogi_acc_err;
161 u32 ms_plogi_accepts;
162 u32 ms_rejects; /* NS command rejects */
163 u32 ms_plogi_unknown_rsp;
164 u32 ms_plogi_alloc_wait;
165
166 u32 num_rscn; /* Num of RSCN received */
167 u32 num_portid_rscn;/* Num portid format RSCN
168 * received */
169
170 u32 uf_recvs; /* unsolicited recv frames */
171 u32 uf_recv_drops; /* dropped received frames */
172
173 u32 rsvd; /* padding for 64 bit alignment */
174};
175
176/**
177 * BFA port attribute returned in queries
178 */
179struct bfa_port_attr_s {
180 enum bfa_port_state state; /* port state */
181 u32 pid; /* port ID */
182 struct bfa_port_cfg_s port_cfg; /* port configuration */
183 enum bfa_pport_type port_type; /* current topology */
184 u32 loopback; /* cable is externally looped back */
185 wwn_t fabric_name; /* attached switch's nwwn */
186 u8 fabric_ip_addr[BFA_FCS_FABRIC_IPADDR_SZ]; /* attached
187 * fabric's ip addr */
188};
189
190/**
191 * BFA physical port Level events
192 * Arguments below are in BFAL context from Mgmt
193 * BFA_PORT_AEN_ONLINE: [in]: pwwn [out]: pwwn
194 * BFA_PORT_AEN_OFFLINE: [in]: pwwn [out]: pwwn
195 * BFA_PORT_AEN_RLIR: [in]: None [out]: pwwn, rlir_data, rlir_len
196 * BFA_PORT_AEN_SFP_INSERT: [in]: pwwn [out]: port_id, pwwn
197 * BFA_PORT_AEN_SFP_REMOVE: [in]: pwwn [out]: port_id, pwwn
198 * BFA_PORT_AEN_SFP_POM: [in]: pwwn [out]: level, port_id, pwwn
199 * BFA_PORT_AEN_ENABLE: [in]: pwwn [out]: pwwn
200 * BFA_PORT_AEN_DISABLE: [in]: pwwn [out]: pwwn
201 * BFA_PORT_AEN_AUTH_ON: [in]: pwwn [out]: pwwn
202 * BFA_PORT_AEN_AUTH_OFF: [in]: pwwn [out]: pwwn
203 * BFA_PORT_AEN_DISCONNECT: [in]: pwwn [out]: pwwn
204 * BFA_PORT_AEN_QOS_NEG: [in]: pwwn [out]: pwwn
205 * BFA_PORT_AEN_FABRIC_NAME_CHANGE: [in]: pwwn, [out]: pwwn, fwwn
206 *
207 */
208enum bfa_port_aen_event {
209 BFA_PORT_AEN_ONLINE = 1, /* Physical Port online event */
210 BFA_PORT_AEN_OFFLINE = 2, /* Physical Port offline event */
211 BFA_PORT_AEN_RLIR = 3, /* RLIR event, not supported */
212 BFA_PORT_AEN_SFP_INSERT = 4, /* SFP inserted event */
213 BFA_PORT_AEN_SFP_REMOVE = 5, /* SFP removed event */
214 BFA_PORT_AEN_SFP_POM = 6, /* SFP POM event */
215 BFA_PORT_AEN_ENABLE = 7, /* Physical Port enable event */
216 BFA_PORT_AEN_DISABLE = 8, /* Physical Port disable event */
217 BFA_PORT_AEN_AUTH_ON = 9, /* Physical Port auth success event */
218 BFA_PORT_AEN_AUTH_OFF = 10, /* Physical Port auth fail event */
219 BFA_PORT_AEN_DISCONNECT = 11, /* Physical Port disconnect event */
220 BFA_PORT_AEN_QOS_NEG = 12, /* Base Port QOS negotiation event */
221 BFA_PORT_AEN_FABRIC_NAME_CHANGE = 13, /* Fabric Name/WWN change
222 * event */
223 BFA_PORT_AEN_SFP_ACCESS_ERROR = 14, /* SFP read error event */
224 BFA_PORT_AEN_SFP_UNSUPPORT = 15, /* Unsupported SFP event */
225};
226
227enum bfa_port_aen_sfp_pom {
228 BFA_PORT_AEN_SFP_POM_GREEN = 1, /* Normal */
229 BFA_PORT_AEN_SFP_POM_AMBER = 2, /* Warning */
230 BFA_PORT_AEN_SFP_POM_RED = 3, /* Critical */
231 BFA_PORT_AEN_SFP_POM_MAX = BFA_PORT_AEN_SFP_POM_RED
232};
233
234struct bfa_port_aen_data_s {
235 enum bfa_ioc_type_e ioc_type;
236 wwn_t pwwn; /* WWN of the physical port */
237 wwn_t fwwn; /* WWN of the fabric port */
238 mac_t mac; /* MAC addres of the ethernet port,
239 * applicable to CNA port only */
240 int phy_port_num; /*! For SFP related events */
241 enum bfa_port_aen_sfp_pom level; /* Only transitions will
242 * be informed */
243};
244
245#endif /* __BFA_DEFS_PORT_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_pport.h b/drivers/scsi/bfa/include/defs/bfa_defs_pport.h
new file mode 100644
index 000000000000..a000bc4e2d4a
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_pport.h
@@ -0,0 +1,383 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFA_DEFS_PPORT_H__
19#define __BFA_DEFS_PPORT_H__
20
21#include <bfa_os_inc.h>
22#include <protocol/fc.h>
23#include <defs/bfa_defs_types.h>
24#include <defs/bfa_defs_qos.h>
25#include <cna/pstats/phyport_defs.h>
26
27/* Modify char* port_stt[] in bfal_port.c if a new state was added */
28enum bfa_pport_states {
29 BFA_PPORT_ST_UNINIT = 1,
30 BFA_PPORT_ST_ENABLING_QWAIT = 2,
31 BFA_PPORT_ST_ENABLING = 3,
32 BFA_PPORT_ST_LINKDOWN = 4,
33 BFA_PPORT_ST_LINKUP = 5,
34 BFA_PPORT_ST_DISABLING_QWAIT = 6,
35 BFA_PPORT_ST_DISABLING = 7,
36 BFA_PPORT_ST_DISABLED = 8,
37 BFA_PPORT_ST_STOPPED = 9,
38 BFA_PPORT_ST_IOCDOWN = 10,
39 BFA_PPORT_ST_IOCDIS = 11,
40 BFA_PPORT_ST_FWMISMATCH = 12,
41 BFA_PPORT_ST_MAX_STATE,
42};
43
44/**
45 * Port speed settings. Each specific speed is a bit field. Use multiple
46 * bits to specify speeds to be selected for auto-negotiation.
47 */
48enum bfa_pport_speed {
49 BFA_PPORT_SPEED_UNKNOWN = 0,
50 BFA_PPORT_SPEED_1GBPS = 1,
51 BFA_PPORT_SPEED_2GBPS = 2,
52 BFA_PPORT_SPEED_4GBPS = 4,
53 BFA_PPORT_SPEED_8GBPS = 8,
54 BFA_PPORT_SPEED_10GBPS = 10,
55 BFA_PPORT_SPEED_AUTO =
56 (BFA_PPORT_SPEED_1GBPS | BFA_PPORT_SPEED_2GBPS |
57 BFA_PPORT_SPEED_4GBPS | BFA_PPORT_SPEED_8GBPS),
58};
59
60/**
61 * Port operational type (in sync with SNIA port type).
62 */
63enum bfa_pport_type {
64 BFA_PPORT_TYPE_UNKNOWN = 1, /* port type is unkown */
65 BFA_PPORT_TYPE_TRUNKED = 2, /* Trunked mode */
66 BFA_PPORT_TYPE_NPORT = 5, /* P2P with switched fabric */
67 BFA_PPORT_TYPE_NLPORT = 6, /* public loop */
68 BFA_PPORT_TYPE_LPORT = 20, /* private loop */
69 BFA_PPORT_TYPE_P2P = 21, /* P2P with no switched fabric */
70 BFA_PPORT_TYPE_VPORT = 22, /* NPIV - virtual port */
71};
72
73/**
74 * Port topology setting. A port's topology and fabric login status
75 * determine its operational type.
76 */
77enum bfa_pport_topology {
78 BFA_PPORT_TOPOLOGY_NONE = 0, /* No valid topology */
79 BFA_PPORT_TOPOLOGY_P2P = 1, /* P2P only */
80 BFA_PPORT_TOPOLOGY_LOOP = 2, /* LOOP topology */
81 BFA_PPORT_TOPOLOGY_AUTO = 3, /* auto topology selection */
82};
83
84/**
85 * Physical port loopback types.
86 */
87enum bfa_pport_opmode {
88 BFA_PPORT_OPMODE_NORMAL = 0x00, /* normal non-loopback mode */
89 BFA_PPORT_OPMODE_LB_INT = 0x01, /* internal loop back */
90 BFA_PPORT_OPMODE_LB_SLW = 0x02, /* serial link wrapback (serdes) */
91 BFA_PPORT_OPMODE_LB_EXT = 0x04, /* external loop back (serdes) */
92 BFA_PPORT_OPMODE_LB_CBL = 0x08, /* cabled loop back */
93 BFA_PPORT_OPMODE_LB_NLINT = 0x20, /* NL_Port internal loopback */
94};
95
96#define BFA_PPORT_OPMODE_LB_HARD(_mode) \
97 ((_mode == BFA_PPORT_OPMODE_LB_INT) || \
98 (_mode == BFA_PPORT_OPMODE_LB_SLW) || \
99 (_mode == BFA_PPORT_OPMODE_LB_EXT))
100
101/**
102 Port State (in sync with SNIA port state).
103 */
104enum bfa_pport_snia_state {
105 BFA_PPORT_STATE_UNKNOWN = 1, /* port is not initialized */
106 BFA_PPORT_STATE_ONLINE = 2, /* port is ONLINE */
107 BFA_PPORT_STATE_DISABLED = 3, /* port is disabled by user */
108 BFA_PPORT_STATE_BYPASSED = 4, /* port is bypassed (in LOOP) */
109 BFA_PPORT_STATE_DIAG = 5, /* port diagnostics is active */
110 BFA_PPORT_STATE_LINKDOWN = 6, /* link is down */
111 BFA_PPORT_STATE_LOOPBACK = 8, /* port is looped back */
112};
113
114/**
115 * Port link state
116 */
117enum bfa_pport_linkstate {
118 BFA_PPORT_LINKUP = 1, /* Physical port/Trunk link up */
119 BFA_PPORT_LINKDOWN = 2, /* Physical port/Trunk link down */
120 BFA_PPORT_TRUNK_LINKDOWN = 3, /* Trunk link down (new tmaster) */
121};
122
123/**
124 * Port link state event
125 */
126#define bfa_pport_event_t enum bfa_pport_linkstate
127
128/**
129 * Port link state reason code
130 */
131enum bfa_pport_linkstate_rsn {
132 BFA_PPORT_LINKSTATE_RSN_NONE = 0,
133 BFA_PPORT_LINKSTATE_RSN_DISABLED = 1,
134 BFA_PPORT_LINKSTATE_RSN_RX_NOS = 2,
135 BFA_PPORT_LINKSTATE_RSN_RX_OLS = 3,
136 BFA_PPORT_LINKSTATE_RSN_RX_LIP = 4,
137 BFA_PPORT_LINKSTATE_RSN_RX_LIPF7 = 5,
138 BFA_PPORT_LINKSTATE_RSN_SFP_REMOVED = 6,
139 BFA_PPORT_LINKSTATE_RSN_PORT_FAULT = 7,
140 BFA_PPORT_LINKSTATE_RSN_RX_LOS = 8,
141 BFA_PPORT_LINKSTATE_RSN_LOCAL_FAULT = 9,
142 BFA_PPORT_LINKSTATE_RSN_REMOTE_FAULT = 10,
143 BFA_PPORT_LINKSTATE_RSN_TIMEOUT = 11,
144
145
146
147 /* CEE related reason codes/errors */
148 CEE_LLDP_INFO_AGED_OUT = 20,
149 CEE_LLDP_SHUTDOWN_TLV_RCVD = 21,
150 CEE_PEER_NOT_ADVERTISE_DCBX = 22,
151 CEE_PEER_NOT_ADVERTISE_PG = 23,
152 CEE_PEER_NOT_ADVERTISE_PFC = 24,
153 CEE_PEER_NOT_ADVERTISE_FCOE = 25,
154 CEE_PG_NOT_COMPATIBLE = 26,
155 CEE_PFC_NOT_COMPATIBLE = 27,
156 CEE_FCOE_NOT_COMPATIBLE = 28,
157 CEE_BAD_PG_RCVD = 29,
158 CEE_BAD_BW_RCVD = 30,
159 CEE_BAD_PFC_RCVD = 31,
160 CEE_BAD_FCOE_PRI_RCVD = 32,
161 CEE_FCOE_PRI_PFC_OFF = 33,
162 CEE_DUP_CONTROL_TLV_RCVD = 34,
163 CEE_DUP_FEAT_TLV_RCVD = 35,
164 CEE_APPLY_NEW_CFG = 36, /* reason, not an error */
165 CEE_PROTOCOL_INIT = 37, /* reason, not an error */
166 CEE_PHY_LINK_DOWN = 38,
167 CEE_LLS_FCOE_ABSENT = 39,
168 CEE_LLS_FCOE_DOWN = 40
169};
170
171/**
172 * Default Target Rate Limiting Speed.
173 */
174#define BFA_PPORT_DEF_TRL_SPEED BFA_PPORT_SPEED_1GBPS
175
176/**
177 * Physical port configuration
178 */
179struct bfa_pport_cfg_s {
180 u8 topology; /* bfa_pport_topology */
181 u8 speed; /* enum bfa_pport_speed */
182 u8 trunked; /* trunked or not */
183 u8 qos_enabled; /* qos enabled or not */
184 u8 trunk_ports; /* bitmap of trunked ports */
185 u8 cfg_hardalpa; /* is hard alpa configured */
186 u16 maxfrsize; /* maximum frame size */
187 u8 hardalpa; /* configured hard alpa */
188 u8 rx_bbcredit; /* receive buffer credits */
189 u8 tx_bbcredit; /* transmit buffer credits */
190 u8 ratelimit; /* ratelimit enabled or not */
191 u8 trl_def_speed; /* ratelimit default speed */
192 u8 rsvd[3];
193 u16 path_tov; /* device path timeout */
194 u16 q_depth; /* SCSI Queue depth */
195};
196
197/**
198 * Port attribute values.
199 */
200struct bfa_pport_attr_s {
201 /*
202 * Static fields
203 */
204 wwn_t nwwn; /* node wwn */
205 wwn_t pwwn; /* port wwn */
206 enum fc_cos cos_supported; /* supported class of services */
207 u32 rsvd;
208 struct fc_symname_s port_symname; /* port symbolic name */
209 enum bfa_pport_speed speed_supported; /* supported speeds */
210 bfa_boolean_t pbind_enabled; /* Will be set if Persistent binding
211 * enabled. Relevant only in Windows
212 */
213
214 /*
215 * Configured values
216 */
217 struct bfa_pport_cfg_s pport_cfg; /* pport cfg */
218
219 /*
220 * Dynamic field - info from BFA
221 */
222 enum bfa_pport_states port_state; /* current port state */
223 enum bfa_pport_speed speed; /* current speed */
224 enum bfa_pport_topology topology; /* current topology */
225 bfa_boolean_t beacon; /* current beacon status */
226 bfa_boolean_t link_e2e_beacon;/* set if link beacon on */
227 bfa_boolean_t plog_enabled; /* set if portlog is enabled*/
228
229 /*
230 * Dynamic field - info from FCS
231 */
232 u32 pid; /* port ID */
233 enum bfa_pport_type port_type; /* current topology */
234 u32 loopback; /* external loopback */
235 u32 rsvd1;
236 u32 rsvd2; /* padding for 64 bit */
237};
238
239/**
240 * FC Port statistics.
241 */
242struct bfa_pport_fc_stats_s {
243 u64 secs_reset; /* seconds since stats is reset */
244 u64 tx_frames; /* transmitted frames */
245 u64 tx_words; /* transmitted words */
246 u64 rx_frames; /* received frames */
247 u64 rx_words; /* received words */
248 u64 lip_count; /* LIPs seen */
249 u64 nos_count; /* NOS count */
250 u64 error_frames; /* errored frames (sent?) */
251 u64 dropped_frames; /* dropped frames */
252 u64 link_failures; /* link failure count */
253 u64 loss_of_syncs; /* loss of sync count */
254 u64 loss_of_signals;/* loss of signal count */
255 u64 primseq_errs; /* primitive sequence protocol */
256 u64 bad_os_count; /* invalid ordered set */
257 u64 err_enc_out; /* Encoding error outside frame */
258 u64 invalid_crcs; /* frames received with invalid CRC*/
259 u64 undersized_frm; /* undersized frames */
260 u64 oversized_frm; /* oversized frames */
261 u64 bad_eof_frm; /* frames with bad EOF */
262 struct bfa_qos_stats_s qos_stats; /* QoS statistics */
263};
264
265/**
266 * Eth Port statistics.
267 */
268struct bfa_pport_eth_stats_s {
269 u64 secs_reset; /* seconds since stats is reset */
270 u64 frame_64; /* both rx and tx counter */
271 u64 frame_65_127; /* both rx and tx counter */
272 u64 frame_128_255; /* both rx and tx counter */
273 u64 frame_256_511; /* both rx and tx counter */
274 u64 frame_512_1023; /* both rx and tx counter */
275 u64 frame_1024_1518; /* both rx and tx counter */
276 u64 frame_1519_1522; /* both rx and tx counter */
277
278 u64 tx_bytes;
279 u64 tx_packets;
280 u64 tx_mcast_packets;
281 u64 tx_bcast_packets;
282 u64 tx_control_frame;
283 u64 tx_drop;
284 u64 tx_jabber;
285 u64 tx_fcs_error;
286 u64 tx_fragments;
287
288 u64 rx_bytes;
289 u64 rx_packets;
290 u64 rx_mcast_packets;
291 u64 rx_bcast_packets;
292 u64 rx_control_frames;
293 u64 rx_unknown_opcode;
294 u64 rx_drop;
295 u64 rx_jabber;
296 u64 rx_fcs_error;
297 u64 rx_alignment_error;
298 u64 rx_frame_length_error;
299 u64 rx_code_error;
300 u64 rx_fragments;
301
302 u64 rx_pause; /* BPC */
303 u64 rx_zero_pause; /* BPC Pause cancellation */
304 u64 tx_pause; /* BPC */
305 u64 tx_zero_pause; /* BPC Pause cancellation */
306 u64 rx_fcoe_pause; /* BPC */
307 u64 rx_fcoe_zero_pause; /* BPC Pause cancellation */
308 u64 tx_fcoe_pause; /* BPC */
309 u64 tx_fcoe_zero_pause; /* BPC Pause cancellation */
310};
311
312/**
313 * Port statistics.
314 */
315union bfa_pport_stats_u {
316 struct bfa_pport_fc_stats_s fc;
317 struct bfa_pport_eth_stats_s eth;
318};
319
320/**
321 * Port FCP mappings.
322 */
323struct bfa_pport_fcpmap_s {
324 char osdevname[256];
325 u32 bus;
326 u32 target;
327 u32 oslun;
328 u32 fcid;
329 wwn_t nwwn;
330 wwn_t pwwn;
331 u64 fcplun;
332 char luid[256];
333};
334
335/**
336 * Port RNID info.
337 */
338struct bfa_pport_rnid_s {
339 wwn_t wwn;
340 u32 unittype;
341 u32 portid;
342 u32 attached_nodes_num;
343 u16 ip_version;
344 u16 udp_port;
345 u8 ipaddr[16];
346 u16 rsvd;
347 u16 topologydiscoveryflags;
348};
349
350/**
351 * Link state information
352 */
353struct bfa_pport_link_s {
354 u8 linkstate; /* Link state bfa_pport_linkstate */
355 u8 linkstate_rsn; /* bfa_pport_linkstate_rsn_t */
356 u8 topology; /* P2P/LOOP bfa_pport_topology */
357 u8 speed; /* Link speed (1/2/4/8 G) */
358 u32 linkstate_opt; /* Linkstate optional data (debug) */
359 u8 trunked; /* Trunked or not (1 or 0) */
360 u8 resvd[3];
361 struct bfa_qos_attr_s qos_attr; /* QoS Attributes */
362 struct bfa_qos_vc_attr_s qos_vc_attr; /* VC info from ELP */
363 union {
364 struct {
365 u8 tmaster;/* Trunk Master or
366 * not (1 or 0) */
367 u8 tlinks; /* Trunk links bitmap
368 * (linkup) */
369 u8 resv1; /* Reserved */
370 } trunk_info;
371
372 struct {
373 u8 myalpa; /* alpa claimed */
374 u8 login_req; /* Login required or
375 * not (1 or 0) */
376 u8 alpabm_val;/* alpa bitmap valid
377 * or not (1 or 0) */
378 struct fc_alpabm_s alpabm; /* alpa bitmap */
379 } loop_info;
380 } tl;
381};
382
383#endif /* __BFA_DEFS_PPORT_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_qos.h b/drivers/scsi/bfa/include/defs/bfa_defs_qos.h
new file mode 100644
index 000000000000..aadbacd1d2d7
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_qos.h
@@ -0,0 +1,99 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFA_DEFS_QOS_H__
19#define __BFA_DEFS_QOS_H__
20
21/**
22 * QoS states
23 */
24enum bfa_qos_state {
25 BFA_QOS_ONLINE = 1, /* QoS is online */
26 BFA_QOS_OFFLINE = 2, /* QoS is offline */
27};
28
29
30/**
31 * QoS Priority levels.
32 */
33enum bfa_qos_priority {
34 BFA_QOS_UNKNOWN = 0,
35 BFA_QOS_HIGH = 1, /* QoS Priority Level High */
36 BFA_QOS_MED = 2, /* QoS Priority Level Medium */
37 BFA_QOS_LOW = 3, /* QoS Priority Level Low */
38};
39
40
41/**
42 * QoS bandwidth allocation for each priority level
43 */
44enum bfa_qos_bw_alloc {
45 BFA_QOS_BW_HIGH = 60, /* bandwidth allocation for High */
46 BFA_QOS_BW_MED = 30, /* bandwidth allocation for Medium */
47 BFA_QOS_BW_LOW = 10, /* bandwidth allocation for Low */
48};
49
50/**
51 * QoS attribute returned in QoS Query
52 */
53struct bfa_qos_attr_s {
54 enum bfa_qos_state state; /* QoS current state */
55 u32 total_bb_cr; /* Total BB Credits */
56};
57
58/**
59 * These fields should be displayed only from the CLI.
60 * There will be a separate BFAL API (get_qos_vc_attr ?)
61 * to retrieve this.
62 *
63 */
64#define BFA_QOS_MAX_VC 16
65
66struct bfa_qos_vc_info_s {
67 u8 vc_credit;
68 u8 borrow_credit;
69 u8 priority;
70 u8 resvd;
71};
72
73struct bfa_qos_vc_attr_s {
74 u16 total_vc_count; /* Total VC Count */
75 u16 shared_credit;
76 u32 elp_opmode_flags;
77 struct bfa_qos_vc_info_s vc_info[BFA_QOS_MAX_VC]; /* as many as
78 * total_vc_count */
79};
80
81/**
82 * QoS statistics
83 */
84struct bfa_qos_stats_s {
85 u32 flogi_sent; /* QoS Flogi sent */
86 u32 flogi_acc_recvd; /* QoS Flogi Acc received */
87 u32 flogi_rjt_recvd; /* QoS Flogi rejects received */
88 u32 flogi_retries; /* QoS Flogi retries */
89
90 u32 elp_recvd; /* QoS ELP received */
91 u32 elp_accepted; /* QoS ELP Accepted */
92 u32 elp_rejected; /* QoS ELP rejected */
93 u32 elp_dropped; /* QoS ELP dropped */
94
95 u32 qos_rscn_recvd; /* QoS RSCN received */
96 u32 rsvd; /* padding for 64 bit alignment */
97};
98
99#endif /* __BFA_DEFS_QOS_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_rport.h b/drivers/scsi/bfa/include/defs/bfa_defs_rport.h
new file mode 100644
index 000000000000..e0af59d6d2f6
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_rport.h
@@ -0,0 +1,199 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFA_DEFS_RPORT_H__
19#define __BFA_DEFS_RPORT_H__
20
21#include <bfa_os_inc.h>
22#include <protocol/types.h>
23#include <defs/bfa_defs_pport.h>
24#include <defs/bfa_defs_port.h>
25#include <defs/bfa_defs_qos.h>
26
27/**
28 * FCS remote port states
29 */
30enum bfa_rport_state {
31 BFA_RPORT_UNINIT = 0, /* PORT is not yet initialized */
32 BFA_RPORT_OFFLINE = 1, /* rport is offline */
33 BFA_RPORT_PLOGI = 2, /* PLOGI to rport is in progress */
34 BFA_RPORT_ONLINE = 3, /* login to rport is complete */
35 BFA_RPORT_PLOGI_RETRY = 4, /* retrying login to rport */
36 BFA_RPORT_NSQUERY = 5, /* nameserver query */
37 BFA_RPORT_ADISC = 6, /* ADISC authentication */
38 BFA_RPORT_LOGO = 7, /* logging out with rport */
39 BFA_RPORT_LOGORCV = 8, /* handling LOGO from rport */
40 BFA_RPORT_NSDISC = 9, /* re-discover rport */
41};
42
43/**
44 * Rport Scsi Function : Initiator/Target.
45 */
46enum bfa_rport_function {
47 BFA_RPORT_INITIATOR = 0x01, /* SCSI Initiator */
48 BFA_RPORT_TARGET = 0x02, /* SCSI Target */
49};
50
51/**
52 * port/node symbolic names for rport
53 */
54#define BFA_RPORT_SYMNAME_MAXLEN 255
55struct bfa_rport_symname_s {
56 char symname[BFA_RPORT_SYMNAME_MAXLEN];
57};
58
59struct bfa_rport_hal_stats_s {
60 u32 sm_un_cr; /* uninit: create events */
61 u32 sm_un_unexp; /* uninit: exception events */
62 u32 sm_cr_on; /* created: online events */
63 u32 sm_cr_del; /* created: delete events */
64 u32 sm_cr_hwf; /* created: IOC down */
65 u32 sm_cr_unexp; /* created: exception events */
66 u32 sm_fwc_rsp; /* fw create: f/w responses */
67 u32 sm_fwc_del; /* fw create: delete events */
68 u32 sm_fwc_off; /* fw create: offline events */
69 u32 sm_fwc_hwf; /* fw create: IOC down */
70 u32 sm_fwc_unexp; /* fw create: exception events*/
71 u32 sm_on_off; /* online: offline events */
72 u32 sm_on_del; /* online: delete events */
73 u32 sm_on_hwf; /* online: IOC down events */
74 u32 sm_on_unexp; /* online: exception events */
75 u32 sm_fwd_rsp; /* fw delete: fw responses */
76 u32 sm_fwd_del; /* fw delete: delete events */
77 u32 sm_fwd_hwf; /* fw delete: IOC down events */
78 u32 sm_fwd_unexp; /* fw delete: exception events*/
79 u32 sm_off_del; /* offline: delete events */
80 u32 sm_off_on; /* offline: online events */
81 u32 sm_off_hwf; /* offline: IOC down events */
82 u32 sm_off_unexp; /* offline: exception events */
83 u32 sm_del_fwrsp; /* delete: fw responses */
84 u32 sm_del_hwf; /* delete: IOC down events */
85 u32 sm_del_unexp; /* delete: exception events */
86 u32 sm_delp_fwrsp; /* delete pend: fw responses */
87 u32 sm_delp_hwf; /* delete pend: IOC downs */
88 u32 sm_delp_unexp; /* delete pend: exceptions */
89 u32 sm_offp_fwrsp; /* off-pending: fw responses */
90 u32 sm_offp_del; /* off-pending: deletes */
91 u32 sm_offp_hwf; /* off-pending: IOC downs */
92 u32 sm_offp_unexp; /* off-pending: exceptions */
93 u32 sm_iocd_off; /* IOC down: offline events */
94 u32 sm_iocd_del; /* IOC down: delete events */
95 u32 sm_iocd_on; /* IOC down: online events */
96 u32 sm_iocd_unexp; /* IOC down: exceptions */
97 u32 rsvd;
98};
99
100/**
101 * FCS remote port statistics
102 */
103struct bfa_rport_stats_s {
104 u32 offlines; /* remote port offline count */
105 u32 onlines; /* remote port online count */
106 u32 rscns; /* RSCN affecting rport */
107 u32 plogis; /* plogis sent */
108 u32 plogi_accs; /* plogi accepts */
109 u32 plogi_timeouts; /* plogi timeouts */
110 u32 plogi_rejects; /* rcvd plogi rejects */
111 u32 plogi_failed; /* local failure */
112 u32 plogi_rcvd; /* plogis rcvd */
113 u32 prli_rcvd; /* inbound PRLIs */
114 u32 adisc_rcvd; /* ADISCs received */
115 u32 adisc_rejects; /* recvd ADISC rejects */
116 u32 adisc_sent; /* ADISC requests sent */
117 u32 adisc_accs; /* ADISC accepted by rport */
118 u32 adisc_failed; /* ADISC failed (no response) */
119 u32 adisc_rejected; /* ADISC rejected by us */
120 u32 logos; /* logos sent */
121 u32 logo_accs; /* LOGO accepts from rport */
122 u32 logo_failed; /* LOGO failures */
123 u32 logo_rejected; /* LOGO rejects from rport */
124 u32 logo_rcvd; /* LOGO from remote port */
125
126 u32 rpsc_rcvd; /* RPSC received */
127 u32 rpsc_rejects; /* recvd RPSC rejects */
128 u32 rpsc_sent; /* RPSC requests sent */
129 u32 rpsc_accs; /* RPSC accepted by rport */
130 u32 rpsc_failed; /* RPSC failed (no response) */
131 u32 rpsc_rejected; /* RPSC rejected by us */
132
133 u32 rsvd;
134 struct bfa_rport_hal_stats_s hal_stats; /* BFA rport stats */
135};
136
137/**
138 * Rport's QoS attributes
139 */
140struct bfa_rport_qos_attr_s {
141 enum bfa_qos_priority qos_priority; /* rport's QoS priority */
142 u32 qos_flow_id; /* QoS flow Id */
143};
144
145/**
146 * FCS remote port attributes returned in queries
147 */
148struct bfa_rport_attr_s {
149 wwn_t nwwn; /* node wwn */
150 wwn_t pwwn; /* port wwn */
151 enum fc_cos cos_supported; /* supported class of services */
152 u32 pid; /* port ID */
153 u32 df_sz; /* Max payload size */
154 enum bfa_rport_state state; /* Rport State machine state */
155 enum fc_cos fc_cos; /* FC classes of services */
156 bfa_boolean_t cisc; /* CISC capable device */
157 struct bfa_rport_symname_s symname; /* Symbolic Name */
158 enum bfa_rport_function scsi_function; /* Initiator/Target */
159 struct bfa_rport_qos_attr_s qos_attr; /* qos attributes */
160 enum bfa_pport_speed curr_speed; /* operating speed got from
161 * RPSC ELS. UNKNOWN, if RPSC
162 * is not supported */
163 bfa_boolean_t trl_enforced; /* TRL enforced ? TRUE/FALSE */
164 enum bfa_pport_speed assigned_speed; /* Speed assigned by the user.
165 * will be used if RPSC is not
166 * supported by the rport */
167};
168
169#define bfa_rport_aen_qos_data_t struct bfa_rport_qos_attr_s
170
171/**
172 * BFA remote port events
173 * Arguments below are in BFAL context from Mgmt
174 * BFA_RPORT_AEN_ONLINE: [in]: lpwwn [out]: vf_id, lpwwn, rpwwn
175 * BFA_RPORT_AEN_OFFLINE: [in]: lpwwn [out]: vf_id, lpwwn, rpwwn
176 * BFA_RPORT_AEN_DISCONNECT:[in]: lpwwn [out]: vf_id, lpwwn, rpwwn
177 * BFA_RPORT_AEN_QOS_PRIO: [in]: lpwwn [out]: vf_id, lpwwn, rpwwn, prio
178 * BFA_RPORT_AEN_QOS_FLOWID:[in]: lpwwn [out]: vf_id, lpwwn, rpwwn, flow_id
179 */
180enum bfa_rport_aen_event {
181 BFA_RPORT_AEN_ONLINE = 1, /* RPort online event */
182 BFA_RPORT_AEN_OFFLINE = 2, /* RPort offline event */
183 BFA_RPORT_AEN_DISCONNECT = 3, /* RPort disconnect event */
184 BFA_RPORT_AEN_QOS_PRIO = 4, /* QOS priority change event */
185 BFA_RPORT_AEN_QOS_FLOWID = 5, /* QOS flow Id change event */
186};
187
188struct bfa_rport_aen_data_s {
189 u16 vf_id; /* vf_id of this logical port */
190 u16 rsvd[3];
191 wwn_t ppwwn; /* WWN of its physical port */
192 wwn_t lpwwn; /* WWN of this logical port */
193 wwn_t rpwwn; /* WWN of this remote port */
194 union {
195 bfa_rport_aen_qos_data_t qos;
196 } priv;
197};
198
199#endif /* __BFA_DEFS_RPORT_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_status.h b/drivers/scsi/bfa/include/defs/bfa_defs_status.h
new file mode 100644
index 000000000000..cdceaeb9f4b8
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_status.h
@@ -0,0 +1,255 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17#ifndef __BFA_DEFS_STATUS_H__
18#define __BFA_DEFS_STATUS_H__
19
20/**
21 * API status return values
22 *
23 * NOTE: The error msgs are auto generated from the comments. Only singe line
24 * comments are supported
25 */
26enum bfa_status {
27 BFA_STATUS_OK = 0, /* Success */
28 BFA_STATUS_FAILED = 1, /* Operation failed */
29 BFA_STATUS_EINVAL = 2, /* Invalid params Check input
30 * parameters */
31 BFA_STATUS_ENOMEM = 3, /* Out of resources */
32 BFA_STATUS_ENOSYS = 4, /* Function not implemented */
33 BFA_STATUS_ETIMER = 5, /* Timer expired - Retry, if
34 * persists, contact support */
35 BFA_STATUS_EPROTOCOL = 6, /* Protocol error */
36 BFA_STATUS_ENOFCPORTS = 7, /* No FC ports resources */
37 BFA_STATUS_NOFLASH = 8, /* Flash not present */
38 BFA_STATUS_BADFLASH = 9, /* Flash is corrupted or bad */
39 BFA_STATUS_SFP_UNSUPP = 10, /* Unsupported SFP - Replace SFP */
40 BFA_STATUS_UNKNOWN_VFID = 11, /* VF_ID not found */
41 BFA_STATUS_DATACORRUPTED = 12, /* Diag returned data corrupted
42 * contact support */
43 BFA_STATUS_DEVBUSY = 13, /* Device busy - Retry operation */
44 BFA_STATUS_ABORTED = 14, /* Operation aborted */
45 BFA_STATUS_NODEV = 15, /* Dev is not present */
46 BFA_STATUS_HDMA_FAILED = 16, /* Host dma failed contact support */
47 BFA_STATUS_FLASH_BAD_LEN = 17, /* Flash bad length */
48 BFA_STATUS_UNKNOWN_LWWN = 18, /* LPORT PWWN not found */
49 BFA_STATUS_UNKNOWN_RWWN = 19, /* RPORT PWWN not found */
50 BFA_STATUS_FCPT_LS_RJT = 20, /* Got LS_RJT for FC Pass
51 * through Req */
52 BFA_STATUS_VPORT_EXISTS = 21, /* VPORT already exists */
53 BFA_STATUS_VPORT_MAX = 22, /* Reached max VPORT supported
54 * limit */
55 BFA_STATUS_UNSUPP_SPEED = 23, /* Invalid Speed Check speed
56 * setting */
57 BFA_STATUS_INVLD_DFSZ = 24, /* Invalid Max data field size */
58 BFA_STATUS_CNFG_FAILED = 25, /* Setting can not be persisted */
59 BFA_STATUS_CMD_NOTSUPP = 26, /* Command/API not supported */
60 BFA_STATUS_NO_ADAPTER = 27, /* No Brocade Adapter Found */
61 BFA_STATUS_LINKDOWN = 28, /* Link is down - Check or replace
62 * SFP/cable */
63 BFA_STATUS_FABRIC_RJT = 29, /* Reject from attached fabric */
64 BFA_STATUS_UNKNOWN_VWWN = 30, /* VPORT PWWN not found */
65 BFA_STATUS_NSLOGIN_FAILED = 31, /* Nameserver login failed */
66 BFA_STATUS_NO_RPORTS = 32, /* No remote ports found */
67 BFA_STATUS_NSQUERY_FAILED = 33, /* Nameserver query failed */
68 BFA_STATUS_PORT_OFFLINE = 34, /* Port is not online */
69 BFA_STATUS_RPORT_OFFLINE = 35, /* RPORT is not online */
70 BFA_STATUS_TGTOPEN_FAILED = 36, /* Remote SCSI target open failed */
71 BFA_STATUS_BAD_LUNS = 37, /* No valid LUNs found */
72 BFA_STATUS_IO_FAILURE = 38, /* SCSI target IO failure */
73 BFA_STATUS_NO_FABRIC = 39, /* No switched fabric present */
74 BFA_STATUS_EBADF = 40, /* Bad file descriptor */
75 BFA_STATUS_EINTR = 41, /* A signal was caught during ioctl */
76 BFA_STATUS_EIO = 42, /* I/O error */
77 BFA_STATUS_ENOTTY = 43, /* Inappropriate I/O control
78 * operation */
79 BFA_STATUS_ENXIO = 44, /* No such device or address */
80 BFA_STATUS_EFOPEN = 45, /* Failed to open file */
81 BFA_STATUS_VPORT_WWN_BP = 46, /* WWN is same as base port's WWN */
82 BFA_STATUS_PORT_NOT_DISABLED = 47, /* Port not disabled disable port
83 * first */
84 BFA_STATUS_BADFRMHDR = 48, /* Bad frame header */
85 BFA_STATUS_BADFRMSZ = 49, /* Bad frame size check and replace
86 * SFP/cable */
87 BFA_STATUS_MISSINGFRM = 50, /* Missing frame check and replace
88 * SFP/cable */
89 BFA_STATUS_LINKTIMEOUT = 51, /* Link timeout check and replace
90 * SFP/cable */
91 BFA_STATUS_NO_FCPIM_NEXUS = 52, /* No FCP Nexus exists with the
92 * rport */
93 BFA_STATUS_CHECKSUM_FAIL = 53, /* checksum failure */
94 BFA_STATUS_GZME_FAILED = 54, /* Get zone member query failed */
95 BFA_STATUS_SCSISTART_REQD = 55, /* SCSI disk require START command */
96 BFA_STATUS_IOC_FAILURE = 56, /* IOC failure - Retry, if persists
97 * contact support */
98 BFA_STATUS_INVALID_WWN = 57, /* Invalid WWN */
99 BFA_STATUS_MISMATCH = 58, /* Version mismatch */
100 BFA_STATUS_IOC_ENABLED = 59, /* IOC is already enabled */
101 BFA_STATUS_ADAPTER_ENABLED = 60, /* Adapter is not disabled disable
102 * adapter first */
103 BFA_STATUS_IOC_NON_OP = 61, /* IOC is not operational. Enable IOC
104 * and if it still fails,
105 * contact support */
106 BFA_STATUS_ADDR_MAP_FAILURE = 62, /* PCI base address not mapped
107 * in OS */
108 BFA_STATUS_SAME_NAME = 63, /* Name exists! use a different
109 * name */
110 BFA_STATUS_PENDING = 64, /* API completes asynchronously */
111 BFA_STATUS_8G_SPD = 65, /* Speed setting not valid for
112 * 8G HBA */
113 BFA_STATUS_4G_SPD = 66, /* Speed setting not valid for
114 * 4G HBA */
115 BFA_STATUS_AD_IS_ENABLE = 67, /* Adapter is already enabled */
116 BFA_STATUS_EINVAL_TOV = 68, /* Invalid path failover TOV */
117 BFA_STATUS_EINVAL_QDEPTH = 69, /* Invalid queue depth value */
118 BFA_STATUS_VERSION_FAIL = 70, /* Application/Driver version
119 * mismatch */
120 BFA_STATUS_DIAG_BUSY = 71, /* diag busy */
121 BFA_STATUS_BEACON_ON = 72, /* Port Beacon already on */
122 BFA_STATUS_BEACON_OFF = 73, /* Port Beacon already off */
123 BFA_STATUS_LBEACON_ON = 74, /* Link End-to-End Beacon already
124 * on */
125 BFA_STATUS_LBEACON_OFF = 75, /* Link End-to-End Beacon already
126 * off */
127 BFA_STATUS_PORT_NOT_INITED = 76, /* Port not initialized */
128 BFA_STATUS_RPSC_ENABLED = 77, /* Target has a valid speed */
129 BFA_STATUS_ENOFSAVE = 78, /* No saved firmware trace */
130 BFA_STATUS_BAD_FILE = 79, /* Not a valid Brocade Boot Code
131 * file */
132 BFA_STATUS_RLIM_EN = 80, /* Target rate limiting is already
133 * enabled */
134 BFA_STATUS_RLIM_DIS = 81, /* Target rate limiting is already
135 * disabled */
136 BFA_STATUS_IOC_DISABLED = 82, /* IOC is already disabled */
137 BFA_STATUS_ADAPTER_DISABLED = 83, /* Adapter is already disabled */
138 BFA_STATUS_BIOS_DISABLED = 84, /* Bios is already disabled */
139 BFA_STATUS_AUTH_ENABLED = 85, /* Authentication is already
140 * enabled */
141 BFA_STATUS_AUTH_DISABLED = 86, /* Authentication is already
142 * disabled */
143 BFA_STATUS_ERROR_TRL_ENABLED = 87, /* Target rate limiting is
144 * enabled */
145 BFA_STATUS_ERROR_QOS_ENABLED = 88, /* QoS is enabled */
146 BFA_STATUS_NO_SFP_DEV = 89, /* No SFP device check or replace SFP */
147 BFA_STATUS_MEMTEST_FAILED = 90, /* Memory test failed contact
148 * support */
149 BFA_STATUS_INVALID_DEVID = 91, /* Invalid device id provided */
150 BFA_STATUS_QOS_ENABLED = 92, /* QOS is already enabled */
151 BFA_STATUS_QOS_DISABLED = 93, /* QOS is already disabled */
152 BFA_STATUS_INCORRECT_DRV_CONFIG = 94, /* Check configuration
153 * key/value pair */
154 BFA_STATUS_REG_FAIL = 95, /* Can't read windows registry */
155 BFA_STATUS_IM_INV_CODE = 96, /* Invalid IOCTL code */
156 BFA_STATUS_IM_INV_VLAN = 97, /* Invalid VLAN ID */
157 BFA_STATUS_IM_INV_ADAPT_NAME = 98, /* Invalid adapter name */
158 BFA_STATUS_IM_LOW_RESOURCES = 99, /* Memory allocation failure in
159 * driver */
160 BFA_STATUS_IM_VLANID_IS_PVID = 100, /* Given VLAN id same as PVID */
161 BFA_STATUS_IM_VLANID_EXISTS = 101, /* Given VLAN id already exists */
162 BFA_STATUS_IM_FW_UPDATE_FAIL = 102, /* Updating firmware with new
163 * VLAN ID failed */
164 BFA_STATUS_PORTLOG_ENABLED = 103, /* Port Log is already enabled */
165 BFA_STATUS_PORTLOG_DISABLED = 104, /* Port Log is already disabled */
166 BFA_STATUS_FILE_NOT_FOUND = 105, /* Specified file could not be
167 * found */
168 BFA_STATUS_QOS_FC_ONLY = 106, /* QOS can be enabled for FC mode
169 * only */
170 BFA_STATUS_RLIM_FC_ONLY = 107, /* RATELIM can be enabled for FC mode
171 * only */
172 BFA_STATUS_CT_SPD = 108, /* Invalid speed selection for Catapult. */
173 BFA_STATUS_LEDTEST_OP = 109, /* LED test is operating */
174 BFA_STATUS_CEE_NOT_DN = 110, /* eth port is not at down state, please
175 * bring down first */
176 BFA_STATUS_10G_SPD = 111, /* Speed setting not valid for 10G HBA */
177 BFA_STATUS_IM_INV_TEAM_NAME = 112, /* Invalid team name */
178 BFA_STATUS_IM_DUP_TEAM_NAME = 113, /* Given team name already
179 * exists */
180 BFA_STATUS_IM_ADAPT_ALREADY_IN_TEAM = 114, /* Given adapter is part
181 * of another team */
182 BFA_STATUS_IM_ADAPT_HAS_VLANS = 115, /* Adapter has VLANs configured.
183 * Delete all VLANs before
184 * creating team */
185 BFA_STATUS_IM_PVID_MISMATCH = 116, /* Mismatching PVIDs configured
186 * for adapters */
187 BFA_STATUS_IM_LINK_SPEED_MISMATCH = 117, /* Mismatching link speeds
188 * configured for adapters */
189 BFA_STATUS_IM_MTU_MISMATCH = 118, /* Mismatching MTUs configured for
190 * adapters */
191 BFA_STATUS_IM_RSS_MISMATCH = 119, /* Mismatching RSS parameters
192 * configured for adapters */
193 BFA_STATUS_IM_HDS_MISMATCH = 120, /* Mismatching HDS parameters
194 * configured for adapters */
195 BFA_STATUS_IM_OFFLOAD_MISMATCH = 121, /* Mismatching offload
196 * parameters configured for
197 * adapters */
198 BFA_STATUS_IM_PORT_PARAMS = 122, /* Error setting port parameters */
199 BFA_STATUS_IM_PORT_NOT_IN_TEAM = 123, /* Port is not part of team */
200 BFA_STATUS_IM_CANNOT_REM_PRI = 124, /* Primary adapter cannot be
201 * removed. Change primary before
202 * removing */
203 BFA_STATUS_IM_MAX_PORTS_REACHED = 125, /* Exceeding maximum ports
204 * per team */
205 BFA_STATUS_IM_LAST_PORT_DELETE = 126, /* Last port in team being
206 * deleted */
207 BFA_STATUS_IM_NO_DRIVER = 127, /* IM driver is not installed */
208 BFA_STATUS_IM_MAX_VLANS_REACHED = 128, /* Exceeding maximum VLANs
209 * per port */
210 BFA_STATUS_TOMCAT_SPD_NOT_ALLOWED = 129, /* Bios speed config not
211 * allowed for CNA */
212 BFA_STATUS_NO_MINPORT_DRIVER = 130, /* Miniport driver is not
213 * loaded */
214 BFA_STATUS_CARD_TYPE_MISMATCH = 131, /* Card type mismatch */
215 BFA_STATUS_BAD_ASICBLK = 132, /* Bad ASIC block */
216 BFA_STATUS_NO_DRIVER = 133, /* Storage/Ethernet driver not loaded */
217 BFA_STATUS_INVALID_MAC = 134, /* Invalid mac address */
218 BFA_STATUS_IM_NO_VLAN = 135, /* No VLANs configured on the adapter */
219 BFA_STATUS_IM_ETH_LB_FAILED = 136, /* Ethernet loopback test failed */
220 BFA_STATUS_IM_PVID_REMOVE = 137, /* Cannot remove port vlan (PVID) */
221 BFA_STATUS_IM_PVID_EDIT = 138, /* Cannot edit port vlan (PVID) */
222 BFA_STATUS_CNA_NO_BOOT = 139, /* Boot upload not allowed for CNA */
223 BFA_STATUS_IM_PVID_NON_ZERO = 140, /* Port VLAN ID (PVID) is Set to
224 * Non-Zero Value */
225 BFA_STATUS_IM_INETCFG_LOCK_FAILED = 141, /* Acquiring Network
226 * Subsytem Lock Failed.Please
227 * try after some time */
228 BFA_STATUS_IM_GET_INETCFG_FAILED = 142, /* Acquiring Network Subsytem
229 * handle Failed. Please try
230 * after some time */
231 BFA_STATUS_IM_NOT_BOUND = 143, /* Brocade 10G Ethernet Service is not
232 * Enabled on this port */
233 BFA_STATUS_INSUFFICIENT_PERMS = 144, /* User doesn't have sufficient
234 * permissions to execute the BCU
235 * application */
236 BFA_STATUS_IM_INV_VLAN_NAME = 145, /* Invalid/Reserved Vlan name
237 * string. The name is not allowed
238 * for the normal Vlans */
239 BFA_STATUS_CMD_NOTSUPP_CNA = 146, /* Command not supported for CNA */
240 BFA_STATUS_IM_PASSTHRU_EDIT = 147, /* Can not edit passthru vlan id */
241 BFA_STATUS_IM_BIND_FAILED = 148, /*! < IM Driver bind operation
242 * failed */
243 BFA_STATUS_IM_UNBIND_FAILED = 149, /* ! < IM Driver unbind operation
244 * failed */
245 BFA_STATUS_MAX_VAL /* Unknown error code */
246};
247#define bfa_status_t enum bfa_status
248
249enum bfa_eproto_status {
250 BFA_EPROTO_BAD_ACCEPT = 0,
251 BFA_EPROTO_UNKNOWN_RSP = 1
252};
253#define bfa_eproto_status_t enum bfa_eproto_status
254
255#endif /* __BFA_DEFS_STATUS_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_tin.h b/drivers/scsi/bfa/include/defs/bfa_defs_tin.h
new file mode 100644
index 000000000000..e05a2db7abed
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_tin.h
@@ -0,0 +1,118 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFA_DEFS_TIN_H__
19#define __BFA_DEFS_TIN_H__
20
21#include <protocol/types.h>
22#include <protocol/fc.h>
23
24/**
25 * FCS tin states
26 */
27enum bfa_tin_state_e {
28 BFA_TIN_SM_OFFLINE = 0, /* tin is offline */
29 BFA_TIN_SM_WOS_LOGIN = 1, /* Waiting PRLI ACC/RJT from ULP */
30 BFA_TIN_SM_WFW_ONLINE = 2, /* Waiting ACK to PRLI ACC from FW */
31 BFA_TIN_SM_ONLINE = 3, /* tin login is complete */
32 BFA_TIN_SM_WIO_RELOGIN = 4, /* tin relogin is in progress */
33 BFA_TIN_SM_WIO_LOGOUT = 5, /* Processing of PRLO req from
34 * Initiator is in progress
35 */
36 BFA_TIN_SM_WOS_LOGOUT = 6, /* Processing of PRLO req from
37 * Initiator is in progress
38 */
39 BFA_TIN_SM_WIO_CLEAN = 7, /* Waiting for IO cleanup before tin
40 * is offline. This can be triggered
41 * by RPORT LOGO (rcvd/sent) or by
42 * PRLO (rcvd/sent)
43 */
44};
45
46struct bfa_prli_req_s {
47 struct fchs_s fchs;
48 struct fc_prli_s prli_payload;
49};
50
51struct bfa_prlo_req_s {
52 struct fchs_s fchs;
53 struct fc_prlo_s prlo_payload;
54};
55
56void bfa_tin_send_login_rsp(void *bfa_tin, u32 login_rsp,
57 struct fc_ls_rjt_s rjt_payload);
58void bfa_tin_send_logout_rsp(void *bfa_tin, u32 logout_rsp,
59 struct fc_ls_rjt_s rjt_payload);
60/**
61 * FCS target port statistics
62 */
63struct bfa_tin_stats_s {
64 u32 onlines; /* ITN nexus onlines (PRLI done) */
65 u32 offlines; /* ITN Nexus offlines */
66 u32 prli_req_parse_err; /* prli req parsing errors */
67 u32 prli_rsp_rjt; /* num prli rsp rejects sent */
68 u32 prli_rsp_acc; /* num prli rsp accepts sent */
69 u32 cleanup_comps; /* ITN cleanup completions */
70};
71
72/**
73 * FCS tin attributes returned in queries
74 */
75struct bfa_tin_attr_s {
76 enum bfa_tin_state_e state;
77 u8 seq_retry; /* Sequence retry supported */
78 u8 rsvd[3];
79};
80
81/**
82 * BFA TIN async event data structure for BFAL
83 */
84enum bfa_tin_aen_event {
85 BFA_TIN_AEN_ONLINE = 1, /* Target online */
86 BFA_TIN_AEN_OFFLINE = 2, /* Target offline */
87 BFA_TIN_AEN_DISCONNECT = 3, /* Target disconnected */
88};
89
90/**
91 * BFA TIN event data structure.
92 */
93struct bfa_tin_aen_data_s {
94 u16 vf_id; /* vf_id of the IT nexus */
95 u16 rsvd[3];
96 wwn_t lpwwn; /* WWN of logical port */
97 wwn_t rpwwn; /* WWN of remote(target) port */
98};
99
100/**
101 * Below APIs are needed from BFA driver
102 * Move these to BFA driver public header file?
103 */
104/* TIN rcvd new PRLI & gets bfad_tin_t ptr from driver this callback */
105void *bfad_tin_rcvd_login_req(void *bfad_tm_port, void *bfa_tin,
106 wwn_t rp_wwn, u32 rp_fcid,
107 struct bfa_prli_req_s prli_req);
108/* TIN rcvd new PRLO */
109void bfad_tin_rcvd_logout_req(void *bfad_tin, wwn_t rp_wwn, u32 rp_fcid,
110 struct bfa_prlo_req_s prlo_req);
111/* TIN is online and ready for IO */
112void bfad_tin_online(void *bfad_tin);
113/* TIN is offline and BFA driver can shutdown its upper stack */
114void bfad_tin_offline(void *bfad_tin);
115/* TIN does not need this BFA driver tin tag anymore, so can be freed */
116void bfad_tin_res_free(void *bfad_tin);
117
118#endif /* __BFA_DEFS_TIN_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_tsensor.h b/drivers/scsi/bfa/include/defs/bfa_defs_tsensor.h
new file mode 100644
index 000000000000..31881d218515
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_tsensor.h
@@ -0,0 +1,43 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFA_DEFS_TSENSOR_H__
19#define __BFA_DEFS_TSENSOR_H__
20
21#include <bfa_os_inc.h>
22#include <defs/bfa_defs_types.h>
23
24/**
25 * Temperature sensor status values
26 */
27enum bfa_tsensor_status {
28 BFA_TSENSOR_STATUS_UNKNOWN = 1, /* unkown status */
29 BFA_TSENSOR_STATUS_FAULTY = 2, /* sensor is faulty */
30 BFA_TSENSOR_STATUS_BELOW_MIN = 3, /* temperature below mininum */
31 BFA_TSENSOR_STATUS_NOMINAL = 4, /* normal temperature */
32 BFA_TSENSOR_STATUS_ABOVE_MAX = 5, /* temperature above maximum */
33};
34
35/**
36 * Temperature sensor attribute
37 */
38struct bfa_tsensor_attr_s {
39 enum bfa_tsensor_status status; /* temperature sensor status */
40 u32 value; /* current temperature in celsius */
41};
42
43#endif /* __BFA_DEFS_TSENSOR_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_types.h b/drivers/scsi/bfa/include/defs/bfa_defs_types.h
new file mode 100644
index 000000000000..4348332b107a
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_types.h
@@ -0,0 +1,30 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17#ifndef __BFA_DEFS_TYPES_H__
18#define __BFA_DEFS_TYPES_H__
19
20#include <bfa_os_inc.h>
21
22enum bfa_boolean {
23 BFA_FALSE = 0,
24 BFA_TRUE = 1
25};
26#define bfa_boolean_t enum bfa_boolean
27
28#define BFA_STRING_32 32
29
30#endif /* __BFA_DEFS_TYPES_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_version.h b/drivers/scsi/bfa/include/defs/bfa_defs_version.h
new file mode 100644
index 000000000000..f8902a2c9aad
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_version.h
@@ -0,0 +1,22 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17#ifndef __BFA_DEFS_VERSION_H__
18#define __BFA_DEFS_VERSION_H__
19
20#define BFA_VERSION_LEN 64
21
22#endif
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_vf.h b/drivers/scsi/bfa/include/defs/bfa_defs_vf.h
new file mode 100644
index 000000000000..3235be5e9423
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_vf.h
@@ -0,0 +1,74 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFA_DEFS_VF_H__
19#define __BFA_DEFS_VF_H__
20
21#include <bfa_os_inc.h>
22#include <defs/bfa_defs_port.h>
23#include <protocol/types.h>
24
25/**
26 * VF states
27 */
28enum bfa_vf_state {
29 BFA_VF_UNINIT = 0, /* fabric is not yet initialized */
30 BFA_VF_LINK_DOWN = 1, /* link is down */
31 BFA_VF_FLOGI = 2, /* flogi is in progress */
32 BFA_VF_AUTH = 3, /* authentication in progress */
33 BFA_VF_NOFABRIC = 4, /* fabric is not present */
34 BFA_VF_ONLINE = 5, /* login to fabric is complete */
35 BFA_VF_EVFP = 6, /* EVFP is in progress */
36 BFA_VF_ISOLATED = 7, /* port isolated due to vf_id mismatch */
37};
38
39/**
40 * VF statistics
41 */
42struct bfa_vf_stats_s {
43 u32 flogi_sent; /* Num FLOGIs sent */
44 u32 flogi_rsp_err; /* FLOGI response errors */
45 u32 flogi_acc_err; /* FLOGI accept errors */
46 u32 flogi_accepts; /* FLOGI accepts received */
47 u32 flogi_rejects; /* FLOGI rejects received */
48 u32 flogi_unknown_rsp; /* Unknown responses for FLOGI */
49 u32 flogi_alloc_wait; /* Allocation waits prior to
50 * sending FLOGI
51 */
52 u32 flogi_rcvd; /* FLOGIs received */
53 u32 flogi_rejected; /* Incoming FLOGIs rejected */
54 u32 fabric_onlines; /* Internal fabric online
55 * notification sent to other
56 * modules
57 */
58 u32 fabric_offlines; /* Internal fabric offline
59 * notification sent to other
60 * modules
61 */
62 u32 resvd;
63};
64
65/**
66 * VF attributes returned in queries
67 */
68struct bfa_vf_attr_s {
69 enum bfa_vf_state state; /* VF state */
70 u32 rsvd;
71 wwn_t fabric_name; /* fabric name */
72};
73
74#endif /* __BFA_DEFS_VF_H__ */
diff --git a/drivers/scsi/bfa/include/defs/bfa_defs_vport.h b/drivers/scsi/bfa/include/defs/bfa_defs_vport.h
new file mode 100644
index 000000000000..9f021f43b3b4
--- /dev/null
+++ b/drivers/scsi/bfa/include/defs/bfa_defs_vport.h
@@ -0,0 +1,91 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFA_DEFS_VPORT_H__
19#define __BFA_DEFS_VPORT_H__
20
21#include <bfa_os_inc.h>
22#include <defs/bfa_defs_port.h>
23#include <protocol/types.h>
24
25/**
26 * VPORT states
27 */
28enum bfa_vport_state {
29 BFA_FCS_VPORT_UNINIT = 0,
30 BFA_FCS_VPORT_CREATED = 1,
31 BFA_FCS_VPORT_OFFLINE = 1,
32 BFA_FCS_VPORT_FDISC_SEND = 2,
33 BFA_FCS_VPORT_FDISC = 3,
34 BFA_FCS_VPORT_FDISC_RETRY = 4,
35 BFA_FCS_VPORT_ONLINE = 5,
36 BFA_FCS_VPORT_DELETING = 6,
37 BFA_FCS_VPORT_CLEANUP = 6,
38 BFA_FCS_VPORT_LOGO_SEND = 7,
39 BFA_FCS_VPORT_LOGO = 8,
40 BFA_FCS_VPORT_ERROR = 9,
41 BFA_FCS_VPORT_MAX_STATE,
42};
43
44/**
45 * vport statistics
46 */
47struct bfa_vport_stats_s {
48 struct bfa_port_stats_s port_stats; /* base class (port) stats */
49 /*
50 * TODO - remove
51 */
52
53 u32 fdisc_sent; /* num fdisc sent */
54 u32 fdisc_accepts; /* fdisc accepts */
55 u32 fdisc_retries; /* fdisc retries */
56 u32 fdisc_timeouts; /* fdisc timeouts */
57 u32 fdisc_rsp_err; /* fdisc response error */
58 u32 fdisc_acc_bad; /* bad fdisc accepts */
59 u32 fdisc_rejects; /* fdisc rejects */
60 u32 fdisc_unknown_rsp;
61 /*
62 *!< fdisc rsp unknown error
63 */
64 u32 fdisc_alloc_wait;/* fdisc req (fcxp)alloc wait */
65
66 u32 logo_alloc_wait;/* logo req (fcxp) alloc wait */
67 u32 logo_sent; /* logo sent */
68 u32 logo_accepts; /* logo accepts */
69 u32 logo_rejects; /* logo rejects */
70 u32 logo_rsp_err; /* logo rsp errors */
71 u32 logo_unknown_rsp;
72 /* logo rsp unknown errors */
73
74 u32 fab_no_npiv; /* fabric does not support npiv */
75
76 u32 fab_offline; /* offline events from fab SM */
77 u32 fab_online; /* online events from fab SM */
78 u32 fab_cleanup; /* cleanup request from fab SM */
79 u32 rsvd;
80};
81
82/**
83 * BFA vport attribute returned in queries
84 */
85struct bfa_vport_attr_s {
86 struct bfa_port_attr_s port_attr; /* base class (port) attributes */
87 enum bfa_vport_state vport_state; /* vport state */
88 u32 rsvd;
89};
90
91#endif /* __BFA_DEFS_VPORT_H__ */
diff --git a/drivers/scsi/bfa/include/fcb/bfa_fcb.h b/drivers/scsi/bfa/include/fcb/bfa_fcb.h
new file mode 100644
index 000000000000..2963b0bc30e7
--- /dev/null
+++ b/drivers/scsi/bfa/include/fcb/bfa_fcb.h
@@ -0,0 +1,33 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * bfa_fcb.h BFA FCS callback interfaces
20 */
21
22#ifndef __BFA_FCB_H__
23#define __BFA_FCB_H__
24
25/**
26 * fcb Main fcs callbacks
27 */
28
29void bfa_fcb_exit(struct bfad_s *bfad);
30
31
32
33#endif /* __BFA_FCB_H__ */
diff --git a/drivers/scsi/bfa/include/fcb/bfa_fcb_fcpim.h b/drivers/scsi/bfa/include/fcb/bfa_fcb_fcpim.h
new file mode 100644
index 000000000000..a6c70aee0aa3
--- /dev/null
+++ b/drivers/scsi/bfa/include/fcb/bfa_fcb_fcpim.h
@@ -0,0 +1,76 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19* : bfad_fcpim.h - BFA FCS initiator mode remote port callbacks
20 */
21
22#ifndef __BFAD_FCB_FCPIM_H__
23#define __BFAD_FCB_FCPIM_H__
24
25struct bfad_itnim_s;
26
27/*
28 * RPIM callbacks
29 */
30
31/**
32 * Memory allocation for remote port instance. Called before PRLI is
33 * initiated to the remote target port.
34 *
35 * @param[in] bfad - driver instance
36 * @param[out] itnim - FCS remote port (IM) instance
37 * @param[out] itnim_drv - driver remote port (IM) instance
38 *
39 * @return None
40 */
41void bfa_fcb_itnim_alloc(struct bfad_s *bfad, struct bfa_fcs_itnim_s **itnim,
42 struct bfad_itnim_s **itnim_drv);
43
44/**
45 * Free remote port (IM) instance.
46 *
47 * @param[in] bfad - driver instance
48 * @param[in] itnim_drv - driver remote port instance
49 *
50 * @return None
51 */
52void bfa_fcb_itnim_free(struct bfad_s *bfad,
53 struct bfad_itnim_s *itnim_drv);
54
55/**
56 * Notification of when login with a remote target device is complete.
57 *
58 * @param[in] itnim_drv - driver remote port instance
59 *
60 * @return None
61 */
62void bfa_fcb_itnim_online(struct bfad_itnim_s *itnim_drv);
63
64/**
65 * Notification when login with the remote device is severed.
66 *
67 * @param[in] itnim_drv - driver remote port instance
68 *
69 * @return None
70 */
71void bfa_fcb_itnim_offline(struct bfad_itnim_s *itnim_drv);
72
73void bfa_fcb_itnim_tov_begin(struct bfad_itnim_s *itnim_drv);
74void bfa_fcb_itnim_tov(struct bfad_itnim_s *itnim_drv);
75
76#endif /* __BFAD_FCB_FCPIM_H__ */
diff --git a/drivers/scsi/bfa/include/fcb/bfa_fcb_port.h b/drivers/scsi/bfa/include/fcb/bfa_fcb_port.h
new file mode 100644
index 000000000000..5fd7f986fa32
--- /dev/null
+++ b/drivers/scsi/bfa/include/fcb/bfa_fcb_port.h
@@ -0,0 +1,113 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * bfa_fcb_port.h BFA FCS virtual port driver interfaces
20 */
21
22#ifndef __BFA_FCB_PORT_H__
23#define __BFA_FCB_PORT_H__
24
25#include <fcb/bfa_fcb_vport.h>
26/**
27 * fcs_port_fcb FCS port driver interfaces
28 */
29
30/*
31 * Forward declarations
32 */
33struct bfad_port_s;
34
35/*
36 * Callback functions from BFA FCS to driver
37 */
38
39/**
40 * Call from FCS to driver module when a port is instantiated. The port
41 * can be a base port or a virtual port with in the base fabric or
42 * a virtual fabric.
43 *
44 * On this callback, driver is supposed to create scsi_host, scsi_tgt or
45 * network interfaces bases on ports personality/roles.
46 *
47 * base port of base fabric: vf_drv == NULL && vp_drv == NULL
48 * vport of base fabric: vf_drv == NULL && vp_drv != NULL
49 * base port of VF: vf_drv != NULL && vp_drv == NULL
50 * vport of VF: vf_drv != NULL && vp_drv != NULL
51 *
52 * @param[in] bfad - driver instance
53 * @param[in] port - FCS port instance
54 * @param[in] roles - port roles: IM, TM, IP
55 * @param[in] vf_drv - VF driver instance, NULL if base fabric (no VF)
56 * @param[in] vp_drv - vport driver instance, NULL if base port
57 *
58 * @return None
59 */
60struct bfad_port_s *bfa_fcb_port_new(struct bfad_s *bfad,
61 struct bfa_fcs_port_s *port,
62 enum bfa_port_role roles, struct bfad_vf_s *vf_drv,
63 struct bfad_vport_s *vp_drv);
64
65/**
66 * Call from FCS to driver module when a port is deleted. The port
67 * can be a base port or a virtual port with in the base fabric or
68 * a virtual fabric.
69 *
70 * @param[in] bfad - driver instance
71 * @param[in] roles - port roles: IM, TM, IP
72 * @param[in] vf_drv - VF driver instance, NULL if base fabric (no VF)
73 * @param[in] vp_drv - vport driver instance, NULL if base port
74 *
75 * @return None
76 */
77void bfa_fcb_port_delete(struct bfad_s *bfad, enum bfa_port_role roles,
78 struct bfad_vf_s *vf_drv, struct bfad_vport_s *vp_drv);
79
80/**
81 * Notification when port transitions to ONLINE state.
82 *
83 * Online notification is a logical link up for the local port. This
84 * notification is sent after a successfull FLOGI, or a successful
85 * link initialization in proviate-loop or N2N topologies.
86 *
87 * @param[in] bfad - driver instance
88 * @param[in] roles - port roles: IM, TM, IP
89 * @param[in] vf_drv - VF driver instance, NULL if base fabric (no VF)
90 * @param[in] vp_drv - vport driver instance, NULL if base port
91 *
92 * @return None
93 */
94void bfa_fcb_port_online(struct bfad_s *bfad, enum bfa_port_role roles,
95 struct bfad_vf_s *vf_drv, struct bfad_vport_s *vp_drv);
96
97/**
98 * Notification when port transitions to OFFLINE state.
99 *
100 * Offline notification is a logical link down for the local port.
101 *
102 * @param[in] bfad - driver instance
103 * @param[in] roles - port roles: IM, TM, IP
104 * @param[in] vf_drv - VF driver instance, NULL if base fabric (no VF)
105 * @param[in] vp_drv - vport driver instance, NULL if base port
106 *
107 * @return None
108 */
109void bfa_fcb_port_offline(struct bfad_s *bfad, enum bfa_port_role roles,
110 struct bfad_vf_s *vf_drv, struct bfad_vport_s *vp_drv);
111
112
113#endif /* __BFA_FCB_PORT_H__ */
diff --git a/drivers/scsi/bfa/include/fcb/bfa_fcb_rport.h b/drivers/scsi/bfa/include/fcb/bfa_fcb_rport.h
new file mode 100644
index 000000000000..e0261bb6d1c1
--- /dev/null
+++ b/drivers/scsi/bfa/include/fcb/bfa_fcb_rport.h
@@ -0,0 +1,80 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * bfa_fcb_rport.h BFA FCS rport driver interfaces
20 */
21
22#ifndef __BFA_FCB_RPORT_H__
23#define __BFA_FCB_RPORT_H__
24
25/**
26 * fcs_rport_fcb Remote port driver interfaces
27 */
28
29
30struct bfad_rport_s;
31
32/*
33 * Callback functions from BFA FCS to driver
34 */
35
36/**
37 * Completion callback for bfa_fcs_rport_add().
38 *
39 * @param[in] rport_drv - driver instance of rport
40 *
41 * @return None
42 */
43void bfa_fcb_rport_add(struct bfad_rport_s *rport_drv);
44
45/**
46 * Completion callback for bfa_fcs_rport_remove().
47 *
48 * @param[in] rport_drv - driver instance of rport
49 *
50 * @return None
51 */
52void bfa_fcb_rport_remove(struct bfad_rport_s *rport_drv);
53
54/**
55 * Call to allocate a rport instance.
56 *
57 * @param[in] bfad - driver instance
58 * @param[out] rport - BFA FCS instance of rport
59 * @param[out] rport_drv - driver instance of rport
60 *
61 * @retval BFA_STATUS_OK - successfully allocated
62 * @retval BFA_STATUS_ENOMEM - cannot allocate
63 */
64bfa_status_t bfa_fcb_rport_alloc(struct bfad_s *bfad,
65 struct bfa_fcs_rport_s **rport,
66 struct bfad_rport_s **rport_drv);
67
68/**
69 * Call to free rport memory resources.
70 *
71 * @param[in] bfad - driver instance
72 * @param[in] rport_drv - driver instance of rport
73 *
74 * @return None
75 */
76void bfa_fcb_rport_free(struct bfad_s *bfad, struct bfad_rport_s **rport_drv);
77
78
79
80#endif /* __BFA_FCB_RPORT_H__ */
diff --git a/drivers/scsi/bfa/include/fcb/bfa_fcb_vf.h b/drivers/scsi/bfa/include/fcb/bfa_fcb_vf.h
new file mode 100644
index 000000000000..cfd3fac0a4e2
--- /dev/null
+++ b/drivers/scsi/bfa/include/fcb/bfa_fcb_vf.h
@@ -0,0 +1,47 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * bfa_fcb_vf.h BFA FCS virtual fabric driver interfaces
20 */
21
22#ifndef __BFA_FCB_VF_H__
23#define __BFA_FCB_VF_H__
24
25/**
26 * fcs_vf_fcb Virtual fabric driver intrefaces
27 */
28
29
30struct bfad_vf_s;
31
32/*
33 * Callback functions from BFA FCS to driver
34 */
35
36/**
37 * Completion callback for bfa_fcs_vf_stop().
38 *
39 * @param[in] vf_drv - driver instance of vf
40 *
41 * @return None
42 */
43void bfa_fcb_vf_stop(struct bfad_vf_s *vf_drv);
44
45
46
47#endif /* __BFA_FCB_VF_H__ */
diff --git a/drivers/scsi/bfa/include/fcb/bfa_fcb_vport.h b/drivers/scsi/bfa/include/fcb/bfa_fcb_vport.h
new file mode 100644
index 000000000000..a39f474c2fcf
--- /dev/null
+++ b/drivers/scsi/bfa/include/fcb/bfa_fcb_vport.h
@@ -0,0 +1,47 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * bfa_fcb_vport.h BFA FCS virtual port driver interfaces
20 */
21
22#ifndef __BFA_FCB_VPORT_H__
23#define __BFA_FCB_VPORT_H__
24
25/**
26 * fcs_vport_fcb Virtual port driver interfaces
27 */
28
29
30struct bfad_vport_s;
31
32/*
33 * Callback functions from BFA FCS to driver
34 */
35
36/**
37 * Completion callback for bfa_fcs_vport_delete().
38 *
39 * @param[in] vport_drv - driver instance of vport
40 *
41 * @return None
42 */
43void bfa_fcb_vport_delete(struct bfad_vport_s *vport_drv);
44
45
46
47#endif /* __BFA_FCB_VPORT_H__ */
diff --git a/drivers/scsi/bfa/include/fcs/bfa_fcs.h b/drivers/scsi/bfa/include/fcs/bfa_fcs.h
new file mode 100644
index 000000000000..627669c65546
--- /dev/null
+++ b/drivers/scsi/bfa/include/fcs/bfa_fcs.h
@@ -0,0 +1,73 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFA_FCS_H__
19#define __BFA_FCS_H__
20
21#include <cs/bfa_debug.h>
22#include <defs/bfa_defs_status.h>
23#include <defs/bfa_defs_version.h>
24#include <bfa.h>
25#include <fcs/bfa_fcs_fabric.h>
26
27#define BFA_FCS_OS_STR_LEN 64
28
29struct bfa_fcs_stats_s {
30 struct {
31 u32 untagged; /* untagged receive frames */
32 u32 tagged; /* tagged receive frames */
33 u32 vfid_unknown; /* VF id is unknown */
34 } uf;
35};
36
37struct bfa_fcs_driver_info_s {
38 u8 version[BFA_VERSION_LEN]; /* Driver Version */
39 u8 host_machine_name[BFA_FCS_OS_STR_LEN];
40 u8 host_os_name[BFA_FCS_OS_STR_LEN]; /* OS name and version */
41 u8 host_os_patch[BFA_FCS_OS_STR_LEN];/* patch or service pack */
42 u8 os_device_name[BFA_FCS_OS_STR_LEN]; /* Driver Device Name */
43};
44
45struct bfa_fcs_s {
46 struct bfa_s *bfa; /* corresponding BFA bfa instance */
47 struct bfad_s *bfad; /* corresponding BDA driver instance */
48 struct bfa_log_mod_s *logm; /* driver logging module instance */
49 struct bfa_trc_mod_s *trcmod; /* tracing module */
50 struct bfa_aen_s *aen; /* aen component */
51 bfa_boolean_t vf_enabled; /* VF mode is enabled */
52 bfa_boolean_t min_cfg; /* min cfg enabled/disabled */
53 u16 port_vfid; /* port default VF ID */
54 struct bfa_fcs_driver_info_s driver_info;
55 struct bfa_fcs_fabric_s fabric; /* base fabric state machine */
56 struct bfa_fcs_stats_s stats; /* FCS statistics */
57 struct bfa_wc_s wc; /* waiting counter */
58};
59
60/*
61 * bfa fcs API functions
62 */
63void bfa_fcs_init(struct bfa_fcs_s *fcs, struct bfa_s *bfa, struct bfad_s *bfad,
64 bfa_boolean_t min_cfg);
65void bfa_fcs_driver_info_init(struct bfa_fcs_s *fcs,
66 struct bfa_fcs_driver_info_s *driver_info);
67void bfa_fcs_exit(struct bfa_fcs_s *fcs);
68void bfa_fcs_trc_init(struct bfa_fcs_s *fcs, struct bfa_trc_mod_s *trcmod);
69void bfa_fcs_log_init(struct bfa_fcs_s *fcs, struct bfa_log_mod_s *logmod);
70void bfa_fcs_aen_init(struct bfa_fcs_s *fcs, struct bfa_aen_s *aen);
71void bfa_fcs_start(struct bfa_fcs_s *fcs);
72
73#endif /* __BFA_FCS_H__ */
diff --git a/drivers/scsi/bfa/include/fcs/bfa_fcs_auth.h b/drivers/scsi/bfa/include/fcs/bfa_fcs_auth.h
new file mode 100644
index 000000000000..28c4c9ff08b3
--- /dev/null
+++ b/drivers/scsi/bfa/include/fcs/bfa_fcs_auth.h
@@ -0,0 +1,82 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFA_FCS_AUTH_H__
19#define __BFA_FCS_AUTH_H__
20
21struct bfa_fcs_s;
22
23#include <defs/bfa_defs_status.h>
24#include <defs/bfa_defs_auth.h>
25#include <defs/bfa_defs_vf.h>
26#include <cs/bfa_q.h>
27#include <cs/bfa_sm.h>
28#include <defs/bfa_defs_pport.h>
29#include <fcs/bfa_fcs_lport.h>
30#include <protocol/fc_sp.h>
31
32struct bfa_fcs_fabric_s;
33
34
35
36struct bfa_fcs_auth_s {
37 bfa_sm_t sm; /* state machine */
38 bfa_boolean_t policy; /* authentication enabled/disabled */
39 enum bfa_auth_status status; /* authentication status */
40 enum auth_rjt_codes rjt_code; /* auth reject status */
41 enum auth_rjt_code_exps rjt_code_exp; /* auth reject reason */
42 enum bfa_auth_algo algo; /* Authentication algorithm */
43 struct bfa_auth_stats_s stats; /* Statistics */
44 enum auth_dh_gid group; /* DH(diffie-hellman) Group */
45 enum bfa_auth_secretsource source; /* Secret source */
46 char secret[BFA_AUTH_SECRET_STRING_LEN];
47 /* secret string */
48 u8 secret_len;
49 /* secret string length */
50 u8 nretries;
51 /* number of retries */
52 struct bfa_fcs_fabric_s *fabric;/* pointer to fabric */
53 u8 sentcode; /* pointer to response data */
54 u8 *response; /* pointer to response data */
55 struct bfa_timer_s delay_timer; /* delay timer */
56 struct bfa_fcxp_s *fcxp; /* pointer to fcxp */
57 struct bfa_fcxp_wqe_s fcxp_wqe;
58};
59
60/**
61 * bfa fcs authentication public functions
62 */
63bfa_status_t bfa_fcs_auth_get_attr(struct bfa_fcs_s *port,
64 struct bfa_auth_attr_s *attr);
65bfa_status_t bfa_fcs_auth_set_policy(struct bfa_fcs_s *port,
66 bfa_boolean_t policy);
67enum bfa_auth_status bfa_fcs_auth_get_status(struct bfa_fcs_s *port);
68bfa_status_t bfa_fcs_auth_set_algo(struct bfa_fcs_s *port,
69 enum bfa_auth_algo algo);
70bfa_status_t bfa_fcs_auth_get_stats(struct bfa_fcs_s *port,
71 struct bfa_auth_stats_s *stats);
72bfa_status_t bfa_fcs_auth_set_dh_group(struct bfa_fcs_s *port, int group);
73bfa_status_t bfa_fcs_auth_set_secretstring(struct bfa_fcs_s *port,
74 char *secret);
75bfa_status_t bfa_fcs_auth_set_secretstring_encrypt(struct bfa_fcs_s *port,
76 u32 secret[], u32 len);
77bfa_status_t bfa_fcs_auth_set_secretsource(struct bfa_fcs_s *port,
78 enum bfa_auth_secretsource src);
79bfa_status_t bfa_fcs_auth_reset_stats(struct bfa_fcs_s *port);
80bfa_status_t bfa_fcs_auth_reinit(struct bfa_fcs_s *port);
81
82#endif /* __BFA_FCS_AUTH_H__ */
diff --git a/drivers/scsi/bfa/include/fcs/bfa_fcs_fabric.h b/drivers/scsi/bfa/include/fcs/bfa_fcs_fabric.h
new file mode 100644
index 000000000000..4ffd2242d3de
--- /dev/null
+++ b/drivers/scsi/bfa/include/fcs/bfa_fcs_fabric.h
@@ -0,0 +1,112 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFA_FCS_FABRIC_H__
19#define __BFA_FCS_FABRIC_H__
20
21struct bfa_fcs_s;
22
23#include <defs/bfa_defs_status.h>
24#include <defs/bfa_defs_vf.h>
25#include <cs/bfa_q.h>
26#include <cs/bfa_sm.h>
27#include <defs/bfa_defs_pport.h>
28#include <fcs/bfa_fcs_lport.h>
29#include <protocol/fc_sp.h>
30#include <fcs/bfa_fcs_auth.h>
31
32/*
33 * forward declaration
34 */
35struct bfad_vf_s;
36
37enum bfa_fcs_fabric_type {
38 BFA_FCS_FABRIC_UNKNOWN = 0,
39 BFA_FCS_FABRIC_SWITCHED = 1,
40 BFA_FCS_FABRIC_PLOOP = 2,
41 BFA_FCS_FABRIC_N2N = 3,
42};
43
44
45struct bfa_fcs_fabric_s {
46 struct list_head qe; /* queue element */
47 bfa_sm_t sm; /* state machine */
48 struct bfa_fcs_s *fcs; /* FCS instance */
49 struct bfa_fcs_port_s bport; /* base logical port */
50 enum bfa_fcs_fabric_type fab_type; /* fabric type */
51 enum bfa_pport_type oper_type; /* current link topology */
52 u8 is_vf; /* is virtual fabric? */
53 u8 is_npiv; /* is NPIV supported ? */
54 u8 is_auth; /* is Security/Auth supported ? */
55 u16 bb_credit; /* BB credit from fabric */
56 u16 vf_id; /* virtual fabric ID */
57 u16 num_vports; /* num vports */
58 u16 rsvd;
59 struct list_head vport_q; /* queue of virtual ports */
60 struct list_head vf_q; /* queue of virtual fabrics */
61 struct bfad_vf_s *vf_drv; /* driver vf structure */
62 struct bfa_timer_s link_timer; /* Link Failure timer. Vport */
63 wwn_t fabric_name; /* attached fabric name */
64 bfa_boolean_t auth_reqd; /* authentication required */
65 struct bfa_timer_s delay_timer; /* delay timer */
66 union {
67 u16 swp_vfid;/* switch port VF id */
68 } event_arg;
69 struct bfa_fcs_auth_s auth; /* authentication config */
70 struct bfa_wc_s wc; /* wait counter for delete */
71 struct bfa_vf_stats_s stats; /* fabric/vf stats */
72 struct bfa_lps_s *lps; /* lport login services */
73 u8 fabric_ip_addr[BFA_FCS_FABRIC_IPADDR_SZ]; /* attached
74 * fabric's ip addr
75 */
76};
77
78#define bfa_fcs_fabric_npiv_capable(__f) (__f)->is_npiv
79#define bfa_fcs_fabric_is_switched(__f) \
80 ((__f)->fab_type == BFA_FCS_FABRIC_SWITCHED)
81
82/**
83 * The design calls for a single implementation of base fabric and vf.
84 */
85#define bfa_fcs_vf_t struct bfa_fcs_fabric_s
86
87struct bfa_vf_event_s {
88 u32 undefined;
89};
90
91/**
92 * bfa fcs vf public functions
93 */
94bfa_status_t bfa_fcs_vf_mode_enable(struct bfa_fcs_s *fcs, u16 vf_id);
95bfa_status_t bfa_fcs_vf_mode_disable(struct bfa_fcs_s *fcs);
96bfa_status_t bfa_fcs_vf_create(bfa_fcs_vf_t *vf, struct bfa_fcs_s *fcs,
97 u16 vf_id, struct bfa_port_cfg_s *port_cfg,
98 struct bfad_vf_s *vf_drv);
99bfa_status_t bfa_fcs_vf_delete(bfa_fcs_vf_t *vf);
100void bfa_fcs_vf_start(bfa_fcs_vf_t *vf);
101bfa_status_t bfa_fcs_vf_stop(bfa_fcs_vf_t *vf);
102void bfa_fcs_vf_list(struct bfa_fcs_s *fcs, u16 *vf_ids, int *nvfs);
103void bfa_fcs_vf_list_all(struct bfa_fcs_s *fcs, u16 *vf_ids, int *nvfs);
104void bfa_fcs_vf_get_attr(bfa_fcs_vf_t *vf, struct bfa_vf_attr_s *vf_attr);
105void bfa_fcs_vf_get_stats(bfa_fcs_vf_t *vf,
106 struct bfa_vf_stats_s *vf_stats);
107void bfa_fcs_vf_clear_stats(bfa_fcs_vf_t *vf);
108void bfa_fcs_vf_get_ports(bfa_fcs_vf_t *vf, wwn_t vpwwn[], int *nports);
109bfa_fcs_vf_t *bfa_fcs_vf_lookup(struct bfa_fcs_s *fcs, u16 vf_id);
110struct bfad_vf_s *bfa_fcs_vf_get_drv_vf(bfa_fcs_vf_t *vf);
111
112#endif /* __BFA_FCS_FABRIC_H__ */
diff --git a/drivers/scsi/bfa/include/fcs/bfa_fcs_fcpim.h b/drivers/scsi/bfa/include/fcs/bfa_fcs_fcpim.h
new file mode 100644
index 000000000000..e719f2c3eb35
--- /dev/null
+++ b/drivers/scsi/bfa/include/fcs/bfa_fcs_fcpim.h
@@ -0,0 +1,131 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * bfa_fcs_fcpim.h BFA FCS FCP Initiator Mode interfaces/defines.
20 */
21
22#ifndef __BFA_FCS_FCPIM_H__
23#define __BFA_FCS_FCPIM_H__
24
25#include <defs/bfa_defs_status.h>
26#include <defs/bfa_defs_itnim.h>
27#include <fcs/bfa_fcs.h>
28#include <fcs/bfa_fcs_rport.h>
29#include <fcs/bfa_fcs_lport.h>
30#include <bfa_fcpim.h>
31
32/*
33 * forward declarations
34 */
35struct bfad_itnim_s;
36
37struct bfa_fcs_itnim_s {
38 bfa_sm_t sm; /* state machine */
39 struct bfa_fcs_rport_s *rport; /* parent remote rport */
40 struct bfad_itnim_s *itnim_drv; /* driver peer instance */
41 struct bfa_fcs_s *fcs; /* fcs instance */
42 struct bfa_timer_s timer; /* timer functions */
43 struct bfa_itnim_s *bfa_itnim; /* BFA itnim struct */
44 bfa_boolean_t seq_rec; /* seq recovery support */
45 bfa_boolean_t rec_support; /* REC supported */
46 bfa_boolean_t conf_comp; /* FCP_CONF support */
47 bfa_boolean_t task_retry_id; /* task retry id supp */
48 struct bfa_fcxp_wqe_s fcxp_wqe; /* wait qelem for fcxp */
49 struct bfa_fcxp_s *fcxp; /* FCXP in use */
50 struct bfa_itnim_stats_s stats; /* itn statistics */
51};
52
53
54static inline struct bfad_port_s *
55bfa_fcs_itnim_get_drvport(struct bfa_fcs_itnim_s *itnim)
56{
57 return itnim->rport->port->bfad_port;
58}
59
60
61static inline struct bfa_fcs_port_s *
62bfa_fcs_itnim_get_port(struct bfa_fcs_itnim_s *itnim)
63{
64 return itnim->rport->port;
65}
66
67
68static inline wwn_t
69bfa_fcs_itnim_get_nwwn(struct bfa_fcs_itnim_s *itnim)
70{
71 return itnim->rport->nwwn;
72}
73
74
75static inline wwn_t
76bfa_fcs_itnim_get_pwwn(struct bfa_fcs_itnim_s *itnim)
77{
78 return itnim->rport->pwwn;
79}
80
81
82static inline u32
83bfa_fcs_itnim_get_fcid(struct bfa_fcs_itnim_s *itnim)
84{
85 return itnim->rport->pid;
86}
87
88
89static inline u32
90bfa_fcs_itnim_get_maxfrsize(struct bfa_fcs_itnim_s *itnim)
91{
92 return itnim->rport->maxfrsize;
93}
94
95
96static inline enum fc_cos
97bfa_fcs_itnim_get_cos(struct bfa_fcs_itnim_s *itnim)
98{
99 return itnim->rport->fc_cos;
100}
101
102
103static inline struct bfad_itnim_s *
104bfa_fcs_itnim_get_drvitn(struct bfa_fcs_itnim_s *itnim)
105{
106 return itnim->itnim_drv;
107}
108
109
110static inline struct bfa_itnim_s *
111bfa_fcs_itnim_get_halitn(struct bfa_fcs_itnim_s *itnim)
112{
113 return itnim->bfa_itnim;
114}
115
116/**
117 * bfa fcs FCP Initiator mode API functions
118 */
119void bfa_fcs_itnim_get_attr(struct bfa_fcs_itnim_s *itnim,
120 struct bfa_itnim_attr_s *attr);
121void bfa_fcs_itnim_get_stats(struct bfa_fcs_itnim_s *itnim,
122 struct bfa_itnim_stats_s *stats);
123struct bfa_fcs_itnim_s *bfa_fcs_itnim_lookup(struct bfa_fcs_port_s *port,
124 wwn_t rpwwn);
125bfa_status_t bfa_fcs_itnim_attr_get(struct bfa_fcs_port_s *port, wwn_t rpwwn,
126 struct bfa_itnim_attr_s *attr);
127bfa_status_t bfa_fcs_itnim_stats_get(struct bfa_fcs_port_s *port, wwn_t rpwwn,
128 struct bfa_itnim_stats_s *stats);
129bfa_status_t bfa_fcs_itnim_stats_clear(struct bfa_fcs_port_s *port,
130 wwn_t rpwwn);
131#endif /* __BFA_FCS_FCPIM_H__ */
diff --git a/drivers/scsi/bfa/include/fcs/bfa_fcs_fdmi.h b/drivers/scsi/bfa/include/fcs/bfa_fcs_fdmi.h
new file mode 100644
index 000000000000..4441fffc9c82
--- /dev/null
+++ b/drivers/scsi/bfa/include/fcs/bfa_fcs_fdmi.h
@@ -0,0 +1,63 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * bfa_fcs_fdmi.h BFA fcs fdmi module public interface
20 */
21
22#ifndef __BFA_FCS_FDMI_H__
23#define __BFA_FCS_FDMI_H__
24#include <bfa_os_inc.h>
25#include <protocol/fdmi.h>
26
27#define BFA_FCS_FDMI_SUPORTED_SPEEDS (FDMI_TRANS_SPEED_1G | \
28 FDMI_TRANS_SPEED_2G | \
29 FDMI_TRANS_SPEED_4G | \
30 FDMI_TRANS_SPEED_8G)
31
32/*
33* HBA Attribute Block : BFA internal representation. Note : Some variable
34* sizes have been trimmed to suit BFA For Ex : Model will be "Brocade". Based
35 * on this the size has been reduced to 16 bytes from the standard's 64 bytes.
36 */
37struct bfa_fcs_fdmi_hba_attr_s {
38 wwn_t node_name;
39 u8 manufacturer[64];
40 u8 serial_num[64];
41 u8 model[16];
42 u8 model_desc[256];
43 u8 hw_version[8];
44 u8 driver_version[8];
45 u8 option_rom_ver[BFA_VERSION_LEN];
46 u8 fw_version[8];
47 u8 os_name[256];
48 u32 max_ct_pyld;
49};
50
51/*
52 * Port Attribute Block
53 */
54struct bfa_fcs_fdmi_port_attr_s {
55 u8 supp_fc4_types[32]; /* supported FC4 types */
56 u32 supp_speed; /* supported speed */
57 u32 curr_speed; /* current Speed */
58 u32 max_frm_size; /* max frame size */
59 u8 os_device_name[256]; /* OS device Name */
60 u8 host_name[256]; /* host name */
61};
62
63#endif /* __BFA_FCS_FDMI_H__ */
diff --git a/drivers/scsi/bfa/include/fcs/bfa_fcs_lport.h b/drivers/scsi/bfa/include/fcs/bfa_fcs_lport.h
new file mode 100644
index 000000000000..b85cba884b96
--- /dev/null
+++ b/drivers/scsi/bfa/include/fcs/bfa_fcs_lport.h
@@ -0,0 +1,226 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * bfa_fcs_port.h BFA fcs port module public interface
20 */
21
22#ifndef __BFA_FCS_PORT_H__
23#define __BFA_FCS_PORT_H__
24
25#include <defs/bfa_defs_status.h>
26#include <defs/bfa_defs_port.h>
27#include <defs/bfa_defs_pport.h>
28#include <defs/bfa_defs_rport.h>
29#include <cs/bfa_q.h>
30#include <bfa_svc.h>
31#include <cs/bfa_wc.h>
32
33struct bfa_fcs_s;
34struct bfa_fcs_fabric_s;
35
36/*
37* @todo : need to move to a global config file.
38 * Maximum Vports supported per physical port or vf.
39 */
40#define BFA_FCS_MAX_VPORTS_SUPP_CB 255
41#define BFA_FCS_MAX_VPORTS_SUPP_CT 191
42
43/*
44* @todo : need to move to a global config file.
45 * Maximum Rports supported per port (physical/logical).
46 */
47#define BFA_FCS_MAX_RPORTS_SUPP 256 /* @todo : tentative value */
48
49
50struct bfa_fcs_port_ns_s {
51 bfa_sm_t sm; /* state machine */
52 struct bfa_timer_s timer;
53 struct bfa_fcs_port_s *port; /* parent port */
54 struct bfa_fcxp_s *fcxp;
55 struct bfa_fcxp_wqe_s fcxp_wqe;
56};
57
58
59struct bfa_fcs_port_scn_s {
60 bfa_sm_t sm; /* state machine */
61 struct bfa_timer_s timer;
62 struct bfa_fcs_port_s *port; /* parent port */
63 struct bfa_fcxp_s *fcxp;
64 struct bfa_fcxp_wqe_s fcxp_wqe;
65};
66
67
68struct bfa_fcs_port_fdmi_s {
69 bfa_sm_t sm; /* state machine */
70 struct bfa_timer_s timer;
71 struct bfa_fcs_port_ms_s *ms; /* parent ms */
72 struct bfa_fcxp_s *fcxp;
73 struct bfa_fcxp_wqe_s fcxp_wqe;
74 u8 retry_cnt; /* retry count */
75 u8 rsvd[3];
76};
77
78
79struct bfa_fcs_port_ms_s {
80 bfa_sm_t sm; /* state machine */
81 struct bfa_timer_s timer;
82 struct bfa_fcs_port_s *port; /* parent port */
83 struct bfa_fcxp_s *fcxp;
84 struct bfa_fcxp_wqe_s fcxp_wqe;
85 struct bfa_fcs_port_fdmi_s fdmi; /* FDMI component of MS */
86 u8 retry_cnt; /* retry count */
87 u8 rsvd[3];
88};
89
90
91struct bfa_fcs_port_fab_s {
92 struct bfa_fcs_port_ns_s ns; /* NS component of port */
93 struct bfa_fcs_port_scn_s scn; /* scn component of port */
94 struct bfa_fcs_port_ms_s ms; /* MS component of port */
95};
96
97
98
99#define MAX_ALPA_COUNT 127
100
101struct bfa_fcs_port_loop_s {
102 u8 num_alpa; /* Num of ALPA entries in the map */
103 u8 alpa_pos_map[MAX_ALPA_COUNT]; /* ALPA Positional
104 *Map */
105 struct bfa_fcs_port_s *port; /* parent port */
106};
107
108
109
110struct bfa_fcs_port_n2n_s {
111 u32 rsvd;
112 u16 reply_oxid; /* ox_id from the req flogi to be
113 *used in flogi acc */
114 wwn_t rem_port_wwn; /* Attached port's wwn */
115};
116
117
118union bfa_fcs_port_topo_u {
119 struct bfa_fcs_port_fab_s pfab;
120 struct bfa_fcs_port_loop_s ploop;
121 struct bfa_fcs_port_n2n_s pn2n;
122};
123
124
125struct bfa_fcs_port_s {
126 struct list_head qe; /* used by port/vport */
127 bfa_sm_t sm; /* state machine */
128 struct bfa_fcs_fabric_s *fabric; /* parent fabric */
129 struct bfa_port_cfg_s port_cfg; /* port configuration */
130 struct bfa_timer_s link_timer; /* timer for link offline */
131 u32 pid : 24; /* FC address */
132 u8 lp_tag; /* lport tag */
133 u16 num_rports; /* Num of r-ports */
134 struct list_head rport_q; /* queue of discovered r-ports */
135 struct bfa_fcs_s *fcs; /* FCS instance */
136 union bfa_fcs_port_topo_u port_topo; /* fabric/loop/n2n details */
137 struct bfad_port_s *bfad_port; /* driver peer instance */
138 struct bfa_fcs_vport_s *vport; /* NULL for base ports */
139 struct bfa_fcxp_s *fcxp;
140 struct bfa_fcxp_wqe_s fcxp_wqe;
141 struct bfa_port_stats_s stats;
142 struct bfa_wc_s wc; /* waiting counter for events */
143};
144
145#define bfa_fcs_lport_t struct bfa_fcs_port_s
146
147/**
148 * Symbolic Name related defines
149 * Total bytes 255.
150 * Physical Port's symbolic name 128 bytes.
151 * For Vports, Vport's symbolic name is appended to the Physical port's
152 * Symbolic Name.
153 *
154 * Physical Port's symbolic name Format : (Total 128 bytes)
155 * Adapter Model number/name : 12 bytes
156 * Driver Version : 10 bytes
157 * Host Machine Name : 30 bytes
158 * Host OS Info : 48 bytes
159 * Host OS PATCH Info : 16 bytes
160 * ( remaining 12 bytes reserved to be used for separator)
161 */
162#define BFA_FCS_PORT_SYMBNAME_SEPARATOR " | "
163
164#define BFA_FCS_PORT_SYMBNAME_MODEL_SZ 12
165#define BFA_FCS_PORT_SYMBNAME_VERSION_SZ 10
166#define BFA_FCS_PORT_SYMBNAME_MACHINENAME_SZ 30
167#define BFA_FCS_PORT_SYMBNAME_OSINFO_SZ 48
168#define BFA_FCS_PORT_SYMBNAME_OSPATCH_SZ 16
169
170/**
171 * Get FC port ID for a logical port.
172 */
173#define bfa_fcs_port_get_fcid(_lport) ((_lport)->pid)
174#define bfa_fcs_port_get_pwwn(_lport) ((_lport)->port_cfg.pwwn)
175#define bfa_fcs_port_get_nwwn(_lport) ((_lport)->port_cfg.nwwn)
176#define bfa_fcs_port_get_psym_name(_lport) ((_lport)->port_cfg.sym_name)
177#define bfa_fcs_port_is_initiator(_lport) \
178 ((_lport)->port_cfg.roles & BFA_PORT_ROLE_FCP_IM)
179#define bfa_fcs_port_is_target(_lport) \
180 ((_lport)->port_cfg.roles & BFA_PORT_ROLE_FCP_TM)
181#define bfa_fcs_port_get_nrports(_lport) \
182 ((_lport) ? (_lport)->num_rports : 0)
183
184static inline struct bfad_port_s *
185bfa_fcs_port_get_drvport(struct bfa_fcs_port_s *port)
186{
187 return port->bfad_port;
188}
189
190
191#define bfa_fcs_port_get_opertype(_lport) (_lport)->fabric->oper_type
192
193
194#define bfa_fcs_port_get_fabric_name(_lport) (_lport)->fabric->fabric_name
195
196
197#define bfa_fcs_port_get_fabric_ipaddr(_lport) (_lport)->fabric->fabric_ip_addr
198
199/**
200 * bfa fcs port public functions
201 */
202void bfa_fcs_cfg_base_port(struct bfa_fcs_s *fcs,
203 struct bfa_port_cfg_s *port_cfg);
204struct bfa_fcs_port_s *bfa_fcs_get_base_port(struct bfa_fcs_s *fcs);
205void bfa_fcs_port_get_rports(struct bfa_fcs_port_s *port,
206 wwn_t rport_wwns[], int *nrports);
207
208wwn_t bfa_fcs_port_get_rport(struct bfa_fcs_port_s *port, wwn_t wwn,
209 int index, int nrports, bfa_boolean_t bwwn);
210
211struct bfa_fcs_port_s *bfa_fcs_lookup_port(struct bfa_fcs_s *fcs,
212 u16 vf_id, wwn_t lpwwn);
213
214void bfa_fcs_port_get_info(struct bfa_fcs_port_s *port,
215 struct bfa_port_info_s *port_info);
216void bfa_fcs_port_get_attr(struct bfa_fcs_port_s *port,
217 struct bfa_port_attr_s *port_attr);
218void bfa_fcs_port_get_stats(struct bfa_fcs_port_s *fcs_port,
219 struct bfa_port_stats_s *port_stats);
220void bfa_fcs_port_clear_stats(struct bfa_fcs_port_s *fcs_port);
221enum bfa_pport_speed bfa_fcs_port_get_rport_max_speed(
222 struct bfa_fcs_port_s *port);
223void bfa_fcs_port_enable_ipfc_roles(struct bfa_fcs_port_s *fcs_port);
224void bfa_fcs_port_disable_ipfc_roles(struct bfa_fcs_port_s *fcs_port);
225
226#endif /* __BFA_FCS_PORT_H__ */
diff --git a/drivers/scsi/bfa/include/fcs/bfa_fcs_rport.h b/drivers/scsi/bfa/include/fcs/bfa_fcs_rport.h
new file mode 100644
index 000000000000..702b95b76c2d
--- /dev/null
+++ b/drivers/scsi/bfa/include/fcs/bfa_fcs_rport.h
@@ -0,0 +1,104 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __BFA_FCS_RPORT_H__
19#define __BFA_FCS_RPORT_H__
20
21#include <defs/bfa_defs_status.h>
22#include <cs/bfa_q.h>
23#include <fcs/bfa_fcs.h>
24#include <defs/bfa_defs_rport.h>
25
26#define BFA_FCS_RPORT_DEF_DEL_TIMEOUT 90 /* in secs */
27/*
28 * forward declarations
29 */
30struct bfad_rport_s;
31
32struct bfa_fcs_itnim_s;
33struct bfa_fcs_tin_s;
34struct bfa_fcs_iprp_s;
35
36/* Rport Features (RPF) */
37struct bfa_fcs_rpf_s {
38 bfa_sm_t sm; /* state machine */
39 struct bfa_fcs_rport_s *rport; /* parent rport */
40 struct bfa_timer_s timer; /* general purpose timer */
41 struct bfa_fcxp_s *fcxp; /* FCXP needed for discarding */
42 struct bfa_fcxp_wqe_s fcxp_wqe; /* fcxp wait queue element */
43 int rpsc_retries; /* max RPSC retry attempts */
44 enum bfa_pport_speed rpsc_speed; /* Current Speed from RPSC.
45 * O if RPSC fails */
46 enum bfa_pport_speed assigned_speed; /* Speed assigned by the user.
47 * will be used if RPSC is not
48 * supported by the rport */
49};
50
51struct bfa_fcs_rport_s {
52 struct list_head qe; /* used by port/vport */
53 struct bfa_fcs_port_s *port; /* parent FCS port */
54 struct bfa_fcs_s *fcs; /* fcs instance */
55 struct bfad_rport_s *rp_drv; /* driver peer instance */
56 u32 pid; /* port ID of rport */
57 u16 maxfrsize; /* maximum frame size */
58 u16 reply_oxid; /* OX_ID of inbound requests */
59 enum fc_cos fc_cos; /* FC classes of service supp */
60 bfa_boolean_t cisc; /* CISC capable device */
61 wwn_t pwwn; /* port wwn of rport */
62 wwn_t nwwn; /* node wwn of rport */
63 struct bfa_rport_symname_s psym_name; /* port symbolic name */
64 bfa_sm_t sm; /* state machine */
65 struct bfa_timer_s timer; /* general purpose timer */
66 struct bfa_fcs_itnim_s *itnim; /* ITN initiator mode role */
67 struct bfa_fcs_tin_s *tin; /* ITN initiator mode role */
68 struct bfa_fcs_iprp_s *iprp; /* IP/FC role */
69 struct bfa_rport_s *bfa_rport; /* BFA Rport */
70 struct bfa_fcxp_s *fcxp; /* FCXP needed for discarding */
71 int plogi_retries; /* max plogi retry attempts */
72 int ns_retries; /* max NS query retry attempts */
73 struct bfa_fcxp_wqe_s fcxp_wqe; /* fcxp wait queue element */
74 struct bfa_rport_stats_s stats; /* rport stats */
75 enum bfa_rport_function scsi_function; /* Initiator/Target */
76 struct bfa_fcs_rpf_s rpf; /* Rport features module */
77};
78
79static inline struct bfa_rport_s *
80bfa_fcs_rport_get_halrport(struct bfa_fcs_rport_s *rport)
81{
82 return rport->bfa_rport;
83}
84
85/**
86 * bfa fcs rport API functions
87 */
88bfa_status_t bfa_fcs_rport_add(struct bfa_fcs_port_s *port, wwn_t *pwwn,
89 struct bfa_fcs_rport_s *rport,
90 struct bfad_rport_s *rport_drv);
91bfa_status_t bfa_fcs_rport_remove(struct bfa_fcs_rport_s *rport);
92void bfa_fcs_rport_get_attr(struct bfa_fcs_rport_s *rport,
93 struct bfa_rport_attr_s *attr);
94void bfa_fcs_rport_get_stats(struct bfa_fcs_rport_s *rport,
95 struct bfa_rport_stats_s *stats);
96void bfa_fcs_rport_clear_stats(struct bfa_fcs_rport_s *rport);
97struct bfa_fcs_rport_s *bfa_fcs_rport_lookup(struct bfa_fcs_port_s *port,
98 wwn_t rpwwn);
99struct bfa_fcs_rport_s *bfa_fcs_rport_lookup_by_nwwn(
100 struct bfa_fcs_port_s *port, wwn_t rnwwn);
101void bfa_fcs_rport_set_del_timeout(u8 rport_tmo);
102void bfa_fcs_rport_set_speed(struct bfa_fcs_rport_s *rport,
103 enum bfa_pport_speed speed);
104#endif /* __BFA_FCS_RPORT_H__ */
diff --git a/drivers/scsi/bfa/include/fcs/bfa_fcs_vport.h b/drivers/scsi/bfa/include/fcs/bfa_fcs_vport.h
new file mode 100644
index 000000000000..cd33f2cd5c34
--- /dev/null
+++ b/drivers/scsi/bfa/include/fcs/bfa_fcs_vport.h
@@ -0,0 +1,63 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * bfa_fcs_vport.h BFA fcs vport module public interface
20 */
21
22#ifndef __BFA_FCS_VPORT_H__
23#define __BFA_FCS_VPORT_H__
24
25#include <defs/bfa_defs_status.h>
26#include <defs/bfa_defs_port.h>
27#include <defs/bfa_defs_vport.h>
28#include <fcs/bfa_fcs.h>
29#include <fcb/bfa_fcb_vport.h>
30
31struct bfa_fcs_vport_s {
32 struct list_head qe; /* queue elem */
33 bfa_sm_t sm; /* state machine */
34 bfa_fcs_lport_t lport; /* logical port */
35 struct bfa_timer_s timer; /* general purpose timer */
36 struct bfad_vport_s *vport_drv; /* Driver private */
37 struct bfa_vport_stats_s vport_stats; /* vport statistics */
38 struct bfa_lps_s *lps; /* Lport login service */
39 int fdisc_retries;
40};
41
42#define bfa_fcs_vport_get_port(vport) \
43 ((struct bfa_fcs_port_s *)(&vport->port))
44
45/**
46 * bfa fcs vport public functions
47 */
48bfa_status_t bfa_fcs_vport_create(struct bfa_fcs_vport_s *vport,
49 struct bfa_fcs_s *fcs, u16 vf_id,
50 struct bfa_port_cfg_s *port_cfg,
51 struct bfad_vport_s *vport_drv);
52bfa_status_t bfa_fcs_vport_delete(struct bfa_fcs_vport_s *vport);
53bfa_status_t bfa_fcs_vport_start(struct bfa_fcs_vport_s *vport);
54bfa_status_t bfa_fcs_vport_stop(struct bfa_fcs_vport_s *vport);
55void bfa_fcs_vport_get_attr(struct bfa_fcs_vport_s *vport,
56 struct bfa_vport_attr_s *vport_attr);
57void bfa_fcs_vport_get_stats(struct bfa_fcs_vport_s *vport,
58 struct bfa_vport_stats_s *vport_stats);
59void bfa_fcs_vport_clr_stats(struct bfa_fcs_vport_s *vport);
60struct bfa_fcs_vport_s *bfa_fcs_vport_lookup(struct bfa_fcs_s *fcs,
61 u16 vf_id, wwn_t vpwwn);
62
63#endif /* __BFA_FCS_VPORT_H__ */
diff --git a/drivers/scsi/bfa/include/log/bfa_log_fcs.h b/drivers/scsi/bfa/include/log/bfa_log_fcs.h
new file mode 100644
index 000000000000..b6f5df8827f8
--- /dev/null
+++ b/drivers/scsi/bfa/include/log/bfa_log_fcs.h
@@ -0,0 +1,28 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/*
19 * messages define for FCS Module
20 */
21#ifndef __BFA_LOG_FCS_H__
22#define __BFA_LOG_FCS_H__
23#include <cs/bfa_log.h>
24#define BFA_LOG_FCS_FABRIC_NOSWITCH \
25 (((u32) BFA_LOG_FCS_ID << BFA_LOG_MODID_OFFSET) | 1)
26#define BFA_LOG_FCS_FABRIC_ISOLATED \
27 (((u32) BFA_LOG_FCS_ID << BFA_LOG_MODID_OFFSET) | 2)
28#endif
diff --git a/drivers/scsi/bfa/include/log/bfa_log_hal.h b/drivers/scsi/bfa/include/log/bfa_log_hal.h
new file mode 100644
index 000000000000..0412aea2ec30
--- /dev/null
+++ b/drivers/scsi/bfa/include/log/bfa_log_hal.h
@@ -0,0 +1,30 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/* messages define for HAL Module */
19#ifndef __BFA_LOG_HAL_H__
20#define __BFA_LOG_HAL_H__
21#include <cs/bfa_log.h>
22#define BFA_LOG_HAL_ASSERT \
23 (((u32) BFA_LOG_HAL_ID << BFA_LOG_MODID_OFFSET) | 1)
24#define BFA_LOG_HAL_HEARTBEAT_FAILURE \
25 (((u32) BFA_LOG_HAL_ID << BFA_LOG_MODID_OFFSET) | 2)
26#define BFA_LOG_HAL_FCPIM_PARM_INVALID \
27 (((u32) BFA_LOG_HAL_ID << BFA_LOG_MODID_OFFSET) | 3)
28#define BFA_LOG_HAL_SM_ASSERT \
29 (((u32) BFA_LOG_HAL_ID << BFA_LOG_MODID_OFFSET) | 4)
30#endif
diff --git a/drivers/scsi/bfa/include/log/bfa_log_linux.h b/drivers/scsi/bfa/include/log/bfa_log_linux.h
new file mode 100644
index 000000000000..317c0547ee16
--- /dev/null
+++ b/drivers/scsi/bfa/include/log/bfa_log_linux.h
@@ -0,0 +1,44 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/* messages define for LINUX Module */
19#ifndef __BFA_LOG_LINUX_H__
20#define __BFA_LOG_LINUX_H__
21#include <cs/bfa_log.h>
22#define BFA_LOG_LINUX_DEVICE_CLAIMED \
23 (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 1)
24#define BFA_LOG_LINUX_HASH_INIT_FAILED \
25 (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 2)
26#define BFA_LOG_LINUX_SYSFS_FAILED \
27 (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 3)
28#define BFA_LOG_LINUX_MEM_ALLOC_FAILED \
29 (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 4)
30#define BFA_LOG_LINUX_DRIVER_REGISTRATION_FAILED \
31 (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 5)
32#define BFA_LOG_LINUX_ITNIM_FREE \
33 (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 6)
34#define BFA_LOG_LINUX_ITNIM_ONLINE \
35 (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 7)
36#define BFA_LOG_LINUX_ITNIM_OFFLINE \
37 (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 8)
38#define BFA_LOG_LINUX_SCSI_HOST_FREE \
39 (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 9)
40#define BFA_LOG_LINUX_SCSI_ABORT \
41 (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 10)
42#define BFA_LOG_LINUX_SCSI_ABORT_COMP \
43 (((u32) BFA_LOG_LINUX_ID << BFA_LOG_MODID_OFFSET) | 11)
44#endif
diff --git a/drivers/scsi/bfa/include/log/bfa_log_wdrv.h b/drivers/scsi/bfa/include/log/bfa_log_wdrv.h
new file mode 100644
index 000000000000..809a95f7afe2
--- /dev/null
+++ b/drivers/scsi/bfa/include/log/bfa_log_wdrv.h
@@ -0,0 +1,36 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/*
19 * messages define for WDRV Module
20 */
21#ifndef __BFA_LOG_WDRV_H__
22#define __BFA_LOG_WDRV_H__
23#include <cs/bfa_log.h>
24#define BFA_LOG_WDRV_IOC_INIT_ERROR \
25 (((u32) BFA_LOG_WDRV_ID << BFA_LOG_MODID_OFFSET) | 1)
26#define BFA_LOG_WDRV_IOC_INTERNAL_ERROR \
27 (((u32) BFA_LOG_WDRV_ID << BFA_LOG_MODID_OFFSET) | 2)
28#define BFA_LOG_WDRV_IOC_START_ERROR \
29 (((u32) BFA_LOG_WDRV_ID << BFA_LOG_MODID_OFFSET) | 3)
30#define BFA_LOG_WDRV_IOC_STOP_ERROR \
31 (((u32) BFA_LOG_WDRV_ID << BFA_LOG_MODID_OFFSET) | 4)
32#define BFA_LOG_WDRV_INSUFFICIENT_RESOURCES \
33 (((u32) BFA_LOG_WDRV_ID << BFA_LOG_MODID_OFFSET) | 5)
34#define BFA_LOG_WDRV_BASE_ADDRESS_MAP_ERROR \
35 (((u32) BFA_LOG_WDRV_ID << BFA_LOG_MODID_OFFSET) | 6)
36#endif
diff --git a/drivers/scsi/bfa/include/protocol/ct.h b/drivers/scsi/bfa/include/protocol/ct.h
new file mode 100644
index 000000000000..c59d6630b070
--- /dev/null
+++ b/drivers/scsi/bfa/include/protocol/ct.h
@@ -0,0 +1,492 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __CT_H__
19#define __CT_H__
20
21#include <protocol/types.h>
22
23#pragma pack(1)
24
25struct ct_hdr_s{
26 u32 rev_id:8; /* Revision of the CT */
27 u32 in_id:24; /* Initiator Id */
28 u32 gs_type:8; /* Generic service Type */
29 u32 gs_sub_type:8; /* Generic service sub type */
30 u32 options:8; /* options */
31 u32 rsvrd:8; /* reserved */
32 u32 cmd_rsp_code:16;/* ct command/response code */
33 u32 max_res_size:16;/* maximum/residual size */
34 u32 frag_id:8; /* fragment ID */
35 u32 reason_code:8; /* reason code */
36 u32 exp_code:8; /* explanation code */
37 u32 vendor_unq:8; /* vendor unique */
38};
39
40/*
41 * defines for the Revision
42 */
43enum {
44 CT_GS3_REVISION = 0x01,
45};
46
47/*
48 * defines for gs_type
49 */
50enum {
51 CT_GSTYPE_KEYSERVICE = 0xF7,
52 CT_GSTYPE_ALIASSERVICE = 0xF8,
53 CT_GSTYPE_MGMTSERVICE = 0xFA,
54 CT_GSTYPE_TIMESERVICE = 0xFB,
55 CT_GSTYPE_DIRSERVICE = 0xFC,
56};
57
58/*
59 * defines for gs_sub_type for gs type directory service
60 */
61enum {
62 CT_GSSUBTYPE_NAMESERVER = 0x02,
63};
64
65/*
66 * defines for gs_sub_type for gs type management service
67 */
68enum {
69 CT_GSSUBTYPE_CFGSERVER = 0x01,
70 CT_GSSUBTYPE_UNZONED_NS = 0x02,
71 CT_GSSUBTYPE_ZONESERVER = 0x03,
72 CT_GSSUBTYPE_LOCKSERVER = 0x04,
73 CT_GSSUBTYPE_HBA_MGMTSERVER = 0x10, /* for FDMI */
74};
75
76/*
77 * defines for CT response code field
78 */
79enum {
80 CT_RSP_REJECT = 0x8001,
81 CT_RSP_ACCEPT = 0x8002,
82};
83
84/*
85 * defintions for CT reason code
86 */
87enum {
88 CT_RSN_INV_CMD = 0x01,
89 CT_RSN_INV_VER = 0x02,
90 CT_RSN_LOGIC_ERR = 0x03,
91 CT_RSN_INV_SIZE = 0x04,
92 CT_RSN_LOGICAL_BUSY = 0x05,
93 CT_RSN_PROTO_ERR = 0x07,
94 CT_RSN_UNABLE_TO_PERF = 0x09,
95 CT_RSN_NOT_SUPP = 0x0B,
96 CT_RSN_SERVER_NOT_AVBL = 0x0D,
97 CT_RSN_SESSION_COULD_NOT_BE_ESTBD = 0x0E,
98 CT_RSN_VENDOR_SPECIFIC = 0xFF,
99
100};
101
102/*
103 * definitions for explanations code for Name server
104 */
105enum {
106 CT_NS_EXP_NOADDITIONAL = 0x00,
107 CT_NS_EXP_ID_NOT_REG = 0x01,
108 CT_NS_EXP_PN_NOT_REG = 0x02,
109 CT_NS_EXP_NN_NOT_REG = 0x03,
110 CT_NS_EXP_CS_NOT_REG = 0x04,
111 CT_NS_EXP_IPN_NOT_REG = 0x05,
112 CT_NS_EXP_IPA_NOT_REG = 0x06,
113 CT_NS_EXP_FT_NOT_REG = 0x07,
114 CT_NS_EXP_SPN_NOT_REG = 0x08,
115 CT_NS_EXP_SNN_NOT_REG = 0x09,
116 CT_NS_EXP_PT_NOT_REG = 0x0A,
117 CT_NS_EXP_IPP_NOT_REG = 0x0B,
118 CT_NS_EXP_FPN_NOT_REG = 0x0C,
119 CT_NS_EXP_HA_NOT_REG = 0x0D,
120 CT_NS_EXP_FD_NOT_REG = 0x0E,
121 CT_NS_EXP_FF_NOT_REG = 0x0F,
122 CT_NS_EXP_ACCESSDENIED = 0x10,
123 CT_NS_EXP_UNACCEPTABLE_ID = 0x11,
124 CT_NS_EXP_DATABASEEMPTY = 0x12,
125 CT_NS_EXP_NOT_REG_IN_SCOPE = 0x13,
126 CT_NS_EXP_DOM_ID_NOT_PRESENT = 0x14,
127 CT_NS_EXP_PORT_NUM_NOT_PRESENT = 0x15,
128 CT_NS_EXP_NO_DEVICE_ATTACHED = 0x16
129};
130
131/*
132 * defintions for the explanation code for all servers
133 */
134enum {
135 CT_EXP_AUTH_EXCEPTION = 0xF1,
136 CT_EXP_DB_FULL = 0xF2,
137 CT_EXP_DB_EMPTY = 0xF3,
138 CT_EXP_PROCESSING_REQ = 0xF4,
139 CT_EXP_UNABLE_TO_VERIFY_CONN = 0xF5,
140 CT_EXP_DEVICES_NOT_IN_CMN_ZONE = 0xF6
141};
142
143/*
144 * Command codes for Name server
145 */
146enum {
147 GS_GID_PN = 0x0121, /* Get Id on port name */
148 GS_GPN_ID = 0x0112, /* Get port name on ID */
149 GS_GNN_ID = 0x0113, /* Get node name on ID */
150 GS_GID_FT = 0x0171, /* Get Id on FC4 type */
151 GS_GSPN_ID = 0x0118, /* Get symbolic PN on ID */
152 GS_RFT_ID = 0x0217, /* Register fc4type on ID */
153 GS_RSPN_ID = 0x0218, /* Register symbolic PN on ID */
154 GS_RPN_ID = 0x0212, /* Register port name */
155 GS_RNN_ID = 0x0213, /* Register node name */
156 GS_RCS_ID = 0x0214, /* Register class of service */
157 GS_RPT_ID = 0x021A, /* Register port type */
158 GS_GA_NXT = 0x0100, /* Get all next */
159 GS_RFF_ID = 0x021F, /* Register FC4 Feature */
160};
161
162struct fcgs_id_req_s{
163 u32 rsvd:8;
164 u32 dap:24; /* port identifier */
165};
166#define fcgs_gpnid_req_t struct fcgs_id_req_s
167#define fcgs_gnnid_req_t struct fcgs_id_req_s
168#define fcgs_gspnid_req_t struct fcgs_id_req_s
169
170struct fcgs_gidpn_req_s{
171 wwn_t port_name; /* port wwn */
172};
173
174struct fcgs_gidpn_resp_s{
175 u32 rsvd:8;
176 u32 dap:24; /* port identifier */
177};
178
179/**
180 * RFT_ID
181 */
182struct fcgs_rftid_req_s {
183 u32 rsvd:8;
184 u32 dap:24; /* port identifier */
185 u32 fc4_type[8]; /* fc4 types */
186};
187
188/**
189 * RFF_ID : Register FC4 features.
190 */
191
192#define FC_GS_FCP_FC4_FEATURE_INITIATOR 0x02
193#define FC_GS_FCP_FC4_FEATURE_TARGET 0x01
194
195struct fcgs_rffid_req_s{
196 u32 rsvd :8;
197 u32 dap :24; /* port identifier */
198 u32 rsvd1 :16;
199 u32 fc4ftr_bits :8; /* fc4 feature bits */
200 u32 fc4_type :8; /* corresponding FC4 Type */
201};
202
203/**
204 * GID_FT Request
205 */
206struct fcgs_gidft_req_s{
207 u8 reserved;
208 u8 domain_id; /* domain, 0 - all fabric */
209 u8 area_id; /* area, 0 - whole domain */
210 u8 fc4_type; /* FC_TYPE_FCP for SCSI devices */
211}; /* GID_FT Request */
212
213/**
214 * GID_FT Response
215 */
216struct fcgs_gidft_resp_s {
217 u8 last:1; /* last port identifier flag */
218 u8 reserved:7;
219 u32 pid:24; /* port identifier */
220}; /* GID_FT Response */
221
222/**
223 * RSPN_ID
224 */
225struct fcgs_rspnid_req_s{
226 u32 rsvd:8;
227 u32 dap:24; /* port identifier */
228 u8 spn_len; /* symbolic port name length */
229 u8 spn[256]; /* symbolic port name */
230};
231
232/**
233 * RPN_ID
234 */
235struct fcgs_rpnid_req_s{
236 u32 rsvd:8;
237 u32 port_id:24;
238 wwn_t port_name;
239};
240
241/**
242 * RNN_ID
243 */
244struct fcgs_rnnid_req_s{
245 u32 rsvd:8;
246 u32 port_id:24;
247 wwn_t node_name;
248};
249
250/**
251 * RCS_ID
252 */
253struct fcgs_rcsid_req_s{
254 u32 rsvd:8;
255 u32 port_id:24;
256 u32 cos;
257};
258
259/**
260 * RPT_ID
261 */
262struct fcgs_rptid_req_s{
263 u32 rsvd:8;
264 u32 port_id:24;
265 u32 port_type:8;
266 u32 rsvd1:24;
267};
268
269/**
270 * GA_NXT Request
271 */
272struct fcgs_ganxt_req_s{
273 u32 rsvd:8;
274 u32 port_id:24;
275};
276
277/**
278 * GA_NXT Response
279 */
280struct fcgs_ganxt_rsp_s{
281 u32 port_type:8; /* Port Type */
282 u32 port_id:24; /* Port Identifier */
283 wwn_t port_name; /* Port Name */
284 u8 spn_len; /* Length of Symbolic Port Name */
285 char spn[255]; /* Symbolic Port Name */
286 wwn_t node_name; /* Node Name */
287 u8 snn_len; /* Length of Symbolic Node Name */
288 char snn[255]; /* Symbolic Node Name */
289 u8 ipa[8]; /* Initial Process Associator */
290 u8 ip[16]; /* IP Address */
291 u32 cos; /* Class of Service */
292 u32 fc4types[8]; /* FC-4 TYPEs */
293 wwn_t fabric_port_name;
294 /* Fabric Port Name */
295 u32 rsvd:8; /* Reserved */
296 u32 hard_addr:24; /* Hard Address */
297};
298
299/*
300 * Fabric Config Server
301 */
302
303/*
304 * Command codes for Fabric Configuration Server
305 */
306enum {
307 GS_FC_GFN_CMD = 0x0114, /* GS FC Get Fabric Name */
308 GS_FC_GMAL_CMD = 0x0116, /* GS FC GMAL */
309 GS_FC_TRACE_CMD = 0x0400, /* GS FC Trace Route */
310 GS_FC_PING_CMD = 0x0401, /* GS FC Ping */
311};
312
313/*
314 * Source or Destination Port Tags.
315 */
316enum {
317 GS_FTRACE_TAG_NPORT_ID = 1,
318 GS_FTRACE_TAG_NPORT_NAME = 2,
319};
320
321/*
322* Port Value : Could be a Port id or wwn
323 */
324union fcgs_port_val_u{
325 u32 nport_id;
326 wwn_t nport_wwn;
327};
328
329#define GS_FTRACE_MAX_HOP_COUNT 20
330#define GS_FTRACE_REVISION 1
331
332/*
333 * Ftrace Related Structures.
334 */
335
336/*
337 * STR (Switch Trace) Reject Reason Codes. From FC-SW.
338 */
339enum {
340 GS_FTRACE_STR_CMD_COMPLETED_SUCC = 0,
341 GS_FTRACE_STR_CMD_NOT_SUPP_IN_NEXT_SWITCH,
342 GS_FTRACE_STR_NO_RESP_FROM_NEXT_SWITCH,
343 GS_FTRACE_STR_MAX_HOP_CNT_REACHED,
344 GS_FTRACE_STR_SRC_PORT_NOT_FOUND,
345 GS_FTRACE_STR_DST_PORT_NOT_FOUND,
346 GS_FTRACE_STR_DEVICES_NOT_IN_COMMON_ZONE,
347 GS_FTRACE_STR_NO_ROUTE_BW_PORTS,
348 GS_FTRACE_STR_NO_ADDL_EXPLN,
349 GS_FTRACE_STR_FABRIC_BUSY,
350 GS_FTRACE_STR_FABRIC_BUILD_IN_PROGRESS,
351 GS_FTRACE_STR_VENDOR_SPECIFIC_ERR_START = 0xf0,
352 GS_FTRACE_STR_VENDOR_SPECIFIC_ERR_END = 0xff,
353};
354
355/*
356 * Ftrace Request
357 */
358struct fcgs_ftrace_req_s{
359 u32 revision;
360 u16 src_port_tag; /* Source Port tag */
361 u16 src_port_len; /* Source Port len */
362 union fcgs_port_val_u src_port_val; /* Source Port value */
363 u16 dst_port_tag; /* Destination Port tag */
364 u16 dst_port_len; /* Destination Port len */
365 union fcgs_port_val_u dst_port_val; /* Destination Port value */
366 u32 token;
367 u8 vendor_id[8]; /* T10 Vendor Identifier */
368 u8 vendor_info[8]; /* Vendor specific Info */
369 u32 max_hop_cnt; /* Max Hop Count */
370};
371
372/*
373 * Path info structure
374 */
375struct fcgs_ftrace_path_info_s{
376 wwn_t switch_name; /* Switch WWN */
377 u32 domain_id;
378 wwn_t ingress_port_name; /* Ingress ports wwn */
379 u32 ingress_phys_port_num; /* Ingress ports physical port
380 * number
381 */
382 wwn_t egress_port_name; /* Ingress ports wwn */
383 u32 egress_phys_port_num; /* Ingress ports physical port
384 * number
385 */
386};
387
388/*
389 * Ftrace Acc Response
390 */
391struct fcgs_ftrace_resp_s{
392 u32 revision;
393 u32 token;
394 u8 vendor_id[8]; /* T10 Vendor Identifier */
395 u8 vendor_info[8]; /* Vendor specific Info */
396 u32 str_rej_reason_code; /* STR Reject Reason Code */
397 u32 num_path_info_entries; /* No. of path info entries */
398 /*
399 * path info entry/entries.
400 */
401 struct fcgs_ftrace_path_info_s path_info[1];
402
403};
404
405/*
406* Fabric Config Server : FCPing
407 */
408
409/*
410 * FC Ping Request
411 */
412struct fcgs_fcping_req_s{
413 u32 revision;
414 u16 port_tag;
415 u16 port_len; /* Port len */
416 union fcgs_port_val_u port_val; /* Port value */
417 u32 token;
418};
419
420/*
421 * FC Ping Response
422 */
423struct fcgs_fcping_resp_s{
424 u32 token;
425};
426
427/*
428 * Command codes for zone server query.
429 */
430enum {
431 ZS_GZME = 0x0124, /* Get zone member extended */
432};
433
434/*
435 * ZS GZME request
436 */
437#define ZS_GZME_ZNAMELEN 32
438struct zs_gzme_req_s{
439 u8 znamelen;
440 u8 rsvd[3];
441 u8 zname[ZS_GZME_ZNAMELEN];
442};
443
444enum zs_mbr_type{
445 ZS_MBR_TYPE_PWWN = 1,
446 ZS_MBR_TYPE_DOMPORT = 2,
447 ZS_MBR_TYPE_PORTID = 3,
448 ZS_MBR_TYPE_NWWN = 4,
449};
450
451struct zs_mbr_wwn_s{
452 u8 mbr_type;
453 u8 rsvd[3];
454 wwn_t wwn;
455};
456
457struct zs_query_resp_s{
458 u32 nmbrs; /* number of zone members */
459 struct zs_mbr_wwn_s mbr[1];
460};
461
462/*
463 * GMAL Command ( Get ( interconnect Element) Management Address List)
464 * To retrieve the IP Address of a Switch.
465 */
466
467#define CT_GMAL_RESP_PREFIX_TELNET "telnet://"
468#define CT_GMAL_RESP_PREFIX_HTTP "http://"
469
470/* GMAL/GFN request */
471struct fcgs_req_s {
472 wwn_t wwn; /* PWWN/NWWN */
473};
474
475#define fcgs_gmal_req_t struct fcgs_req_s
476#define fcgs_gfn_req_t struct fcgs_req_s
477
478/* Accept Response to GMAL */
479struct fcgs_gmal_resp_s {
480 u32 ms_len; /* Num of entries */
481 u8 ms_ma[256];
482};
483
484struct fc_gmal_entry_s {
485 u8 len;
486 u8 prefix[7]; /* like "http://" */
487 u8 ip_addr[248];
488};
489
490#pragma pack()
491
492#endif
diff --git a/drivers/scsi/bfa/include/protocol/fc.h b/drivers/scsi/bfa/include/protocol/fc.h
new file mode 100644
index 000000000000..3e39ba58cfb5
--- /dev/null
+++ b/drivers/scsi/bfa/include/protocol/fc.h
@@ -0,0 +1,1105 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __FC_H__
19#define __FC_H__
20
21#include <protocol/types.h>
22
23#pragma pack(1)
24
25/*
26 * Fibre Channel Header Structure (FCHS) definition
27 */
28struct fchs_s {
29#ifdef __BIGENDIAN
30 u32 routing:4; /* routing bits */
31 u32 cat_info:4; /* category info */
32#else
33 u32 cat_info:4; /* category info */
34 u32 routing:4; /* routing bits */
35#endif
36 u32 d_id:24; /* destination identifier */
37
38 u32 cs_ctl:8; /* class specific control */
39 u32 s_id:24; /* source identifier */
40
41 u32 type:8; /* data structure type */
42 u32 f_ctl:24; /* initial frame control */
43
44 u8 seq_id; /* sequence identifier */
45 u8 df_ctl; /* data field control */
46 u16 seq_cnt; /* sequence count */
47
48 u16 ox_id; /* originator exchange ID */
49 u16 rx_id; /* responder exchange ID */
50
51 u32 ro; /* relative offset */
52};
53/*
54 * Fibre Channel BB_E Header Structure
55 */
56struct fcbbehs_s {
57 u16 ver_rsvd;
58 u32 rsvd[2];
59 u32 rsvd__sof;
60};
61
62#define FC_SEQ_ID_MAX 256
63
64/*
65 * routing bit definitions
66 */
67enum {
68 FC_RTG_FC4_DEV_DATA = 0x0, /* FC-4 Device Data */
69 FC_RTG_EXT_LINK = 0x2, /* Extended Link Data */
70 FC_RTG_FC4_LINK_DATA = 0x3, /* FC-4 Link Data */
71 FC_RTG_VIDEO_DATA = 0x4, /* Video Data */
72 FC_RTG_EXT_HDR = 0x5, /* VFT, IFR or Encapsuled */
73 FC_RTG_BASIC_LINK = 0x8, /* Basic Link data */
74 FC_RTG_LINK_CTRL = 0xC, /* Link Control */
75};
76
77/*
78 * information category for extended link data and FC-4 Link Data
79 */
80enum {
81 FC_CAT_LD_REQUEST = 0x2, /* Request */
82 FC_CAT_LD_REPLY = 0x3, /* Reply */
83 FC_CAT_LD_DIAG = 0xF, /* for DIAG use only */
84};
85
86/*
87 * information category for extended headers (VFT, IFR or encapsulation)
88 */
89enum {
90 FC_CAT_VFT_HDR = 0x0, /* Virtual fabric tagging header */
91 FC_CAT_IFR_HDR = 0x1, /* Inter-Fabric routing header */
92 FC_CAT_ENC_HDR = 0x2, /* Encapsulation header */
93};
94
95/*
96 * information category for FC-4 device data
97 */
98enum {
99 FC_CAT_UNCATEG_INFO = 0x0, /* Uncategorized information */
100 FC_CAT_SOLICIT_DATA = 0x1, /* Solicited Data */
101 FC_CAT_UNSOLICIT_CTRL = 0x2, /* Unsolicited Control */
102 FC_CAT_SOLICIT_CTRL = 0x3, /* Solicited Control */
103 FC_CAT_UNSOLICIT_DATA = 0x4, /* Unsolicited Data */
104 FC_CAT_DATA_DESC = 0x5, /* Data Descriptor */
105 FC_CAT_UNSOLICIT_CMD = 0x6, /* Unsolicited Command */
106 FC_CAT_CMD_STATUS = 0x7, /* Command Status */
107};
108
109/*
110 * information category for Link Control
111 */
112enum {
113 FC_CAT_ACK_1 = 0x00,
114 FC_CAT_ACK_0_N = 0x01,
115 FC_CAT_P_RJT = 0x02,
116 FC_CAT_F_RJT = 0x03,
117 FC_CAT_P_BSY = 0x04,
118 FC_CAT_F_BSY_DATA = 0x05,
119 FC_CAT_F_BSY_LINK_CTL = 0x06,
120 FC_CAT_F_LCR = 0x07,
121 FC_CAT_NTY = 0x08,
122 FC_CAT_END = 0x09,
123};
124
125/*
126 * Type Field Definitions. FC-PH Section 18.5 pg. 165
127 */
128enum {
129 FC_TYPE_BLS = 0x0, /* Basic Link Service */
130 FC_TYPE_ELS = 0x1, /* Extended Link Service */
131 FC_TYPE_IP = 0x5, /* IP */
132 FC_TYPE_FCP = 0x8, /* SCSI-FCP */
133 FC_TYPE_GPP = 0x9, /* SCSI_GPP */
134 FC_TYPE_SERVICES = 0x20, /* Fibre Channel Services */
135 FC_TYPE_FC_FSS = 0x22, /* Fabric Switch Services */
136 FC_TYPE_FC_AL = 0x23, /* FC-AL */
137 FC_TYPE_FC_SNMP = 0x24, /* FC-SNMP */
138 FC_TYPE_MAX = 256, /* 256 FC-4 types */
139};
140
141struct fc_fc4types_s{
142 u8 bits[FC_TYPE_MAX / 8];
143};
144
145/*
146 * Frame Control Definitions. FC-PH Table-45. pg. 168
147 */
148enum {
149 FCTL_EC_ORIG = 0x000000, /* exchange originator */
150 FCTL_EC_RESP = 0x800000, /* exchange responder */
151 FCTL_SEQ_INI = 0x000000, /* sequence initiator */
152 FCTL_SEQ_REC = 0x400000, /* sequence recipient */
153 FCTL_FS_EXCH = 0x200000, /* first sequence of xchg */
154 FCTL_LS_EXCH = 0x100000, /* last sequence of xchg */
155 FCTL_END_SEQ = 0x080000, /* last frame of sequence */
156 FCTL_SI_XFER = 0x010000, /* seq initiative transfer */
157 FCTL_RO_PRESENT = 0x000008, /* relative offset present */
158 FCTL_FILLBYTE_MASK = 0x000003 /* , fill byte mask */
159};
160
161/*
162 * Fabric Well Known Addresses
163 */
164enum {
165 FC_MIN_WELL_KNOWN_ADDR = 0xFFFFF0,
166 FC_DOMAIN_CONTROLLER_MASK = 0xFFFC00,
167 FC_ALIAS_SERVER = 0xFFFFF8,
168 FC_MGMT_SERVER = 0xFFFFFA,
169 FC_TIME_SERVER = 0xFFFFFB,
170 FC_NAME_SERVER = 0xFFFFFC,
171 FC_FABRIC_CONTROLLER = 0xFFFFFD,
172 FC_FABRIC_PORT = 0xFFFFFE,
173 FC_BROADCAST_SERVER = 0xFFFFFF
174};
175
176/*
177 * domain/area/port defines
178 */
179#define FC_DOMAIN_MASK 0xFF0000
180#define FC_DOMAIN_SHIFT 16
181#define FC_AREA_MASK 0x00FF00
182#define FC_AREA_SHIFT 8
183#define FC_PORT_MASK 0x0000FF
184#define FC_PORT_SHIFT 0
185
186#define FC_GET_DOMAIN(p) (((p) & FC_DOMAIN_MASK) >> FC_DOMAIN_SHIFT)
187#define FC_GET_AREA(p) (((p) & FC_AREA_MASK) >> FC_AREA_SHIFT)
188#define FC_GET_PORT(p) (((p) & FC_PORT_MASK) >> FC_PORT_SHIFT)
189
190#define FC_DOMAIN_CTRLR(p) (FC_DOMAIN_CONTROLLER_MASK | (FC_GET_DOMAIN(p)))
191
192enum {
193 FC_RXID_ANY = 0xFFFFU,
194};
195
196/*
197 * generic ELS command
198 */
199struct fc_els_cmd_s{
200 u32 els_code:8; /* ELS Command Code */
201 u32 reserved:24;
202};
203
204/*
205 * ELS Command Codes. FC-PH Table-75. pg. 223
206 */
207enum {
208 FC_ELS_LS_RJT = 0x1, /* Link Service Reject. */
209 FC_ELS_ACC = 0x02, /* Accept */
210 FC_ELS_PLOGI = 0x03, /* N_Port Login. */
211 FC_ELS_FLOGI = 0x04, /* F_Port Login. */
212 FC_ELS_LOGO = 0x05, /* Logout. */
213 FC_ELS_ABTX = 0x06, /* Abort Exchange */
214 FC_ELS_RES = 0x08, /* Read Exchange status */
215 FC_ELS_RSS = 0x09, /* Read sequence status block */
216 FC_ELS_RSI = 0x0A, /* Request Sequence Initiative */
217 FC_ELS_ESTC = 0x0C, /* Estimate Credit. */
218 FC_ELS_RTV = 0x0E, /* Read Timeout Value. */
219 FC_ELS_RLS = 0x0F, /* Read Link Status. */
220 FC_ELS_ECHO = 0x10, /* Echo */
221 FC_ELS_TEST = 0x11, /* Test */
222 FC_ELS_RRQ = 0x12, /* Reinstate Recovery Qualifier. */
223 FC_ELS_REC = 0x13, /* Add this for TAPE support in FCR */
224 FC_ELS_PRLI = 0x20, /* Process Login */
225 FC_ELS_PRLO = 0x21, /* Process Logout. */
226 FC_ELS_SCN = 0x22, /* State Change Notification. */
227 FC_ELS_TPRLO = 0x24, /* Third Party Process Logout. */
228 FC_ELS_PDISC = 0x50, /* Discover N_Port Parameters. */
229 FC_ELS_FDISC = 0x51, /* Discover F_Port Parameters. */
230 FC_ELS_ADISC = 0x52, /* Discover Address. */
231 FC_ELS_FAN = 0x60, /* Fabric Address Notification */
232 FC_ELS_RSCN = 0x61, /* Reg State Change Notification */
233 FC_ELS_SCR = 0x62, /* State Change Registration. */
234 FC_ELS_RTIN = 0x77, /* Mangement server request */
235 FC_ELS_RNID = 0x78, /* Mangement server request */
236 FC_ELS_RLIR = 0x79, /* Registered Link Incident Record */
237
238 FC_ELS_RPSC = 0x7D, /* Report Port Speed Capabilities */
239 FC_ELS_QSA = 0x7E, /* Query Security Attributes. Ref FC-SP */
240 FC_ELS_E2E_LBEACON = 0x81,
241 /* End-to-End Link Beacon */
242 FC_ELS_AUTH = 0x90, /* Authentication. Ref FC-SP */
243 FC_ELS_RFCN = 0x97, /* Request Fabric Change Notification. Ref
244 *FC-SP */
245
246};
247
248/*
249 * Version numbers for FC-PH standards,
250 * used in login to indicate what port
251 * supports. See FC-PH-X table 158.
252 */
253enum {
254 FC_PH_VER_4_3 = 0x09,
255 FC_PH_VER_PH_3 = 0x20,
256};
257
258/*
259 * PDU size defines
260 */
261enum {
262 FC_MIN_PDUSZ = 512,
263 FC_MAX_PDUSZ = 2112,
264};
265
266/*
267 * N_Port PLOGI Common Service Parameters.
268 * FC-PH-x. Figure-76. pg. 308.
269 */
270struct fc_plogi_csp_s{
271 u8 verhi; /* FC-PH high version */
272 u8 verlo; /* FC-PH low version */
273 u16 bbcred; /* BB_Credit */
274
275#ifdef __BIGENDIAN
276 u8 ciro:1, /* continuously increasing RO */
277 rro:1, /* random relative offset */
278 npiv_supp:1, /* NPIV supported */
279 port_type:1, /* N_Port/F_port */
280 altbbcred:1, /* alternate BB_Credit */
281 resolution:1, /* ms/ns ED_TOV resolution */
282 vvl_info:1, /* VVL Info included */
283 reserved1:1;
284
285 u8 hg_supp:1,
286 query_dbc:1,
287 security:1,
288 sync_cap:1,
289 r_t_tov:1,
290 dh_dup_supp:1,
291 cisc:1, /* continuously increasing seq count */
292 payload:1;
293#else
294 u8 reserved2:2,
295 resolution:1, /* ms/ns ED_TOV resolution */
296 altbbcred:1, /* alternate BB_Credit */
297 port_type:1, /* N_Port/F_port */
298 npiv_supp:1, /* NPIV supported */
299 rro:1, /* random relative offset */
300 ciro:1; /* continuously increasing RO */
301
302 u8 payload:1,
303 cisc:1, /* continuously increasing seq count */
304 dh_dup_supp:1,
305 r_t_tov:1,
306 sync_cap:1,
307 security:1,
308 query_dbc:1,
309 hg_supp:1;
310#endif
311
312 u16 rxsz; /* recieve data_field size */
313
314 u16 conseq;
315 u16 ro_bitmap;
316
317 u32 e_d_tov;
318};
319
320/*
321 * N_Port PLOGI Class Specific Parameters.
322 * FC-PH-x. Figure 78. pg. 318.
323 */
324struct fc_plogi_clp_s{
325#ifdef __BIGENDIAN
326 u32 class_valid:1;
327 u32 intermix:1; /* class intermix supported if set =1.
328 * valid only for class1. Reserved for
329 * class2 & class3
330 */
331 u32 reserved1:2;
332 u32 sequential:1;
333 u32 reserved2:3;
334#else
335 u32 reserved2:3;
336 u32 sequential:1;
337 u32 reserved1:2;
338 u32 intermix:1; /* class intermix supported if set =1.
339 * valid only for class1. Reserved for
340 * class2 & class3
341 */
342 u32 class_valid:1;
343#endif
344
345 u32 reserved3:24;
346
347 u32 reserved4:16;
348 u32 rxsz:16; /* Receive data_field size */
349
350 u32 reserved5:8;
351 u32 conseq:8;
352 u32 e2e_credit:16; /* end to end credit */
353
354 u32 reserved7:8;
355 u32 ospx:8;
356 u32 reserved8:16;
357};
358
359#define FLOGI_VVL_BRCD 0x42524344 /* ASCII value for each character in
360 * string "BRCD" */
361
362/*
363 * PLOGI els command and reply payload
364 */
365struct fc_logi_s{
366 struct fc_els_cmd_s els_cmd; /* ELS command code */
367 struct fc_plogi_csp_s csp; /* common service params */
368 wwn_t port_name;
369 wwn_t node_name;
370 struct fc_plogi_clp_s class1; /* class 1 service parameters */
371 struct fc_plogi_clp_s class2; /* class 2 service parameters */
372 struct fc_plogi_clp_s class3; /* class 3 service parameters */
373 struct fc_plogi_clp_s class4; /* class 4 service parameters */
374 u8 vvl[16]; /* vendor version level */
375};
376
377/*
378 * LOGO els command payload
379 */
380struct fc_logo_s{
381 struct fc_els_cmd_s els_cmd; /* ELS command code */
382 u32 res1:8;
383 u32 nport_id:24; /* N_Port identifier of source */
384 wwn_t orig_port_name; /* Port name of the LOGO originator */
385};
386
387/*
388 * ADISC els command payload
389 */
390struct fc_adisc_s {
391 struct fc_els_cmd_s els_cmd; /* ELS command code */
392 u32 res1:8;
393 u32 orig_HA:24; /* originator hard address */
394 wwn_t orig_port_name; /* originator port name */
395 wwn_t orig_node_name; /* originator node name */
396 u32 res2:8;
397 u32 nport_id:24; /* originator NPortID */
398};
399
400/*
401 * Exchange status block
402 */
403struct fc_exch_status_blk_s{
404 u32 oxid:16;
405 u32 rxid:16;
406 u32 res1:8;
407 u32 orig_np:24; /* originator NPortID */
408 u32 res2:8;
409 u32 resp_np:24; /* responder NPortID */
410 u32 es_bits;
411 u32 res3;
412 /*
413 * un modified section of the fields
414 */
415};
416
417/*
418 * RES els command payload
419 */
420struct fc_res_s {
421 struct fc_els_cmd_s els_cmd; /* ELS command code */
422 u32 res1:8;
423 u32 nport_id:24; /* N_Port identifier of source */
424 u32 oxid:16;
425 u32 rxid:16;
426 u8 assoc_hdr[32];
427};
428
429/*
430 * RES els accept payload
431 */
432struct fc_res_acc_s{
433 struct fc_els_cmd_s els_cmd; /* ELS command code */
434 struct fc_exch_status_blk_s fc_exch_blk; /* Exchange status block */
435};
436
437/*
438 * REC els command payload
439 */
440struct fc_rec_s {
441 struct fc_els_cmd_s els_cmd; /* ELS command code */
442 u32 res1:8;
443 u32 nport_id:24; /* N_Port identifier of source */
444 u32 oxid:16;
445 u32 rxid:16;
446};
447
448#define FC_REC_ESB_OWN_RSP 0x80000000 /* responder owns */
449#define FC_REC_ESB_SI 0x40000000 /* SI is owned */
450#define FC_REC_ESB_COMP 0x20000000 /* exchange is complete */
451#define FC_REC_ESB_ENDCOND_ABN 0x10000000 /* abnormal ending */
452#define FC_REC_ESB_RQACT 0x04000000 /* recovery qual active */
453#define FC_REC_ESB_ERRP_MSK 0x03000000
454#define FC_REC_ESB_OXID_INV 0x00800000 /* invalid OXID */
455#define FC_REC_ESB_RXID_INV 0x00400000 /* invalid RXID */
456#define FC_REC_ESB_PRIO_INUSE 0x00200000
457
458/*
459 * REC els accept payload
460 */
461struct fc_rec_acc_s {
462 struct fc_els_cmd_s els_cmd; /* ELS command code */
463 u32 oxid:16;
464 u32 rxid:16;
465 u32 res1:8;
466 u32 orig_id:24; /* N_Port id of exchange originator */
467 u32 res2:8;
468 u32 resp_id:24; /* N_Port id of exchange responder */
469 u32 count; /* data transfer count */
470 u32 e_stat; /* exchange status */
471};
472
473/*
474 * RSI els payload
475 */
476struct fc_rsi_s {
477 struct fc_els_cmd_s els_cmd;
478 u32 res1:8;
479 u32 orig_sid:24;
480 u32 oxid:16;
481 u32 rxid:16;
482};
483
484/*
485 * structure for PRLI paramater pages, both request & response
486 * see FC-PH-X table 113 & 115 for explanation also FCP table 8
487 */
488struct fc_prli_params_s{
489 u32 reserved: 16;
490#ifdef __BIGENDIAN
491 u32 reserved1: 5;
492 u32 rec_support : 1;
493 u32 task_retry_id : 1;
494 u32 retry : 1;
495
496 u32 confirm : 1;
497 u32 doverlay:1;
498 u32 initiator:1;
499 u32 target:1;
500 u32 cdmix:1;
501 u32 drmix:1;
502 u32 rxrdisab:1;
503 u32 wxrdisab:1;
504#else
505 u32 retry : 1;
506 u32 task_retry_id : 1;
507 u32 rec_support : 1;
508 u32 reserved1: 5;
509
510 u32 wxrdisab:1;
511 u32 rxrdisab:1;
512 u32 drmix:1;
513 u32 cdmix:1;
514 u32 target:1;
515 u32 initiator:1;
516 u32 doverlay:1;
517 u32 confirm : 1;
518#endif
519};
520
521/*
522 * valid values for rspcode in PRLI ACC payload
523 */
524enum {
525 FC_PRLI_ACC_XQTD = 0x1, /* request executed */
526 FC_PRLI_ACC_PREDEF_IMG = 0x5, /* predefined image - no prli needed */
527};
528
529struct fc_prli_params_page_s{
530 u32 type:8;
531 u32 codext:8;
532#ifdef __BIGENDIAN
533 u32 origprocasv:1;
534 u32 rsppav:1;
535 u32 imagepair:1;
536 u32 reserved1:1;
537 u32 rspcode:4;
538#else
539 u32 rspcode:4;
540 u32 reserved1:1;
541 u32 imagepair:1;
542 u32 rsppav:1;
543 u32 origprocasv:1;
544#endif
545 u32 reserved2:8;
546
547 u32 origprocas;
548 u32 rspprocas;
549 struct fc_prli_params_s servparams;
550};
551
552/*
553 * PRLI request and accept payload, FC-PH-X tables 112 & 114
554 */
555struct fc_prli_s{
556 u32 command:8;
557 u32 pglen:8;
558 u32 pagebytes:16;
559 struct fc_prli_params_page_s parampage;
560};
561
562/*
563 * PRLO logout params page
564 */
565struct fc_prlo_params_page_s{
566 u32 type:8;
567 u32 type_ext:8;
568#ifdef __BIGENDIAN
569 u32 opa_valid:1; /* originator process associator
570 * valid
571 */
572 u32 rpa_valid:1; /* responder process associator valid */
573 u32 res1:14;
574#else
575 u32 res1:14;
576 u32 rpa_valid:1; /* responder process associator valid */
577 u32 opa_valid:1; /* originator process associator
578 * valid
579 */
580#endif
581 u32 orig_process_assc;
582 u32 resp_process_assc;
583
584 u32 res2;
585};
586
587/*
588 * PRLO els command payload
589 */
590struct fc_prlo_s{
591 u32 command:8;
592 u32 page_len:8;
593 u32 payload_len:16;
594 struct fc_prlo_params_page_s prlo_params[1];
595};
596
597/*
598 * PRLO Logout response parameter page
599 */
600struct fc_prlo_acc_params_page_s{
601 u32 type:8;
602 u32 type_ext:8;
603
604#ifdef __BIGENDIAN
605 u32 opa_valid:1; /* originator process associator
606 * valid
607 */
608 u32 rpa_valid:1; /* responder process associator valid */
609 u32 res1:14;
610#else
611 u32 res1:14;
612 u32 rpa_valid:1; /* responder process associator valid */
613 u32 opa_valid:1; /* originator process associator
614 * valid
615 */
616#endif
617 u32 orig_process_assc;
618 u32 resp_process_assc;
619
620 u32 fc4type_csp;
621};
622
623/*
624 * PRLO els command ACC payload
625 */
626struct fc_prlo_acc_s{
627 u32 command:8;
628 u32 page_len:8;
629 u32 payload_len:16;
630 struct fc_prlo_acc_params_page_s prlo_acc_params[1];
631};
632
633/*
634 * SCR els command payload
635 */
636enum {
637 FC_SCR_REG_FUNC_FABRIC_DETECTED = 0x01,
638 FC_SCR_REG_FUNC_N_PORT_DETECTED = 0x02,
639 FC_SCR_REG_FUNC_FULL = 0x03,
640 FC_SCR_REG_FUNC_CLEAR_REG = 0xFF,
641};
642
643/* SCR VU registrations */
644enum {
645 FC_VU_SCR_REG_FUNC_FABRIC_NAME_CHANGE = 0x01
646};
647
648struct fc_scr_s{
649 u32 command:8;
650 u32 res:24;
651 u32 vu_reg_func:8; /* Vendor Unique Registrations */
652 u32 res1:16;
653 u32 reg_func:8;
654};
655
656/*
657 * Information category for Basic link data
658 */
659enum {
660 FC_CAT_NOP = 0x0,
661 FC_CAT_ABTS = 0x1,
662 FC_CAT_RMC = 0x2,
663 FC_CAT_BA_ACC = 0x4,
664 FC_CAT_BA_RJT = 0x5,
665 FC_CAT_PRMT = 0x6,
666};
667
668/*
669 * LS_RJT els reply payload
670 */
671struct fc_ls_rjt_s {
672 struct fc_els_cmd_s els_cmd; /* ELS command code */
673 u32 res1:8;
674 u32 reason_code:8; /* Reason code for reject */
675 u32 reason_code_expl:8; /* Reason code explanation */
676 u32 vendor_unique:8; /* Vendor specific */
677};
678
679/*
680 * LS_RJT reason codes
681 */
682enum {
683 FC_LS_RJT_RSN_INV_CMD_CODE = 0x01,
684 FC_LS_RJT_RSN_LOGICAL_ERROR = 0x03,
685 FC_LS_RJT_RSN_LOGICAL_BUSY = 0x05,
686 FC_LS_RJT_RSN_PROTOCOL_ERROR = 0x07,
687 FC_LS_RJT_RSN_UNABLE_TO_PERF_CMD = 0x09,
688 FC_LS_RJT_RSN_CMD_NOT_SUPP = 0x0B,
689};
690
691/*
692 * LS_RJT reason code explanation
693 */
694enum {
695 FC_LS_RJT_EXP_NO_ADDL_INFO = 0x00,
696 FC_LS_RJT_EXP_SPARMS_ERR_OPTIONS = 0x01,
697 FC_LS_RJT_EXP_SPARMS_ERR_INI_CTL = 0x03,
698 FC_LS_RJT_EXP_SPARMS_ERR_REC_CTL = 0x05,
699 FC_LS_RJT_EXP_SPARMS_ERR_RXSZ = 0x07,
700 FC_LS_RJT_EXP_SPARMS_ERR_CONSEQ = 0x09,
701 FC_LS_RJT_EXP_SPARMS_ERR_CREDIT = 0x0B,
702 FC_LS_RJT_EXP_INV_PORT_NAME = 0x0D,
703 FC_LS_RJT_EXP_INV_NODE_FABRIC_NAME = 0x0E,
704 FC_LS_RJT_EXP_INV_CSP = 0x0F,
705 FC_LS_RJT_EXP_INV_ASSOC_HDR = 0x11,
706 FC_LS_RJT_EXP_ASSOC_HDR_REQD = 0x13,
707 FC_LS_RJT_EXP_INV_ORIG_S_ID = 0x15,
708 FC_LS_RJT_EXP_INV_OXID_RXID_COMB = 0x17,
709 FC_LS_RJT_EXP_CMD_ALREADY_IN_PROG = 0x19,
710 FC_LS_RJT_EXP_LOGIN_REQUIRED = 0x1E,
711 FC_LS_RJT_EXP_INVALID_NPORT_ID = 0x1F,
712 FC_LS_RJT_EXP_INSUFF_RES = 0x29,
713 FC_LS_RJT_EXP_CMD_NOT_SUPP = 0x2C,
714 FC_LS_RJT_EXP_INV_PAYLOAD_LEN = 0x2D,
715};
716
717/*
718 * RRQ els command payload
719 */
720struct fc_rrq_s{
721 struct fc_els_cmd_s els_cmd; /* ELS command code */
722 u32 res1:8;
723 u32 s_id:24; /* exchange originator S_ID */
724
725 u32 ox_id:16; /* originator exchange ID */
726 u32 rx_id:16; /* responder exchange ID */
727
728 u32 res2[8]; /* optional association header */
729};
730
731/*
732 * ABTS BA_ACC reply payload
733 */
734struct fc_ba_acc_s{
735 u32 seq_id_valid:8; /* set to 0x00 for Abort Exchange */
736 u32 seq_id:8; /* invalid for Abort Exchange */
737 u32 res2:16;
738 u32 ox_id:16; /* OX_ID from ABTS frame */
739 u32 rx_id:16; /* RX_ID from ABTS frame */
740 u32 low_seq_cnt:16; /* set to 0x0000 for Abort Exchange */
741 u32 high_seq_cnt:16;/* set to 0xFFFF for Abort Exchange */
742};
743
744/*
745 * ABTS BA_RJT reject payload
746 */
747struct fc_ba_rjt_s{
748 u32 res1:8; /* Reserved */
749 u32 reason_code:8; /* reason code for reject */
750 u32 reason_expl:8; /* reason code explanation */
751 u32 vendor_unique:8;/* vendor unique reason code,set to 0 */
752};
753
754/*
755 * TPRLO logout parameter page
756 */
757struct fc_tprlo_params_page_s{
758 u32 type:8;
759 u32 type_ext:8;
760
761#ifdef __BIGENDIAN
762 u32 opa_valid:1;
763 u32 rpa_valid:1;
764 u32 tpo_nport_valid:1;
765 u32 global_process_logout:1;
766 u32 res1:12;
767#else
768 u32 res1:12;
769 u32 global_process_logout:1;
770 u32 tpo_nport_valid:1;
771 u32 rpa_valid:1;
772 u32 opa_valid:1;
773#endif
774
775 u32 orig_process_assc;
776 u32 resp_process_assc;
777
778 u32 res2:8;
779 u32 tpo_nport_id;
780};
781
782/*
783 * TPRLO ELS command payload
784 */
785struct fc_tprlo_s{
786 u32 command:8;
787 u32 page_len:8;
788 u32 payload_len:16;
789
790 struct fc_tprlo_params_page_s tprlo_params[1];
791};
792
793enum fc_tprlo_type{
794 FC_GLOBAL_LOGO = 1,
795 FC_TPR_LOGO
796};
797
798/*
799 * TPRLO els command ACC payload
800 */
801struct fc_tprlo_acc_s{
802 u32 command:8;
803 u32 page_len:8;
804 u32 payload_len:16;
805 struct fc_prlo_acc_params_page_s tprlo_acc_params[1];
806};
807
808/*
809 * RSCN els command req payload
810 */
811#define FC_RSCN_PGLEN 0x4
812
813enum fc_rscn_format{
814 FC_RSCN_FORMAT_PORTID = 0x0,
815 FC_RSCN_FORMAT_AREA = 0x1,
816 FC_RSCN_FORMAT_DOMAIN = 0x2,
817 FC_RSCN_FORMAT_FABRIC = 0x3,
818};
819
820struct fc_rscn_event_s{
821 u32 format:2;
822 u32 qualifier:4;
823 u32 resvd:2;
824 u32 portid:24;
825};
826
827struct fc_rscn_pl_s{
828 u8 command;
829 u8 pagelen;
830 u16 payldlen;
831 struct fc_rscn_event_s event[1];
832};
833
834/*
835 * ECHO els command req payload
836 */
837struct fc_echo_s {
838 struct fc_els_cmd_s els_cmd;
839};
840
841/*
842 * RNID els command
843 */
844
845#define RNID_NODEID_DATA_FORMAT_COMMON 0x00
846#define RNID_NODEID_DATA_FORMAT_FCP3 0x08
847#define RNID_NODEID_DATA_FORMAT_DISCOVERY 0xDF
848
849#define RNID_ASSOCIATED_TYPE_UNKNOWN 0x00000001
850#define RNID_ASSOCIATED_TYPE_OTHER 0x00000002
851#define RNID_ASSOCIATED_TYPE_HUB 0x00000003
852#define RNID_ASSOCIATED_TYPE_SWITCH 0x00000004
853#define RNID_ASSOCIATED_TYPE_GATEWAY 0x00000005
854#define RNID_ASSOCIATED_TYPE_STORAGE_DEVICE 0x00000009
855#define RNID_ASSOCIATED_TYPE_HOST 0x0000000A
856#define RNID_ASSOCIATED_TYPE_STORAGE_SUBSYSTEM 0x0000000B
857#define RNID_ASSOCIATED_TYPE_STORAGE_ACCESS_DEVICE 0x0000000E
858#define RNID_ASSOCIATED_TYPE_NAS_SERVER 0x00000011
859#define RNID_ASSOCIATED_TYPE_BRIDGE 0x00000002
860#define RNID_ASSOCIATED_TYPE_VIRTUALIZATION_DEVICE 0x00000003
861#define RNID_ASSOCIATED_TYPE_MULTI_FUNCTION_DEVICE 0x000000FF
862
863/*
864 * RNID els command payload
865 */
866struct fc_rnid_cmd_s{
867 struct fc_els_cmd_s els_cmd;
868 u32 node_id_data_format:8;
869 u32 reserved:24;
870};
871
872/*
873 * RNID els response payload
874 */
875
876struct fc_rnid_common_id_data_s{
877 wwn_t port_name;
878 wwn_t node_name;
879};
880
881struct fc_rnid_general_topology_data_s{
882 u32 vendor_unique[4];
883 u32 asso_type;
884 u32 phy_port_num;
885 u32 num_attached_nodes;
886 u32 node_mgmt:8;
887 u32 ip_version:8;
888 u32 udp_tcp_port_num:16;
889 u32 ip_address[4];
890 u32 reserved:16;
891 u32 vendor_specific:16;
892};
893
894struct fc_rnid_acc_s{
895 struct fc_els_cmd_s els_cmd;
896 u32 node_id_data_format:8;
897 u32 common_id_data_length:8;
898 u32 reserved:8;
899 u32 specific_id_data_length:8;
900 struct fc_rnid_common_id_data_s common_id_data;
901 struct fc_rnid_general_topology_data_s gen_topology_data;
902};
903
904#define RNID_ASSOCIATED_TYPE_UNKNOWN 0x00000001
905#define RNID_ASSOCIATED_TYPE_OTHER 0x00000002
906#define RNID_ASSOCIATED_TYPE_HUB 0x00000003
907#define RNID_ASSOCIATED_TYPE_SWITCH 0x00000004
908#define RNID_ASSOCIATED_TYPE_GATEWAY 0x00000005
909#define RNID_ASSOCIATED_TYPE_STORAGE_DEVICE 0x00000009
910#define RNID_ASSOCIATED_TYPE_HOST 0x0000000A
911#define RNID_ASSOCIATED_TYPE_STORAGE_SUBSYSTEM 0x0000000B
912#define RNID_ASSOCIATED_TYPE_STORAGE_ACCESS_DEVICE 0x0000000E
913#define RNID_ASSOCIATED_TYPE_NAS_SERVER 0x00000011
914#define RNID_ASSOCIATED_TYPE_BRIDGE 0x00000002
915#define RNID_ASSOCIATED_TYPE_VIRTUALIZATION_DEVICE 0x00000003
916#define RNID_ASSOCIATED_TYPE_MULTI_FUNCTION_DEVICE 0x000000FF
917
918enum fc_rpsc_speed_cap{
919 RPSC_SPEED_CAP_1G = 0x8000,
920 RPSC_SPEED_CAP_2G = 0x4000,
921 RPSC_SPEED_CAP_4G = 0x2000,
922 RPSC_SPEED_CAP_10G = 0x1000,
923 RPSC_SPEED_CAP_8G = 0x0800,
924 RPSC_SPEED_CAP_16G = 0x0400,
925
926 RPSC_SPEED_CAP_UNKNOWN = 0x0001,
927};
928
929enum fc_rpsc_op_speed_s{
930 RPSC_OP_SPEED_1G = 0x8000,
931 RPSC_OP_SPEED_2G = 0x4000,
932 RPSC_OP_SPEED_4G = 0x2000,
933 RPSC_OP_SPEED_10G = 0x1000,
934 RPSC_OP_SPEED_8G = 0x0800,
935 RPSC_OP_SPEED_16G = 0x0400,
936
937 RPSC_OP_SPEED_NOT_EST = 0x0001, /*! speed not established */
938};
939
940struct fc_rpsc_speed_info_s{
941 u16 port_speed_cap; /*! see fc_rpsc_speed_cap_t */
942 u16 port_op_speed; /*! see fc_rpsc_op_speed_t */
943};
944
945enum link_e2e_beacon_subcmd{
946 LINK_E2E_BEACON_ON = 1,
947 LINK_E2E_BEACON_OFF = 2
948};
949
950enum beacon_type{
951 BEACON_TYPE_NORMAL = 1, /*! Normal Beaconing. Green */
952 BEACON_TYPE_WARN = 2, /*! Warning Beaconing. Yellow/Amber */
953 BEACON_TYPE_CRITICAL = 3 /*! Critical Beaconing. Red */
954};
955
956struct link_e2e_beacon_param_s {
957 u8 beacon_type; /* Beacon Type. See beacon_type_t */
958 u8 beacon_frequency;
959 /* Beacon frequency. Number of blinks
960 * per 10 seconds
961 */
962 u16 beacon_duration;/* Beacon duration (in Seconds). The
963 * command operation should be
964 * terminated at the end of this
965 * timeout value.
966 *
967 * Ignored if diag_sub_cmd is
968 * LINK_E2E_BEACON_OFF.
969 *
970 * If 0, beaconing will continue till a
971 * BEACON OFF request is received
972 */
973};
974
975/*
976 * Link E2E beacon request/good response format. For LS_RJTs use fc_ls_rjt_t
977 */
978struct link_e2e_beacon_req_s{
979 u32 ls_code; /*! FC_ELS_E2E_LBEACON in requests *
980 *or FC_ELS_ACC in good replies */
981 u32 ls_sub_cmd; /*! See link_e2e_beacon_subcmd_t */
982 struct link_e2e_beacon_param_s beacon_parm;
983};
984
985/**
986 * If RPSC request is sent to the Domain Controller, the request is for
987 * all the ports within that domain (TODO - I don't think FOS implements
988 * this...).
989 */
990struct fc_rpsc_cmd_s{
991 struct fc_els_cmd_s els_cmd;
992};
993
994/*
995 * RPSC Acc
996 */
997struct fc_rpsc_acc_s{
998 u32 command:8;
999 u32 rsvd:8;
1000 u32 num_entries:16;
1001
1002 struct fc_rpsc_speed_info_s speed_info[1];
1003};
1004
1005/**
1006 * If RPSC2 request is sent to the Domain Controller,
1007 */
1008#define FC_BRCD_TOKEN 0x42524344
1009
1010struct fc_rpsc2_cmd_s{
1011 struct fc_els_cmd_s els_cmd;
1012 u32 token;
1013 u16 resvd;
1014 u16 num_pids; /* Number of pids in the request */
1015 struct {
1016 u32 rsvd1:8;
1017 u32 pid:24; /* port identifier */
1018 } pid_list[1];
1019};
1020
1021enum fc_rpsc2_port_type{
1022 RPSC2_PORT_TYPE_UNKNOWN = 0,
1023 RPSC2_PORT_TYPE_NPORT = 1,
1024 RPSC2_PORT_TYPE_NLPORT = 2,
1025 RPSC2_PORT_TYPE_NPIV_PORT = 0x5f,
1026 RPSC2_PORT_TYPE_NPORT_TRUNK = 0x6f,
1027};
1028
1029/*
1030 * RPSC2 portInfo entry structure
1031 */
1032struct fc_rpsc2_port_info_s{
1033 u32 pid; /* PID */
1034 u16 resvd1;
1035 u16 index; /* port number / index */
1036 u8 resvd2;
1037 u8 type; /* port type N/NL/... */
1038 u16 speed; /* port Operating Speed */
1039};
1040
1041/*
1042 * RPSC2 Accept payload
1043 */
1044struct fc_rpsc2_acc_s{
1045 u8 els_cmd;
1046 u8 resvd;
1047 u16 num_pids; /* Number of pids in the request */
1048 struct fc_rpsc2_port_info_s port_info[1]; /* port information */
1049};
1050
1051/**
1052 * bit fields so that multiple classes can be specified
1053 */
1054enum fc_cos{
1055 FC_CLASS_2 = 0x04,
1056 FC_CLASS_3 = 0x08,
1057 FC_CLASS_2_3 = 0x0C,
1058};
1059
1060/*
1061 * symbolic name
1062 */
1063struct fc_symname_s{
1064 u8 symname[FC_SYMNAME_MAX];
1065};
1066
1067struct fc_alpabm_s{
1068 u8 alpa_bm[FC_ALPA_MAX / 8];
1069};
1070
1071/*
1072 * protocol default timeout values
1073 */
1074#define FC_ED_TOV 2
1075#define FC_REC_TOV (FC_ED_TOV + 1)
1076#define FC_RA_TOV 10
1077#define FC_ELS_TOV (2 * FC_RA_TOV)
1078
1079/*
1080 * virtual fabric related defines
1081 */
1082#define FC_VF_ID_NULL 0 /* must not be used as VF_ID */
1083#define FC_VF_ID_MIN 1
1084#define FC_VF_ID_MAX 0xEFF
1085#define FC_VF_ID_CTL 0xFEF /* control VF_ID */
1086
1087/**
1088 * Virtual Fabric Tagging header format
1089 * @caution This is defined only in BIG ENDIAN format.
1090 */
1091struct fc_vft_s{
1092 u32 r_ctl:8;
1093 u32 ver:2;
1094 u32 type:4;
1095 u32 res_a:2;
1096 u32 priority:3;
1097 u32 vf_id:12;
1098 u32 res_b:1;
1099 u32 hopct:8;
1100 u32 res_c:24;
1101};
1102
1103#pragma pack()
1104
1105#endif
diff --git a/drivers/scsi/bfa/include/protocol/fc_sp.h b/drivers/scsi/bfa/include/protocol/fc_sp.h
new file mode 100644
index 000000000000..55bb0b31d04b
--- /dev/null
+++ b/drivers/scsi/bfa/include/protocol/fc_sp.h
@@ -0,0 +1,224 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __FC_SP_H__
19#define __FC_SP_H__
20
21#include <protocol/types.h>
22
23#pragma pack(1)
24
25enum auth_els_flags{
26 FC_AUTH_ELS_MORE_FRAGS_FLAG = 0x80, /*! bit-7. More Fragments
27 * Follow
28 */
29 FC_AUTH_ELS_CONCAT_FLAG = 0x40, /*! bit-6. Concatenation Flag */
30 FC_AUTH_ELS_SEQ_NUM_FLAG = 0x01 /*! bit-0. Sequence Number */
31};
32
33enum auth_msg_codes{
34 FC_AUTH_MC_AUTH_RJT = 0x0A, /*! Auth Reject */
35 FC_AUTH_MC_AUTH_NEG = 0x0B, /*! Auth Negotiate */
36 FC_AUTH_MC_AUTH_DONE = 0x0C, /*! Auth Done */
37
38 FC_AUTH_MC_DHCHAP_CHAL = 0x10, /*! DHCHAP Challenge */
39 FC_AUTH_MC_DHCHAP_REPLY = 0x11, /*! DHCHAP Reply */
40 FC_AUTH_MC_DHCHAP_SUCC = 0x12, /*! DHCHAP Success */
41
42 FC_AUTH_MC_FCAP_REQ = 0x13, /*! FCAP Request */
43 FC_AUTH_MC_FCAP_ACK = 0x14, /*! FCAP Acknowledge */
44 FC_AUTH_MC_FCAP_CONF = 0x15, /*! FCAP Confirm */
45
46 FC_AUTH_MC_FCPAP_INIT = 0x16, /*! FCPAP Init */
47 FC_AUTH_MC_FCPAP_ACC = 0x17, /*! FCPAP Accept */
48 FC_AUTH_MC_FCPAP_COMP = 0x18, /*! FCPAP Complete */
49
50 FC_AUTH_MC_IKE_SA_INIT = 0x22, /*! IKE SA INIT */
51 FC_AUTH_MC_IKE_SA_AUTH = 0x23, /*! IKE SA Auth */
52 FC_AUTH_MC_IKE_CREATE_CHILD_SA = 0x24, /*! IKE Create Child SA */
53 FC_AUTH_MC_IKE_INFO = 0x25, /*! IKE informational */
54};
55
56enum auth_proto_version{
57 FC_AUTH_PROTO_VER_1 = 1, /*! Protocol Version 1 */
58};
59
60enum {
61 FC_AUTH_ELS_COMMAND_CODE = 0x90,/*! Authentication ELS Command code */
62 FC_AUTH_PROTO_PARAM_LEN_SZ = 4, /*! Size of Proto Parameter Len Field */
63 FC_AUTH_PROTO_PARAM_VAL_SZ = 4, /*! Size of Proto Parameter Val Field */
64 FC_MAX_AUTH_SECRET_LEN = 256,
65 /*! Maximum secret string length */
66 FC_AUTH_NUM_USABLE_PROTO_LEN_SZ = 4,
67 /*! Size of usable protocols field */
68 FC_AUTH_RESP_VALUE_LEN_SZ = 4,
69 /*! Size of response value length */
70 FC_MAX_CHAP_KEY_LEN = 256, /*! Maximum md5 digest length */
71 FC_MAX_AUTH_RETRIES = 3, /*! Maximum number of retries */
72 FC_MD5_DIGEST_LEN = 16, /*! MD5 digest length */
73 FC_SHA1_DIGEST_LEN = 20, /*! SHA1 digest length */
74 FC_MAX_DHG_SUPPORTED = 1, /*! Maximum DH Groups supported */
75 FC_MAX_ALG_SUPPORTED = 1, /*! Maximum algorithms supported */
76 FC_MAX_PROTO_SUPPORTED = 1, /*! Maximum protocols supported */
77 FC_START_TXN_ID = 2, /*! Starting transaction ID */
78};
79
80enum auth_proto_id{
81 FC_AUTH_PROTO_DHCHAP = 0x00000001,
82 FC_AUTH_PROTO_FCAP = 0x00000002,
83 FC_AUTH_PROTO_FCPAP = 0x00000003,
84 FC_AUTH_PROTO_IKEv2 = 0x00000004,
85 FC_AUTH_PROTO_IKEv2_AUTH = 0x00000005,
86};
87
88struct auth_name_s{
89 u16 name_tag; /*! Name Tag = 1 for Authentication */
90 u16 name_len; /*! Name Length = 8 for Authentication
91 */
92 wwn_t name; /*! Name. TODO - is this PWWN */
93};
94
95
96enum auth_hash_func{
97 FC_AUTH_HASH_FUNC_MD5 = 0x00000005,
98 FC_AUTH_HASH_FUNC_SHA_1 = 0x00000006,
99};
100
101enum auth_dh_gid{
102 FC_AUTH_DH_GID_0_DHG_NULL = 0x00000000,
103 FC_AUTH_DH_GID_1_DHG_1024 = 0x00000001,
104 FC_AUTH_DH_GID_2_DHG_1280 = 0x00000002,
105 FC_AUTH_DH_GID_3_DHG_1536 = 0x00000003,
106 FC_AUTH_DH_GID_4_DHG_2048 = 0x00000004,
107 FC_AUTH_DH_GID_6_DHG_3072 = 0x00000006,
108 FC_AUTH_DH_GID_7_DHG_4096 = 0x00000007,
109 FC_AUTH_DH_GID_8_DHG_6144 = 0x00000008,
110 FC_AUTH_DH_GID_9_DHG_8192 = 0x00000009,
111};
112
113struct auth_els_msg_s {
114 u8 auth_els_code; /* Authentication ELS Code (0x90) */
115 u8 auth_els_flag; /* Authentication ELS Flags */
116 u8 auth_msg_code; /* Authentication Message Code */
117 u8 proto_version; /* Protocol Version */
118 u32 msg_len; /* Message Length */
119 u32 trans_id; /* Transaction Identifier (T_ID) */
120
121 /* Msg payload follows... */
122};
123
124
125enum auth_neg_param_tags {
126 FC_AUTH_NEG_DHCHAP_HASHLIST = 0x0001,
127 FC_AUTH_NEG_DHCHAP_DHG_ID_LIST = 0x0002,
128};
129
130
131struct dhchap_param_format_s {
132 u16 tag; /*! Parameter Tag. See
133 * auth_neg_param_tags_t
134 */
135 u16 word_cnt;
136
137 /* followed by variable length parameter value... */
138};
139
140struct auth_proto_params_s {
141 u32 proto_param_len;
142 u32 proto_id;
143
144 /*
145 * Followed by variable length Protocol specific parameters. DH-CHAP
146 * uses dhchap_param_format_t
147 */
148};
149
150struct auth_neg_msg_s {
151 struct auth_name_s auth_ini_name;
152 u32 usable_auth_protos;
153 struct auth_proto_params_s proto_params[1]; /*! (1..usable_auth_proto)
154 * protocol params
155 */
156};
157
158struct auth_dh_val_s {
159 u32 dh_val_len;
160 u32 dh_val[1];
161};
162
163struct auth_dhchap_chal_msg_s {
164 struct auth_els_msg_s hdr;
165 struct auth_name_s auth_responder_name; /* TODO VRK - is auth_name_t
166 * type OK?
167 */
168 u32 hash_id;
169 u32 dh_grp_id;
170 u32 chal_val_len;
171 char chal_val[1];
172
173 /* ...followed by variable Challenge length/value and DH length/value */
174};
175
176
177enum auth_rjt_codes {
178 FC_AUTH_RJT_CODE_AUTH_FAILURE = 0x01,
179 FC_AUTH_RJT_CODE_LOGICAL_ERR = 0x02,
180};
181
182enum auth_rjt_code_exps {
183 FC_AUTH_CEXP_AUTH_MECH_NOT_USABLE = 0x01,
184 FC_AUTH_CEXP_DH_GROUP_NOT_USABLE = 0x02,
185 FC_AUTH_CEXP_HASH_FUNC_NOT_USABLE = 0x03,
186 FC_AUTH_CEXP_AUTH_XACT_STARTED = 0x04,
187 FC_AUTH_CEXP_AUTH_FAILED = 0x05,
188 FC_AUTH_CEXP_INCORRECT_PLD = 0x06,
189 FC_AUTH_CEXP_INCORRECT_PROTO_MSG = 0x07,
190 FC_AUTH_CEXP_RESTART_AUTH_PROTO = 0x08,
191 FC_AUTH_CEXP_AUTH_CONCAT_NOT_SUPP = 0x09,
192 FC_AUTH_CEXP_PROTO_VER_NOT_SUPP = 0x0A,
193};
194
195enum auth_status {
196 FC_AUTH_STATE_INPROGRESS = 0, /*! authentication in progress */
197 FC_AUTH_STATE_FAILED = 1, /*! authentication failed */
198 FC_AUTH_STATE_SUCCESS = 2 /*! authentication successful */
199};
200
201struct auth_rjt_msg_s {
202 struct auth_els_msg_s hdr;
203 u8 reason_code;
204 u8 reason_code_exp;
205 u8 rsvd[2];
206};
207
208
209struct auth_dhchap_neg_msg_s {
210 struct auth_els_msg_s hdr;
211 struct auth_neg_msg_s nego;
212};
213
214struct auth_dhchap_reply_msg_s {
215 struct auth_els_msg_s hdr;
216
217 /*
218 * followed by response value length & Value + DH Value Length & Value
219 */
220};
221
222#pragma pack()
223
224#endif /* __FC_SP_H__ */
diff --git a/drivers/scsi/bfa/include/protocol/fcp.h b/drivers/scsi/bfa/include/protocol/fcp.h
new file mode 100644
index 000000000000..9ade68ad2853
--- /dev/null
+++ b/drivers/scsi/bfa/include/protocol/fcp.h
@@ -0,0 +1,186 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __FCPPROTO_H__
19#define __FCPPROTO_H__
20
21#include <protocol/scsi.h>
22
23#pragma pack(1)
24
25enum {
26 FCP_RJT = 0x01000000, /* SRR reject */
27 FCP_SRR_ACCEPT = 0x02000000, /* SRR accept */
28 FCP_SRR = 0x14000000, /* Sequence Retransmission Request */
29};
30
31/*
32 * SRR FC-4 LS payload
33 */
34struct fc_srr_s{
35 u32 ls_cmd;
36 u32 ox_id:16; /* ox-id */
37 u32 rx_id:16; /* rx-id */
38 u32 ro; /* relative offset */
39 u32 r_ctl:8; /* R_CTL for I.U. */
40 u32 res:24;
41};
42
43
44/*
45 * FCP_CMND definitions
46 */
47#define FCP_CMND_CDB_LEN 16
48#define FCP_CMND_LUN_LEN 8
49
50struct fcp_cmnd_s{
51 lun_t lun; /* 64-bit LU number */
52 u8 crn; /* command reference number */
53#ifdef __BIGENDIAN
54 u8 resvd:1,
55 priority:4, /* FCP-3: SAM-3 priority */
56 taskattr:3; /* scsi task attribute */
57#else
58 u8 taskattr:3, /* scsi task attribute */
59 priority:4, /* FCP-3: SAM-3 priority */
60 resvd:1;
61#endif
62 u8 tm_flags; /* task management flags */
63#ifdef __BIGENDIAN
64 u8 addl_cdb_len:6, /* additional CDB length words */
65 iodir:2; /* read/write FCP_DATA IUs */
66#else
67 u8 iodir:2, /* read/write FCP_DATA IUs */
68 addl_cdb_len:6; /* additional CDB length */
69#endif
70 struct scsi_cdb_s cdb;
71
72 /*
73 * !!! additional cdb bytes follows here!!!
74 */
75 u32 fcp_dl; /* bytes to be transferred */
76};
77
78#define fcp_cmnd_cdb_len(_cmnd) ((_cmnd)->addl_cdb_len * 4 + FCP_CMND_CDB_LEN)
79#define fcp_cmnd_fcpdl(_cmnd) ((&(_cmnd)->fcp_dl)[(_cmnd)->addl_cdb_len])
80
81/*
82 * fcp_cmnd_t.iodir field values
83 */
84enum fcp_iodir{
85 FCP_IODIR_NONE = 0,
86 FCP_IODIR_WRITE = 1,
87 FCP_IODIR_READ = 2,
88 FCP_IODIR_RW = 3,
89};
90
91/*
92 * Task attribute field
93 */
94enum {
95 FCP_TASK_ATTR_SIMPLE = 0,
96 FCP_TASK_ATTR_HOQ = 1,
97 FCP_TASK_ATTR_ORDERED = 2,
98 FCP_TASK_ATTR_ACA = 4,
99 FCP_TASK_ATTR_UNTAGGED = 5, /* obsolete in FCP-3 */
100};
101
102/*
103 * Task management flags field - only one bit shall be set
104 */
105#ifndef BIT
106#define BIT(_x) (1 << (_x))
107#endif
108enum fcp_tm_cmnd{
109 FCP_TM_ABORT_TASK_SET = BIT(1),
110 FCP_TM_CLEAR_TASK_SET = BIT(2),
111 FCP_TM_LUN_RESET = BIT(4),
112 FCP_TM_TARGET_RESET = BIT(5), /* obsolete in FCP-3 */
113 FCP_TM_CLEAR_ACA = BIT(6),
114};
115
116/*
117 * FCP_XFER_RDY IU defines
118 */
119struct fcp_xfer_rdy_s{
120 u32 data_ro;
121 u32 burst_len;
122 u32 reserved;
123};
124
125/*
126 * FCP_RSP residue flags
127 */
128enum fcp_residue{
129 FCP_NO_RESIDUE = 0, /* no residue */
130 FCP_RESID_OVER = 1, /* more data left that was not sent */
131 FCP_RESID_UNDER = 2, /* less data than requested */
132};
133
134enum {
135 FCP_RSPINFO_GOOD = 0,
136 FCP_RSPINFO_DATALEN_MISMATCH = 1,
137 FCP_RSPINFO_CMND_INVALID = 2,
138 FCP_RSPINFO_ROLEN_MISMATCH = 3,
139 FCP_RSPINFO_TM_NOT_SUPP = 4,
140 FCP_RSPINFO_TM_FAILED = 5,
141};
142
143struct fcp_rspinfo_s{
144 u32 res0:24;
145 u32 rsp_code:8; /* response code (as above) */
146 u32 res1;
147};
148
149struct fcp_resp_s{
150 u32 reserved[2]; /* 2 words reserved */
151 u16 reserved2;
152#ifdef __BIGENDIAN
153 u8 reserved3:3;
154 u8 fcp_conf_req:1; /* FCP_CONF is requested */
155 u8 resid_flags:2; /* underflow/overflow */
156 u8 sns_len_valid:1;/* sense len is valid */
157 u8 rsp_len_valid:1;/* response len is valid */
158#else
159 u8 rsp_len_valid:1;/* response len is valid */
160 u8 sns_len_valid:1;/* sense len is valid */
161 u8 resid_flags:2; /* underflow/overflow */
162 u8 fcp_conf_req:1; /* FCP_CONF is requested */
163 u8 reserved3:3;
164#endif
165 u8 scsi_status; /* one byte SCSI status */
166 u32 residue; /* residual data bytes */
167 u32 sns_len; /* length od sense info */
168 u32 rsp_len; /* length of response info */
169};
170
171#define fcp_snslen(__fcprsp) ((__fcprsp)->sns_len_valid ? \
172 (__fcprsp)->sns_len : 0)
173#define fcp_rsplen(__fcprsp) ((__fcprsp)->rsp_len_valid ? \
174 (__fcprsp)->rsp_len : 0)
175#define fcp_rspinfo(__fcprsp) ((struct fcp_rspinfo_s *)((__fcprsp) + 1))
176#define fcp_snsinfo(__fcprsp) (((u8 *)fcp_rspinfo(__fcprsp)) + \
177 fcp_rsplen(__fcprsp))
178
179struct fcp_cmnd_fr_s{
180 struct fchs_s fchs;
181 struct fcp_cmnd_s fcp;
182};
183
184#pragma pack()
185
186#endif
diff --git a/drivers/scsi/bfa/include/protocol/fdmi.h b/drivers/scsi/bfa/include/protocol/fdmi.h
new file mode 100644
index 000000000000..6c05c268c71b
--- /dev/null
+++ b/drivers/scsi/bfa/include/protocol/fdmi.h
@@ -0,0 +1,163 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __FDMI_H__
19#define __FDMI_H__
20
21#include <protocol/types.h>
22#include <protocol/fc.h>
23#include <protocol/ct.h>
24
25#pragma pack(1)
26
27/*
28 * FDMI Command Codes
29 */
30#define FDMI_GRHL 0x0100
31#define FDMI_GHAT 0x0101
32#define FDMI_GRPL 0x0102
33#define FDMI_GPAT 0x0110
34#define FDMI_RHBA 0x0200
35#define FDMI_RHAT 0x0201
36#define FDMI_RPRT 0x0210
37#define FDMI_RPA 0x0211
38#define FDMI_DHBA 0x0300
39#define FDMI_DPRT 0x0310
40
41/*
42 * FDMI reason codes
43 */
44#define FDMI_NO_ADDITIONAL_EXP 0x00
45#define FDMI_HBA_ALREADY_REG 0x10
46#define FDMI_HBA_ATTRIB_NOT_REG 0x11
47#define FDMI_HBA_ATTRIB_MULTIPLE 0x12
48#define FDMI_HBA_ATTRIB_LENGTH_INVALID 0x13
49#define FDMI_HBA_ATTRIB_NOT_PRESENT 0x14
50#define FDMI_PORT_ORIG_NOT_IN_LIST 0x15
51#define FDMI_PORT_HBA_NOT_IN_LIST 0x16
52#define FDMI_PORT_ATTRIB_NOT_REG 0x20
53#define FDMI_PORT_NOT_REG 0x21
54#define FDMI_PORT_ATTRIB_MULTIPLE 0x22
55#define FDMI_PORT_ATTRIB_LENGTH_INVALID 0x23
56#define FDMI_PORT_ALREADY_REGISTEREED 0x24
57
58/*
59 * FDMI Transmission Speed Mask values
60 */
61#define FDMI_TRANS_SPEED_1G 0x00000001
62#define FDMI_TRANS_SPEED_2G 0x00000002
63#define FDMI_TRANS_SPEED_10G 0x00000004
64#define FDMI_TRANS_SPEED_4G 0x00000008
65#define FDMI_TRANS_SPEED_8G 0x00000010
66#define FDMI_TRANS_SPEED_16G 0x00000020
67#define FDMI_TRANS_SPEED_UNKNOWN 0x00008000
68
69/*
70 * FDMI HBA attribute types
71 */
72enum fdmi_hba_attribute_type {
73 FDMI_HBA_ATTRIB_NODENAME = 1, /* 0x0001 */
74 FDMI_HBA_ATTRIB_MANUFACTURER, /* 0x0002 */
75 FDMI_HBA_ATTRIB_SERIALNUM, /* 0x0003 */
76 FDMI_HBA_ATTRIB_MODEL, /* 0x0004 */
77 FDMI_HBA_ATTRIB_MODEL_DESC, /* 0x0005 */
78 FDMI_HBA_ATTRIB_HW_VERSION, /* 0x0006 */
79 FDMI_HBA_ATTRIB_DRIVER_VERSION, /* 0x0007 */
80 FDMI_HBA_ATTRIB_ROM_VERSION, /* 0x0008 */
81 FDMI_HBA_ATTRIB_FW_VERSION, /* 0x0009 */
82 FDMI_HBA_ATTRIB_OS_NAME, /* 0x000A */
83 FDMI_HBA_ATTRIB_MAX_CT, /* 0x000B */
84
85 FDMI_HBA_ATTRIB_MAX_TYPE
86};
87
88/*
89 * FDMI Port attribute types
90 */
91enum fdmi_port_attribute_type {
92 FDMI_PORT_ATTRIB_FC4_TYPES = 1, /* 0x0001 */
93 FDMI_PORT_ATTRIB_SUPP_SPEED, /* 0x0002 */
94 FDMI_PORT_ATTRIB_PORT_SPEED, /* 0x0003 */
95 FDMI_PORT_ATTRIB_FRAME_SIZE, /* 0x0004 */
96 FDMI_PORT_ATTRIB_DEV_NAME, /* 0x0005 */
97 FDMI_PORT_ATTRIB_HOST_NAME, /* 0x0006 */
98
99 FDMI_PORT_ATTR_MAX_TYPE
100};
101
102/*
103 * FDMI attribute
104 */
105struct fdmi_attr_s {
106 u16 type;
107 u16 len;
108 u8 value[1];
109};
110
111/*
112 * HBA Attribute Block
113 */
114struct fdmi_hba_attr_s {
115 u32 attr_count; /* # of attributes */
116 struct fdmi_attr_s hba_attr; /* n attributes */
117};
118
119/*
120 * Registered Port List
121 */
122struct fdmi_port_list_s {
123 u32 num_ports; /* number Of Port Entries */
124 wwn_t port_entry; /* one or more */
125};
126
127/*
128 * Port Attribute Block
129 */
130struct fdmi_port_attr_s {
131 u32 attr_count; /* # of attributes */
132 struct fdmi_attr_s port_attr; /* n attributes */
133};
134
135/*
136 * FDMI Register HBA Attributes
137 */
138struct fdmi_rhba_s {
139 wwn_t hba_id; /* HBA Identifier */
140 struct fdmi_port_list_s port_list; /* Registered Port List */
141 struct fdmi_hba_attr_s hba_attr_blk; /* HBA attribute block */
142};
143
144/*
145 * FDMI Register Port
146 */
147struct fdmi_rprt_s {
148 wwn_t hba_id; /* HBA Identifier */
149 wwn_t port_name; /* Port wwn */
150 struct fdmi_port_attr_s port_attr_blk; /* Port Attr Block */
151};
152
153/*
154 * FDMI Register Port Attributes
155 */
156struct fdmi_rpa_s {
157 wwn_t port_name; /* port wwn */
158 struct fdmi_port_attr_s port_attr_blk; /* Port Attr Block */
159};
160
161#pragma pack()
162
163#endif
diff --git a/drivers/scsi/bfa/include/protocol/pcifw.h b/drivers/scsi/bfa/include/protocol/pcifw.h
new file mode 100644
index 000000000000..6830dc3ee58a
--- /dev/null
+++ b/drivers/scsi/bfa/include/protocol/pcifw.h
@@ -0,0 +1,75 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * pcifw.h PCI FW related headers
20 */
21
22#ifndef __PCIFW_H__
23#define __PCIFW_H__
24
25#pragma pack(1)
26
27struct pnp_hdr_s{
28 u32 signature; /* "$PnP" */
29 u8 rev; /* Struct revision */
30 u8 len; /* Header structure len in multiples
31 * of 16 bytes */
32 u16 off; /* Offset to next header 00 if none */
33 u8 rsvd; /* Reserved byte */
34 u8 cksum; /* 8-bit checksum for this header */
35 u32 pnp_dev_id; /* PnP Device Id */
36 u16 mfstr; /* Pointer to manufacturer string */
37 u16 prstr; /* Pointer to product string */
38 u8 devtype[3]; /* Device Type Code */
39 u8 devind; /* Device Indicator */
40 u16 bcventr; /* Bootstrap entry vector */
41 u16 rsvd2; /* Reserved */
42 u16 sriv; /* Static resource information vector */
43};
44
45struct pci_3_0_ds_s{
46 u32 sig; /* Signature "PCIR" */
47 u16 vendid; /* Vendor ID */
48 u16 devid; /* Device ID */
49 u16 devlistoff; /* Device List Offset */
50 u16 len; /* PCI Data Structure Length */
51 u8 rev; /* PCI Data Structure Revision */
52 u8 clcode[3]; /* Class Code */
53 u16 imglen; /* Code image length in multiples of
54 * 512 bytes */
55 u16 coderev; /* Revision level of code/data */
56 u8 codetype; /* Code type 0x00 - BIOS */
57 u8 indr; /* Last image indicator */
58 u16 mrtimglen; /* Max Run Time Image Length */
59 u16 cuoff; /* Config Utility Code Header Offset */
60 u16 dmtfclp; /* DMTF CLP entry point offset */
61};
62
63struct pci_optrom_hdr_s{
64 u16 sig; /* Signature 0x55AA */
65 u8 len; /* Option ROM length in units of 512 bytes */
66 u8 inivec[3]; /* Initialization vector */
67 u8 rsvd[16]; /* Reserved field */
68 u16 verptr; /* Pointer to version string - private */
69 u16 pcids; /* Pointer to PCI data structure */
70 u16 pnphdr; /* Pointer to PnP expansion header */
71};
72
73#pragma pack()
74
75#endif
diff --git a/drivers/scsi/bfa/include/protocol/scsi.h b/drivers/scsi/bfa/include/protocol/scsi.h
new file mode 100644
index 000000000000..b220e6b4f6e1
--- /dev/null
+++ b/drivers/scsi/bfa/include/protocol/scsi.h
@@ -0,0 +1,1648 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __SCSI_H__
19#define __SCSI_H__
20
21#include <protocol/types.h>
22
23#pragma pack(1)
24
25/*
26 * generic SCSI cdb definition
27 */
28#define SCSI_MAX_CDBLEN 16
29struct scsi_cdb_s{
30 u8 scsi_cdb[SCSI_MAX_CDBLEN];
31};
32
33/*
34 * scsi lun serial number definition
35 */
36#define SCSI_LUN_SN_LEN 32
37struct scsi_lun_sn_s{
38 u8 lun_sn[SCSI_LUN_SN_LEN];
39};
40
41/*
42 * SCSI Direct Access Commands
43 */
44enum {
45 SCSI_OP_TEST_UNIT_READY = 0x00,
46 SCSI_OP_REQUEST_SENSE = 0x03,
47 SCSI_OP_FORMAT_UNIT = 0x04,
48 SCSI_OP_READ6 = 0x08,
49 SCSI_OP_WRITE6 = 0x0A,
50 SCSI_OP_WRITE_FILEMARKS = 0x10,
51 SCSI_OP_INQUIRY = 0x12,
52 SCSI_OP_MODE_SELECT6 = 0x15,
53 SCSI_OP_RESERVE6 = 0x16,
54 SCSI_OP_RELEASE6 = 0x17,
55 SCSI_OP_MODE_SENSE6 = 0x1A,
56 SCSI_OP_START_STOP_UNIT = 0x1B,
57 SCSI_OP_SEND_DIAGNOSTIC = 0x1D,
58 SCSI_OP_READ_CAPACITY = 0x25,
59 SCSI_OP_READ10 = 0x28,
60 SCSI_OP_WRITE10 = 0x2A,
61 SCSI_OP_VERIFY10 = 0x2F,
62 SCSI_OP_READ_DEFECT_DATA = 0x37,
63 SCSI_OP_LOG_SELECT = 0x4C,
64 SCSI_OP_LOG_SENSE = 0x4D,
65 SCSI_OP_MODE_SELECT10 = 0x55,
66 SCSI_OP_RESERVE10 = 0x56,
67 SCSI_OP_RELEASE10 = 0x57,
68 SCSI_OP_MODE_SENSE10 = 0x5A,
69 SCSI_OP_PER_RESERVE_IN = 0x5E,
70 SCSI_OP_PER_RESERVE_OUR = 0x5E,
71 SCSI_OP_READ16 = 0x88,
72 SCSI_OP_WRITE16 = 0x8A,
73 SCSI_OP_VERIFY16 = 0x8F,
74 SCSI_OP_READ_CAPACITY16 = 0x9E,
75 SCSI_OP_REPORT_LUNS = 0xA0,
76 SCSI_OP_READ12 = 0xA8,
77 SCSI_OP_WRITE12 = 0xAA,
78 SCSI_OP_UNDEF = 0xFF,
79};
80
81/*
82 * SCSI START_STOP_UNIT command
83 */
84struct scsi_start_stop_unit_s{
85 u8 opcode;
86#ifdef __BIGENDIAN
87 u8 lun:3;
88 u8 reserved1:4;
89 u8 immed:1;
90#else
91 u8 immed:1;
92 u8 reserved1:4;
93 u8 lun:3;
94#endif
95 u8 reserved2;
96 u8 reserved3;
97#ifdef __BIGENDIAN
98 u8 power_conditions:4;
99 u8 reserved4:2;
100 u8 loEj:1;
101 u8 start:1;
102#else
103 u8 start:1;
104 u8 loEj:1;
105 u8 reserved4:2;
106 u8 power_conditions:4;
107#endif
108 u8 control;
109};
110
111/*
112 * SCSI SEND_DIAGNOSTIC command
113 */
114struct scsi_send_diagnostic_s{
115 u8 opcode;
116#ifdef __BIGENDIAN
117 u8 self_test_code:3;
118 u8 pf:1;
119 u8 reserved1:1;
120 u8 self_test:1;
121 u8 dev_offl:1;
122 u8 unit_offl:1;
123#else
124 u8 unit_offl:1;
125 u8 dev_offl:1;
126 u8 self_test:1;
127 u8 reserved1:1;
128 u8 pf:1;
129 u8 self_test_code:3;
130#endif
131 u8 reserved2;
132
133 u8 param_list_length[2]; /* MSB first */
134 u8 control;
135
136};
137
138/*
139 * SCSI READ10/WRITE10 commands
140 */
141struct scsi_rw10_s{
142 u8 opcode;
143#ifdef __BIGENDIAN
144 u8 lun:3;
145 u8 dpo:1; /* Disable Page Out */
146 u8 fua:1; /* Force Unit Access */
147 u8 reserved1:2;
148 u8 rel_adr:1; /* relative address */
149#else
150 u8 rel_adr:1;
151 u8 reserved1:2;
152 u8 fua:1;
153 u8 dpo:1;
154 u8 lun:3;
155#endif
156 u8 lba0; /* logical block address - MSB */
157 u8 lba1;
158 u8 lba2;
159 u8 lba3; /* LSB */
160 u8 reserved3;
161 u8 xfer_length0; /* transfer length in blocks - MSB */
162 u8 xfer_length1; /* LSB */
163 u8 control;
164};
165
166#define SCSI_CDB10_GET_LBA(cdb) \
167 (((cdb)->lba0 << 24) | ((cdb)->lba1 << 16) | \
168 ((cdb)->lba2 << 8) | (cdb)->lba3)
169
170#define SCSI_CDB10_SET_LBA(cdb, lba) { \
171 (cdb)->lba0 = lba >> 24; \
172 (cdb)->lba1 = (lba >> 16) & 0xFF; \
173 (cdb)->lba2 = (lba >> 8) & 0xFF; \
174 (cdb)->lba3 = lba & 0xFF; \
175}
176
177#define SCSI_CDB10_GET_TL(cdb) \
178 ((cdb)->xfer_length0 << 8 | (cdb)->xfer_length1)
179#define SCSI_CDB10_SET_TL(cdb, tl) { \
180 (cdb)->xfer_length0 = tl >> 8; \
181 (cdb)->xfer_length1 = tl & 0xFF; \
182}
183
184/*
185 * SCSI READ6/WRITE6 commands
186 */
187struct scsi_rw6_s{
188 u8 opcode;
189#ifdef __BIGENDIAN
190 u8 lun:3;
191 u8 lba0:5; /* MSb */
192#else
193 u8 lba0:5; /* MSb */
194 u8 lun:3;
195#endif
196 u8 lba1;
197 u8 lba2; /* LSB */
198 u8 xfer_length;
199 u8 control;
200};
201
202#define SCSI_TAPE_CDB6_GET_TL(cdb) \
203 (((cdb)->tl0 << 16) | ((cdb)->tl1 << 8) | (cdb)->tl2)
204
205#define SCSI_TAPE_CDB6_SET_TL(cdb, tl) { \
206 (cdb)->tl0 = tl >> 16; \
207 (cdb)->tl1 = (tl >> 8) & 0xFF; \
208 (cdb)->tl2 = tl & 0xFF; \
209}
210
211/*
212 * SCSI sequential (TAPE) wrtie command
213 */
214struct scsi_tape_wr_s{
215 u8 opcode;
216#ifdef __BIGENDIAN
217 u8 rsvd:7;
218 u8 fixed:1; /* MSb */
219#else
220 u8 fixed:1; /* MSb */
221 u8 rsvd:7;
222#endif
223 u8 tl0; /* Msb */
224 u8 tl1;
225 u8 tl2; /* Lsb */
226
227 u8 control;
228};
229
230#define SCSI_CDB6_GET_LBA(cdb) \
231 (((cdb)->lba0 << 16) | ((cdb)->lba1 << 8) | (cdb)->lba2)
232
233#define SCSI_CDB6_SET_LBA(cdb, lba) { \
234 (cdb)->lba0 = lba >> 16; \
235 (cdb)->lba1 = (lba >> 8) & 0xFF; \
236 (cdb)->lba2 = lba & 0xFF; \
237}
238
239#define SCSI_CDB6_GET_TL(cdb) ((cdb)->xfer_length)
240#define SCSI_CDB6_SET_TL(cdb, tl) { \
241 (cdb)->xfer_length = tl; \
242}
243
244/*
245 * SCSI sense data format
246 */
247struct scsi_sense_s{
248#ifdef __BIGENDIAN
249 u8 valid:1;
250 u8 rsp_code:7;
251#else
252 u8 rsp_code:7;
253 u8 valid:1;
254#endif
255 u8 seg_num;
256#ifdef __BIGENDIAN
257 u8 file_mark:1;
258 u8 eom:1; /* end of media */
259 u8 ili:1; /* incorrect length indicator */
260 u8 reserved:1;
261 u8 sense_key:4;
262#else
263 u8 sense_key:4;
264 u8 reserved:1;
265 u8 ili:1; /* incorrect length indicator */
266 u8 eom:1; /* end of media */
267 u8 file_mark:1;
268#endif
269 u8 information[4]; /* device-type or command specific info
270 */
271 u8 add_sense_length;
272 /* additional sense length */
273 u8 command_info[4];/* command specific information
274 */
275 u8 asc; /* additional sense code */
276 u8 ascq; /* additional sense code qualifier */
277 u8 fru_code; /* field replaceable unit code */
278#ifdef __BIGENDIAN
279 u8 sksv:1; /* sense key specific valid */
280 u8 c_d:1; /* command/data bit */
281 u8 res1:2;
282 u8 bpv:1; /* bit pointer valid */
283 u8 bpointer:3; /* bit pointer */
284#else
285 u8 bpointer:3; /* bit pointer */
286 u8 bpv:1; /* bit pointer valid */
287 u8 res1:2;
288 u8 c_d:1; /* command/data bit */
289 u8 sksv:1; /* sense key specific valid */
290#endif
291 u8 fpointer[2]; /* field pointer */
292};
293
294#define SCSI_SENSE_CUR_ERR 0x70
295#define SCSI_SENSE_DEF_ERR 0x71
296
297/*
298 * SCSI sense key values
299 */
300#define SCSI_SK_NO_SENSE 0x0
301#define SCSI_SK_REC_ERR 0x1 /* recovered error */
302#define SCSI_SK_NOT_READY 0x2
303#define SCSI_SK_MED_ERR 0x3 /* medium error */
304#define SCSI_SK_HW_ERR 0x4 /* hardware error */
305#define SCSI_SK_ILLEGAL_REQ 0x5
306#define SCSI_SK_UNIT_ATT 0x6 /* unit attention */
307#define SCSI_SK_DATA_PROTECT 0x7
308#define SCSI_SK_BLANK_CHECK 0x8
309#define SCSI_SK_VENDOR_SPEC 0x9
310#define SCSI_SK_COPY_ABORTED 0xA
311#define SCSI_SK_ABORTED_CMND 0xB
312#define SCSI_SK_VOL_OVERFLOW 0xD
313#define SCSI_SK_MISCOMPARE 0xE
314
315/*
316 * SCSI additional sense codes
317 */
318#define SCSI_ASC_NO_ADD_SENSE 0x00
319#define SCSI_ASC_LUN_NOT_READY 0x04
320#define SCSI_ASC_LUN_COMMUNICATION 0x08
321#define SCSI_ASC_WRITE_ERROR 0x0C
322#define SCSI_ASC_INVALID_CMND_CODE 0x20
323#define SCSI_ASC_BAD_LBA 0x21
324#define SCSI_ASC_INVALID_FIELD_IN_CDB 0x24
325#define SCSI_ASC_LUN_NOT_SUPPORTED 0x25
326#define SCSI_ASC_LUN_WRITE_PROTECT 0x27
327#define SCSI_ASC_POWERON_BDR 0x29 /* power on reset, bus reset,
328 * bus device reset
329 */
330#define SCSI_ASC_PARAMS_CHANGED 0x2A
331#define SCSI_ASC_CMND_CLEARED_BY_A_I 0x2F
332#define SCSI_ASC_SAVING_PARAM_NOTSUPP 0x39
333#define SCSI_ASC_TOCC 0x3F /* target operating condtions
334 * changed
335 */
336#define SCSI_ASC_PARITY_ERROR 0x47
337#define SCSI_ASC_CMND_PHASE_ERROR 0x4A
338#define SCSI_ASC_DATA_PHASE_ERROR 0x4B
339#define SCSI_ASC_VENDOR_SPEC 0x7F
340
341/*
342 * SCSI additional sense code qualifiers
343 */
344#define SCSI_ASCQ_CAUSE_NOT_REPORT 0x00
345#define SCSI_ASCQ_BECOMING_READY 0x01
346#define SCSI_ASCQ_INIT_CMD_REQ 0x02
347#define SCSI_ASCQ_FORMAT_IN_PROGRESS 0x04
348#define SCSI_ASCQ_OPERATION_IN_PROGRESS 0x07
349#define SCSI_ASCQ_SELF_TEST_IN_PROGRESS 0x09
350#define SCSI_ASCQ_WR_UNEXP_UNSOL_DATA 0x0C
351#define SCSI_ASCQ_WR_NOTENG_UNSOL_DATA 0x0D
352
353#define SCSI_ASCQ_LBA_OUT_OF_RANGE 0x00
354#define SCSI_ASCQ_INVALID_ELEMENT_ADDR 0x01
355
356#define SCSI_ASCQ_LUN_WRITE_PROTECTED 0x00
357#define SCSI_ASCQ_LUN_HW_WRITE_PROTECTED 0x01
358#define SCSI_ASCQ_LUN_SW_WRITE_PROTECTED 0x02
359
360#define SCSI_ASCQ_POR 0x01 /* power on reset */
361#define SCSI_ASCQ_SBR 0x02 /* scsi bus reset */
362#define SCSI_ASCQ_BDR 0x03 /* bus device reset */
363#define SCSI_ASCQ_DIR 0x04 /* device internal reset */
364
365#define SCSI_ASCQ_MODE_PARAMS_CHANGED 0x01
366#define SCSI_ASCQ_LOG_PARAMS_CHANGED 0x02
367#define SCSI_ASCQ_RESERVATIONS_PREEMPTED 0x03
368#define SCSI_ASCQ_RESERVATIONS_RELEASED 0x04
369#define SCSI_ASCQ_REGISTRATIONS_PREEMPTED 0x05
370
371#define SCSI_ASCQ_MICROCODE_CHANGED 0x01
372#define SCSI_ASCQ_CHANGED_OPER_COND 0x02
373#define SCSI_ASCQ_INQ_CHANGED 0x03 /* inquiry data changed */
374#define SCSI_ASCQ_DI_CHANGED 0x05 /* device id changed */
375#define SCSI_ASCQ_RL_DATA_CHANGED 0x0E /* report luns data changed */
376
377#define SCSI_ASCQ_DP_CRC_ERR 0x01 /* data phase crc error */
378#define SCSI_ASCQ_DP_SCSI_PARITY_ERR 0x02 /* data phase scsi parity error
379 */
380#define SCSI_ASCQ_IU_CRC_ERR 0x03 /* information unit crc error */
381#define SCSI_ASCQ_PROTO_SERV_CRC_ERR 0x05
382
383#define SCSI_ASCQ_LUN_TIME_OUT 0x01
384
385/* ------------------------------------------------------------
386 * SCSI INQUIRY
387 * ------------------------------------------------------------*/
388
389struct scsi_inquiry_s{
390 u8 opcode;
391#ifdef __BIGENDIAN
392 u8 lun:3;
393 u8 reserved1:3;
394 u8 cmd_dt:1;
395 u8 evpd:1;
396#else
397 u8 evpd:1;
398 u8 cmd_dt:1;
399 u8 reserved1:3;
400 u8 lun:3;
401#endif
402 u8 page_code;
403 u8 reserved2;
404 u8 alloc_length;
405 u8 control;
406};
407
408struct scsi_inquiry_vendor_s{
409 u8 vendor_id[8];
410};
411
412struct scsi_inquiry_prodid_s{
413 u8 product_id[16];
414};
415
416struct scsi_inquiry_prodrev_s{
417 u8 product_rev[4];
418};
419
420struct scsi_inquiry_data_s{
421#ifdef __BIGENDIAN
422 u8 peripheral_qual:3; /* peripheral qualifier */
423 u8 device_type:5; /* peripheral device type */
424
425 u8 rmb:1; /* removable medium bit */
426 u8 device_type_mod:7; /* device type modifier */
427
428 u8 version;
429
430 u8 aenc:1; /* async event notification capability
431 */
432 u8 trm_iop:1; /* terminate I/O process */
433 u8 norm_aca:1; /* normal ACA supported */
434 u8 hi_support:1; /* SCSI-3: supports REPORT LUNS */
435 u8 rsp_data_format:4;
436
437 u8 additional_len;
438 u8 sccs:1;
439 u8 reserved1:7;
440
441 u8 reserved2:1;
442 u8 enc_serv:1; /* enclosure service component */
443 u8 reserved3:1;
444 u8 multi_port:1; /* multi-port device */
445 u8 m_chngr:1; /* device in medium transport element */
446 u8 ack_req_q:1; /* SIP specific bit */
447 u8 addr32:1; /* SIP specific bit */
448 u8 addr16:1; /* SIP specific bit */
449
450 u8 rel_adr:1; /* relative address */
451 u8 w_bus32:1;
452 u8 w_bus16:1;
453 u8 synchronous:1;
454 u8 linked_commands:1;
455 u8 trans_dis:1;
456 u8 cmd_queue:1; /* command queueing supported */
457 u8 soft_reset:1; /* soft reset alternative (VS) */
458#else
459 u8 device_type:5; /* peripheral device type */
460 u8 peripheral_qual:3;
461 /* peripheral qualifier */
462
463 u8 device_type_mod:7;
464 /* device type modifier */
465 u8 rmb:1; /* removable medium bit */
466
467 u8 version;
468
469 u8 rsp_data_format:4;
470 u8 hi_support:1; /* SCSI-3: supports REPORT LUNS */
471 u8 norm_aca:1; /* normal ACA supported */
472 u8 terminate_iop:1;/* terminate I/O process */
473 u8 aenc:1; /* async event notification capability
474 */
475
476 u8 additional_len;
477 u8 reserved1:7;
478 u8 sccs:1;
479
480 u8 addr16:1; /* SIP specific bit */
481 u8 addr32:1; /* SIP specific bit */
482 u8 ack_req_q:1; /* SIP specific bit */
483 u8 m_chngr:1; /* device in medium transport element */
484 u8 multi_port:1; /* multi-port device */
485 u8 reserved3:1; /* TBD - Vendor Specific */
486 u8 enc_serv:1; /* enclosure service component */
487 u8 reserved2:1;
488
489 u8 soft_seset:1; /* soft reset alternative (VS) */
490 u8 cmd_queue:1; /* command queueing supported */
491 u8 trans_dis:1;
492 u8 linked_commands:1;
493 u8 synchronous:1;
494 u8 w_bus16:1;
495 u8 w_bus32:1;
496 u8 rel_adr:1; /* relative address */
497#endif
498 struct scsi_inquiry_vendor_s vendor_id;
499 struct scsi_inquiry_prodid_s product_id;
500 struct scsi_inquiry_prodrev_s product_rev;
501 u8 vendor_specific[20];
502 u8 reserved4[40];
503};
504
505/*
506 * inquiry.peripheral_qual field values
507 */
508#define SCSI_DEVQUAL_DEFAULT 0
509#define SCSI_DEVQUAL_NOT_CONNECTED 1
510#define SCSI_DEVQUAL_NOT_SUPPORTED 3
511
512/*
513 * inquiry.device_type field values
514 */
515#define SCSI_DEVICE_DIRECT_ACCESS 0x00
516#define SCSI_DEVICE_SEQ_ACCESS 0x01
517#define SCSI_DEVICE_ARRAY_CONTROLLER 0x0C
518#define SCSI_DEVICE_UNKNOWN 0x1F
519
520/*
521 * inquiry.version
522 */
523#define SCSI_VERSION_ANSI_X3131 2 /* ANSI X3.131 SCSI-2 */
524#define SCSI_VERSION_SPC 3 /* SPC (SCSI-3), ANSI X3.301:1997 */
525#define SCSI_VERSION_SPC_2 4 /* SPC-2 */
526
527/*
528 * response data format
529 */
530#define SCSI_RSP_DATA_FORMAT 2 /* SCSI-2 & SPC */
531
532/*
533 * SCSI inquiry page codes
534 */
535#define SCSI_INQ_PAGE_VPD_PAGES 0x00 /* supported vpd pages */
536#define SCSI_INQ_PAGE_USN_PAGE 0x80 /* unit serial number page */
537#define SCSI_INQ_PAGE_DEV_IDENT 0x83 /* device indentification page
538 */
539#define SCSI_INQ_PAGES_MAX 3
540
541/*
542 * supported vital product data pages
543 */
544struct scsi_inq_page_vpd_pages_s{
545#ifdef __BIGENDIAN
546 u8 peripheral_qual:3;
547 u8 device_type:5;
548#else
549 u8 device_type:5;
550 u8 peripheral_qual:3;
551#endif
552 u8 page_code;
553 u8 reserved;
554 u8 page_length;
555 u8 pages[SCSI_INQ_PAGES_MAX];
556};
557
558/*
559 * Unit serial number page
560 */
561#define SCSI_INQ_USN_LEN 32
562
563struct scsi_inq_usn_s{
564 char usn[SCSI_INQ_USN_LEN];
565};
566
567struct scsi_inq_page_usn_s{
568#ifdef __BIGENDIAN
569 u8 peripheral_qual:3;
570 u8 device_type:5;
571#else
572 u8 device_type:5;
573 u8 peripheral_qual:3;
574#endif
575 u8 page_code;
576 u8 reserved1;
577 u8 page_length;
578 struct scsi_inq_usn_s usn;
579};
580
581enum {
582 SCSI_INQ_DIP_CODE_BINARY = 1, /* identifier has binary value */
583 SCSI_INQ_DIP_CODE_ASCII = 2, /* identifier has ascii value */
584};
585
586enum {
587 SCSI_INQ_DIP_ASSOC_LUN = 0, /* id is associated with device */
588 SCSI_INQ_DIP_ASSOC_PORT = 1, /* id is associated with port that
589 * received the request
590 */
591};
592
593enum {
594 SCSI_INQ_ID_TYPE_VENDOR = 1,
595 SCSI_INQ_ID_TYPE_IEEE = 2,
596 SCSI_INQ_ID_TYPE_FC_FS = 3,
597 SCSI_INQ_ID_TYPE_OTHER = 4,
598};
599
600struct scsi_inq_dip_desc_s{
601#ifdef __BIGENDIAN
602 u8 res0:4;
603 u8 code_set:4;
604 u8 res1:2;
605 u8 association:2;
606 u8 id_type:4;
607#else
608 u8 code_set:4;
609 u8 res0:4;
610 u8 id_type:4;
611 u8 association:2;
612 u8 res1:2;
613#endif
614 u8 res2;
615 u8 id_len;
616 struct scsi_lun_sn_s id;
617};
618
619/*
620 * Device indentification page
621 */
622struct scsi_inq_page_dev_ident_s{
623#ifdef __BIGENDIAN
624 u8 peripheral_qual:3;
625 u8 device_type:5;
626#else
627 u8 device_type:5;
628 u8 peripheral_qual:3;
629#endif
630 u8 page_code;
631 u8 reserved1;
632 u8 page_length;
633 struct scsi_inq_dip_desc_s desc;
634};
635
636/* ------------------------------------------------------------
637 * READ CAPACITY
638 * ------------------------------------------------------------
639 */
640
641struct scsi_read_capacity_s{
642 u8 opcode;
643#ifdef __BIGENDIAN
644 u8 lun:3;
645 u8 reserved1:4;
646 u8 rel_adr:1;
647#else
648 u8 rel_adr:1;
649 u8 reserved1:4;
650 u8 lun:3;
651#endif
652 u8 lba0; /* MSB */
653 u8 lba1;
654 u8 lba2;
655 u8 lba3; /* LSB */
656 u8 reserved2;
657 u8 reserved3;
658#ifdef __BIGENDIAN
659 u8 reserved4:7;
660 u8 pmi:1; /* partial medium indicator */
661#else
662 u8 pmi:1; /* partial medium indicator */
663 u8 reserved4:7;
664#endif
665 u8 control;
666};
667
668struct scsi_read_capacity_data_s{
669 u32 max_lba; /* maximum LBA available */
670 u32 block_length; /* in bytes */
671};
672
673struct scsi_read_capacity16_data_s{
674 u64 lba; /* maximum LBA available */
675 u32 block_length; /* in bytes */
676#ifdef __BIGENDIAN
677 u8 reserved1:4,
678 p_type:3,
679 prot_en:1;
680 u8 reserved2:4,
681 lb_pbe:4; /* logical blocks per physical block
682 * exponent */
683 u16 reserved3:2,
684 lba_align:14; /* lowest aligned logical block
685 * address */
686#else
687 u16 lba_align:14, /* lowest aligned logical block
688 * address */
689 reserved3:2;
690 u8 lb_pbe:4, /* logical blocks per physical block
691 * exponent */
692 reserved2:4;
693 u8 prot_en:1,
694 p_type:3,
695 reserved1:4;
696#endif
697 u64 reserved4;
698 u64 reserved5;
699};
700
701/* ------------------------------------------------------------
702 * REPORT LUNS command
703 * ------------------------------------------------------------
704 */
705
706struct scsi_report_luns_s{
707 u8 opcode; /* A0h - REPORT LUNS opCode */
708 u8 reserved1[5];
709 u8 alloc_length[4];/* allocation length MSB first */
710 u8 reserved2;
711 u8 control;
712};
713
714#define SCSI_REPORT_LUN_ALLOC_LENGTH(rl) \
715 ((rl->alloc_length[0] << 24) | (rl->alloc_length[1] << 16) | \
716 (rl->alloc_length[2] << 8) | (rl->alloc_length[3]))
717
718#define SCSI_REPORT_LUNS_SET_ALLOCLEN(rl, alloc_len) { \
719 (rl)->alloc_length[0] = (alloc_len) >> 24; \
720 (rl)->alloc_length[1] = ((alloc_len) >> 16) & 0xFF; \
721 (rl)->alloc_length[2] = ((alloc_len) >> 8) & 0xFF; \
722 (rl)->alloc_length[3] = (alloc_len) & 0xFF; \
723}
724
725struct scsi_report_luns_data_s{
726 u32 lun_list_length; /* length of LUN list length */
727 u32 reserved;
728 lun_t lun[1]; /* first LUN in lun list */
729};
730
731/* -------------------------------------------------------------
732 * SCSI mode parameters
733 * -----------------------------------------------------------
734 */
735enum {
736 SCSI_DA_MEDIUM_DEF = 0, /* direct access default medium type */
737 SCSI_DA_MEDIUM_SS = 1, /* direct access single sided */
738 SCSI_DA_MEDIUM_DS = 2, /* direct access double sided */
739};
740
741/*
742 * SCSI Mode Select(6) cdb
743 */
744struct scsi_mode_select6_s{
745 u8 opcode;
746#ifdef __BIGENDIAN
747 u8 reserved1:3;
748 u8 pf:1; /* page format */
749 u8 reserved2:3;
750 u8 sp:1; /* save pages if set to 1 */
751#else
752 u8 sp:1; /* save pages if set to 1 */
753 u8 reserved2:3;
754 u8 pf:1; /* page format */
755 u8 reserved1:3;
756#endif
757 u8 reserved3[2];
758 u8 alloc_len;
759 u8 control;
760};
761
762/*
763 * SCSI Mode Select(10) cdb
764 */
765struct scsi_mode_select10_s{
766 u8 opcode;
767#ifdef __BIGENDIAN
768 u8 reserved1:3;
769 u8 pf:1; /* page format */
770 u8 reserved2:3;
771 u8 sp:1; /* save pages if set to 1 */
772#else
773 u8 sp:1; /* save pages if set to 1 */
774 u8 reserved2:3;
775 u8 pf:1; /* page format */
776 u8 reserved1:3;
777#endif
778 u8 reserved3[5];
779 u8 alloc_len_msb;
780 u8 alloc_len_lsb;
781 u8 control;
782};
783
784/*
785 * SCSI Mode Sense(6) cdb
786 */
787struct scsi_mode_sense6_s{
788 u8 opcode;
789#ifdef __BIGENDIAN
790 u8 reserved1:4;
791 u8 dbd:1; /* disable block discriptors if set to 1 */
792 u8 reserved2:3;
793
794 u8 pc:2; /* page control */
795 u8 page_code:6;
796#else
797 u8 reserved2:3;
798 u8 dbd:1; /* disable block descriptors if set to 1 */
799 u8 reserved1:4;
800
801 u8 page_code:6;
802 u8 pc:2; /* page control */
803#endif
804 u8 reserved3;
805 u8 alloc_len;
806 u8 control;
807};
808
809/*
810 * SCSI Mode Sense(10) cdb
811 */
812struct scsi_mode_sense10_s{
813 u8 opcode;
814#ifdef __BIGENDIAN
815 u8 reserved1:3;
816 u8 LLBAA:1; /* long LBA accepted if set to 1 */
817 u8 dbd:1; /* disable block descriptors if set
818 * to 1
819 */
820 u8 reserved2:3;
821
822 u8 pc:2; /* page control */
823 u8 page_code:6;
824#else
825 u8 reserved2:3;
826 u8 dbd:1; /* disable block descriptors if set to
827 * 1
828 */
829 u8 LLBAA:1; /* long LBA accepted if set to 1 */
830 u8 reserved1:3;
831
832 u8 page_code:6;
833 u8 pc:2; /* page control */
834#endif
835 u8 reserved3[4];
836 u8 alloc_len_msb;
837 u8 alloc_len_lsb;
838 u8 control;
839};
840
841#define SCSI_CDB10_GET_AL(cdb) \
842 ((cdb)->alloc_len_msb << 8 | (cdb)->alloc_len_lsb)
843
844#define SCSI_CDB10_SET_AL(cdb, al) { \
845 (cdb)->alloc_len_msb = al >> 8; \
846 (cdb)->alloc_len_lsb = al & 0xFF; \
847}
848
849#define SCSI_CDB6_GET_AL(cdb) ((cdb)->alloc_len)
850
851#define SCSI_CDB6_SET_AL(cdb, al) { \
852 (cdb)->alloc_len = al; \
853}
854
855/*
856 * page control field values
857 */
858#define SCSI_PC_CURRENT_VALUES 0x0
859#define SCSI_PC_CHANGEABLE_VALUES 0x1
860#define SCSI_PC_DEFAULT_VALUES 0x2
861#define SCSI_PC_SAVED_VALUES 0x3
862
863/*
864 * SCSI mode page codes
865 */
866#define SCSI_MP_VENDOR_SPEC 0x00
867#define SCSI_MP_DISC_RECN 0x02 /* disconnect-reconnect page */
868#define SCSI_MP_FORMAT_DEVICE 0x03
869#define SCSI_MP_RDG 0x04 /* rigid disk geometry page */
870#define SCSI_MP_FDP 0x05 /* flexible disk page */
871#define SCSI_MP_CACHING 0x08 /* caching page */
872#define SCSI_MP_CONTROL 0x0A /* control mode page */
873#define SCSI_MP_MED_TYPES_SUP 0x0B /* medium types supported page */
874#define SCSI_MP_INFO_EXCP_CNTL 0x1C /* informational exception control */
875#define SCSI_MP_ALL 0x3F /* return all pages - mode sense only */
876
877/*
878 * mode parameter header
879 */
880struct scsi_mode_param_header6_s{
881 u8 mode_datalen;
882 u8 medium_type;
883
884 /*
885 * device specific parameters expanded for direct access devices
886 */
887#ifdef __BIGENDIAN
888 u32 wp:1; /* write protected */
889 u32 reserved1:2;
890 u32 dpofua:1; /* disable page out + force unit access
891 */
892 u32 reserved2:4;
893#else
894 u32 reserved2:4;
895 u32 dpofua:1; /* disable page out + force unit access
896 */
897 u32 reserved1:2;
898 u32 wp:1; /* write protected */
899#endif
900
901 u8 block_desclen;
902};
903
904struct scsi_mode_param_header10_s{
905 u32 mode_datalen:16;
906 u32 medium_type:8;
907
908 /*
909 * device specific parameters expanded for direct access devices
910 */
911#ifdef __BIGENDIAN
912 u32 wp:1; /* write protected */
913 u32 reserved1:2;
914 u32 dpofua:1; /* disable page out + force unit access
915 */
916 u32 reserved2:4;
917#else
918 u32 reserved2:4;
919 u32 dpofua:1; /* disable page out + force unit access
920 */
921 u32 reserved1:2;
922 u32 wp:1; /* write protected */
923#endif
924
925#ifdef __BIGENDIAN
926 u32 reserved3:7;
927 u32 longlba:1;
928#else
929 u32 longlba:1;
930 u32 reserved3:7;
931#endif
932 u32 reserved4:8;
933 u32 block_desclen:16;
934};
935
936/*
937 * mode parameter block descriptor
938 */
939struct scsi_mode_param_desc_s{
940 u32 nblks;
941 u32 density_code:8;
942 u32 block_length:24;
943};
944
945/*
946 * Disconnect-reconnect mode page format
947 */
948struct scsi_mp_disc_recn_s{
949#ifdef __BIGENDIAN
950 u8 ps:1;
951 u8 reserved1:1;
952 u8 page_code:6;
953#else
954 u8 page_code:6;
955 u8 reserved1:1;
956 u8 ps:1;
957#endif
958 u8 page_len;
959 u8 buf_full_ratio;
960 u8 buf_empty_ratio;
961
962 u8 bil_msb; /* bus inactivity limit -MSB */
963 u8 bil_lsb; /* bus inactivity limit -LSB */
964
965 u8 dtl_msb; /* disconnect time limit - MSB */
966 u8 dtl_lsb; /* disconnect time limit - LSB */
967
968 u8 ctl_msb; /* connect time limit - MSB */
969 u8 ctl_lsb; /* connect time limit - LSB */
970
971 u8 max_burst_len_msb;
972 u8 max_burst_len_lsb;
973#ifdef __BIGENDIAN
974 u8 emdp:1; /* enable modify data pointers */
975 u8 fa:3; /* fair arbitration */
976 u8 dimm:1; /* disconnect immediate */
977 u8 dtdc:3; /* data transfer disconnect control */
978#else
979 u8 dtdc:3; /* data transfer disconnect control */
980 u8 dimm:1; /* disconnect immediate */
981 u8 fa:3; /* fair arbitration */
982 u8 emdp:1; /* enable modify data pointers */
983#endif
984
985 u8 reserved3;
986
987 u8 first_burst_len_msb;
988 u8 first_burst_len_lsb;
989};
990
991/*
992 * SCSI format device mode page
993 */
994struct scsi_mp_format_device_s{
995#ifdef __BIGENDIAN
996 u32 ps:1;
997 u32 reserved1:1;
998 u32 page_code:6;
999#else
1000 u32 page_code:6;
1001 u32 reserved1:1;
1002 u32 ps:1;
1003#endif
1004 u32 page_len:8;
1005 u32 tracks_per_zone:16;
1006
1007 u32 a_sec_per_zone:16;
1008 u32 a_tracks_per_zone:16;
1009
1010 u32 a_tracks_per_lun:16; /* alternate tracks/lun-MSB */
1011 u32 sec_per_track:16; /* sectors/track-MSB */
1012
1013 u32 bytes_per_sector:16;
1014 u32 interleave:16;
1015
1016 u32 tsf:16; /* track skew factor-MSB */
1017 u32 csf:16; /* cylinder skew factor-MSB */
1018
1019#ifdef __BIGENDIAN
1020 u32 ssec:1; /* soft sector formatting */
1021 u32 hsec:1; /* hard sector formatting */
1022 u32 rmb:1; /* removable media */
1023 u32 surf:1; /* surface */
1024 u32 reserved2:4;
1025#else
1026 u32 reserved2:4;
1027 u32 surf:1; /* surface */
1028 u32 rmb:1; /* removable media */
1029 u32 hsec:1; /* hard sector formatting */
1030 u32 ssec:1; /* soft sector formatting */
1031#endif
1032 u32 reserved3:24;
1033};
1034
1035/*
1036 * SCSI rigid disk device geometry page
1037 */
1038struct scsi_mp_rigid_device_geometry_s{
1039#ifdef __BIGENDIAN
1040 u32 ps:1;
1041 u32 reserved1:1;
1042 u32 page_code:6;
1043#else
1044 u32 page_code:6;
1045 u32 reserved1:1;
1046 u32 ps:1;
1047#endif
1048 u32 page_len:8;
1049 u32 num_cylinders0:8;
1050 u32 num_cylinders1:8;
1051
1052 u32 num_cylinders2:8;
1053 u32 num_heads:8;
1054 u32 scwp0:8;
1055 u32 scwp1:8;
1056
1057 u32 scwp2:8;
1058 u32 scrwc0:8;
1059 u32 scrwc1:8;
1060 u32 scrwc2:8;
1061
1062 u32 dsr:16;
1063 u32 lscyl0:8;
1064 u32 lscyl1:8;
1065
1066 u32 lscyl2:8;
1067#ifdef __BIGENDIAN
1068 u32 reserved2:6;
1069 u32 rpl:2; /* rotational position locking */
1070#else
1071 u32 rpl:2; /* rotational position locking */
1072 u32 reserved2:6;
1073#endif
1074 u32 rot_off:8;
1075 u32 reserved3:8;
1076
1077 u32 med_rot_rate:16;
1078 u32 reserved4:16;
1079};
1080
1081/*
1082 * SCSI caching mode page
1083 */
1084struct scsi_mp_caching_s{
1085#ifdef __BIGENDIAN
1086 u8 ps:1;
1087 u8 res1:1;
1088 u8 page_code:6;
1089#else
1090 u8 page_code:6;
1091 u8 res1:1;
1092 u8 ps:1;
1093#endif
1094 u8 page_len;
1095#ifdef __BIGENDIAN
1096 u8 ic:1; /* initiator control */
1097 u8 abpf:1; /* abort pre-fetch */
1098 u8 cap:1; /* caching analysis permitted */
1099 u8 disc:1; /* discontinuity */
1100 u8 size:1; /* size enable */
1101 u8 wce:1; /* write cache enable */
1102 u8 mf:1; /* multiplication factor */
1103 u8 rcd:1; /* read cache disable */
1104
1105 u8 drrp:4; /* demand read retention priority */
1106 u8 wrp:4; /* write retention priority */
1107#else
1108 u8 rcd:1; /* read cache disable */
1109 u8 mf:1; /* multiplication factor */
1110 u8 wce:1; /* write cache enable */
1111 u8 size:1; /* size enable */
1112 u8 disc:1; /* discontinuity */
1113 u8 cap:1; /* caching analysis permitted */
1114 u8 abpf:1; /* abort pre-fetch */
1115 u8 ic:1; /* initiator control */
1116
1117 u8 wrp:4; /* write retention priority */
1118 u8 drrp:4; /* demand read retention priority */
1119#endif
1120 u8 dptl[2];/* disable pre-fetch transfer length */
1121 u8 min_prefetch[2];
1122 u8 max_prefetch[2];
1123 u8 max_prefetch_limit[2];
1124#ifdef __BIGENDIAN
1125 u8 fsw:1; /* force sequential write */
1126 u8 lbcss:1;/* logical block cache segment size */
1127 u8 dra:1; /* disable read ahead */
1128 u8 vs:2; /* vendor specific */
1129 u8 res2:3;
1130#else
1131 u8 res2:3;
1132 u8 vs:2; /* vendor specific */
1133 u8 dra:1; /* disable read ahead */
1134 u8 lbcss:1;/* logical block cache segment size */
1135 u8 fsw:1; /* force sequential write */
1136#endif
1137 u8 num_cache_segs;
1138
1139 u8 cache_seg_size[2];
1140 u8 res3;
1141 u8 non_cache_seg_size[3];
1142};
1143
1144/*
1145 * SCSI control mode page
1146 */
1147struct scsi_mp_control_page_s{
1148#ifdef __BIGENDIAN
1149u8 ps:1;
1150u8 reserved1:1;
1151u8 page_code:6;
1152#else
1153u8 page_code:6;
1154u8 reserved1:1;
1155u8 ps:1;
1156#endif
1157 u8 page_len;
1158#ifdef __BIGENDIAN
1159 u8 tst:3; /* task set type */
1160 u8 reserved3:3;
1161 u8 gltsd:1; /* global logging target save disable */
1162 u8 rlec:1; /* report log exception condition */
1163
1164 u8 qalgo_mod:4; /* queue alogorithm modifier */
1165 u8 reserved4:1;
1166 u8 qerr:2; /* queue error management */
1167 u8 dque:1; /* disable queuing */
1168
1169 u8 reserved5:1;
1170 u8 rac:1; /* report a check */
1171 u8 reserved6:2;
1172 u8 swp:1; /* software write protect */
1173 u8 raerp:1; /* ready AER permission */
1174 u8 uaaerp:1; /* unit attenstion AER permission */
1175 u8 eaerp:1; /* error AER permission */
1176
1177 u8 reserved7:5;
1178 u8 autoload_mod:3;
1179#else
1180 u8 rlec:1; /* report log exception condition */
1181 u8 gltsd:1; /* global logging target save disable */
1182 u8 reserved3:3;
1183 u8 tst:3; /* task set type */
1184
1185 u8 dque:1; /* disable queuing */
1186 u8 qerr:2; /* queue error management */
1187 u8 reserved4:1;
1188 u8 qalgo_mod:4; /* queue alogorithm modifier */
1189
1190 u8 eaerp:1; /* error AER permission */
1191 u8 uaaerp:1; /* unit attenstion AER permission */
1192 u8 raerp:1; /* ready AER permission */
1193 u8 swp:1; /* software write protect */
1194 u8 reserved6:2;
1195 u8 rac:1; /* report a check */
1196 u8 reserved5:1;
1197
1198 u8 autoload_mod:3;
1199 u8 reserved7:5;
1200#endif
1201 u8 rahp_msb; /* ready AER holdoff period - MSB */
1202 u8 rahp_lsb; /* ready AER holdoff period - LSB */
1203
1204 u8 busy_timeout_period_msb;
1205 u8 busy_timeout_period_lsb;
1206
1207 u8 ext_selftest_compl_time_msb;
1208 u8 ext_selftest_compl_time_lsb;
1209};
1210
1211/*
1212 * SCSI medium types supported mode page
1213 */
1214struct scsi_mp_medium_types_sup_s{
1215#ifdef __BIGENDIAN
1216 u8 ps:1;
1217 u8 reserved1:1;
1218 u8 page_code:6;
1219#else
1220 u8 page_code:6;
1221 u8 reserved1:1;
1222 u8 ps:1;
1223#endif
1224 u8 page_len;
1225
1226 u8 reserved3[2];
1227 u8 med_type1_sup; /* medium type one supported */
1228 u8 med_type2_sup; /* medium type two supported */
1229 u8 med_type3_sup; /* medium type three supported */
1230 u8 med_type4_sup; /* medium type four supported */
1231};
1232
1233/*
1234 * SCSI informational exception control mode page
1235 */
1236struct scsi_mp_info_excpt_cntl_s{
1237#ifdef __BIGENDIAN
1238 u8 ps:1;
1239 u8 reserved1:1;
1240 u8 page_code:6;
1241#else
1242 u8 page_code:6;
1243 u8 reserved1:1;
1244 u8 ps:1;
1245#endif
1246 u8 page_len;
1247#ifdef __BIGENDIAN
1248 u8 perf:1; /* performance */
1249 u8 reserved3:1;
1250 u8 ebf:1; /* enable background fucntion */
1251 u8 ewasc:1; /* enable warning */
1252 u8 dexcpt:1; /* disable exception control */
1253 u8 test:1; /* enable test device failure
1254 * notification
1255 */
1256 u8 reserved4:1;
1257 u8 log_error:1;
1258
1259 u8 reserved5:4;
1260 u8 mrie:4; /* method of reporting info
1261 * exceptions
1262 */
1263#else
1264 u8 log_error:1;
1265 u8 reserved4:1;
1266 u8 test:1; /* enable test device failure
1267 * notification
1268 */
1269 u8 dexcpt:1; /* disable exception control */
1270 u8 ewasc:1; /* enable warning */
1271 u8 ebf:1; /* enable background fucntion */
1272 u8 reserved3:1;
1273 u8 perf:1; /* performance */
1274
1275 u8 mrie:4; /* method of reporting info
1276 * exceptions
1277 */
1278 u8 reserved5:4;
1279#endif
1280 u8 interval_timer_msb;
1281 u8 interval_timer_lsb;
1282
1283 u8 report_count_msb;
1284 u8 report_count_lsb;
1285};
1286
1287/*
1288 * Methods of reporting informational exceptions
1289 */
1290#define SCSI_MP_IEC_NO_REPORT 0x0 /* no reporting of exceptions */
1291#define SCSI_MP_IEC_AER 0x1 /* async event reporting */
1292#define SCSI_MP_IEC_UNIT_ATTN 0x2 /* generate unit attenstion */
1293#define SCSI_MO_IEC_COND_REC_ERR 0x3 /* conditionally generate recovered
1294 * error
1295 */
1296#define SCSI_MP_IEC_UNCOND_REC_ERR 0x4 /* unconditionally generate recovered
1297 * error
1298 */
1299#define SCSI_MP_IEC_NO_SENSE 0x5 /* generate no sense */
1300#define SCSI_MP_IEC_ON_REQUEST 0x6 /* only report exceptions on request */
1301
1302/*
1303 * SCSI flexible disk page
1304 */
1305struct scsi_mp_flexible_disk_s{
1306#ifdef __BIGENDIAN
1307 u8 ps:1;
1308 u8 reserved1:1;
1309 u8 page_code:6;
1310#else
1311 u8 page_code:6;
1312 u8 reserved1:1;
1313 u8 ps:1;
1314#endif
1315 u8 page_len;
1316
1317 u8 transfer_rate_msb;
1318 u8 transfer_rate_lsb;
1319
1320 u8 num_heads;
1321 u8 num_sectors;
1322
1323 u8 bytes_per_sector_msb;
1324 u8 bytes_per_sector_lsb;
1325
1326 u8 num_cylinders_msb;
1327 u8 num_cylinders_lsb;
1328
1329 u8 sc_wpc_msb; /* starting cylinder-write
1330 * precompensation msb
1331 */
1332 u8 sc_wpc_lsb; /* starting cylinder-write
1333 * precompensation lsb
1334 */
1335 u8 sc_rwc_msb; /* starting cylinder-reduced write
1336 * current msb
1337 */
1338 u8 sc_rwc_lsb; /* starting cylinder-reduced write
1339 * current lsb
1340 */
1341
1342 u8 dev_step_rate_msb;
1343 u8 dev_step_rate_lsb;
1344
1345 u8 dev_step_pulse_width;
1346
1347 u8 head_sd_msb; /* head settle delay msb */
1348 u8 head_sd_lsb; /* head settle delay lsb */
1349
1350 u8 motor_on_delay;
1351 u8 motor_off_delay;
1352#ifdef __BIGENDIAN
1353 u8 trdy:1; /* true ready bit */
1354 u8 ssn:1; /* start sector number bit */
1355 u8 mo:1; /* motor on bit */
1356 u8 reserved3:5;
1357
1358 u8 reserved4:4;
1359 u8 spc:4; /* step pulse per cylinder */
1360#else
1361 u8 reserved3:5;
1362 u8 mo:1; /* motor on bit */
1363 u8 ssn:1; /* start sector number bit */
1364 u8 trdy:1; /* true ready bit */
1365
1366 u8 spc:4; /* step pulse per cylinder */
1367 u8 reserved4:4;
1368#endif
1369 u8 write_comp;
1370 u8 head_load_delay;
1371 u8 head_unload_delay;
1372#ifdef __BIGENDIAN
1373 u8 pin34:4; /* pin34 usage */
1374 u8 pin2:4; /* pin2 usage */
1375
1376 u8 pin4:4; /* pin4 usage */
1377 u8 pin1:4; /* pin1 usage */
1378#else
1379 u8 pin2:4; /* pin2 usage */
1380 u8 pin34:4; /* pin34 usage */
1381
1382 u8 pin1:4; /* pin1 usage */
1383 u8 pin4:4; /* pin4 usage */
1384#endif
1385 u8 med_rot_rate_msb;
1386 u8 med_rot_rate_lsb;
1387
1388 u8 reserved5[2];
1389};
1390
1391struct scsi_mode_page_format_data6_s{
1392 struct scsi_mode_param_header6_s mph; /* mode page header */
1393 struct scsi_mode_param_desc_s desc; /* block descriptor */
1394 struct scsi_mp_format_device_s format; /* format device data */
1395};
1396
1397struct scsi_mode_page_format_data10_s{
1398 struct scsi_mode_param_header10_s mph; /* mode page header */
1399 struct scsi_mode_param_desc_s desc; /* block descriptor */
1400 struct scsi_mp_format_device_s format; /* format device data */
1401};
1402
1403struct scsi_mode_page_rdg_data6_s{
1404 struct scsi_mode_param_header6_s mph; /* mode page header */
1405 struct scsi_mode_param_desc_s desc; /* block descriptor */
1406 struct scsi_mp_rigid_device_geometry_s rdg;
1407 /* rigid geometry data */
1408};
1409
1410struct scsi_mode_page_rdg_data10_s{
1411 struct scsi_mode_param_header10_s mph; /* mode page header */
1412 struct scsi_mode_param_desc_s desc; /* block descriptor */
1413 struct scsi_mp_rigid_device_geometry_s rdg;
1414 /* rigid geometry data */
1415};
1416
1417struct scsi_mode_page_cache6_s{
1418 struct scsi_mode_param_header6_s mph; /* mode page header */
1419 struct scsi_mode_param_desc_s desc; /* block descriptor */
1420 struct scsi_mp_caching_s cache; /* cache page data */
1421};
1422
1423struct scsi_mode_page_cache10_s{
1424 struct scsi_mode_param_header10_s mph; /* mode page header */
1425 struct scsi_mode_param_desc_s desc; /* block descriptor */
1426 struct scsi_mp_caching_s cache; /* cache page data */
1427};
1428
1429/* --------------------------------------------------------------
1430 * Format Unit command
1431 * ------------------------------------------------------------
1432 */
1433
1434/*
1435 * Format Unit CDB
1436 */
1437struct scsi_format_unit_s{
1438 u8 opcode;
1439#ifdef __BIGENDIAN
1440 u8 res1:3;
1441 u8 fmtdata:1; /* if set, data out phase has format
1442 * data
1443 */
1444 u8 cmplst:1; /* if set, defect list is complete */
1445 u8 def_list:3; /* format of defect descriptor is
1446 * fmtdata =1
1447 */
1448#else
1449 u8 def_list:3; /* format of defect descriptor is
1450 * fmtdata = 1
1451 */
1452 u8 cmplst:1; /* if set, defect list is complete */
1453 u8 fmtdata:1; /* if set, data out phase has format
1454 * data
1455 */
1456 u8 res1:3;
1457#endif
1458 u8 interleave_msb;
1459 u8 interleave_lsb;
1460 u8 vendor_spec;
1461 u8 control;
1462};
1463
1464/*
1465 * h
1466 */
1467struct scsi_reserve6_s{
1468 u8 opcode;
1469#ifdef __BIGENDIAN
1470 u8 reserved:3;
1471 u8 obsolete:4;
1472 u8 extent:1;
1473#else
1474 u8 extent:1;
1475 u8 obsolete:4;
1476 u8 reserved:3;
1477#endif
1478 u8 reservation_id;
1479 u16 param_list_len;
1480 u8 control;
1481};
1482
1483/*
1484 * h
1485 */
1486struct scsi_release6_s{
1487 u8 opcode;
1488#ifdef __BIGENDIAN
1489 u8 reserved1:3;
1490 u8 obsolete:4;
1491 u8 extent:1;
1492#else
1493 u8 extent:1;
1494 u8 obsolete:4;
1495 u8 reserved1:3;
1496#endif
1497 u8 reservation_id;
1498 u16 reserved2;
1499 u8 control;
1500};
1501
1502/*
1503 * h
1504 */
1505struct scsi_reserve10_s{
1506 u8 opcode;
1507#ifdef __BIGENDIAN
1508 u8 reserved1:3;
1509 u8 third_party:1;
1510 u8 reserved2:2;
1511 u8 long_id:1;
1512 u8 extent:1;
1513#else
1514 u8 extent:1;
1515 u8 long_id:1;
1516 u8 reserved2:2;
1517 u8 third_party:1;
1518 u8 reserved1:3;
1519#endif
1520 u8 reservation_id;
1521 u8 third_pty_dev_id;
1522 u8 reserved3;
1523 u8 reserved4;
1524 u8 reserved5;
1525 u16 param_list_len;
1526 u8 control;
1527};
1528
1529struct scsi_release10_s{
1530 u8 opcode;
1531#ifdef __BIGENDIAN
1532 u8 reserved1:3;
1533 u8 third_party:1;
1534 u8 reserved2:2;
1535 u8 long_id:1;
1536 u8 extent:1;
1537#else
1538 u8 extent:1;
1539 u8 long_id:1;
1540 u8 reserved2:2;
1541 u8 third_party:1;
1542 u8 reserved1:3;
1543#endif
1544 u8 reservation_id;
1545 u8 third_pty_dev_id;
1546 u8 reserved3;
1547 u8 reserved4;
1548 u8 reserved5;
1549 u16 param_list_len;
1550 u8 control;
1551};
1552
1553struct scsi_verify10_s{
1554 u8 opcode;
1555#ifdef __BIGENDIAN
1556 u8 lun:3;
1557 u8 dpo:1;
1558 u8 reserved:2;
1559 u8 bytchk:1;
1560 u8 reladdr:1;
1561#else
1562 u8 reladdr:1;
1563 u8 bytchk:1;
1564 u8 reserved:2;
1565 u8 dpo:1;
1566 u8 lun:3;
1567#endif
1568 u8 lba0;
1569 u8 lba1;
1570 u8 lba2;
1571 u8 lba3;
1572 u8 reserved1;
1573 u8 verification_len0;
1574 u8 verification_len1;
1575 u8 control_byte;
1576};
1577
1578struct scsi_request_sense_s{
1579 u8 opcode;
1580#ifdef __BIGENDIAN
1581 u8 lun:3;
1582 u8 reserved:5;
1583#else
1584 u8 reserved:5;
1585 u8 lun:3;
1586#endif
1587 u8 reserved0;
1588 u8 reserved1;
1589 u8 alloc_len;
1590 u8 control_byte;
1591};
1592
1593/* ------------------------------------------------------------
1594 * SCSI status byte values
1595 * ------------------------------------------------------------
1596 */
1597#define SCSI_STATUS_GOOD 0x00
1598#define SCSI_STATUS_CHECK_CONDITION 0x02
1599#define SCSI_STATUS_CONDITION_MET 0x04
1600#define SCSI_STATUS_BUSY 0x08
1601#define SCSI_STATUS_INTERMEDIATE 0x10
1602#define SCSI_STATUS_ICM 0x14 /* intermediate condition met */
1603#define SCSI_STATUS_RESERVATION_CONFLICT 0x18
1604#define SCSI_STATUS_COMMAND_TERMINATED 0x22
1605#define SCSI_STATUS_QUEUE_FULL 0x28
1606#define SCSI_STATUS_ACA_ACTIVE 0x30
1607
1608#define SCSI_MAX_ALLOC_LEN 0xFF /* maximum allocarion length
1609 * in CDBs
1610 */
1611
1612#define SCSI_OP_WRITE_VERIFY10 0x2E
1613#define SCSI_OP_WRITE_VERIFY12 0xAE
1614#define SCSI_OP_UNDEF 0xFF
1615
1616/*
1617 * SCSI WRITE-VERIFY(10) command
1618 */
1619struct scsi_write_verify10_s{
1620 u8 opcode;
1621#ifdef __BIGENDIAN
1622 u8 reserved1:3;
1623 u8 dpo:1; /* Disable Page Out */
1624 u8 reserved2:1;
1625 u8 ebp:1; /* erse by-pass */
1626 u8 bytchk:1; /* byte check */
1627 u8 rel_adr:1; /* relative address */
1628#else
1629 u8 rel_adr:1; /* relative address */
1630 u8 bytchk:1; /* byte check */
1631 u8 ebp:1; /* erse by-pass */
1632 u8 reserved2:1;
1633 u8 dpo:1; /* Disable Page Out */
1634 u8 reserved1:3;
1635#endif
1636 u8 lba0; /* logical block address - MSB */
1637 u8 lba1;
1638 u8 lba2;
1639 u8 lba3; /* LSB */
1640 u8 reserved3;
1641 u8 xfer_length0; /* transfer length in blocks - MSB */
1642 u8 xfer_length1; /* LSB */
1643 u8 control;
1644};
1645
1646#pragma pack()
1647
1648#endif /* __SCSI_H__ */
diff --git a/drivers/scsi/bfa/include/protocol/types.h b/drivers/scsi/bfa/include/protocol/types.h
new file mode 100644
index 000000000000..2875a6cced3b
--- /dev/null
+++ b/drivers/scsi/bfa/include/protocol/types.h
@@ -0,0 +1,42 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * types.h Protocol defined base types
20 */
21
22#ifndef __TYPES_H__
23#define __TYPES_H__
24
25#include <bfa_os_inc.h>
26
27#define wwn_t u64
28#define lun_t u64
29
30#define WWN_NULL (0)
31#define FC_SYMNAME_MAX 256 /* max name server symbolic name size */
32#define FC_ALPA_MAX 128
33
34#pragma pack(1)
35
36#define MAC_ADDRLEN (6)
37struct mac_s { u8 mac[MAC_ADDRLEN]; };
38#define mac_t struct mac_s
39
40#pragma pack()
41
42#endif
diff --git a/drivers/scsi/bfa/loop.c b/drivers/scsi/bfa/loop.c
new file mode 100644
index 000000000000..a418dedebe9e
--- /dev/null
+++ b/drivers/scsi/bfa/loop.c
@@ -0,0 +1,422 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * port_loop.c vport private loop implementation.
20 */
21#include <bfa.h>
22#include <bfa_svc.h>
23#include "fcs_lport.h"
24#include "fcs_rport.h"
25#include "fcs_trcmod.h"
26#include "lport_priv.h"
27
28BFA_TRC_FILE(FCS, LOOP);
29
30/**
31 * ALPA to LIXA bitmap mapping
32 *
33 * ALPA 0x00 (Word 0, Bit 30) is invalid for N_Ports. Also Word 0 Bit 31
34 * is for L_bit (login required) and is filled as ALPA 0x00 here.
35 */
36static const u8 port_loop_alpa_map[] = {
37 0xEF, 0xE8, 0xE4, 0xE2, 0xE1, 0xE0, 0xDC, 0xDA, /* Word 3 Bits 0..7 */
38 0xD9, 0xD6, 0xD5, 0xD4, 0xD3, 0xD2, 0xD1, 0xCE, /* Word 3 Bits 8..15 */
39 0xCD, 0xCC, 0xCB, 0xCA, 0xC9, 0xC7, 0xC6, 0xC5, /* Word 3 Bits 16..23 */
40 0xC3, 0xBC, 0xBA, 0xB9, 0xB6, 0xB5, 0xB4, 0xB3, /* Word 3 Bits 24..31 */
41
42 0xB2, 0xB1, 0xAE, 0xAD, 0xAC, 0xAB, 0xAA, 0xA9, /* Word 2 Bits 0..7 */
43 0xA7, 0xA6, 0xA5, 0xA3, 0x9F, 0x9E, 0x9D, 0x9B, /* Word 2 Bits 8..15 */
44 0x98, 0x97, 0x90, 0x8F, 0x88, 0x84, 0x82, 0x81, /* Word 2 Bits 16..23 */
45 0x80, 0x7C, 0x7A, 0x79, 0x76, 0x75, 0x74, 0x73, /* Word 2 Bits 24..31 */
46
47 0x72, 0x71, 0x6E, 0x6D, 0x6C, 0x6B, 0x6A, 0x69, /* Word 1 Bits 0..7 */
48 0x67, 0x66, 0x65, 0x63, 0x5C, 0x5A, 0x59, 0x56, /* Word 1 Bits 8..15 */
49 0x55, 0x54, 0x53, 0x52, 0x51, 0x4E, 0x4D, 0x4C, /* Word 1 Bits 16..23 */
50 0x4B, 0x4A, 0x49, 0x47, 0x46, 0x45, 0x43, 0x3C, /* Word 1 Bits 24..31 */
51
52 0x3A, 0x39, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, /* Word 0 Bits 0..7 */
53 0x2E, 0x2D, 0x2C, 0x2B, 0x2A, 0x29, 0x27, 0x26, /* Word 0 Bits 8..15 */
54 0x25, 0x23, 0x1F, 0x1E, 0x1D, 0x1B, 0x18, 0x17, /* Word 0 Bits 16..23 */
55 0x10, 0x0F, 0x08, 0x04, 0x02, 0x01, 0x00, 0x00, /* Word 0 Bits 24..31 */
56};
57
58/*
59 * Local Functions
60 */
61bfa_status_t bfa_fcs_port_loop_send_plogi(struct bfa_fcs_port_s *port,
62 u8 alpa);
63
64void bfa_fcs_port_loop_plogi_response(void *fcsarg,
65 struct bfa_fcxp_s *fcxp,
66 void *cbarg,
67 bfa_status_t req_status,
68 u32 rsp_len,
69 u32 resid_len,
70 struct fchs_s *rsp_fchs);
71
72bfa_status_t bfa_fcs_port_loop_send_adisc(struct bfa_fcs_port_s *port,
73 u8 alpa);
74
75void bfa_fcs_port_loop_adisc_response(void *fcsarg,
76 struct bfa_fcxp_s *fcxp,
77 void *cbarg,
78 bfa_status_t req_status,
79 u32 rsp_len,
80 u32 resid_len,
81 struct fchs_s *rsp_fchs);
82
83bfa_status_t bfa_fcs_port_loop_send_plogi_acc(struct bfa_fcs_port_s *port,
84 u8 alpa);
85
86void bfa_fcs_port_loop_plogi_acc_response(void *fcsarg,
87 struct bfa_fcxp_s *fcxp,
88 void *cbarg,
89 bfa_status_t req_status,
90 u32 rsp_len,
91 u32 resid_len,
92 struct fchs_s *rsp_fchs);
93
94bfa_status_t bfa_fcs_port_loop_send_adisc_acc(struct bfa_fcs_port_s *port,
95 u8 alpa);
96
97void bfa_fcs_port_loop_adisc_acc_response(void *fcsarg,
98 struct bfa_fcxp_s *fcxp,
99 void *cbarg,
100 bfa_status_t req_status,
101 u32 rsp_len,
102 u32 resid_len,
103 struct fchs_s *rsp_fchs);
104/**
105 * Called by port to initializar in provate LOOP topology.
106 */
107void
108bfa_fcs_port_loop_init(struct bfa_fcs_port_s *port)
109{
110}
111
112/**
113 * Called by port to notify transition to online state.
114 */
115void
116bfa_fcs_port_loop_online(struct bfa_fcs_port_s *port)
117{
118
119 u8 num_alpa = port->port_topo.ploop.num_alpa;
120 u8 *alpa_pos_map = port->port_topo.ploop.alpa_pos_map;
121 struct bfa_fcs_rport_s *r_port;
122 int ii = 0;
123
124 /*
125 * If the port role is Initiator Mode, create Rports.
126 */
127 if (port->port_cfg.roles == BFA_PORT_ROLE_FCP_IM) {
128 /*
129 * Check if the ALPA positional bitmap is available.
130 * if not, we send PLOGI to all possible ALPAs.
131 */
132 if (num_alpa > 0) {
133 for (ii = 0; ii < num_alpa; ii++) {
134 /*
135 * ignore ALPA of bfa port
136 */
137 if (alpa_pos_map[ii] != port->pid) {
138 r_port = bfa_fcs_rport_create(port,
139 alpa_pos_map[ii]);
140 }
141 }
142 } else {
143 for (ii = 0; ii < MAX_ALPA_COUNT; ii++) {
144 /*
145 * ignore ALPA of bfa port
146 */
147 if ((port_loop_alpa_map[ii] > 0)
148 && (port_loop_alpa_map[ii] != port->pid))
149 bfa_fcs_port_loop_send_plogi(port,
150 port_loop_alpa_map[ii]);
151 /**TBD */
152 }
153 }
154 } else {
155 /*
156 * TBD Target Mode ??
157 */
158 }
159
160}
161
162/**
163 * Called by port to notify transition to offline state.
164 */
165void
166bfa_fcs_port_loop_offline(struct bfa_fcs_port_s *port)
167{
168
169}
170
171/**
172 * Called by port to notify a LIP on the loop.
173 */
174void
175bfa_fcs_port_loop_lip(struct bfa_fcs_port_s *port)
176{
177}
178
179/**
180 * Local Functions.
181 */
182bfa_status_t
183bfa_fcs_port_loop_send_plogi(struct bfa_fcs_port_s *port, u8 alpa)
184{
185 struct fchs_s fchs;
186 struct bfa_fcxp_s *fcxp = NULL;
187 int len;
188
189 bfa_trc(port->fcs, alpa);
190
191 fcxp = bfa_fcxp_alloc(NULL, port->fcs->bfa, 0, 0, NULL, NULL, NULL,
192 NULL);
193 bfa_assert(fcxp);
194
195 len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), alpa,
196 bfa_fcs_port_get_fcid(port), 0,
197 port->port_cfg.pwwn, port->port_cfg.nwwn,
198 bfa_pport_get_maxfrsize(port->fcs->bfa));
199
200 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
201 FC_CLASS_3, len, &fchs,
202 bfa_fcs_port_loop_plogi_response, (void *)port,
203 FC_MAX_PDUSZ, FC_RA_TOV);
204
205 return BFA_STATUS_OK;
206}
207
208/**
209 * Called by fcxp to notify the Plogi response
210 */
211void
212bfa_fcs_port_loop_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
213 void *cbarg, bfa_status_t req_status,
214 u32 rsp_len, u32 resid_len,
215 struct fchs_s *rsp_fchs)
216{
217 struct bfa_fcs_port_s *port = (struct bfa_fcs_port_s *) cbarg;
218 struct fc_logi_s *plogi_resp;
219 struct fc_els_cmd_s *els_cmd;
220
221 bfa_trc(port->fcs, req_status);
222
223 /*
224 * Sanity Checks
225 */
226 if (req_status != BFA_STATUS_OK) {
227 bfa_trc(port->fcs, req_status);
228 /*
229 * @todo
230 * This could mean that the device with this APLA does not
231 * exist on the loop.
232 */
233
234 return;
235 }
236
237 els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp);
238 plogi_resp = (struct fc_logi_s *) els_cmd;
239
240 if (els_cmd->els_code == FC_ELS_ACC) {
241 bfa_fcs_rport_start(port, rsp_fchs, plogi_resp);
242 } else {
243 bfa_trc(port->fcs, plogi_resp->els_cmd.els_code);
244 bfa_assert(0);
245 }
246}
247
248bfa_status_t
249bfa_fcs_port_loop_send_plogi_acc(struct bfa_fcs_port_s *port, u8 alpa)
250{
251 struct fchs_s fchs;
252 struct bfa_fcxp_s *fcxp;
253 int len;
254
255 bfa_trc(port->fcs, alpa);
256
257 fcxp = bfa_fcxp_alloc(NULL, port->fcs->bfa, 0, 0, NULL, NULL, NULL,
258 NULL);
259 bfa_assert(fcxp);
260
261 len = fc_plogi_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), alpa,
262 bfa_fcs_port_get_fcid(port), 0,
263 port->port_cfg.pwwn, port->port_cfg.nwwn,
264 bfa_pport_get_maxfrsize(port->fcs->bfa));
265
266 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
267 FC_CLASS_3, len, &fchs,
268 bfa_fcs_port_loop_plogi_acc_response,
269 (void *)port, FC_MAX_PDUSZ, 0); /* No response
270 * expected
271 */
272
273 return BFA_STATUS_OK;
274}
275
276/*
277 * Plogi Acc Response
278 * We donot do any processing here.
279 */
280void
281bfa_fcs_port_loop_plogi_acc_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
282 void *cbarg, bfa_status_t req_status,
283 u32 rsp_len, u32 resid_len,
284 struct fchs_s *rsp_fchs)
285{
286
287 struct bfa_fcs_port_s *port = (struct bfa_fcs_port_s *) cbarg;
288
289 bfa_trc(port->fcs, port->pid);
290
291 /*
292 * Sanity Checks
293 */
294 if (req_status != BFA_STATUS_OK) {
295 bfa_trc(port->fcs, req_status);
296 return;
297 }
298}
299
300bfa_status_t
301bfa_fcs_port_loop_send_adisc(struct bfa_fcs_port_s *port, u8 alpa)
302{
303 struct fchs_s fchs;
304 struct bfa_fcxp_s *fcxp;
305 int len;
306
307 bfa_trc(port->fcs, alpa);
308
309 fcxp = bfa_fcxp_alloc(NULL, port->fcs->bfa, 0, 0, NULL, NULL, NULL,
310 NULL);
311 bfa_assert(fcxp);
312
313 len = fc_adisc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), alpa,
314 bfa_fcs_port_get_fcid(port), 0,
315 port->port_cfg.pwwn, port->port_cfg.nwwn);
316
317 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
318 FC_CLASS_3, len, &fchs,
319 bfa_fcs_port_loop_adisc_response, (void *)port,
320 FC_MAX_PDUSZ, FC_RA_TOV);
321
322 return BFA_STATUS_OK;
323}
324
325/**
326 * Called by fcxp to notify the ADISC response
327 */
328void
329bfa_fcs_port_loop_adisc_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
330 void *cbarg, bfa_status_t req_status,
331 u32 rsp_len, u32 resid_len,
332 struct fchs_s *rsp_fchs)
333{
334 struct bfa_fcs_port_s *port = (struct bfa_fcs_port_s *) cbarg;
335 struct bfa_fcs_rport_s *rport;
336 struct fc_adisc_s *adisc_resp;
337 struct fc_els_cmd_s *els_cmd;
338 u32 pid = rsp_fchs->s_id;
339
340 bfa_trc(port->fcs, req_status);
341
342 /*
343 * Sanity Checks
344 */
345 if (req_status != BFA_STATUS_OK) {
346 /*
347 * TBD : we may need to retry certain requests
348 */
349 bfa_fcxp_free(fcxp);
350 return;
351 }
352
353 els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp);
354 adisc_resp = (struct fc_adisc_s *) els_cmd;
355
356 if (els_cmd->els_code == FC_ELS_ACC) {
357 } else {
358 bfa_trc(port->fcs, adisc_resp->els_cmd.els_code);
359
360 /*
361 * TBD: we may need to check for reject codes and retry
362 */
363 rport = bfa_fcs_port_get_rport_by_pid(port, pid);
364 if (rport) {
365 list_del(&rport->qe);
366 bfa_fcs_rport_delete(rport);
367 }
368
369 }
370 return;
371}
372
373bfa_status_t
374bfa_fcs_port_loop_send_adisc_acc(struct bfa_fcs_port_s *port, u8 alpa)
375{
376 struct fchs_s fchs;
377 struct bfa_fcxp_s *fcxp;
378 int len;
379
380 bfa_trc(port->fcs, alpa);
381
382 fcxp = bfa_fcxp_alloc(NULL, port->fcs->bfa, 0, 0, NULL, NULL, NULL,
383 NULL);
384 bfa_assert(fcxp);
385
386 len = fc_adisc_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), alpa,
387 bfa_fcs_port_get_fcid(port), 0,
388 port->port_cfg.pwwn, port->port_cfg.nwwn);
389
390 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
391 FC_CLASS_3, len, &fchs,
392 bfa_fcs_port_loop_adisc_acc_response,
393 (void *)port, FC_MAX_PDUSZ, 0); /* no reponse
394 * expected
395 */
396
397 return BFA_STATUS_OK;
398}
399
400/*
401 * Adisc Acc Response
402 * We donot do any processing here.
403 */
404void
405bfa_fcs_port_loop_adisc_acc_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
406 void *cbarg, bfa_status_t req_status,
407 u32 rsp_len, u32 resid_len,
408 struct fchs_s *rsp_fchs)
409{
410
411 struct bfa_fcs_port_s *port = (struct bfa_fcs_port_s *) cbarg;
412
413 bfa_trc(port->fcs, port->pid);
414
415 /*
416 * Sanity Checks
417 */
418 if (req_status != BFA_STATUS_OK) {
419 bfa_trc(port->fcs, req_status);
420 return;
421 }
422}
diff --git a/drivers/scsi/bfa/lport_api.c b/drivers/scsi/bfa/lport_api.c
new file mode 100644
index 000000000000..8f51a83f1834
--- /dev/null
+++ b/drivers/scsi/bfa/lport_api.c
@@ -0,0 +1,291 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * port_api.c BFA FCS port
20 */
21
22#include <fcs/bfa_fcs.h>
23#include <fcs/bfa_fcs_lport.h>
24#include <fcs/bfa_fcs_rport.h>
25#include "fcs_rport.h"
26#include "fcs_fabric.h"
27#include "fcs_trcmod.h"
28#include "fcs_vport.h"
29
30BFA_TRC_FILE(FCS, PORT_API);
31
32
33
34/**
35 * fcs_port_api BFA FCS port API
36 */
37
38void
39bfa_fcs_cfg_base_port(struct bfa_fcs_s *fcs, struct bfa_port_cfg_s *port_cfg)
40{
41}
42
43struct bfa_fcs_port_s *
44bfa_fcs_get_base_port(struct bfa_fcs_s *fcs)
45{
46 return (&fcs->fabric.bport);
47}
48
49wwn_t
50bfa_fcs_port_get_rport(struct bfa_fcs_port_s *port, wwn_t wwn, int index,
51 int nrports, bfa_boolean_t bwwn)
52{
53 struct list_head *qh, *qe;
54 struct bfa_fcs_rport_s *rport = NULL;
55 int i;
56 struct bfa_fcs_s *fcs;
57
58 if (port == NULL || nrports == 0)
59 return (wwn_t) 0;
60
61 fcs = port->fcs;
62 bfa_trc(fcs, (u32) nrports);
63
64 i = 0;
65 qh = &port->rport_q;
66 qe = bfa_q_first(qh);
67
68 while ((qe != qh) && (i < nrports)) {
69 rport = (struct bfa_fcs_rport_s *)qe;
70 if (bfa_os_ntoh3b(rport->pid) > 0xFFF000) {
71 qe = bfa_q_next(qe);
72 bfa_trc(fcs, (u32) rport->pwwn);
73 bfa_trc(fcs, rport->pid);
74 bfa_trc(fcs, i);
75 continue;
76 }
77
78 if (bwwn) {
79 if (!memcmp(&wwn, &rport->pwwn, 8))
80 break;
81 } else {
82 if (i == index)
83 break;
84 }
85
86 i++;
87 qe = bfa_q_next(qe);
88 }
89
90 bfa_trc(fcs, i);
91 if (rport) {
92 return rport->pwwn;
93 } else {
94 return (wwn_t) 0;
95 }
96}
97
98void
99bfa_fcs_port_get_rports(struct bfa_fcs_port_s *port, wwn_t rport_wwns[],
100 int *nrports)
101{
102 struct list_head *qh, *qe;
103 struct bfa_fcs_rport_s *rport = NULL;
104 int i;
105 struct bfa_fcs_s *fcs;
106
107 if (port == NULL || rport_wwns == NULL || *nrports == 0)
108 return;
109
110 fcs = port->fcs;
111 bfa_trc(fcs, (u32) *nrports);
112
113 i = 0;
114 qh = &port->rport_q;
115 qe = bfa_q_first(qh);
116
117 while ((qe != qh) && (i < *nrports)) {
118 rport = (struct bfa_fcs_rport_s *)qe;
119 if (bfa_os_ntoh3b(rport->pid) > 0xFFF000) {
120 qe = bfa_q_next(qe);
121 bfa_trc(fcs, (u32) rport->pwwn);
122 bfa_trc(fcs, rport->pid);
123 bfa_trc(fcs, i);
124 continue;
125 }
126
127 rport_wwns[i] = rport->pwwn;
128
129 i++;
130 qe = bfa_q_next(qe);
131 }
132
133 bfa_trc(fcs, i);
134 *nrports = i;
135 return;
136}
137
138/*
139 * Iterate's through all the rport's in the given port to
140 * determine the maximum operating speed.
141 */
142enum bfa_pport_speed
143bfa_fcs_port_get_rport_max_speed(struct bfa_fcs_port_s *port)
144{
145 struct list_head *qh, *qe;
146 struct bfa_fcs_rport_s *rport = NULL;
147 struct bfa_fcs_s *fcs;
148 enum bfa_pport_speed max_speed = 0;
149 struct bfa_pport_attr_s pport_attr;
150 enum bfa_pport_speed pport_speed;
151
152 if (port == NULL)
153 return 0;
154
155 fcs = port->fcs;
156
157 /*
158 * Get Physical port's current speed
159 */
160 bfa_pport_get_attr(port->fcs->bfa, &pport_attr);
161 pport_speed = pport_attr.speed;
162 bfa_trc(fcs, pport_speed);
163
164 qh = &port->rport_q;
165 qe = bfa_q_first(qh);
166
167 while (qe != qh) {
168 rport = (struct bfa_fcs_rport_s *)qe;
169 if ((bfa_os_ntoh3b(rport->pid) > 0xFFF000)
170 || (bfa_fcs_rport_get_state(rport) == BFA_RPORT_OFFLINE)) {
171 qe = bfa_q_next(qe);
172 continue;
173 }
174
175 if ((rport->rpf.rpsc_speed == BFA_PPORT_SPEED_8GBPS)
176 || (rport->rpf.rpsc_speed > pport_speed)) {
177 max_speed = rport->rpf.rpsc_speed;
178 break;
179 } else if (rport->rpf.rpsc_speed > max_speed) {
180 max_speed = rport->rpf.rpsc_speed;
181 }
182
183 qe = bfa_q_next(qe);
184 }
185
186 bfa_trc(fcs, max_speed);
187 return max_speed;
188}
189
190struct bfa_fcs_port_s *
191bfa_fcs_lookup_port(struct bfa_fcs_s *fcs, u16 vf_id, wwn_t lpwwn)
192{
193 struct bfa_fcs_vport_s *vport;
194 bfa_fcs_vf_t *vf;
195
196 bfa_assert(fcs != NULL);
197
198 vf = bfa_fcs_vf_lookup(fcs, vf_id);
199 if (vf == NULL) {
200 bfa_trc(fcs, vf_id);
201 return (NULL);
202 }
203
204 if (!lpwwn || (vf->bport.port_cfg.pwwn == lpwwn))
205 return (&vf->bport);
206
207 vport = bfa_fcs_fabric_vport_lookup(vf, lpwwn);
208 if (vport)
209 return (&vport->lport);
210
211 return (NULL);
212}
213
214/*
215 * API corresponding to VmWare's NPIV_VPORT_GETINFO.
216 */
217void
218bfa_fcs_port_get_info(struct bfa_fcs_port_s *port,
219 struct bfa_port_info_s *port_info)
220{
221
222 bfa_trc(port->fcs, port->fabric->fabric_name);
223
224 if (port->vport == NULL) {
225 /*
226 * This is a Physical port
227 */
228 port_info->port_type = BFA_PORT_TYPE_PHYSICAL;
229
230 /*
231 * @todo : need to fix the state & reason
232 */
233 port_info->port_state = 0;
234 port_info->offline_reason = 0;
235
236 port_info->port_wwn = bfa_fcs_port_get_pwwn(port);
237 port_info->node_wwn = bfa_fcs_port_get_nwwn(port);
238
239 port_info->max_vports_supp = bfa_fcs_vport_get_max(port->fcs);
240 port_info->num_vports_inuse =
241 bfa_fcs_fabric_vport_count(port->fabric);
242 port_info->max_rports_supp = BFA_FCS_MAX_RPORTS_SUPP;
243 port_info->num_rports_inuse = port->num_rports;
244 } else {
245 /*
246 * This is a virtual port
247 */
248 port_info->port_type = BFA_PORT_TYPE_VIRTUAL;
249
250 /*
251 * @todo : need to fix the state & reason
252 */
253 port_info->port_state = 0;
254 port_info->offline_reason = 0;
255
256 port_info->port_wwn = bfa_fcs_port_get_pwwn(port);
257 port_info->node_wwn = bfa_fcs_port_get_nwwn(port);
258 }
259}
260
261void
262bfa_fcs_port_get_stats(struct bfa_fcs_port_s *fcs_port,
263 struct bfa_port_stats_s *port_stats)
264{
265 bfa_os_memcpy(port_stats, &fcs_port->stats,
266 sizeof(struct bfa_port_stats_s));
267 return;
268}
269
270void
271bfa_fcs_port_clear_stats(struct bfa_fcs_port_s *fcs_port)
272{
273 bfa_os_memset(&fcs_port->stats, 0, sizeof(struct bfa_port_stats_s));
274 return;
275}
276
277void
278bfa_fcs_port_enable_ipfc_roles(struct bfa_fcs_port_s *fcs_port)
279{
280 fcs_port->port_cfg.roles |= BFA_PORT_ROLE_FCP_IPFC;
281 return;
282}
283
284void
285bfa_fcs_port_disable_ipfc_roles(struct bfa_fcs_port_s *fcs_port)
286{
287 fcs_port->port_cfg.roles &= ~BFA_PORT_ROLE_FCP_IPFC;
288 return;
289}
290
291
diff --git a/drivers/scsi/bfa/lport_priv.h b/drivers/scsi/bfa/lport_priv.h
new file mode 100644
index 000000000000..dbae370a599a
--- /dev/null
+++ b/drivers/scsi/bfa/lport_priv.h
@@ -0,0 +1,82 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#ifndef __VP_PRIV_H__
19#define __VP_PRIV_H__
20
21#include <fcs/bfa_fcs_lport.h>
22#include <fcs/bfa_fcs_vport.h>
23
24/*
25 * Functions exported by vps
26 */
27void bfa_fcs_vport_init(struct bfa_fcs_vport_s *vport);
28
29/*
30 * Functions exported by vps
31 */
32void bfa_fcs_vps_online(struct bfa_fcs_port_s *port);
33void bfa_fcs_vps_offline(struct bfa_fcs_port_s *port);
34void bfa_fcs_vps_lip(struct bfa_fcs_port_s *port);
35
36/*
37 * Functions exported by port_fab
38 */
39void bfa_fcs_port_fab_init(struct bfa_fcs_port_s *vport);
40void bfa_fcs_port_fab_online(struct bfa_fcs_port_s *vport);
41void bfa_fcs_port_fab_offline(struct bfa_fcs_port_s *vport);
42void bfa_fcs_port_fab_rx_frame(struct bfa_fcs_port_s *port,
43 u8 *rx_frame, u32 len);
44
45/*
46 * Functions exported by VP-NS.
47 */
48void bfa_fcs_port_ns_init(struct bfa_fcs_port_s *vport);
49void bfa_fcs_port_ns_offline(struct bfa_fcs_port_s *vport);
50void bfa_fcs_port_ns_online(struct bfa_fcs_port_s *vport);
51void bfa_fcs_port_ns_query(struct bfa_fcs_port_s *port);
52
53/*
54 * Functions exported by VP-SCN
55 */
56void bfa_fcs_port_scn_init(struct bfa_fcs_port_s *vport);
57void bfa_fcs_port_scn_offline(struct bfa_fcs_port_s *vport);
58void bfa_fcs_port_scn_online(struct bfa_fcs_port_s *vport);
59void bfa_fcs_port_scn_process_rscn(struct bfa_fcs_port_s *port,
60 struct fchs_s *rx_frame, u32 len);
61
62/*
63 * Functions exported by VP-N2N
64 */
65
66void bfa_fcs_port_n2n_init(struct bfa_fcs_port_s *port);
67void bfa_fcs_port_n2n_online(struct bfa_fcs_port_s *port);
68void bfa_fcs_port_n2n_offline(struct bfa_fcs_port_s *port);
69void bfa_fcs_port_n2n_rx_frame(struct bfa_fcs_port_s *port,
70 u8 *rx_frame, u32 len);
71
72/*
73 * Functions exported by VP-LOOP
74 */
75void bfa_fcs_port_loop_init(struct bfa_fcs_port_s *port);
76void bfa_fcs_port_loop_online(struct bfa_fcs_port_s *port);
77void bfa_fcs_port_loop_offline(struct bfa_fcs_port_s *port);
78void bfa_fcs_port_loop_lip(struct bfa_fcs_port_s *port);
79void bfa_fcs_port_loop_rx_frame(struct bfa_fcs_port_s *port,
80 u8 *rx_frame, u32 len);
81
82#endif /* __VP_PRIV_H__ */
diff --git a/drivers/scsi/bfa/ms.c b/drivers/scsi/bfa/ms.c
new file mode 100644
index 000000000000..c96b3ca007ae
--- /dev/null
+++ b/drivers/scsi/bfa/ms.c
@@ -0,0 +1,759 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18
19#include <bfa.h>
20#include <bfa_svc.h>
21#include "fcs_lport.h"
22#include "fcs_rport.h"
23#include "fcs_trcmod.h"
24#include "fcs_fcxp.h"
25#include "lport_priv.h"
26
27BFA_TRC_FILE(FCS, MS);
28
29#define BFA_FCS_MS_CMD_MAX_RETRIES 2
30/*
31 * forward declarations
32 */
33static void bfa_fcs_port_ms_send_plogi(void *ms_cbarg,
34 struct bfa_fcxp_s *fcxp_alloced);
35static void bfa_fcs_port_ms_timeout(void *arg);
36static void bfa_fcs_port_ms_plogi_response(void *fcsarg,
37 struct bfa_fcxp_s *fcxp,
38 void *cbarg,
39 bfa_status_t req_status,
40 u32 rsp_len,
41 u32 resid_len,
42 struct fchs_s *rsp_fchs);
43
44static void bfa_fcs_port_ms_send_gmal(void *ms_cbarg,
45 struct bfa_fcxp_s *fcxp_alloced);
46static void bfa_fcs_port_ms_gmal_response(void *fcsarg,
47 struct bfa_fcxp_s *fcxp,
48 void *cbarg,
49 bfa_status_t req_status,
50 u32 rsp_len,
51 u32 resid_len,
52 struct fchs_s *rsp_fchs);
53static void bfa_fcs_port_ms_send_gfn(void *ms_cbarg,
54 struct bfa_fcxp_s *fcxp_alloced);
55static void bfa_fcs_port_ms_gfn_response(void *fcsarg,
56 struct bfa_fcxp_s *fcxp,
57 void *cbarg,
58 bfa_status_t req_status,
59 u32 rsp_len,
60 u32 resid_len,
61 struct fchs_s *rsp_fchs);
62/**
63 * fcs_ms_sm FCS MS state machine
64 */
65
66/**
67 * MS State Machine events
68 */
69enum port_ms_event {
70 MSSM_EVENT_PORT_ONLINE = 1,
71 MSSM_EVENT_PORT_OFFLINE = 2,
72 MSSM_EVENT_RSP_OK = 3,
73 MSSM_EVENT_RSP_ERROR = 4,
74 MSSM_EVENT_TIMEOUT = 5,
75 MSSM_EVENT_FCXP_SENT = 6,
76 MSSM_EVENT_PORT_FABRIC_RSCN = 7
77};
78
79static void bfa_fcs_port_ms_sm_offline(struct bfa_fcs_port_ms_s *ms,
80 enum port_ms_event event);
81static void bfa_fcs_port_ms_sm_plogi_sending(struct bfa_fcs_port_ms_s *ms,
82 enum port_ms_event event);
83static void bfa_fcs_port_ms_sm_plogi(struct bfa_fcs_port_ms_s *ms,
84 enum port_ms_event event);
85static void bfa_fcs_port_ms_sm_plogi_retry(struct bfa_fcs_port_ms_s *ms,
86 enum port_ms_event event);
87static void bfa_fcs_port_ms_sm_gmal_sending(struct bfa_fcs_port_ms_s *ms,
88 enum port_ms_event event);
89static void bfa_fcs_port_ms_sm_gmal(struct bfa_fcs_port_ms_s *ms,
90 enum port_ms_event event);
91static void bfa_fcs_port_ms_sm_gmal_retry(struct bfa_fcs_port_ms_s *ms,
92 enum port_ms_event event);
93static void bfa_fcs_port_ms_sm_gfn_sending(struct bfa_fcs_port_ms_s *ms,
94 enum port_ms_event event);
95static void bfa_fcs_port_ms_sm_gfn(struct bfa_fcs_port_ms_s *ms,
96 enum port_ms_event event);
97static void bfa_fcs_port_ms_sm_gfn_retry(struct bfa_fcs_port_ms_s *ms,
98 enum port_ms_event event);
99static void bfa_fcs_port_ms_sm_online(struct bfa_fcs_port_ms_s *ms,
100 enum port_ms_event event);
101/**
102 * Start in offline state - awaiting NS to send start.
103 */
104static void
105bfa_fcs_port_ms_sm_offline(struct bfa_fcs_port_ms_s *ms,
106 enum port_ms_event event)
107{
108 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
109 bfa_trc(ms->port->fcs, event);
110
111 switch (event) {
112 case MSSM_EVENT_PORT_ONLINE:
113 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_plogi_sending);
114 bfa_fcs_port_ms_send_plogi(ms, NULL);
115 break;
116
117 case MSSM_EVENT_PORT_OFFLINE:
118 break;
119
120 default:
121 bfa_assert(0);
122 }
123}
124
125static void
126bfa_fcs_port_ms_sm_plogi_sending(struct bfa_fcs_port_ms_s *ms,
127 enum port_ms_event event)
128{
129 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
130 bfa_trc(ms->port->fcs, event);
131
132 switch (event) {
133 case MSSM_EVENT_FCXP_SENT:
134 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_plogi);
135 break;
136
137 case MSSM_EVENT_PORT_OFFLINE:
138 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
139 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
140 &ms->fcxp_wqe);
141 break;
142
143 default:
144 bfa_assert(0);
145 }
146}
147
148static void
149bfa_fcs_port_ms_sm_plogi(struct bfa_fcs_port_ms_s *ms, enum port_ms_event event)
150{
151 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
152 bfa_trc(ms->port->fcs, event);
153
154 switch (event) {
155 case MSSM_EVENT_RSP_ERROR:
156 /*
157 * Start timer for a delayed retry
158 */
159 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_plogi_retry);
160 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port), &ms->timer,
161 bfa_fcs_port_ms_timeout, ms,
162 BFA_FCS_RETRY_TIMEOUT);
163 break;
164
165 case MSSM_EVENT_RSP_OK:
166 /*
167 * since plogi is done, now invoke MS related sub-modules
168 */
169 bfa_fcs_port_fdmi_online(ms);
170
171 /**
172 * if this is a Vport, go to online state.
173 */
174 if (ms->port->vport) {
175 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_online);
176 break;
177 }
178
179 /*
180 * For a base port we need to get the
181 * switch's IP address.
182 */
183 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gmal_sending);
184 bfa_fcs_port_ms_send_gmal(ms, NULL);
185 break;
186
187 case MSSM_EVENT_PORT_OFFLINE:
188 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
189 bfa_fcxp_discard(ms->fcxp);
190 break;
191
192 default:
193 bfa_assert(0);
194 }
195}
196
197static void
198bfa_fcs_port_ms_sm_plogi_retry(struct bfa_fcs_port_ms_s *ms,
199 enum port_ms_event event)
200{
201 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
202 bfa_trc(ms->port->fcs, event);
203
204 switch (event) {
205 case MSSM_EVENT_TIMEOUT:
206 /*
207 * Retry Timer Expired. Re-send
208 */
209 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_plogi_sending);
210 bfa_fcs_port_ms_send_plogi(ms, NULL);
211 break;
212
213 case MSSM_EVENT_PORT_OFFLINE:
214 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
215 bfa_timer_stop(&ms->timer);
216 break;
217
218 default:
219 bfa_assert(0);
220 }
221}
222
223static void
224bfa_fcs_port_ms_sm_online(struct bfa_fcs_port_ms_s *ms,
225 enum port_ms_event event)
226{
227 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
228 bfa_trc(ms->port->fcs, event);
229
230 switch (event) {
231 case MSSM_EVENT_PORT_OFFLINE:
232 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
233 /*
234 * now invoke MS related sub-modules
235 */
236 bfa_fcs_port_fdmi_offline(ms);
237 break;
238
239 case MSSM_EVENT_PORT_FABRIC_RSCN:
240 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gfn_sending);
241 ms->retry_cnt = 0;
242 bfa_fcs_port_ms_send_gfn(ms, NULL);
243 break;
244
245 default:
246 bfa_assert(0);
247 }
248}
249
250static void
251bfa_fcs_port_ms_sm_gmal_sending(struct bfa_fcs_port_ms_s *ms,
252 enum port_ms_event event)
253{
254 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
255 bfa_trc(ms->port->fcs, event);
256
257 switch (event) {
258 case MSSM_EVENT_FCXP_SENT:
259 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gmal);
260 break;
261
262 case MSSM_EVENT_PORT_OFFLINE:
263 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
264 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
265 &ms->fcxp_wqe);
266 break;
267
268 default:
269 bfa_assert(0);
270 }
271}
272
273static void
274bfa_fcs_port_ms_sm_gmal(struct bfa_fcs_port_ms_s *ms, enum port_ms_event event)
275{
276 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
277 bfa_trc(ms->port->fcs, event);
278
279 switch (event) {
280 case MSSM_EVENT_RSP_ERROR:
281 /*
282 * Start timer for a delayed retry
283 */
284 if (ms->retry_cnt++ < BFA_FCS_MS_CMD_MAX_RETRIES) {
285 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gmal_retry);
286 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
287 &ms->timer, bfa_fcs_port_ms_timeout, ms,
288 BFA_FCS_RETRY_TIMEOUT);
289 } else {
290 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gfn_sending);
291 bfa_fcs_port_ms_send_gfn(ms, NULL);
292 ms->retry_cnt = 0;
293 }
294 break;
295
296 case MSSM_EVENT_RSP_OK:
297 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gfn_sending);
298 bfa_fcs_port_ms_send_gfn(ms, NULL);
299 break;
300
301 case MSSM_EVENT_PORT_OFFLINE:
302 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
303 bfa_fcxp_discard(ms->fcxp);
304 break;
305
306 default:
307 bfa_assert(0);
308 }
309}
310
311static void
312bfa_fcs_port_ms_sm_gmal_retry(struct bfa_fcs_port_ms_s *ms,
313 enum port_ms_event event)
314{
315 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
316 bfa_trc(ms->port->fcs, event);
317
318 switch (event) {
319 case MSSM_EVENT_TIMEOUT:
320 /*
321 * Retry Timer Expired. Re-send
322 */
323 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gmal_sending);
324 bfa_fcs_port_ms_send_gmal(ms, NULL);
325 break;
326
327 case MSSM_EVENT_PORT_OFFLINE:
328 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
329 bfa_timer_stop(&ms->timer);
330 break;
331
332 default:
333 bfa_assert(0);
334 }
335}
336
337/**
338 * ms_pvt MS local functions
339 */
340
341static void
342bfa_fcs_port_ms_send_gmal(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
343{
344 struct bfa_fcs_port_ms_s *ms = ms_cbarg;
345 struct bfa_fcs_port_s *port = ms->port;
346 struct fchs_s fchs;
347 int len;
348 struct bfa_fcxp_s *fcxp;
349
350 bfa_trc(port->fcs, port->pid);
351
352 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
353 if (!fcxp) {
354 bfa_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe,
355 bfa_fcs_port_ms_send_gmal, ms);
356 return;
357 }
358 ms->fcxp = fcxp;
359
360 len = fc_gmal_req_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
361 bfa_fcs_port_get_fcid(port),
362 bfa_lps_get_peer_nwwn(port->fabric->lps));
363
364 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
365 FC_CLASS_3, len, &fchs, bfa_fcs_port_ms_gmal_response,
366 (void *)ms, FC_MAX_PDUSZ, FC_RA_TOV);
367
368 bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT);
369}
370
371static void
372bfa_fcs_port_ms_gmal_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
373 void *cbarg, bfa_status_t req_status,
374 u32 rsp_len, u32 resid_len,
375 struct fchs_s *rsp_fchs)
376{
377 struct bfa_fcs_port_ms_s *ms = (struct bfa_fcs_port_ms_s *)cbarg;
378 struct bfa_fcs_port_s *port = ms->port;
379 struct ct_hdr_s *cthdr = NULL;
380 struct fcgs_gmal_resp_s *gmal_resp;
381 struct fc_gmal_entry_s *gmal_entry;
382 u32 num_entries;
383 u8 *rsp_str;
384
385 bfa_trc(port->fcs, req_status);
386 bfa_trc(port->fcs, port->port_cfg.pwwn);
387
388 /*
389 * Sanity Checks
390 */
391 if (req_status != BFA_STATUS_OK) {
392 bfa_trc(port->fcs, req_status);
393 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
394 return;
395 }
396
397 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
398 cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
399
400 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
401 gmal_resp = (struct fcgs_gmal_resp_s *)(cthdr + 1);
402 num_entries = bfa_os_ntohl(gmal_resp->ms_len);
403 if (num_entries == 0) {
404 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
405 return;
406 }
407 /*
408 * The response could contain multiple Entries.
409 * Entries for SNMP interface, etc.
410 * We look for the entry with a telnet prefix.
411 * First "http://" entry refers to IP addr
412 */
413
414 gmal_entry = (struct fc_gmal_entry_s *)gmal_resp->ms_ma;
415 while (num_entries > 0) {
416 if (strncmp
417 (gmal_entry->prefix, CT_GMAL_RESP_PREFIX_HTTP,
418 sizeof(gmal_entry->prefix)) == 0) {
419
420 /*
421 * if the IP address is terminating with a '/',
422 * remove it. *Byte 0 consists of the length
423 * of the string.
424 */
425 rsp_str = &(gmal_entry->prefix[0]);
426 if (rsp_str[gmal_entry->len - 1] == '/')
427 rsp_str[gmal_entry->len - 1] = 0;
428 /*
429 * copy IP Address to fabric
430 */
431 strncpy(bfa_fcs_port_get_fabric_ipaddr(port),
432 gmal_entry->ip_addr,
433 BFA_FCS_FABRIC_IPADDR_SZ);
434 break;
435 } else {
436 --num_entries;
437 ++gmal_entry;
438 }
439 }
440
441 bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK);
442 return;
443 }
444
445 bfa_trc(port->fcs, cthdr->reason_code);
446 bfa_trc(port->fcs, cthdr->exp_code);
447 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
448}
449
450static void
451bfa_fcs_port_ms_sm_gfn_sending(struct bfa_fcs_port_ms_s *ms,
452 enum port_ms_event event)
453{
454 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
455 bfa_trc(ms->port->fcs, event);
456
457 switch (event) {
458 case MSSM_EVENT_FCXP_SENT:
459 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gfn);
460 break;
461
462 case MSSM_EVENT_PORT_OFFLINE:
463 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
464 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
465 &ms->fcxp_wqe);
466 break;
467
468 default:
469 bfa_assert(0);
470 }
471}
472
473static void
474bfa_fcs_port_ms_sm_gfn(struct bfa_fcs_port_ms_s *ms, enum port_ms_event event)
475{
476 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
477 bfa_trc(ms->port->fcs, event);
478
479 switch (event) {
480 case MSSM_EVENT_RSP_ERROR:
481 /*
482 * Start timer for a delayed retry
483 */
484 if (ms->retry_cnt++ < BFA_FCS_MS_CMD_MAX_RETRIES) {
485 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gfn_retry);
486 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ms->port),
487 &ms->timer, bfa_fcs_port_ms_timeout, ms,
488 BFA_FCS_RETRY_TIMEOUT);
489 } else {
490 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_online);
491 ms->retry_cnt = 0;
492 }
493 break;
494
495 case MSSM_EVENT_RSP_OK:
496 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_online);
497 break;
498
499 case MSSM_EVENT_PORT_OFFLINE:
500 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
501 bfa_fcxp_discard(ms->fcxp);
502 break;
503
504 default:
505 bfa_assert(0);
506 }
507}
508
509static void
510bfa_fcs_port_ms_sm_gfn_retry(struct bfa_fcs_port_ms_s *ms,
511 enum port_ms_event event)
512{
513 bfa_trc(ms->port->fcs, ms->port->port_cfg.pwwn);
514 bfa_trc(ms->port->fcs, event);
515
516 switch (event) {
517 case MSSM_EVENT_TIMEOUT:
518 /*
519 * Retry Timer Expired. Re-send
520 */
521 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_gfn_sending);
522 bfa_fcs_port_ms_send_gfn(ms, NULL);
523 break;
524
525 case MSSM_EVENT_PORT_OFFLINE:
526 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
527 bfa_timer_stop(&ms->timer);
528 break;
529
530 default:
531 bfa_assert(0);
532 }
533}
534
535/**
536 * ms_pvt MS local functions
537 */
538
539static void
540bfa_fcs_port_ms_send_gfn(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
541{
542 struct bfa_fcs_port_ms_s *ms = ms_cbarg;
543 struct bfa_fcs_port_s *port = ms->port;
544 struct fchs_s fchs;
545 int len;
546 struct bfa_fcxp_s *fcxp;
547
548 bfa_trc(port->fcs, port->pid);
549
550 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
551 if (!fcxp) {
552 bfa_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe,
553 bfa_fcs_port_ms_send_gfn, ms);
554 return;
555 }
556 ms->fcxp = fcxp;
557
558 len = fc_gfn_req_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
559 bfa_fcs_port_get_fcid(port),
560 bfa_lps_get_peer_nwwn(port->fabric->lps));
561
562 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
563 FC_CLASS_3, len, &fchs, bfa_fcs_port_ms_gfn_response,
564 (void *)ms, FC_MAX_PDUSZ, FC_RA_TOV);
565
566 bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT);
567}
568
569static void
570bfa_fcs_port_ms_gfn_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
571 bfa_status_t req_status, u32 rsp_len,
572 u32 resid_len, struct fchs_s *rsp_fchs)
573{
574 struct bfa_fcs_port_ms_s *ms = (struct bfa_fcs_port_ms_s *)cbarg;
575 struct bfa_fcs_port_s *port = ms->port;
576 struct ct_hdr_s *cthdr = NULL;
577 wwn_t *gfn_resp;
578
579 bfa_trc(port->fcs, req_status);
580 bfa_trc(port->fcs, port->port_cfg.pwwn);
581
582 /*
583 * Sanity Checks
584 */
585 if (req_status != BFA_STATUS_OK) {
586 bfa_trc(port->fcs, req_status);
587 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
588 return;
589 }
590
591 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
592 cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
593
594 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
595 gfn_resp = (wwn_t *) (cthdr + 1);
596 /*
597 * check if it has actually changed
598 */
599 if ((memcmp
600 ((void *)&bfa_fcs_port_get_fabric_name(port), gfn_resp,
601 sizeof(wwn_t)) != 0))
602 bfa_fcs_fabric_set_fabric_name(port->fabric, *gfn_resp);
603 bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK);
604 return;
605 }
606
607 bfa_trc(port->fcs, cthdr->reason_code);
608 bfa_trc(port->fcs, cthdr->exp_code);
609 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
610}
611
612/**
613 * ms_pvt MS local functions
614 */
615
616static void
617bfa_fcs_port_ms_send_plogi(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced)
618{
619 struct bfa_fcs_port_ms_s *ms = ms_cbarg;
620 struct bfa_fcs_port_s *port = ms->port;
621 struct fchs_s fchs;
622 int len;
623 struct bfa_fcxp_s *fcxp;
624
625 bfa_trc(port->fcs, port->pid);
626
627 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
628 if (!fcxp) {
629 port->stats.ms_plogi_alloc_wait++;
630 bfa_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe,
631 bfa_fcs_port_ms_send_plogi, ms);
632 return;
633 }
634 ms->fcxp = fcxp;
635
636 len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
637 bfa_os_hton3b(FC_MGMT_SERVER),
638 bfa_fcs_port_get_fcid(port), 0,
639 port->port_cfg.pwwn, port->port_cfg.nwwn,
640 bfa_pport_get_maxfrsize(port->fcs->bfa));
641
642 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
643 FC_CLASS_3, len, &fchs, bfa_fcs_port_ms_plogi_response,
644 (void *)ms, FC_MAX_PDUSZ, FC_RA_TOV);
645
646 port->stats.ms_plogi_sent++;
647 bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT);
648}
649
650static void
651bfa_fcs_port_ms_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
652 void *cbarg, bfa_status_t req_status,
653 u32 rsp_len, u32 resid_len,
654 struct fchs_s *rsp_fchs)
655{
656 struct bfa_fcs_port_ms_s *ms = (struct bfa_fcs_port_ms_s *)cbarg;
657
658 struct bfa_fcs_port_s *port = ms->port;
659 struct fc_els_cmd_s *els_cmd;
660 struct fc_ls_rjt_s *ls_rjt;
661
662 bfa_trc(port->fcs, req_status);
663 bfa_trc(port->fcs, port->port_cfg.pwwn);
664
665 /*
666 * Sanity Checks
667 */
668 if (req_status != BFA_STATUS_OK) {
669 port->stats.ms_plogi_rsp_err++;
670 bfa_trc(port->fcs, req_status);
671 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
672 return;
673 }
674
675 els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp);
676
677 switch (els_cmd->els_code) {
678
679 case FC_ELS_ACC:
680 if (rsp_len < sizeof(struct fc_logi_s)) {
681 bfa_trc(port->fcs, rsp_len);
682 port->stats.ms_plogi_acc_err++;
683 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
684 break;
685 }
686 port->stats.ms_plogi_accepts++;
687 bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK);
688 break;
689
690 case FC_ELS_LS_RJT:
691 ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
692
693 bfa_trc(port->fcs, ls_rjt->reason_code);
694 bfa_trc(port->fcs, ls_rjt->reason_code_expl);
695
696 port->stats.ms_rejects++;
697 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
698 break;
699
700 default:
701 port->stats.ms_plogi_unknown_rsp++;
702 bfa_trc(port->fcs, els_cmd->els_code);
703 bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR);
704 }
705}
706
707static void
708bfa_fcs_port_ms_timeout(void *arg)
709{
710 struct bfa_fcs_port_ms_s *ms = (struct bfa_fcs_port_ms_s *)arg;
711
712 ms->port->stats.ms_timeouts++;
713 bfa_sm_send_event(ms, MSSM_EVENT_TIMEOUT);
714}
715
716
717void
718bfa_fcs_port_ms_init(struct bfa_fcs_port_s *port)
719{
720 struct bfa_fcs_port_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port);
721
722 ms->port = port;
723 bfa_sm_set_state(ms, bfa_fcs_port_ms_sm_offline);
724
725 /*
726 * Invoke init routines of sub modules.
727 */
728 bfa_fcs_port_fdmi_init(ms);
729}
730
731void
732bfa_fcs_port_ms_offline(struct bfa_fcs_port_s *port)
733{
734 struct bfa_fcs_port_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port);
735
736 ms->port = port;
737 bfa_sm_send_event(ms, MSSM_EVENT_PORT_OFFLINE);
738}
739
740void
741bfa_fcs_port_ms_online(struct bfa_fcs_port_s *port)
742{
743 struct bfa_fcs_port_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port);
744
745 ms->port = port;
746 bfa_sm_send_event(ms, MSSM_EVENT_PORT_ONLINE);
747}
748
749void
750bfa_fcs_port_ms_fabric_rscn(struct bfa_fcs_port_s *port)
751{
752 struct bfa_fcs_port_ms_s *ms = BFA_FCS_GET_MS_FROM_PORT(port);
753
754 /*
755 * @todo. Handle this only when in Online state
756 */
757 if (bfa_sm_cmp_state(ms, bfa_fcs_port_ms_sm_online))
758 bfa_sm_send_event(ms, MSSM_EVENT_PORT_FABRIC_RSCN);
759}
diff --git a/drivers/scsi/bfa/n2n.c b/drivers/scsi/bfa/n2n.c
new file mode 100644
index 000000000000..735456824346
--- /dev/null
+++ b/drivers/scsi/bfa/n2n.c
@@ -0,0 +1,105 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * n2n.c n2n implementation.
20 */
21#include <bfa.h>
22#include <bfa_svc.h>
23#include "fcs_lport.h"
24#include "fcs_rport.h"
25#include "fcs_trcmod.h"
26#include "lport_priv.h"
27
28BFA_TRC_FILE(FCS, N2N);
29
30/**
31 * Called by fcs/port to initialize N2N topology.
32 */
33void
34bfa_fcs_port_n2n_init(struct bfa_fcs_port_s *port)
35{
36}
37
38/**
39 * Called by fcs/port to notify transition to online state.
40 */
41void
42bfa_fcs_port_n2n_online(struct bfa_fcs_port_s *port)
43{
44 struct bfa_fcs_port_n2n_s *n2n_port = &port->port_topo.pn2n;
45 struct bfa_port_cfg_s *pcfg = &port->port_cfg;
46 struct bfa_fcs_rport_s *rport;
47
48 bfa_trc(port->fcs, pcfg->pwwn);
49
50 /*
51 * If our PWWN is > than that of the r-port, we have to initiate PLOGI
52 * and assign an Address. if not, we need to wait for its PLOGI.
53 *
54 * If our PWWN is < than that of the remote port, it will send a PLOGI
55 * with the PIDs assigned. The rport state machine take care of this
56 * incoming PLOGI.
57 */
58 if (memcmp
59 ((void *)&pcfg->pwwn, (void *)&n2n_port->rem_port_wwn,
60 sizeof(wwn_t)) > 0) {
61 port->pid = N2N_LOCAL_PID;
62 /**
63 * First, check if we know the device by pwwn.
64 */
65 rport = bfa_fcs_port_get_rport_by_pwwn(port,
66 n2n_port->rem_port_wwn);
67 if (rport) {
68 bfa_trc(port->fcs, rport->pid);
69 bfa_trc(port->fcs, rport->pwwn);
70 rport->pid = N2N_REMOTE_PID;
71 bfa_fcs_rport_online(rport);
72 return;
73 }
74
75 /*
76 * In n2n there can be only one rport. Delete the old one whose
77 * pid should be zero, because it is offline.
78 */
79 if (port->num_rports > 0) {
80 rport = bfa_fcs_port_get_rport_by_pid(port, 0);
81 bfa_assert(rport != NULL);
82 if (rport) {
83 bfa_trc(port->fcs, rport->pwwn);
84 bfa_fcs_rport_delete(rport);
85 }
86 }
87 bfa_fcs_rport_create(port, N2N_REMOTE_PID);
88 }
89}
90
91/**
92 * Called by fcs/port to notify transition to offline state.
93 */
94void
95bfa_fcs_port_n2n_offline(struct bfa_fcs_port_s *port)
96{
97 struct bfa_fcs_port_n2n_s *n2n_port = &port->port_topo.pn2n;
98
99 bfa_trc(port->fcs, port->pid);
100 port->pid = 0;
101 n2n_port->rem_port_wwn = 0;
102 n2n_port->reply_oxid = 0;
103}
104
105
diff --git a/drivers/scsi/bfa/ns.c b/drivers/scsi/bfa/ns.c
new file mode 100644
index 000000000000..59fea99d67a4
--- /dev/null
+++ b/drivers/scsi/bfa/ns.c
@@ -0,0 +1,1243 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * @page ns_sm_info VPORT NS State Machine
20 *
21 * @section ns_sm_interactions VPORT NS State Machine Interactions
22 *
23 * @section ns_sm VPORT NS State Machine
24 * img ns_sm.jpg
25 */
26#include <bfa.h>
27#include <bfa_svc.h>
28#include <bfa_iocfc.h>
29#include "fcs_lport.h"
30#include "fcs_rport.h"
31#include "fcs_trcmod.h"
32#include "fcs_fcxp.h"
33#include "fcs.h"
34#include "lport_priv.h"
35
36BFA_TRC_FILE(FCS, NS);
37
38/*
39 * forward declarations
40 */
41static void bfa_fcs_port_ns_send_plogi(void *ns_cbarg,
42 struct bfa_fcxp_s *fcxp_alloced);
43static void bfa_fcs_port_ns_send_rspn_id(void *ns_cbarg,
44 struct bfa_fcxp_s *fcxp_alloced);
45static void bfa_fcs_port_ns_send_rft_id(void *ns_cbarg,
46 struct bfa_fcxp_s *fcxp_alloced);
47static void bfa_fcs_port_ns_send_rff_id(void *ns_cbarg,
48 struct bfa_fcxp_s *fcxp_alloced);
49static void bfa_fcs_port_ns_send_gid_ft(void *ns_cbarg,
50 struct bfa_fcxp_s *fcxp_alloced);
51static void bfa_fcs_port_ns_timeout(void *arg);
52static void bfa_fcs_port_ns_plogi_response(void *fcsarg,
53 struct bfa_fcxp_s *fcxp,
54 void *cbarg,
55 bfa_status_t req_status,
56 u32 rsp_len,
57 u32 resid_len,
58 struct fchs_s *rsp_fchs);
59static void bfa_fcs_port_ns_rspn_id_response(void *fcsarg,
60 struct bfa_fcxp_s *fcxp,
61 void *cbarg,
62 bfa_status_t req_status,
63 u32 rsp_len,
64 u32 resid_len,
65 struct fchs_s *rsp_fchs);
66static void bfa_fcs_port_ns_rft_id_response(void *fcsarg,
67 struct bfa_fcxp_s *fcxp,
68 void *cbarg,
69 bfa_status_t req_status,
70 u32 rsp_len,
71 u32 resid_len,
72 struct fchs_s *rsp_fchs);
73static void bfa_fcs_port_ns_rff_id_response(void *fcsarg,
74 struct bfa_fcxp_s *fcxp,
75 void *cbarg,
76 bfa_status_t req_status,
77 u32 rsp_len,
78 u32 resid_len,
79 struct fchs_s *rsp_fchs);
80static void bfa_fcs_port_ns_gid_ft_response(void *fcsarg,
81 struct bfa_fcxp_s *fcxp,
82 void *cbarg,
83 bfa_status_t req_status,
84 u32 rsp_len,
85 u32 resid_len,
86 struct fchs_s *rsp_fchs);
87static void bfa_fcs_port_ns_process_gidft_pids(struct bfa_fcs_port_s *port,
88 u32 *pid_buf,
89 u32 n_pids);
90
91static void bfa_fcs_port_ns_boot_target_disc(struct bfa_fcs_port_s *port);
92/**
93 * fcs_ns_sm FCS nameserver interface state machine
94 */
95
96/**
97 * VPort NS State Machine events
98 */
99enum vport_ns_event {
100 NSSM_EVENT_PORT_ONLINE = 1,
101 NSSM_EVENT_PORT_OFFLINE = 2,
102 NSSM_EVENT_PLOGI_SENT = 3,
103 NSSM_EVENT_RSP_OK = 4,
104 NSSM_EVENT_RSP_ERROR = 5,
105 NSSM_EVENT_TIMEOUT = 6,
106 NSSM_EVENT_NS_QUERY = 7,
107 NSSM_EVENT_RSPNID_SENT = 8,
108 NSSM_EVENT_RFTID_SENT = 9,
109 NSSM_EVENT_RFFID_SENT = 10,
110 NSSM_EVENT_GIDFT_SENT = 11,
111};
112
113static void bfa_fcs_port_ns_sm_offline(struct bfa_fcs_port_ns_s *ns,
114 enum vport_ns_event event);
115static void bfa_fcs_port_ns_sm_plogi_sending(struct bfa_fcs_port_ns_s *ns,
116 enum vport_ns_event event);
117static void bfa_fcs_port_ns_sm_plogi(struct bfa_fcs_port_ns_s *ns,
118 enum vport_ns_event event);
119static void bfa_fcs_port_ns_sm_plogi_retry(struct bfa_fcs_port_ns_s *ns,
120 enum vport_ns_event event);
121static void bfa_fcs_port_ns_sm_sending_rspn_id(struct bfa_fcs_port_ns_s *ns,
122 enum vport_ns_event event);
123static void bfa_fcs_port_ns_sm_rspn_id(struct bfa_fcs_port_ns_s *ns,
124 enum vport_ns_event event);
125static void bfa_fcs_port_ns_sm_rspn_id_retry(struct bfa_fcs_port_ns_s *ns,
126 enum vport_ns_event event);
127static void bfa_fcs_port_ns_sm_sending_rft_id(struct bfa_fcs_port_ns_s *ns,
128 enum vport_ns_event event);
129static void bfa_fcs_port_ns_sm_rft_id_retry(struct bfa_fcs_port_ns_s *ns,
130 enum vport_ns_event event);
131static void bfa_fcs_port_ns_sm_rft_id(struct bfa_fcs_port_ns_s *ns,
132 enum vport_ns_event event);
133static void bfa_fcs_port_ns_sm_sending_rff_id(struct bfa_fcs_port_ns_s *ns,
134 enum vport_ns_event event);
135static void bfa_fcs_port_ns_sm_rff_id_retry(struct bfa_fcs_port_ns_s *ns,
136 enum vport_ns_event event);
137static void bfa_fcs_port_ns_sm_rff_id(struct bfa_fcs_port_ns_s *ns,
138 enum vport_ns_event event);
139static void bfa_fcs_port_ns_sm_sending_gid_ft(struct bfa_fcs_port_ns_s *ns,
140 enum vport_ns_event event);
141static void bfa_fcs_port_ns_sm_gid_ft(struct bfa_fcs_port_ns_s *ns,
142 enum vport_ns_event event);
143static void bfa_fcs_port_ns_sm_gid_ft_retry(struct bfa_fcs_port_ns_s *ns,
144 enum vport_ns_event event);
145static void bfa_fcs_port_ns_sm_online(struct bfa_fcs_port_ns_s *ns,
146 enum vport_ns_event event);
147/**
148 * Start in offline state - awaiting linkup
149 */
150static void
151bfa_fcs_port_ns_sm_offline(struct bfa_fcs_port_ns_s *ns,
152 enum vport_ns_event event)
153{
154 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
155 bfa_trc(ns->port->fcs, event);
156
157 switch (event) {
158 case NSSM_EVENT_PORT_ONLINE:
159 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_plogi_sending);
160 bfa_fcs_port_ns_send_plogi(ns, NULL);
161 break;
162
163 case NSSM_EVENT_PORT_OFFLINE:
164 break;
165
166 default:
167 bfa_assert(0);
168 }
169}
170
171static void
172bfa_fcs_port_ns_sm_plogi_sending(struct bfa_fcs_port_ns_s *ns,
173 enum vport_ns_event event)
174{
175 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
176 bfa_trc(ns->port->fcs, event);
177
178 switch (event) {
179 case NSSM_EVENT_PLOGI_SENT:
180 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_plogi);
181 break;
182
183 case NSSM_EVENT_PORT_OFFLINE:
184 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
185 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
186 &ns->fcxp_wqe);
187 break;
188
189 default:
190 bfa_assert(0);
191 }
192}
193
194static void
195bfa_fcs_port_ns_sm_plogi(struct bfa_fcs_port_ns_s *ns,
196 enum vport_ns_event event)
197{
198 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
199 bfa_trc(ns->port->fcs, event);
200
201 switch (event) {
202 case NSSM_EVENT_RSP_ERROR:
203 /*
204 * Start timer for a delayed retry
205 */
206 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_plogi_retry);
207 ns->port->stats.ns_retries++;
208 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), &ns->timer,
209 bfa_fcs_port_ns_timeout, ns,
210 BFA_FCS_RETRY_TIMEOUT);
211 break;
212
213 case NSSM_EVENT_RSP_OK:
214 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_sending_rspn_id);
215 bfa_fcs_port_ns_send_rspn_id(ns, NULL);
216 break;
217
218 case NSSM_EVENT_PORT_OFFLINE:
219 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
220 bfa_fcxp_discard(ns->fcxp);
221 break;
222
223 default:
224 bfa_assert(0);
225 }
226}
227
228static void
229bfa_fcs_port_ns_sm_plogi_retry(struct bfa_fcs_port_ns_s *ns,
230 enum vport_ns_event event)
231{
232 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
233 bfa_trc(ns->port->fcs, event);
234
235 switch (event) {
236 case NSSM_EVENT_TIMEOUT:
237 /*
238 * Retry Timer Expired. Re-send
239 */
240 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_plogi_sending);
241 bfa_fcs_port_ns_send_plogi(ns, NULL);
242 break;
243
244 case NSSM_EVENT_PORT_OFFLINE:
245 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
246 bfa_timer_stop(&ns->timer);
247 break;
248
249 default:
250 bfa_assert(0);
251 }
252}
253
254static void
255bfa_fcs_port_ns_sm_sending_rspn_id(struct bfa_fcs_port_ns_s *ns,
256 enum vport_ns_event event)
257{
258 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
259 bfa_trc(ns->port->fcs, event);
260
261 switch (event) {
262 case NSSM_EVENT_RSPNID_SENT:
263 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_rspn_id);
264 break;
265
266 case NSSM_EVENT_PORT_OFFLINE:
267 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
268 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
269 &ns->fcxp_wqe);
270 break;
271
272 default:
273 bfa_assert(0);
274 }
275}
276
277static void
278bfa_fcs_port_ns_sm_rspn_id(struct bfa_fcs_port_ns_s *ns,
279 enum vport_ns_event event)
280{
281 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
282 bfa_trc(ns->port->fcs, event);
283
284 switch (event) {
285 case NSSM_EVENT_RSP_ERROR:
286 /*
287 * Start timer for a delayed retry
288 */
289 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_rspn_id_retry);
290 ns->port->stats.ns_retries++;
291 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), &ns->timer,
292 bfa_fcs_port_ns_timeout, ns,
293 BFA_FCS_RETRY_TIMEOUT);
294 break;
295
296 case NSSM_EVENT_RSP_OK:
297 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_sending_rft_id);
298 bfa_fcs_port_ns_send_rft_id(ns, NULL);
299 break;
300
301 case NSSM_EVENT_PORT_OFFLINE:
302 bfa_fcxp_discard(ns->fcxp);
303 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
304 break;
305
306 default:
307 bfa_assert(0);
308 }
309}
310
311static void
312bfa_fcs_port_ns_sm_rspn_id_retry(struct bfa_fcs_port_ns_s *ns,
313 enum vport_ns_event event)
314{
315 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
316 bfa_trc(ns->port->fcs, event);
317
318 switch (event) {
319 case NSSM_EVENT_TIMEOUT:
320 /*
321 * Retry Timer Expired. Re-send
322 */
323 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_sending_rspn_id);
324 bfa_fcs_port_ns_send_rspn_id(ns, NULL);
325 break;
326
327 case NSSM_EVENT_PORT_OFFLINE:
328 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
329 bfa_timer_stop(&ns->timer);
330 break;
331
332 default:
333 bfa_assert(0);
334 }
335}
336
337static void
338bfa_fcs_port_ns_sm_sending_rft_id(struct bfa_fcs_port_ns_s *ns,
339 enum vport_ns_event event)
340{
341 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
342 bfa_trc(ns->port->fcs, event);
343
344 switch (event) {
345 case NSSM_EVENT_RFTID_SENT:
346 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_rft_id);
347 break;
348
349 case NSSM_EVENT_PORT_OFFLINE:
350 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
351 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
352 &ns->fcxp_wqe);
353 break;
354
355 default:
356 bfa_assert(0);
357 }
358}
359
360static void
361bfa_fcs_port_ns_sm_rft_id(struct bfa_fcs_port_ns_s *ns,
362 enum vport_ns_event event)
363{
364 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
365 bfa_trc(ns->port->fcs, event);
366
367 switch (event) {
368 case NSSM_EVENT_RSP_OK:
369 /*
370 * Now move to register FC4 Features
371 */
372 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_sending_rff_id);
373 bfa_fcs_port_ns_send_rff_id(ns, NULL);
374 break;
375
376 case NSSM_EVENT_RSP_ERROR:
377 /*
378 * Start timer for a delayed retry
379 */
380 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_rft_id_retry);
381 ns->port->stats.ns_retries++;
382 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), &ns->timer,
383 bfa_fcs_port_ns_timeout, ns,
384 BFA_FCS_RETRY_TIMEOUT);
385 break;
386
387 case NSSM_EVENT_PORT_OFFLINE:
388 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
389 bfa_fcxp_discard(ns->fcxp);
390 break;
391
392 default:
393 bfa_assert(0);
394 }
395}
396
397static void
398bfa_fcs_port_ns_sm_rft_id_retry(struct bfa_fcs_port_ns_s *ns,
399 enum vport_ns_event event)
400{
401 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
402 bfa_trc(ns->port->fcs, event);
403
404 switch (event) {
405 case NSSM_EVENT_TIMEOUT:
406 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_sending_rft_id);
407 bfa_fcs_port_ns_send_rft_id(ns, NULL);
408 break;
409
410 case NSSM_EVENT_PORT_OFFLINE:
411 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
412 bfa_timer_stop(&ns->timer);
413 break;
414
415 default:
416 bfa_assert(0);
417 }
418}
419
420static void
421bfa_fcs_port_ns_sm_sending_rff_id(struct bfa_fcs_port_ns_s *ns,
422 enum vport_ns_event event)
423{
424 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
425 bfa_trc(ns->port->fcs, event);
426
427 switch (event) {
428 case NSSM_EVENT_RFFID_SENT:
429 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_rff_id);
430 break;
431
432 case NSSM_EVENT_PORT_OFFLINE:
433 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
434 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
435 &ns->fcxp_wqe);
436 break;
437
438 default:
439 bfa_assert(0);
440 }
441}
442
443static void
444bfa_fcs_port_ns_sm_rff_id(struct bfa_fcs_port_ns_s *ns,
445 enum vport_ns_event event)
446{
447 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
448 bfa_trc(ns->port->fcs, event);
449
450 switch (event) {
451 case NSSM_EVENT_RSP_OK:
452
453 /*
454 * If min cfg mode is enabled, we donot initiate rport
455 * discovery with the fabric. Instead, we will retrieve the
456 * boot targets from HAL/FW.
457 */
458 if (__fcs_min_cfg(ns->port->fcs)) {
459 bfa_fcs_port_ns_boot_target_disc(ns->port);
460 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_online);
461 return;
462 }
463
464 /*
465 * If the port role is Initiator Mode issue NS query.
466 * If it is Target Mode, skip this and go to online.
467 */
468 if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port)) {
469 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_sending_gid_ft);
470 bfa_fcs_port_ns_send_gid_ft(ns, NULL);
471 } else if (BFA_FCS_VPORT_IS_TARGET_MODE(ns->port)) {
472 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_online);
473 }
474 /*
475 * kick off mgmt srvr state machine
476 */
477 bfa_fcs_port_ms_online(ns->port);
478 break;
479
480 case NSSM_EVENT_RSP_ERROR:
481 /*
482 * Start timer for a delayed retry
483 */
484 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_rff_id_retry);
485 ns->port->stats.ns_retries++;
486 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), &ns->timer,
487 bfa_fcs_port_ns_timeout, ns,
488 BFA_FCS_RETRY_TIMEOUT);
489 break;
490
491 case NSSM_EVENT_PORT_OFFLINE:
492 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
493 bfa_fcxp_discard(ns->fcxp);
494 break;
495
496 default:
497 bfa_assert(0);
498 }
499}
500
501static void
502bfa_fcs_port_ns_sm_rff_id_retry(struct bfa_fcs_port_ns_s *ns,
503 enum vport_ns_event event)
504{
505 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
506 bfa_trc(ns->port->fcs, event);
507
508 switch (event) {
509 case NSSM_EVENT_TIMEOUT:
510 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_sending_rff_id);
511 bfa_fcs_port_ns_send_rff_id(ns, NULL);
512 break;
513
514 case NSSM_EVENT_PORT_OFFLINE:
515 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
516 bfa_timer_stop(&ns->timer);
517 break;
518
519 default:
520 bfa_assert(0);
521 }
522}
523static void
524bfa_fcs_port_ns_sm_sending_gid_ft(struct bfa_fcs_port_ns_s *ns,
525 enum vport_ns_event event)
526{
527 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
528 bfa_trc(ns->port->fcs, event);
529
530 switch (event) {
531 case NSSM_EVENT_GIDFT_SENT:
532 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_gid_ft);
533 break;
534
535 case NSSM_EVENT_PORT_OFFLINE:
536 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
537 bfa_fcxp_walloc_cancel(BFA_FCS_GET_HAL_FROM_PORT(ns->port),
538 &ns->fcxp_wqe);
539 break;
540
541 default:
542 bfa_assert(0);
543 }
544}
545
546static void
547bfa_fcs_port_ns_sm_gid_ft(struct bfa_fcs_port_ns_s *ns,
548 enum vport_ns_event event)
549{
550 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
551 bfa_trc(ns->port->fcs, event);
552
553 switch (event) {
554 case NSSM_EVENT_RSP_OK:
555 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_online);
556 break;
557
558 case NSSM_EVENT_RSP_ERROR:
559 /*
560 * TBD: for certain reject codes, we don't need to retry
561 */
562 /*
563 * Start timer for a delayed retry
564 */
565 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_gid_ft_retry);
566 ns->port->stats.ns_retries++;
567 bfa_timer_start(BFA_FCS_GET_HAL_FROM_PORT(ns->port), &ns->timer,
568 bfa_fcs_port_ns_timeout, ns,
569 BFA_FCS_RETRY_TIMEOUT);
570 break;
571
572 case NSSM_EVENT_PORT_OFFLINE:
573 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
574 bfa_fcxp_discard(ns->fcxp);
575 break;
576
577 default:
578 bfa_assert(0);
579 }
580}
581
582static void
583bfa_fcs_port_ns_sm_gid_ft_retry(struct bfa_fcs_port_ns_s *ns,
584 enum vport_ns_event event)
585{
586 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
587 bfa_trc(ns->port->fcs, event);
588
589 switch (event) {
590 case NSSM_EVENT_TIMEOUT:
591 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_sending_gid_ft);
592 bfa_fcs_port_ns_send_gid_ft(ns, NULL);
593 break;
594
595 case NSSM_EVENT_PORT_OFFLINE:
596 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
597 bfa_timer_stop(&ns->timer);
598 break;
599
600 default:
601 bfa_assert(0);
602 }
603}
604
605static void
606bfa_fcs_port_ns_sm_online(struct bfa_fcs_port_ns_s *ns,
607 enum vport_ns_event event)
608{
609 bfa_trc(ns->port->fcs, ns->port->port_cfg.pwwn);
610 bfa_trc(ns->port->fcs, event);
611
612 switch (event) {
613 case NSSM_EVENT_PORT_OFFLINE:
614 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
615 break;
616
617 case NSSM_EVENT_NS_QUERY:
618 /*
619 * If the port role is Initiator Mode issue NS query.
620 * If it is Target Mode, skip this and go to online.
621 */
622 if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port)) {
623 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_sending_gid_ft);
624 bfa_fcs_port_ns_send_gid_ft(ns, NULL);
625 };
626 break;
627
628 default:
629 bfa_assert(0);
630 }
631}
632
633
634
635/**
636 * ns_pvt Nameserver local functions
637 */
638
639static void
640bfa_fcs_port_ns_send_plogi(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
641{
642 struct bfa_fcs_port_ns_s *ns = ns_cbarg;
643 struct bfa_fcs_port_s *port = ns->port;
644 struct fchs_s fchs;
645 int len;
646 struct bfa_fcxp_s *fcxp;
647
648 bfa_trc(port->fcs, port->pid);
649
650 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
651 if (!fcxp) {
652 port->stats.ns_plogi_alloc_wait++;
653 bfa_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
654 bfa_fcs_port_ns_send_plogi, ns);
655 return;
656 }
657 ns->fcxp = fcxp;
658
659 len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
660 bfa_os_hton3b(FC_NAME_SERVER),
661 bfa_fcs_port_get_fcid(port), 0,
662 port->port_cfg.pwwn, port->port_cfg.nwwn,
663 bfa_pport_get_maxfrsize(port->fcs->bfa));
664
665 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
666 FC_CLASS_3, len, &fchs, bfa_fcs_port_ns_plogi_response,
667 (void *)ns, FC_MAX_PDUSZ, FC_RA_TOV);
668 port->stats.ns_plogi_sent++;
669
670 bfa_sm_send_event(ns, NSSM_EVENT_PLOGI_SENT);
671}
672
673static void
674bfa_fcs_port_ns_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
675 void *cbarg, bfa_status_t req_status,
676 u32 rsp_len, u32 resid_len,
677 struct fchs_s *rsp_fchs)
678{
679 struct bfa_fcs_port_ns_s *ns = (struct bfa_fcs_port_ns_s *)cbarg;
680 struct bfa_fcs_port_s *port = ns->port;
681 /* struct fc_logi_s *plogi_resp; */
682 struct fc_els_cmd_s *els_cmd;
683 struct fc_ls_rjt_s *ls_rjt;
684
685 bfa_trc(port->fcs, req_status);
686 bfa_trc(port->fcs, port->port_cfg.pwwn);
687
688 /*
689 * Sanity Checks
690 */
691 if (req_status != BFA_STATUS_OK) {
692 bfa_trc(port->fcs, req_status);
693 port->stats.ns_plogi_rsp_err++;
694 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
695 return;
696 }
697
698 els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp);
699
700 switch (els_cmd->els_code) {
701
702 case FC_ELS_ACC:
703 if (rsp_len < sizeof(struct fc_logi_s)) {
704 bfa_trc(port->fcs, rsp_len);
705 port->stats.ns_plogi_acc_err++;
706 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
707 break;
708 }
709 port->stats.ns_plogi_accepts++;
710 bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
711 break;
712
713 case FC_ELS_LS_RJT:
714 ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
715
716 bfa_trc(port->fcs, ls_rjt->reason_code);
717 bfa_trc(port->fcs, ls_rjt->reason_code_expl);
718
719 port->stats.ns_rejects++;
720
721 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
722 break;
723
724 default:
725 port->stats.ns_plogi_unknown_rsp++;
726 bfa_trc(port->fcs, els_cmd->els_code);
727 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
728 }
729}
730
731/**
732 * Register the symbolic port name.
733 */
734static void
735bfa_fcs_port_ns_send_rspn_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
736{
737 struct bfa_fcs_port_ns_s *ns = ns_cbarg;
738 struct bfa_fcs_port_s *port = ns->port;
739 struct fchs_s fchs;
740 int len;
741 struct bfa_fcxp_s *fcxp;
742 u8 symbl[256];
743 u8 *psymbl = &symbl[0];
744
745 bfa_os_memset(symbl, 0, sizeof(symbl));
746
747 bfa_trc(port->fcs, port->port_cfg.pwwn);
748
749 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
750 if (!fcxp) {
751 port->stats.ns_rspnid_alloc_wait++;
752 bfa_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
753 bfa_fcs_port_ns_send_rspn_id, ns);
754 return;
755 }
756 ns->fcxp = fcxp;
757
758 /*
759 * for V-Port, form a Port Symbolic Name
760 */
761 if (port->vport) {
762 /**For Vports,
763 * we append the vport's port symbolic name to that of the base port.
764 */
765
766 strncpy((char *)psymbl,
767 (char *)
768 &(bfa_fcs_port_get_psym_name
769 (bfa_fcs_get_base_port(port->fcs))),
770 strlen((char *)
771 &bfa_fcs_port_get_psym_name(bfa_fcs_get_base_port
772 (port->fcs))));
773
774 /*
775 * Ensure we have a null terminating string.
776 */
777 ((char *)
778 psymbl)[strlen((char *)
779 &bfa_fcs_port_get_psym_name
780 (bfa_fcs_get_base_port(port->fcs)))] = 0;
781
782 strncat((char *)psymbl,
783 (char *)&(bfa_fcs_port_get_psym_name(port)),
784 strlen((char *)&bfa_fcs_port_get_psym_name(port)));
785 } else {
786 psymbl = (u8 *) &(bfa_fcs_port_get_psym_name(port));
787 }
788
789 len = fc_rspnid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
790 bfa_fcs_port_get_fcid(port), 0, psymbl);
791
792 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
793 FC_CLASS_3, len, &fchs, bfa_fcs_port_ns_rspn_id_response,
794 (void *)ns, FC_MAX_PDUSZ, FC_RA_TOV);
795
796 port->stats.ns_rspnid_sent++;
797
798 bfa_sm_send_event(ns, NSSM_EVENT_RSPNID_SENT);
799}
800
801static void
802bfa_fcs_port_ns_rspn_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
803 void *cbarg, bfa_status_t req_status,
804 u32 rsp_len, u32 resid_len,
805 struct fchs_s *rsp_fchs)
806{
807 struct bfa_fcs_port_ns_s *ns = (struct bfa_fcs_port_ns_s *)cbarg;
808 struct bfa_fcs_port_s *port = ns->port;
809 struct ct_hdr_s *cthdr = NULL;
810
811 bfa_trc(port->fcs, port->port_cfg.pwwn);
812
813 /*
814 * Sanity Checks
815 */
816 if (req_status != BFA_STATUS_OK) {
817 bfa_trc(port->fcs, req_status);
818 port->stats.ns_rspnid_rsp_err++;
819 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
820 return;
821 }
822
823 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
824 cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
825
826 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
827 port->stats.ns_rspnid_accepts++;
828 bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
829 return;
830 }
831
832 port->stats.ns_rspnid_rejects++;
833 bfa_trc(port->fcs, cthdr->reason_code);
834 bfa_trc(port->fcs, cthdr->exp_code);
835 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
836}
837
838/**
839 * Register FC4-Types
840 * TBD, Need to retrieve this from the OS driver, in case IPFC is enabled ?
841 */
842static void
843bfa_fcs_port_ns_send_rft_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
844{
845 struct bfa_fcs_port_ns_s *ns = ns_cbarg;
846 struct bfa_fcs_port_s *port = ns->port;
847 struct fchs_s fchs;
848 int len;
849 struct bfa_fcxp_s *fcxp;
850
851 bfa_trc(port->fcs, port->port_cfg.pwwn);
852
853 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
854 if (!fcxp) {
855 port->stats.ns_rftid_alloc_wait++;
856 bfa_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
857 bfa_fcs_port_ns_send_rft_id, ns);
858 return;
859 }
860 ns->fcxp = fcxp;
861
862 len = fc_rftid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
863 bfa_fcs_port_get_fcid(port), 0,
864 port->port_cfg.roles);
865
866 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
867 FC_CLASS_3, len, &fchs, bfa_fcs_port_ns_rft_id_response,
868 (void *)ns, FC_MAX_PDUSZ, FC_RA_TOV);
869
870 port->stats.ns_rftid_sent++;
871 bfa_sm_send_event(ns, NSSM_EVENT_RFTID_SENT);
872}
873
874static void
875bfa_fcs_port_ns_rft_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
876 void *cbarg, bfa_status_t req_status,
877 u32 rsp_len, u32 resid_len,
878 struct fchs_s *rsp_fchs)
879{
880 struct bfa_fcs_port_ns_s *ns = (struct bfa_fcs_port_ns_s *)cbarg;
881 struct bfa_fcs_port_s *port = ns->port;
882 struct ct_hdr_s *cthdr = NULL;
883
884 bfa_trc(port->fcs, port->port_cfg.pwwn);
885
886 /*
887 * Sanity Checks
888 */
889 if (req_status != BFA_STATUS_OK) {
890 bfa_trc(port->fcs, req_status);
891 port->stats.ns_rftid_rsp_err++;
892 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
893 return;
894 }
895
896 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
897 cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
898
899 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
900 port->stats.ns_rftid_accepts++;
901 bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
902 return;
903 }
904
905 port->stats.ns_rftid_rejects++;
906 bfa_trc(port->fcs, cthdr->reason_code);
907 bfa_trc(port->fcs, cthdr->exp_code);
908 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
909}
910
911/**
912* Register FC4-Features : Should be done after RFT_ID
913 */
914static void
915bfa_fcs_port_ns_send_rff_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
916{
917 struct bfa_fcs_port_ns_s *ns = ns_cbarg;
918 struct bfa_fcs_port_s *port = ns->port;
919 struct fchs_s fchs;
920 int len;
921 struct bfa_fcxp_s *fcxp;
922 u8 fc4_ftrs = 0;
923
924 bfa_trc(port->fcs, port->port_cfg.pwwn);
925
926 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
927 if (!fcxp) {
928 port->stats.ns_rffid_alloc_wait++;
929 bfa_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
930 bfa_fcs_port_ns_send_rff_id, ns);
931 return;
932 }
933 ns->fcxp = fcxp;
934
935 if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port)) {
936 fc4_ftrs = FC_GS_FCP_FC4_FEATURE_INITIATOR;
937 } else if (BFA_FCS_VPORT_IS_TARGET_MODE(ns->port)) {
938 fc4_ftrs = FC_GS_FCP_FC4_FEATURE_TARGET;
939 }
940
941 len = fc_rffid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
942 bfa_fcs_port_get_fcid(port), 0, FC_TYPE_FCP,
943 fc4_ftrs);
944
945 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
946 FC_CLASS_3, len, &fchs, bfa_fcs_port_ns_rff_id_response,
947 (void *)ns, FC_MAX_PDUSZ, FC_RA_TOV);
948
949 port->stats.ns_rffid_sent++;
950 bfa_sm_send_event(ns, NSSM_EVENT_RFFID_SENT);
951}
952
953static void
954bfa_fcs_port_ns_rff_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
955 void *cbarg, bfa_status_t req_status,
956 u32 rsp_len, u32 resid_len,
957 struct fchs_s *rsp_fchs)
958{
959 struct bfa_fcs_port_ns_s *ns = (struct bfa_fcs_port_ns_s *)cbarg;
960 struct bfa_fcs_port_s *port = ns->port;
961 struct ct_hdr_s *cthdr = NULL;
962
963 bfa_trc(port->fcs, port->port_cfg.pwwn);
964
965 /*
966 * Sanity Checks
967 */
968 if (req_status != BFA_STATUS_OK) {
969 bfa_trc(port->fcs, req_status);
970 port->stats.ns_rffid_rsp_err++;
971 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
972 return;
973 }
974
975 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
976 cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
977
978 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
979 port->stats.ns_rffid_accepts++;
980 bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
981 return;
982 }
983
984 port->stats.ns_rffid_rejects++;
985 bfa_trc(port->fcs, cthdr->reason_code);
986 bfa_trc(port->fcs, cthdr->exp_code);
987
988 if (cthdr->reason_code == CT_RSN_NOT_SUPP) {
989 /*
990 * if this command is not supported, we don't retry
991 */
992 bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
993 } else {
994 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
995 }
996}
997
998/**
999 * Query Fabric for FC4-Types Devices.
1000 *
1001* TBD : Need to use a local (FCS private) response buffer, since the response
1002 * can be larger than 2K.
1003 */
1004static void
1005bfa_fcs_port_ns_send_gid_ft(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1006{
1007 struct bfa_fcs_port_ns_s *ns = ns_cbarg;
1008 struct bfa_fcs_port_s *port = ns->port;
1009 struct fchs_s fchs;
1010 int len;
1011 struct bfa_fcxp_s *fcxp;
1012
1013 bfa_trc(port->fcs, port->pid);
1014
1015 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
1016 if (!fcxp) {
1017 port->stats.ns_gidft_alloc_wait++;
1018 bfa_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe,
1019 bfa_fcs_port_ns_send_gid_ft, ns);
1020 return;
1021 }
1022 ns->fcxp = fcxp;
1023
1024 /*
1025 * This query is only initiated for FCP initiator mode.
1026 */
1027 len = fc_gid_ft_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), ns->port->pid,
1028 FC_TYPE_FCP);
1029
1030 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1031 FC_CLASS_3, len, &fchs, bfa_fcs_port_ns_gid_ft_response,
1032 (void *)ns, bfa_fcxp_get_maxrsp(port->fcs->bfa),
1033 FC_RA_TOV);
1034
1035 port->stats.ns_gidft_sent++;
1036
1037 bfa_sm_send_event(ns, NSSM_EVENT_GIDFT_SENT);
1038}
1039
1040static void
1041bfa_fcs_port_ns_gid_ft_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
1042 void *cbarg, bfa_status_t req_status,
1043 u32 rsp_len, u32 resid_len,
1044 struct fchs_s *rsp_fchs)
1045{
1046 struct bfa_fcs_port_ns_s *ns = (struct bfa_fcs_port_ns_s *)cbarg;
1047 struct bfa_fcs_port_s *port = ns->port;
1048 struct ct_hdr_s *cthdr = NULL;
1049 u32 n_pids;
1050
1051 bfa_trc(port->fcs, port->port_cfg.pwwn);
1052
1053 /*
1054 * Sanity Checks
1055 */
1056 if (req_status != BFA_STATUS_OK) {
1057 bfa_trc(port->fcs, req_status);
1058 port->stats.ns_gidft_rsp_err++;
1059 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
1060 return;
1061 }
1062
1063 if (resid_len != 0) {
1064 /*
1065 * TBD : we will need to allocate a larger buffer & retry the
1066 * command
1067 */
1068 bfa_trc(port->fcs, rsp_len);
1069 bfa_trc(port->fcs, resid_len);
1070 return;
1071 }
1072
1073 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
1074 cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
1075
1076 switch (cthdr->cmd_rsp_code) {
1077
1078 case CT_RSP_ACCEPT:
1079
1080 port->stats.ns_gidft_accepts++;
1081 n_pids = (fc_get_ctresp_pyld_len(rsp_len) / sizeof(u32));
1082 bfa_trc(port->fcs, n_pids);
1083 bfa_fcs_port_ns_process_gidft_pids(port,
1084 (u32 *) (cthdr + 1),
1085 n_pids);
1086 bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
1087 break;
1088
1089 case CT_RSP_REJECT:
1090
1091 /*
1092 * Check the reason code & explanation.
1093 * There may not have been any FC4 devices in the fabric
1094 */
1095 port->stats.ns_gidft_rejects++;
1096 bfa_trc(port->fcs, cthdr->reason_code);
1097 bfa_trc(port->fcs, cthdr->exp_code);
1098
1099 if ((cthdr->reason_code == CT_RSN_UNABLE_TO_PERF)
1100 && (cthdr->exp_code == CT_NS_EXP_FT_NOT_REG)) {
1101
1102 bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK);
1103 } else {
1104 /*
1105 * for all other errors, retry
1106 */
1107 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
1108 }
1109 break;
1110
1111 default:
1112 port->stats.ns_gidft_unknown_rsp++;
1113 bfa_trc(port->fcs, cthdr->cmd_rsp_code);
1114 bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR);
1115 }
1116}
1117
1118/**
1119 * This routine will be called by bfa_timer on timer timeouts.
1120 *
1121 * param[in] port - pointer to bfa_fcs_port_t.
1122 *
1123 * return
1124 * void
1125 *
1126* Special Considerations:
1127 *
1128 * note
1129 */
1130static void
1131bfa_fcs_port_ns_timeout(void *arg)
1132{
1133 struct bfa_fcs_port_ns_s *ns = (struct bfa_fcs_port_ns_s *)arg;
1134
1135 ns->port->stats.ns_timeouts++;
1136 bfa_sm_send_event(ns, NSSM_EVENT_TIMEOUT);
1137}
1138
1139/*
1140 * Process the PID list in GID_FT response
1141 */
1142static void
1143bfa_fcs_port_ns_process_gidft_pids(struct bfa_fcs_port_s *port,
1144 u32 *pid_buf, u32 n_pids)
1145{
1146 struct fcgs_gidft_resp_s *gidft_entry;
1147 struct bfa_fcs_rport_s *rport;
1148 u32 ii;
1149
1150 for (ii = 0; ii < n_pids; ii++) {
1151 gidft_entry = (struct fcgs_gidft_resp_s *) &pid_buf[ii];
1152
1153 if (gidft_entry->pid == port->pid)
1154 continue;
1155
1156 /*
1157 * Check if this rport already exists
1158 */
1159 rport = bfa_fcs_port_get_rport_by_pid(port, gidft_entry->pid);
1160 if (rport == NULL) {
1161 /*
1162 * this is a new device. create rport
1163 */
1164 rport = bfa_fcs_rport_create(port, gidft_entry->pid);
1165 } else {
1166 /*
1167 * this rport already exists
1168 */
1169 bfa_fcs_rport_scn(rport);
1170 }
1171
1172 bfa_trc(port->fcs, gidft_entry->pid);
1173
1174 /*
1175 * if the last entry bit is set, bail out.
1176 */
1177 if (gidft_entry->last)
1178 return;
1179 }
1180}
1181
1182/**
1183 * fcs_ns_public FCS nameserver public interfaces
1184 */
1185
1186/*
1187 * Functions called by port/fab.
1188 * These will send relevant Events to the ns state machine.
1189 */
1190void
1191bfa_fcs_port_ns_init(struct bfa_fcs_port_s *port)
1192{
1193 struct bfa_fcs_port_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);
1194
1195 ns->port = port;
1196 bfa_sm_set_state(ns, bfa_fcs_port_ns_sm_offline);
1197}
1198
1199void
1200bfa_fcs_port_ns_offline(struct bfa_fcs_port_s *port)
1201{
1202 struct bfa_fcs_port_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);
1203
1204 ns->port = port;
1205 bfa_sm_send_event(ns, NSSM_EVENT_PORT_OFFLINE);
1206}
1207
1208void
1209bfa_fcs_port_ns_online(struct bfa_fcs_port_s *port)
1210{
1211 struct bfa_fcs_port_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);
1212
1213 ns->port = port;
1214 bfa_sm_send_event(ns, NSSM_EVENT_PORT_ONLINE);
1215}
1216
1217void
1218bfa_fcs_port_ns_query(struct bfa_fcs_port_s *port)
1219{
1220 struct bfa_fcs_port_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port);
1221
1222 bfa_trc(port->fcs, port->pid);
1223 bfa_sm_send_event(ns, NSSM_EVENT_NS_QUERY);
1224}
1225
1226static void
1227bfa_fcs_port_ns_boot_target_disc(struct bfa_fcs_port_s *port)
1228{
1229
1230 struct bfa_fcs_rport_s *rport;
1231 u8 nwwns;
1232 wwn_t *wwns;
1233 int ii;
1234
1235 bfa_iocfc_get_bootwwns(port->fcs->bfa, &nwwns, &wwns);
1236
1237 for (ii = 0; ii < nwwns; ++ii) {
1238 rport = bfa_fcs_rport_create_by_wwn(port, wwns[ii]);
1239 bfa_assert(rport);
1240 }
1241}
1242
1243
diff --git a/drivers/scsi/bfa/plog.c b/drivers/scsi/bfa/plog.c
new file mode 100644
index 000000000000..86af818d17bb
--- /dev/null
+++ b/drivers/scsi/bfa/plog.c
@@ -0,0 +1,184 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#include <bfa_os_inc.h>
19#include <cs/bfa_plog.h>
20#include <cs/bfa_debug.h>
21
22static int
23plkd_validate_logrec(struct bfa_plog_rec_s *pl_rec)
24{
25 if ((pl_rec->log_type != BFA_PL_LOG_TYPE_INT)
26 && (pl_rec->log_type != BFA_PL_LOG_TYPE_STRING))
27 return 1;
28
29 if ((pl_rec->log_type != BFA_PL_LOG_TYPE_INT)
30 && (pl_rec->log_num_ints > BFA_PL_INT_LOG_SZ))
31 return 1;
32
33 return 0;
34}
35
36static void
37bfa_plog_add(struct bfa_plog_s *plog, struct bfa_plog_rec_s *pl_rec)
38{
39 u16 tail;
40 struct bfa_plog_rec_s *pl_recp;
41
42 if (plog->plog_enabled == 0)
43 return;
44
45 if (plkd_validate_logrec(pl_rec)) {
46 bfa_assert(0);
47 return;
48 }
49
50 tail = plog->tail;
51
52 pl_recp = &(plog->plog_recs[tail]);
53
54 bfa_os_memcpy(pl_recp, pl_rec, sizeof(struct bfa_plog_rec_s));
55
56 pl_recp->tv = BFA_TRC_TS(plog);
57 BFA_PL_LOG_REC_INCR(plog->tail);
58
59 if (plog->head == plog->tail)
60 BFA_PL_LOG_REC_INCR(plog->head);
61}
62
63void
64bfa_plog_init(struct bfa_plog_s *plog)
65{
66 bfa_os_memset((char *)plog, 0, sizeof(struct bfa_plog_s));
67
68 bfa_os_memcpy(plog->plog_sig, BFA_PL_SIG_STR, BFA_PL_SIG_LEN);
69 plog->head = plog->tail = 0;
70 plog->plog_enabled = 1;
71}
72
73void
74bfa_plog_str(struct bfa_plog_s *plog, enum bfa_plog_mid mid,
75 enum bfa_plog_eid event,
76 u16 misc, char *log_str)
77{
78 struct bfa_plog_rec_s lp;
79
80 if (plog->plog_enabled) {
81 bfa_os_memset(&lp, 0, sizeof(struct bfa_plog_rec_s));
82 lp.mid = mid;
83 lp.eid = event;
84 lp.log_type = BFA_PL_LOG_TYPE_STRING;
85 lp.misc = misc;
86 strncpy(lp.log_entry.string_log, log_str,
87 BFA_PL_STRING_LOG_SZ - 1);
88 lp.log_entry.string_log[BFA_PL_STRING_LOG_SZ - 1] = '\0';
89 bfa_plog_add(plog, &lp);
90 }
91}
92
93void
94bfa_plog_intarr(struct bfa_plog_s *plog, enum bfa_plog_mid mid,
95 enum bfa_plog_eid event,
96 u16 misc, u32 *intarr, u32 num_ints)
97{
98 struct bfa_plog_rec_s lp;
99 u32 i;
100
101 if (num_ints > BFA_PL_INT_LOG_SZ)
102 num_ints = BFA_PL_INT_LOG_SZ;
103
104 if (plog->plog_enabled) {
105 bfa_os_memset(&lp, 0, sizeof(struct bfa_plog_rec_s));
106 lp.mid = mid;
107 lp.eid = event;
108 lp.log_type = BFA_PL_LOG_TYPE_INT;
109 lp.misc = misc;
110
111 for (i = 0; i < num_ints; i++)
112 bfa_os_assign(lp.log_entry.int_log[i],
113 intarr[i]);
114
115 lp.log_num_ints = (u8) num_ints;
116
117 bfa_plog_add(plog, &lp);
118 }
119}
120
121void
122bfa_plog_fchdr(struct bfa_plog_s *plog, enum bfa_plog_mid mid,
123 enum bfa_plog_eid event,
124 u16 misc, struct fchs_s *fchdr)
125{
126 struct bfa_plog_rec_s lp;
127 u32 *tmp_int = (u32 *) fchdr;
128 u32 ints[BFA_PL_INT_LOG_SZ];
129
130 if (plog->plog_enabled) {
131 bfa_os_memset(&lp, 0, sizeof(struct bfa_plog_rec_s));
132
133 ints[0] = tmp_int[0];
134 ints[1] = tmp_int[1];
135 ints[2] = tmp_int[4];
136
137 bfa_plog_intarr(plog, mid, event, misc, ints, 3);
138 }
139}
140
141void
142bfa_plog_fchdr_and_pl(struct bfa_plog_s *plog, enum bfa_plog_mid mid,
143 enum bfa_plog_eid event, u16 misc, struct fchs_s *fchdr,
144 u32 pld_w0)
145{
146 struct bfa_plog_rec_s lp;
147 u32 *tmp_int = (u32 *) fchdr;
148 u32 ints[BFA_PL_INT_LOG_SZ];
149
150 if (plog->plog_enabled) {
151 bfa_os_memset(&lp, 0, sizeof(struct bfa_plog_rec_s));
152
153 ints[0] = tmp_int[0];
154 ints[1] = tmp_int[1];
155 ints[2] = tmp_int[4];
156 ints[3] = pld_w0;
157
158 bfa_plog_intarr(plog, mid, event, misc, ints, 4);
159 }
160}
161
162void
163bfa_plog_clear(struct bfa_plog_s *plog)
164{
165 plog->head = plog->tail = 0;
166}
167
168void
169bfa_plog_enable(struct bfa_plog_s *plog)
170{
171 plog->plog_enabled = 1;
172}
173
174void
175bfa_plog_disable(struct bfa_plog_s *plog)
176{
177 plog->plog_enabled = 0;
178}
179
180bfa_boolean_t
181bfa_plog_get_setting(struct bfa_plog_s *plog)
182{
183 return((bfa_boolean_t)plog->plog_enabled);
184}
diff --git a/drivers/scsi/bfa/rport.c b/drivers/scsi/bfa/rport.c
new file mode 100644
index 000000000000..9cf58bb138dc
--- /dev/null
+++ b/drivers/scsi/bfa/rport.c
@@ -0,0 +1,2618 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * rport.c Remote port implementation.
20 */
21
22#include <bfa.h>
23#include <bfa_svc.h>
24#include "fcbuild.h"
25#include "fcs_vport.h"
26#include "fcs_lport.h"
27#include "fcs_rport.h"
28#include "fcs_fcpim.h"
29#include "fcs_fcptm.h"
30#include "fcs_trcmod.h"
31#include "fcs_fcxp.h"
32#include "fcs.h"
33#include <fcb/bfa_fcb_rport.h>
34#include <aen/bfa_aen_rport.h>
35
36BFA_TRC_FILE(FCS, RPORT);
37
38#define BFA_FCS_RPORT_MAX_RETRIES (5)
39
40/* In millisecs */
41static u32 bfa_fcs_rport_del_timeout =
42 BFA_FCS_RPORT_DEF_DEL_TIMEOUT * 1000;
43
44/*
45 * forward declarations
46 */
47static struct bfa_fcs_rport_s *bfa_fcs_rport_alloc(struct bfa_fcs_port_s *port,
48 wwn_t pwwn, u32 rpid);
49static void bfa_fcs_rport_free(struct bfa_fcs_rport_s *rport);
50static void bfa_fcs_rport_hal_online(struct bfa_fcs_rport_s *rport);
51static void bfa_fcs_rport_online_action(struct bfa_fcs_rport_s *rport);
52static void bfa_fcs_rport_offline_action(struct bfa_fcs_rport_s *rport);
53static void bfa_fcs_rport_update(struct bfa_fcs_rport_s *rport,
54 struct fc_logi_s *plogi);
55static void bfa_fcs_rport_fc4_pause(struct bfa_fcs_rport_s *rport);
56static void bfa_fcs_rport_fc4_resume(struct bfa_fcs_rport_s *rport);
57static void bfa_fcs_rport_timeout(void *arg);
58static void bfa_fcs_rport_send_plogi(void *rport_cbarg,
59 struct bfa_fcxp_s *fcxp_alloced);
60static void bfa_fcs_rport_send_plogiacc(void *rport_cbarg,
61 struct bfa_fcxp_s *fcxp_alloced);
62static void bfa_fcs_rport_plogi_response(void *fcsarg,
63 struct bfa_fcxp_s *fcxp,
64 void *cbarg,
65 bfa_status_t req_status,
66 u32 rsp_len,
67 u32 resid_len,
68 struct fchs_s *rsp_fchs);
69static void bfa_fcs_rport_send_adisc(void *rport_cbarg,
70 struct bfa_fcxp_s *fcxp_alloced);
71static void bfa_fcs_rport_adisc_response(void *fcsarg,
72 struct bfa_fcxp_s *fcxp,
73 void *cbarg,
74 bfa_status_t req_status,
75 u32 rsp_len,
76 u32 resid_len,
77 struct fchs_s *rsp_fchs);
78static void bfa_fcs_rport_send_gidpn(void *rport_cbarg,
79 struct bfa_fcxp_s *fcxp_alloced);
80static void bfa_fcs_rport_gidpn_response(void *fcsarg,
81 struct bfa_fcxp_s *fcxp,
82 void *cbarg,
83 bfa_status_t req_status,
84 u32 rsp_len,
85 u32 resid_len,
86 struct fchs_s *rsp_fchs);
87static void bfa_fcs_rport_send_logo(void *rport_cbarg,
88 struct bfa_fcxp_s *fcxp_alloced);
89static void bfa_fcs_rport_send_logo_acc(void *rport_cbarg);
90static void bfa_fcs_rport_process_prli(struct bfa_fcs_rport_s *rport,
91 struct fchs_s *rx_fchs, u16 len);
92static void bfa_fcs_rport_send_ls_rjt(struct bfa_fcs_rport_s *rport,
93 struct fchs_s *rx_fchs, u8 reason_code,
94 u8 reason_code_expl);
95static void bfa_fcs_rport_process_adisc(struct bfa_fcs_rport_s *rport,
96 struct fchs_s *rx_fchs, u16 len);
97/**
98 * fcs_rport_sm FCS rport state machine events
99 */
100
101enum rport_event {
102 RPSM_EVENT_PLOGI_SEND = 1, /* new rport; start with PLOGI */
103 RPSM_EVENT_PLOGI_RCVD = 2, /* Inbound PLOGI from remote port */
104 RPSM_EVENT_PLOGI_COMP = 3, /* PLOGI completed to rport */
105 RPSM_EVENT_LOGO_RCVD = 4, /* LOGO from remote device */
106 RPSM_EVENT_LOGO_IMP = 5, /* implicit logo for SLER */
107 RPSM_EVENT_FCXP_SENT = 6, /* Frame from has been sent */
108 RPSM_EVENT_DELETE = 7, /* RPORT delete request */
109 RPSM_EVENT_SCN = 8, /* state change notification */
110 RPSM_EVENT_ACCEPTED = 9,/* Good response from remote device */
111 RPSM_EVENT_FAILED = 10, /* Request to rport failed. */
112 RPSM_EVENT_TIMEOUT = 11, /* Rport SM timeout event */
113 RPSM_EVENT_HCB_ONLINE = 12, /* BFA rport online callback */
114 RPSM_EVENT_HCB_OFFLINE = 13, /* BFA rport offline callback */
115 RPSM_EVENT_FC4_OFFLINE = 14, /* FC-4 offline complete */
116 RPSM_EVENT_ADDRESS_CHANGE = 15, /* Rport's PID has changed */
117 RPSM_EVENT_ADDRESS_DISC = 16 /* Need to Discover rport's PID */
118};
119
120static void bfa_fcs_rport_sm_uninit(struct bfa_fcs_rport_s *rport,
121 enum rport_event event);
122static void bfa_fcs_rport_sm_plogi_sending(struct bfa_fcs_rport_s *rport,
123 enum rport_event event);
124static void bfa_fcs_rport_sm_plogiacc_sending(struct bfa_fcs_rport_s *rport,
125 enum rport_event event);
126static void bfa_fcs_rport_sm_plogi_retry(struct bfa_fcs_rport_s *rport,
127 enum rport_event event);
128static void bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport,
129 enum rport_event event);
130static void bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport,
131 enum rport_event event);
132static void bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s *rport,
133 enum rport_event event);
134static void bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s *rport,
135 enum rport_event event);
136static void bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport,
137 enum rport_event event);
138static void bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport,
139 enum rport_event event);
140static void bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport,
141 enum rport_event event);
142static void bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport,
143 enum rport_event event);
144static void bfa_fcs_rport_sm_fc4_logosend(struct bfa_fcs_rport_s *rport,
145 enum rport_event event);
146static void bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s *rport,
147 enum rport_event event);
148static void bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport,
149 enum rport_event event);
150static void bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s *rport,
151 enum rport_event event);
152static void bfa_fcs_rport_sm_hcb_logosend(struct bfa_fcs_rport_s *rport,
153 enum rport_event event);
154static void bfa_fcs_rport_sm_logo_sending(struct bfa_fcs_rport_s *rport,
155 enum rport_event event);
156static void bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s *rport,
157 enum rport_event event);
158static void bfa_fcs_rport_sm_nsdisc_sending(struct bfa_fcs_rport_s *rport,
159 enum rport_event event);
160static void bfa_fcs_rport_sm_nsdisc_retry(struct bfa_fcs_rport_s *rport,
161 enum rport_event event);
162static void bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
163 enum rport_event event);
164static void bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
165 enum rport_event event);
166
167static struct bfa_sm_table_s rport_sm_table[] = {
168 {BFA_SM(bfa_fcs_rport_sm_uninit), BFA_RPORT_UNINIT},
169 {BFA_SM(bfa_fcs_rport_sm_plogi_sending), BFA_RPORT_PLOGI},
170 {BFA_SM(bfa_fcs_rport_sm_plogiacc_sending), BFA_RPORT_ONLINE},
171 {BFA_SM(bfa_fcs_rport_sm_plogi_retry), BFA_RPORT_PLOGI_RETRY},
172 {BFA_SM(bfa_fcs_rport_sm_plogi), BFA_RPORT_PLOGI},
173 {BFA_SM(bfa_fcs_rport_sm_hal_online), BFA_RPORT_ONLINE},
174 {BFA_SM(bfa_fcs_rport_sm_online), BFA_RPORT_ONLINE},
175 {BFA_SM(bfa_fcs_rport_sm_nsquery_sending), BFA_RPORT_NSQUERY},
176 {BFA_SM(bfa_fcs_rport_sm_nsquery), BFA_RPORT_NSQUERY},
177 {BFA_SM(bfa_fcs_rport_sm_adisc_sending), BFA_RPORT_ADISC},
178 {BFA_SM(bfa_fcs_rport_sm_adisc), BFA_RPORT_ADISC},
179 {BFA_SM(bfa_fcs_rport_sm_fc4_logorcv), BFA_RPORT_LOGORCV},
180 {BFA_SM(bfa_fcs_rport_sm_fc4_logosend), BFA_RPORT_LOGO},
181 {BFA_SM(bfa_fcs_rport_sm_fc4_offline), BFA_RPORT_OFFLINE},
182 {BFA_SM(bfa_fcs_rport_sm_hcb_offline), BFA_RPORT_OFFLINE},
183 {BFA_SM(bfa_fcs_rport_sm_hcb_logorcv), BFA_RPORT_LOGORCV},
184 {BFA_SM(bfa_fcs_rport_sm_hcb_logosend), BFA_RPORT_LOGO},
185 {BFA_SM(bfa_fcs_rport_sm_logo_sending), BFA_RPORT_LOGO},
186 {BFA_SM(bfa_fcs_rport_sm_offline), BFA_RPORT_OFFLINE},
187 {BFA_SM(bfa_fcs_rport_sm_nsdisc_sending), BFA_RPORT_NSDISC},
188 {BFA_SM(bfa_fcs_rport_sm_nsdisc_retry), BFA_RPORT_NSDISC},
189 {BFA_SM(bfa_fcs_rport_sm_nsdisc_sent), BFA_RPORT_NSDISC},
190};
191
192/**
193 * Beginning state.
194 */
195static void
196bfa_fcs_rport_sm_uninit(struct bfa_fcs_rport_s *rport, enum rport_event event)
197{
198 bfa_trc(rport->fcs, rport->pwwn);
199 bfa_trc(rport->fcs, rport->pid);
200 bfa_trc(rport->fcs, event);
201
202 switch (event) {
203 case RPSM_EVENT_PLOGI_SEND:
204 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
205 rport->plogi_retries = 0;
206 bfa_fcs_rport_send_plogi(rport, NULL);
207 break;
208
209 case RPSM_EVENT_PLOGI_RCVD:
210 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
211 bfa_fcs_rport_send_plogiacc(rport, NULL);
212 break;
213
214 case RPSM_EVENT_PLOGI_COMP:
215 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
216 bfa_fcs_rport_hal_online(rport);
217 break;
218
219 case RPSM_EVENT_ADDRESS_CHANGE:
220 case RPSM_EVENT_ADDRESS_DISC:
221 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
222 rport->ns_retries = 0;
223 bfa_fcs_rport_send_gidpn(rport, NULL);
224 break;
225
226 default:
227 bfa_assert(0);
228 }
229}
230
231/**
232 * PLOGI is being sent.
233 */
234static void
235bfa_fcs_rport_sm_plogi_sending(struct bfa_fcs_rport_s *rport,
236 enum rport_event event)
237{
238 bfa_trc(rport->fcs, rport->pwwn);
239 bfa_trc(rport->fcs, rport->pid);
240 bfa_trc(rport->fcs, event);
241
242 switch (event) {
243 case RPSM_EVENT_FCXP_SENT:
244 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi);
245 break;
246
247 case RPSM_EVENT_DELETE:
248 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
249 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
250 bfa_fcs_rport_free(rport);
251 break;
252
253 case RPSM_EVENT_PLOGI_RCVD:
254 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
255 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
256 bfa_fcs_rport_send_plogiacc(rport, NULL);
257 break;
258
259 case RPSM_EVENT_ADDRESS_CHANGE:
260 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
261 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
262 rport->ns_retries = 0;
263 bfa_fcs_rport_send_gidpn(rport, NULL);
264 break;
265
266 case RPSM_EVENT_LOGO_IMP:
267 rport->pid = 0;
268 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
269 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
270 bfa_timer_start(rport->fcs->bfa, &rport->timer,
271 bfa_fcs_rport_timeout, rport,
272 bfa_fcs_rport_del_timeout);
273 break;
274
275 case RPSM_EVENT_SCN:
276 break;
277
278 default:
279 bfa_assert(0);
280 }
281}
282
283/**
284 * PLOGI is being sent.
285 */
286static void
287bfa_fcs_rport_sm_plogiacc_sending(struct bfa_fcs_rport_s *rport,
288 enum rport_event event)
289{
290 bfa_trc(rport->fcs, rport->pwwn);
291 bfa_trc(rport->fcs, rport->pid);
292 bfa_trc(rport->fcs, event);
293
294 switch (event) {
295 case RPSM_EVENT_FCXP_SENT:
296 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
297 bfa_fcs_rport_hal_online(rport);
298 break;
299
300 case RPSM_EVENT_DELETE:
301 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
302 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
303 bfa_fcs_rport_free(rport);
304 break;
305
306 case RPSM_EVENT_SCN:
307 /**
308 * Ignore, SCN is possibly online notification.
309 */
310 break;
311
312 case RPSM_EVENT_ADDRESS_CHANGE:
313 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
314 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
315 rport->ns_retries = 0;
316 bfa_fcs_rport_send_gidpn(rport, NULL);
317 break;
318
319 case RPSM_EVENT_LOGO_IMP:
320 rport->pid = 0;
321 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
322 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
323 bfa_timer_start(rport->fcs->bfa, &rport->timer,
324 bfa_fcs_rport_timeout, rport,
325 bfa_fcs_rport_del_timeout);
326 break;
327
328 case RPSM_EVENT_HCB_OFFLINE:
329 /**
330 * Ignore BFA callback, on a PLOGI receive we call bfa offline.
331 */
332 break;
333
334 default:
335 bfa_assert(0);
336 }
337}
338
339/**
340 * PLOGI is sent.
341 */
342static void
343bfa_fcs_rport_sm_plogi_retry(struct bfa_fcs_rport_s *rport,
344 enum rport_event event)
345{
346 bfa_trc(rport->fcs, rport->pwwn);
347 bfa_trc(rport->fcs, rport->pid);
348 bfa_trc(rport->fcs, event);
349
350 switch (event) {
351 case RPSM_EVENT_SCN:
352 bfa_timer_stop(&rport->timer);
353 /*
354 * !! fall through !!
355 */
356
357 case RPSM_EVENT_TIMEOUT:
358 rport->plogi_retries++;
359 if (rport->plogi_retries < BFA_FCS_RPORT_MAX_RETRIES) {
360 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
361 bfa_fcs_rport_send_plogi(rport, NULL);
362 } else {
363 rport->pid = 0;
364 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
365 bfa_timer_start(rport->fcs->bfa, &rport->timer,
366 bfa_fcs_rport_timeout, rport,
367 bfa_fcs_rport_del_timeout);
368 }
369 break;
370
371 case RPSM_EVENT_DELETE:
372 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
373 bfa_timer_stop(&rport->timer);
374 bfa_fcs_rport_free(rport);
375 break;
376
377 case RPSM_EVENT_LOGO_RCVD:
378 break;
379
380 case RPSM_EVENT_PLOGI_RCVD:
381 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
382 bfa_timer_stop(&rport->timer);
383 bfa_fcs_rport_send_plogiacc(rport, NULL);
384 break;
385
386 case RPSM_EVENT_ADDRESS_CHANGE:
387 bfa_timer_stop(&rport->timer);
388 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
389 rport->ns_retries = 0;
390 bfa_fcs_rport_send_gidpn(rport, NULL);
391 break;
392
393 case RPSM_EVENT_LOGO_IMP:
394 rport->pid = 0;
395 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
396 bfa_timer_stop(&rport->timer);
397 bfa_timer_start(rport->fcs->bfa, &rport->timer,
398 bfa_fcs_rport_timeout, rport,
399 bfa_fcs_rport_del_timeout);
400 break;
401
402 case RPSM_EVENT_PLOGI_COMP:
403 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
404 bfa_timer_stop(&rport->timer);
405 bfa_fcs_rport_hal_online(rport);
406 break;
407
408 default:
409 bfa_assert(0);
410 }
411}
412
413/**
414 * PLOGI is sent.
415 */
416static void
417bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport, enum rport_event event)
418{
419 bfa_trc(rport->fcs, rport->pwwn);
420 bfa_trc(rport->fcs, rport->pid);
421 bfa_trc(rport->fcs, event);
422
423 switch (event) {
424 case RPSM_EVENT_ACCEPTED:
425 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
426 rport->plogi_retries = 0;
427 bfa_fcs_rport_hal_online(rport);
428 break;
429
430 case RPSM_EVENT_LOGO_RCVD:
431 bfa_fcs_rport_send_logo_acc(rport);
432 bfa_fcxp_discard(rport->fcxp);
433 /*
434 * !! fall through !!
435 */
436 case RPSM_EVENT_FAILED:
437 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_retry);
438 bfa_timer_start(rport->fcs->bfa, &rport->timer,
439 bfa_fcs_rport_timeout, rport,
440 BFA_FCS_RETRY_TIMEOUT);
441 break;
442
443 case RPSM_EVENT_LOGO_IMP:
444 rport->pid = 0;
445 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
446 bfa_fcxp_discard(rport->fcxp);
447 bfa_timer_start(rport->fcs->bfa, &rport->timer,
448 bfa_fcs_rport_timeout, rport,
449 bfa_fcs_rport_del_timeout);
450 break;
451
452 case RPSM_EVENT_ADDRESS_CHANGE:
453 bfa_fcxp_discard(rport->fcxp);
454 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
455 rport->ns_retries = 0;
456 bfa_fcs_rport_send_gidpn(rport, NULL);
457 break;
458
459 case RPSM_EVENT_PLOGI_RCVD:
460 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
461 bfa_fcxp_discard(rport->fcxp);
462 bfa_fcs_rport_send_plogiacc(rport, NULL);
463 break;
464
465 case RPSM_EVENT_SCN:
466 /**
467 * Ignore SCN - wait for PLOGI response.
468 */
469 break;
470
471 case RPSM_EVENT_DELETE:
472 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
473 bfa_fcxp_discard(rport->fcxp);
474 bfa_fcs_rport_free(rport);
475 break;
476
477 case RPSM_EVENT_PLOGI_COMP:
478 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
479 bfa_fcxp_discard(rport->fcxp);
480 bfa_fcs_rport_hal_online(rport);
481 break;
482
483 default:
484 bfa_assert(0);
485 }
486}
487
488/**
489 * PLOGI is complete. Awaiting BFA rport online callback. FC-4s
490 * are offline.
491 */
492static void
493bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport,
494 enum rport_event event)
495{
496 bfa_trc(rport->fcs, rport->pwwn);
497 bfa_trc(rport->fcs, rport->pid);
498 bfa_trc(rport->fcs, event);
499
500 switch (event) {
501 case RPSM_EVENT_HCB_ONLINE:
502 bfa_sm_set_state(rport, bfa_fcs_rport_sm_online);
503 bfa_fcs_rport_online_action(rport);
504 break;
505
506 case RPSM_EVENT_LOGO_RCVD:
507 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logorcv);
508 bfa_rport_offline(rport->bfa_rport);
509 break;
510
511 case RPSM_EVENT_LOGO_IMP:
512 case RPSM_EVENT_ADDRESS_CHANGE:
513 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline);
514 bfa_rport_offline(rport->bfa_rport);
515 break;
516
517 case RPSM_EVENT_PLOGI_RCVD:
518 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
519 bfa_rport_offline(rport->bfa_rport);
520 bfa_fcs_rport_send_plogiacc(rport, NULL);
521 break;
522
523 case RPSM_EVENT_DELETE:
524 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logosend);
525 bfa_rport_offline(rport->bfa_rport);
526 break;
527
528 case RPSM_EVENT_SCN:
529 /**
530 * @todo
531 * Ignore SCN - PLOGI just completed, FC-4 login should detect
532 * device failures.
533 */
534 break;
535
536 default:
537 bfa_assert(0);
538 }
539}
540
541/**
542 * Rport is ONLINE. FC-4s active.
543 */
544static void
545bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s *rport, enum rport_event event)
546{
547 bfa_trc(rport->fcs, rport->pwwn);
548 bfa_trc(rport->fcs, rport->pid);
549 bfa_trc(rport->fcs, event);
550
551 switch (event) {
552 case RPSM_EVENT_SCN:
553 /**
554 * Pause FC-4 activity till rport is authenticated.
555 * In switched fabrics, check presence of device in nameserver
556 * first.
557 */
558 bfa_fcs_rport_fc4_pause(rport);
559
560 if (bfa_fcs_fabric_is_switched(rport->port->fabric)) {
561 bfa_sm_set_state(rport,
562 bfa_fcs_rport_sm_nsquery_sending);
563 rport->ns_retries = 0;
564 bfa_fcs_rport_send_gidpn(rport, NULL);
565 } else {
566 bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_sending);
567 bfa_fcs_rport_send_adisc(rport, NULL);
568 }
569 break;
570
571 case RPSM_EVENT_PLOGI_RCVD:
572 case RPSM_EVENT_LOGO_IMP:
573 case RPSM_EVENT_ADDRESS_CHANGE:
574 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
575 bfa_fcs_rport_offline_action(rport);
576 break;
577
578 case RPSM_EVENT_DELETE:
579 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
580 bfa_fcs_rport_offline_action(rport);
581 break;
582
583 case RPSM_EVENT_LOGO_RCVD:
584 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
585 bfa_fcs_rport_offline_action(rport);
586 break;
587
588 case RPSM_EVENT_PLOGI_COMP:
589 break;
590
591 default:
592 bfa_assert(0);
593 }
594}
595
596/**
597 * An SCN event is received in ONLINE state. NS query is being sent
598 * prior to ADISC authentication with rport. FC-4s are paused.
599 */
600static void
601bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s *rport,
602 enum rport_event event)
603{
604 bfa_trc(rport->fcs, rport->pwwn);
605 bfa_trc(rport->fcs, rport->pid);
606 bfa_trc(rport->fcs, event);
607
608 switch (event) {
609 case RPSM_EVENT_FCXP_SENT:
610 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsquery);
611 break;
612
613 case RPSM_EVENT_DELETE:
614 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
615 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
616 bfa_fcs_rport_offline_action(rport);
617 break;
618
619 case RPSM_EVENT_SCN:
620 /**
621 * ignore SCN, wait for response to query itself
622 */
623 break;
624
625 case RPSM_EVENT_LOGO_RCVD:
626 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
627 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
628 bfa_fcs_rport_offline_action(rport);
629 break;
630
631 case RPSM_EVENT_LOGO_IMP:
632 rport->pid = 0;
633 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
634 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
635 bfa_timer_start(rport->fcs->bfa, &rport->timer,
636 bfa_fcs_rport_timeout, rport,
637 bfa_fcs_rport_del_timeout);
638 break;
639
640 case RPSM_EVENT_PLOGI_RCVD:
641 case RPSM_EVENT_ADDRESS_CHANGE:
642 case RPSM_EVENT_PLOGI_COMP:
643 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
644 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
645 bfa_fcs_rport_offline_action(rport);
646 break;
647
648 default:
649 bfa_assert(0);
650 }
651}
652
653/**
654 * An SCN event is received in ONLINE state. NS query is sent to rport.
655 * FC-4s are paused.
656 */
657static void
658bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport, enum rport_event event)
659{
660 bfa_trc(rport->fcs, rport->pwwn);
661 bfa_trc(rport->fcs, rport->pid);
662 bfa_trc(rport->fcs, event);
663
664 switch (event) {
665 case RPSM_EVENT_ACCEPTED:
666 bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_sending);
667 bfa_fcs_rport_send_adisc(rport, NULL);
668 break;
669
670 case RPSM_EVENT_FAILED:
671 rport->ns_retries++;
672 if (rport->ns_retries < BFA_FCS_RPORT_MAX_RETRIES) {
673 bfa_sm_set_state(rport,
674 bfa_fcs_rport_sm_nsquery_sending);
675 bfa_fcs_rport_send_gidpn(rport, NULL);
676 } else {
677 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
678 bfa_fcs_rport_offline_action(rport);
679 }
680 break;
681
682 case RPSM_EVENT_DELETE:
683 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
684 bfa_fcxp_discard(rport->fcxp);
685 bfa_fcs_rport_offline_action(rport);
686 break;
687
688 case RPSM_EVENT_SCN:
689 break;
690
691 case RPSM_EVENT_LOGO_RCVD:
692 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
693 bfa_fcxp_discard(rport->fcxp);
694 bfa_fcs_rport_offline_action(rport);
695 break;
696
697 case RPSM_EVENT_PLOGI_COMP:
698 case RPSM_EVENT_ADDRESS_CHANGE:
699 case RPSM_EVENT_PLOGI_RCVD:
700 case RPSM_EVENT_LOGO_IMP:
701 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
702 bfa_fcxp_discard(rport->fcxp);
703 bfa_fcs_rport_offline_action(rport);
704 break;
705
706 default:
707 bfa_assert(0);
708 }
709}
710
711/**
712 * An SCN event is received in ONLINE state. ADISC is being sent for
713 * authenticating with rport. FC-4s are paused.
714 */
715static void
716bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport,
717 enum rport_event event)
718{
719 bfa_trc(rport->fcs, rport->pwwn);
720 bfa_trc(rport->fcs, rport->pid);
721 bfa_trc(rport->fcs, event);
722
723 switch (event) {
724 case RPSM_EVENT_FCXP_SENT:
725 bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc);
726 break;
727
728 case RPSM_EVENT_DELETE:
729 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
730 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
731 bfa_fcs_rport_offline_action(rport);
732 break;
733
734 case RPSM_EVENT_LOGO_IMP:
735 case RPSM_EVENT_ADDRESS_CHANGE:
736 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
737 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
738 bfa_fcs_rport_offline_action(rport);
739 break;
740
741 case RPSM_EVENT_LOGO_RCVD:
742 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
743 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
744 bfa_fcs_rport_offline_action(rport);
745 break;
746
747 case RPSM_EVENT_SCN:
748 break;
749
750 case RPSM_EVENT_PLOGI_RCVD:
751 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
752 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
753 bfa_fcs_rport_offline_action(rport);
754 break;
755
756 default:
757 bfa_assert(0);
758 }
759}
760
761/**
762 * An SCN event is received in ONLINE state. ADISC is to rport.
763 * FC-4s are paused.
764 */
765static void
766bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport, enum rport_event event)
767{
768 bfa_trc(rport->fcs, rport->pwwn);
769 bfa_trc(rport->fcs, rport->pid);
770 bfa_trc(rport->fcs, event);
771
772 switch (event) {
773 case RPSM_EVENT_ACCEPTED:
774 bfa_sm_set_state(rport, bfa_fcs_rport_sm_online);
775 bfa_fcs_rport_fc4_resume(rport);
776 break;
777
778 case RPSM_EVENT_PLOGI_RCVD:
779 /**
780 * Too complex to cleanup FC-4 & rport and then acc to PLOGI.
781 * At least go offline when a PLOGI is received.
782 */
783 bfa_fcxp_discard(rport->fcxp);
784 /*
785 * !!! fall through !!!
786 */
787
788 case RPSM_EVENT_FAILED:
789 case RPSM_EVENT_ADDRESS_CHANGE:
790 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
791 bfa_fcs_rport_offline_action(rport);
792 break;
793
794 case RPSM_EVENT_DELETE:
795 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
796 bfa_fcxp_discard(rport->fcxp);
797 bfa_fcs_rport_offline_action(rport);
798 break;
799
800 case RPSM_EVENT_SCN:
801 /**
802 * already processing RSCN
803 */
804 break;
805
806 case RPSM_EVENT_LOGO_IMP:
807 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
808 bfa_fcxp_discard(rport->fcxp);
809 bfa_fcs_rport_offline_action(rport);
810 break;
811
812 case RPSM_EVENT_LOGO_RCVD:
813 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
814 bfa_fcxp_discard(rport->fcxp);
815 bfa_fcs_rport_offline_action(rport);
816 break;
817
818 default:
819 bfa_assert(0);
820 }
821}
822
823/**
824 * Rport has sent LOGO. Awaiting FC-4 offline completion callback.
825 */
826static void
827bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport,
828 enum rport_event event)
829{
830 bfa_trc(rport->fcs, rport->pwwn);
831 bfa_trc(rport->fcs, rport->pid);
832 bfa_trc(rport->fcs, event);
833
834 switch (event) {
835 case RPSM_EVENT_FC4_OFFLINE:
836 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logorcv);
837 bfa_rport_offline(rport->bfa_rport);
838 break;
839
840 case RPSM_EVENT_DELETE:
841 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
842 break;
843
844 case RPSM_EVENT_LOGO_RCVD:
845 case RPSM_EVENT_ADDRESS_CHANGE:
846 break;
847
848 default:
849 bfa_assert(0);
850 }
851}
852
853/**
854 * LOGO needs to be sent to rport. Awaiting FC-4 offline completion
855 * callback.
856 */
857static void
858bfa_fcs_rport_sm_fc4_logosend(struct bfa_fcs_rport_s *rport,
859 enum rport_event event)
860{
861 bfa_trc(rport->fcs, rport->pwwn);
862 bfa_trc(rport->fcs, rport->pid);
863 bfa_trc(rport->fcs, event);
864
865 switch (event) {
866 case RPSM_EVENT_FC4_OFFLINE:
867 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logosend);
868 bfa_rport_offline(rport->bfa_rport);
869 break;
870
871 default:
872 bfa_assert(0);
873 }
874}
875
876/**
877 * Rport is going offline. Awaiting FC-4 offline completion callback.
878 */
879static void
880bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s *rport,
881 enum rport_event event)
882{
883 bfa_trc(rport->fcs, rport->pwwn);
884 bfa_trc(rport->fcs, rport->pid);
885 bfa_trc(rport->fcs, event);
886
887 switch (event) {
888 case RPSM_EVENT_FC4_OFFLINE:
889 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline);
890 bfa_rport_offline(rport->bfa_rport);
891 break;
892
893 case RPSM_EVENT_SCN:
894 case RPSM_EVENT_LOGO_IMP:
895 case RPSM_EVENT_LOGO_RCVD:
896 case RPSM_EVENT_ADDRESS_CHANGE:
897 /**
898 * rport is already going offline.
899 * SCN - ignore and wait till transitioning to offline state
900 */
901 break;
902
903 case RPSM_EVENT_DELETE:
904 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
905 break;
906
907 default:
908 bfa_assert(0);
909 }
910}
911
912/**
913 * Rport is offline. FC-4s are offline. Awaiting BFA rport offline
914 * callback.
915 */
916static void
917bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport,
918 enum rport_event event)
919{
920 bfa_trc(rport->fcs, rport->pwwn);
921 bfa_trc(rport->fcs, rport->pid);
922 bfa_trc(rport->fcs, event);
923
924 switch (event) {
925 case RPSM_EVENT_HCB_OFFLINE:
926 case RPSM_EVENT_ADDRESS_CHANGE:
927 if (bfa_fcs_port_is_online(rport->port)) {
928 bfa_sm_set_state(rport,
929 bfa_fcs_rport_sm_nsdisc_sending);
930 rport->ns_retries = 0;
931 bfa_fcs_rport_send_gidpn(rport, NULL);
932 } else {
933 rport->pid = 0;
934 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
935 bfa_timer_start(rport->fcs->bfa, &rport->timer,
936 bfa_fcs_rport_timeout, rport,
937 bfa_fcs_rport_del_timeout);
938 }
939 break;
940
941 case RPSM_EVENT_DELETE:
942 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
943 bfa_fcs_rport_free(rport);
944 break;
945
946 case RPSM_EVENT_SCN:
947 case RPSM_EVENT_LOGO_RCVD:
948 /**
949 * Ignore, already offline.
950 */
951 break;
952
953 default:
954 bfa_assert(0);
955 }
956}
957
958/**
959 * Rport is offline. FC-4s are offline. Awaiting BFA rport offline
960 * callback to send LOGO accept.
961 */
962static void
963bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s *rport,
964 enum rport_event event)
965{
966 bfa_trc(rport->fcs, rport->pwwn);
967 bfa_trc(rport->fcs, rport->pid);
968 bfa_trc(rport->fcs, event);
969
970 switch (event) {
971 case RPSM_EVENT_HCB_OFFLINE:
972 case RPSM_EVENT_ADDRESS_CHANGE:
973 if (rport->pid)
974 bfa_fcs_rport_send_logo_acc(rport);
975 /*
976 * If the lport is online and if the rport is not a well known
977 * address port, we try to re-discover the r-port.
978 */
979 if (bfa_fcs_port_is_online(rport->port)
980 && (!BFA_FCS_PID_IS_WKA(rport->pid))) {
981 bfa_sm_set_state(rport,
982 bfa_fcs_rport_sm_nsdisc_sending);
983 rport->ns_retries = 0;
984 bfa_fcs_rport_send_gidpn(rport, NULL);
985 } else {
986 /*
987 * if it is not a well known address, reset the pid to
988 *
989 */
990 if (!BFA_FCS_PID_IS_WKA(rport->pid))
991 rport->pid = 0;
992 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
993 bfa_timer_start(rport->fcs->bfa, &rport->timer,
994 bfa_fcs_rport_timeout, rport,
995 bfa_fcs_rport_del_timeout);
996 }
997 break;
998
999 case RPSM_EVENT_DELETE:
1000 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logosend);
1001 break;
1002
1003 case RPSM_EVENT_LOGO_IMP:
1004 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline);
1005 break;
1006
1007 case RPSM_EVENT_LOGO_RCVD:
1008 /**
1009 * Ignore - already processing a LOGO.
1010 */
1011 break;
1012
1013 default:
1014 bfa_assert(0);
1015 }
1016}
1017
1018/**
1019 * Rport is being deleted. FC-4s are offline. Awaiting BFA rport offline
1020 * callback to send LOGO.
1021 */
1022static void
1023bfa_fcs_rport_sm_hcb_logosend(struct bfa_fcs_rport_s *rport,
1024 enum rport_event event)
1025{
1026 bfa_trc(rport->fcs, rport->pwwn);
1027 bfa_trc(rport->fcs, rport->pid);
1028 bfa_trc(rport->fcs, event);
1029
1030 switch (event) {
1031 case RPSM_EVENT_HCB_OFFLINE:
1032 bfa_sm_set_state(rport, bfa_fcs_rport_sm_logo_sending);
1033 bfa_fcs_rport_send_logo(rport, NULL);
1034 break;
1035
1036 case RPSM_EVENT_LOGO_RCVD:
1037 case RPSM_EVENT_ADDRESS_CHANGE:
1038 break;
1039
1040 default:
1041 bfa_assert(0);
1042 }
1043}
1044
1045/**
1046 * Rport is being deleted. FC-4s are offline. LOGO is being sent.
1047 */
1048static void
1049bfa_fcs_rport_sm_logo_sending(struct bfa_fcs_rport_s *rport,
1050 enum rport_event event)
1051{
1052 bfa_trc(rport->fcs, rport->pwwn);
1053 bfa_trc(rport->fcs, rport->pid);
1054 bfa_trc(rport->fcs, event);
1055
1056 switch (event) {
1057 case RPSM_EVENT_FCXP_SENT:
1058 /*
1059 * Once LOGO is sent, we donot wait for the response
1060 */
1061 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1062 bfa_fcs_rport_free(rport);
1063 break;
1064
1065 case RPSM_EVENT_SCN:
1066 case RPSM_EVENT_ADDRESS_CHANGE:
1067 break;
1068
1069 case RPSM_EVENT_LOGO_RCVD:
1070 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1071 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
1072 bfa_fcs_rport_free(rport);
1073 break;
1074
1075 default:
1076 bfa_assert(0);
1077 }
1078}
1079
1080/**
1081 * Rport is offline. FC-4s are offline. BFA rport is offline.
1082 * Timer active to delete stale rport.
1083 */
1084static void
1085bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s *rport, enum rport_event event)
1086{
1087 bfa_trc(rport->fcs, rport->pwwn);
1088 bfa_trc(rport->fcs, rport->pid);
1089 bfa_trc(rport->fcs, event);
1090
1091 switch (event) {
1092 case RPSM_EVENT_TIMEOUT:
1093 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1094 bfa_fcs_rport_free(rport);
1095 break;
1096
1097 case RPSM_EVENT_SCN:
1098 case RPSM_EVENT_ADDRESS_CHANGE:
1099 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
1100 bfa_timer_stop(&rport->timer);
1101 rport->ns_retries = 0;
1102 bfa_fcs_rport_send_gidpn(rport, NULL);
1103 break;
1104
1105 case RPSM_EVENT_DELETE:
1106 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1107 bfa_timer_stop(&rport->timer);
1108 bfa_fcs_rport_free(rport);
1109 break;
1110
1111 case RPSM_EVENT_PLOGI_RCVD:
1112 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
1113 bfa_timer_stop(&rport->timer);
1114 bfa_fcs_rport_send_plogiacc(rport, NULL);
1115 break;
1116
1117 case RPSM_EVENT_LOGO_RCVD:
1118 case RPSM_EVENT_LOGO_IMP:
1119 break;
1120
1121 case RPSM_EVENT_PLOGI_COMP:
1122 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
1123 bfa_timer_stop(&rport->timer);
1124 bfa_fcs_rport_hal_online(rport);
1125 break;
1126
1127 case RPSM_EVENT_PLOGI_SEND:
1128 bfa_timer_stop(&rport->timer);
1129 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
1130 rport->plogi_retries = 0;
1131 bfa_fcs_rport_send_plogi(rport, NULL);
1132 break;
1133
1134 default:
1135 bfa_assert(0);
1136 }
1137}
1138
1139/**
1140 * Rport address has changed. Nameserver discovery request is being sent.
1141 */
1142static void
1143bfa_fcs_rport_sm_nsdisc_sending(struct bfa_fcs_rport_s *rport,
1144 enum rport_event event)
1145{
1146 bfa_trc(rport->fcs, rport->pwwn);
1147 bfa_trc(rport->fcs, rport->pid);
1148 bfa_trc(rport->fcs, event);
1149
1150 switch (event) {
1151 case RPSM_EVENT_FCXP_SENT:
1152 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sent);
1153 break;
1154
1155 case RPSM_EVENT_DELETE:
1156 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1157 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
1158 bfa_fcs_rport_free(rport);
1159 break;
1160
1161 case RPSM_EVENT_PLOGI_RCVD:
1162 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
1163 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
1164 bfa_fcs_rport_send_plogiacc(rport, NULL);
1165 break;
1166
1167 case RPSM_EVENT_SCN:
1168 case RPSM_EVENT_LOGO_RCVD:
1169 case RPSM_EVENT_PLOGI_SEND:
1170 break;
1171
1172 case RPSM_EVENT_ADDRESS_CHANGE:
1173 rport->ns_retries = 0; /* reset the retry count */
1174 break;
1175
1176 case RPSM_EVENT_LOGO_IMP:
1177 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
1178 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
1179 bfa_timer_start(rport->fcs->bfa, &rport->timer,
1180 bfa_fcs_rport_timeout, rport,
1181 bfa_fcs_rport_del_timeout);
1182 break;
1183
1184 case RPSM_EVENT_PLOGI_COMP:
1185 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
1186 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
1187 bfa_fcs_rport_hal_online(rport);
1188 break;
1189
1190 default:
1191 bfa_assert(0);
1192 }
1193}
1194
1195/**
1196 * Nameserver discovery failed. Waiting for timeout to retry.
1197 */
1198static void
1199bfa_fcs_rport_sm_nsdisc_retry(struct bfa_fcs_rport_s *rport,
1200 enum rport_event event)
1201{
1202 bfa_trc(rport->fcs, rport->pwwn);
1203 bfa_trc(rport->fcs, rport->pid);
1204 bfa_trc(rport->fcs, event);
1205
1206 switch (event) {
1207 case RPSM_EVENT_TIMEOUT:
1208 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
1209 bfa_fcs_rport_send_gidpn(rport, NULL);
1210 break;
1211
1212 case RPSM_EVENT_SCN:
1213 case RPSM_EVENT_ADDRESS_CHANGE:
1214 bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
1215 bfa_timer_stop(&rport->timer);
1216 rport->ns_retries = 0;
1217 bfa_fcs_rport_send_gidpn(rport, NULL);
1218 break;
1219
1220 case RPSM_EVENT_DELETE:
1221 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1222 bfa_timer_stop(&rport->timer);
1223 bfa_fcs_rport_free(rport);
1224 break;
1225
1226 case RPSM_EVENT_PLOGI_RCVD:
1227 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
1228 bfa_timer_stop(&rport->timer);
1229 bfa_fcs_rport_send_plogiacc(rport, NULL);
1230 break;
1231
1232 case RPSM_EVENT_LOGO_IMP:
1233 rport->pid = 0;
1234 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
1235 bfa_timer_stop(&rport->timer);
1236 bfa_timer_start(rport->fcs->bfa, &rport->timer,
1237 bfa_fcs_rport_timeout, rport,
1238 bfa_fcs_rport_del_timeout);
1239 break;
1240
1241 case RPSM_EVENT_LOGO_RCVD:
1242 bfa_fcs_rport_send_logo_acc(rport);
1243 break;
1244
1245 case RPSM_EVENT_PLOGI_COMP:
1246 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
1247 bfa_timer_stop(&rport->timer);
1248 bfa_fcs_rport_hal_online(rport);
1249 break;
1250
1251 default:
1252 bfa_assert(0);
1253 }
1254}
1255
1256/**
1257 * Rport address has changed. Nameserver discovery request is sent.
1258 */
1259static void
1260bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
1261 enum rport_event event)
1262{
1263 bfa_trc(rport->fcs, rport->pwwn);
1264 bfa_trc(rport->fcs, rport->pid);
1265 bfa_trc(rport->fcs, event);
1266
1267 switch (event) {
1268 case RPSM_EVENT_ACCEPTED:
1269 case RPSM_EVENT_ADDRESS_CHANGE:
1270 if (rport->pid) {
1271 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
1272 bfa_fcs_rport_send_plogi(rport, NULL);
1273 } else {
1274 bfa_sm_set_state(rport,
1275 bfa_fcs_rport_sm_nsdisc_sending);
1276 rport->ns_retries = 0;
1277 bfa_fcs_rport_send_gidpn(rport, NULL);
1278 }
1279 break;
1280
1281 case RPSM_EVENT_FAILED:
1282 rport->ns_retries++;
1283 if (rport->ns_retries < BFA_FCS_RPORT_MAX_RETRIES) {
1284 bfa_sm_set_state(rport,
1285 bfa_fcs_rport_sm_nsdisc_sending);
1286 bfa_fcs_rport_send_gidpn(rport, NULL);
1287 } else {
1288 rport->pid = 0;
1289 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
1290 bfa_timer_start(rport->fcs->bfa, &rport->timer,
1291 bfa_fcs_rport_timeout, rport,
1292 bfa_fcs_rport_del_timeout);
1293 };
1294 break;
1295
1296 case RPSM_EVENT_DELETE:
1297 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1298 bfa_fcxp_discard(rport->fcxp);
1299 bfa_fcs_rport_free(rport);
1300 break;
1301
1302 case RPSM_EVENT_PLOGI_RCVD:
1303 bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
1304 bfa_fcxp_discard(rport->fcxp);
1305 bfa_fcs_rport_send_plogiacc(rport, NULL);
1306 break;
1307
1308 case RPSM_EVENT_LOGO_IMP:
1309 rport->pid = 0;
1310 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
1311 bfa_fcxp_discard(rport->fcxp);
1312 bfa_timer_start(rport->fcs->bfa, &rport->timer,
1313 bfa_fcs_rport_timeout, rport,
1314 bfa_fcs_rport_del_timeout);
1315 break;
1316
1317 case RPSM_EVENT_SCN:
1318 /**
1319 * ignore, wait for NS query response
1320 */
1321 break;
1322
1323 case RPSM_EVENT_LOGO_RCVD:
1324 /**
1325 * Not logged-in yet. Accept LOGO.
1326 */
1327 bfa_fcs_rport_send_logo_acc(rport);
1328 break;
1329
1330 case RPSM_EVENT_PLOGI_COMP:
1331 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
1332 bfa_fcxp_discard(rport->fcxp);
1333 bfa_fcs_rport_hal_online(rport);
1334 break;
1335
1336 default:
1337 bfa_assert(0);
1338 }
1339}
1340
1341
1342
1343/**
1344 * fcs_rport_private FCS RPORT provate functions
1345 */
1346
1347static void
1348bfa_fcs_rport_send_plogi(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1349{
1350 struct bfa_fcs_rport_s *rport = rport_cbarg;
1351 struct bfa_fcs_port_s *port = rport->port;
1352 struct fchs_s fchs;
1353 int len;
1354 struct bfa_fcxp_s *fcxp;
1355
1356 bfa_trc(rport->fcs, rport->pwwn);
1357
1358 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
1359 if (!fcxp) {
1360 bfa_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1361 bfa_fcs_rport_send_plogi, rport);
1362 return;
1363 }
1364 rport->fcxp = fcxp;
1365
1366 len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
1367 bfa_fcs_port_get_fcid(port), 0,
1368 port->port_cfg.pwwn, port->port_cfg.nwwn,
1369 bfa_pport_get_maxfrsize(port->fcs->bfa));
1370
1371 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1372 FC_CLASS_3, len, &fchs, bfa_fcs_rport_plogi_response,
1373 (void *)rport, FC_MAX_PDUSZ, FC_RA_TOV);
1374
1375 rport->stats.plogis++;
1376 bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
1377}
1378
1379static void
1380bfa_fcs_rport_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
1381 bfa_status_t req_status, u32 rsp_len,
1382 u32 resid_len, struct fchs_s *rsp_fchs)
1383{
1384 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *)cbarg;
1385 struct fc_logi_s *plogi_rsp;
1386 struct fc_ls_rjt_s *ls_rjt;
1387 struct bfa_fcs_rport_s *twin;
1388 struct list_head *qe;
1389
1390 bfa_trc(rport->fcs, rport->pwwn);
1391
1392 /*
1393 * Sanity Checks
1394 */
1395 if (req_status != BFA_STATUS_OK) {
1396 bfa_trc(rport->fcs, req_status);
1397 rport->stats.plogi_failed++;
1398 bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1399 return;
1400 }
1401
1402 plogi_rsp = (struct fc_logi_s *) BFA_FCXP_RSP_PLD(fcxp);
1403
1404 /**
1405 * Check for failure first.
1406 */
1407 if (plogi_rsp->els_cmd.els_code != FC_ELS_ACC) {
1408 ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
1409
1410 bfa_trc(rport->fcs, ls_rjt->reason_code);
1411 bfa_trc(rport->fcs, ls_rjt->reason_code_expl);
1412
1413 rport->stats.plogi_rejects++;
1414 bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1415 return;
1416 }
1417
1418 /**
1419 * PLOGI is complete. Make sure this device is not one of the known
1420 * device with a new FC port address.
1421 */
1422 list_for_each(qe, &rport->port->rport_q) {
1423 twin = (struct bfa_fcs_rport_s *)qe;
1424 if (twin == rport)
1425 continue;
1426 if (!rport->pwwn && (plogi_rsp->port_name == twin->pwwn)) {
1427 bfa_trc(rport->fcs, twin->pid);
1428 bfa_trc(rport->fcs, rport->pid);
1429
1430 /*
1431 * Update plogi stats in twin
1432 */
1433 twin->stats.plogis += rport->stats.plogis;
1434 twin->stats.plogi_rejects += rport->stats.plogi_rejects;
1435 twin->stats.plogi_timeouts +=
1436 rport->stats.plogi_timeouts;
1437 twin->stats.plogi_failed += rport->stats.plogi_failed;
1438 twin->stats.plogi_rcvd += rport->stats.plogi_rcvd;
1439 twin->stats.plogi_accs++;
1440
1441 bfa_fcs_rport_delete(rport);
1442
1443 bfa_fcs_rport_update(twin, plogi_rsp);
1444 twin->pid = rsp_fchs->s_id;
1445 bfa_sm_send_event(twin, RPSM_EVENT_PLOGI_COMP);
1446 return;
1447 }
1448 }
1449
1450 /**
1451 * Normal login path -- no evil twins.
1452 */
1453 rport->stats.plogi_accs++;
1454 bfa_fcs_rport_update(rport, plogi_rsp);
1455 bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED);
1456}
1457
1458static void
1459bfa_fcs_rport_send_plogiacc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1460{
1461 struct bfa_fcs_rport_s *rport = rport_cbarg;
1462 struct bfa_fcs_port_s *port = rport->port;
1463 struct fchs_s fchs;
1464 int len;
1465 struct bfa_fcxp_s *fcxp;
1466
1467 bfa_trc(rport->fcs, rport->pwwn);
1468 bfa_trc(rport->fcs, rport->reply_oxid);
1469
1470 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
1471 if (!fcxp) {
1472 bfa_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1473 bfa_fcs_rport_send_plogiacc, rport);
1474 return;
1475 }
1476 rport->fcxp = fcxp;
1477
1478 len = fc_plogi_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
1479 bfa_fcs_port_get_fcid(port), rport->reply_oxid,
1480 port->port_cfg.pwwn, port->port_cfg.nwwn,
1481 bfa_pport_get_maxfrsize(port->fcs->bfa));
1482
1483 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1484 FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
1485
1486 bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
1487}
1488
1489static void
1490bfa_fcs_rport_send_adisc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1491{
1492 struct bfa_fcs_rport_s *rport = rport_cbarg;
1493 struct bfa_fcs_port_s *port = rport->port;
1494 struct fchs_s fchs;
1495 int len;
1496 struct bfa_fcxp_s *fcxp;
1497
1498 bfa_trc(rport->fcs, rport->pwwn);
1499
1500 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
1501 if (!fcxp) {
1502 bfa_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1503 bfa_fcs_rport_send_adisc, rport);
1504 return;
1505 }
1506 rport->fcxp = fcxp;
1507
1508 len = fc_adisc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
1509 bfa_fcs_port_get_fcid(port), 0,
1510 port->port_cfg.pwwn, port->port_cfg.nwwn);
1511
1512 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1513 FC_CLASS_3, len, &fchs, bfa_fcs_rport_adisc_response,
1514 rport, FC_MAX_PDUSZ, FC_RA_TOV);
1515
1516 rport->stats.adisc_sent++;
1517 bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
1518}
1519
1520static void
1521bfa_fcs_rport_adisc_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
1522 bfa_status_t req_status, u32 rsp_len,
1523 u32 resid_len, struct fchs_s *rsp_fchs)
1524{
1525 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *)cbarg;
1526 void *pld = bfa_fcxp_get_rspbuf(fcxp);
1527 struct fc_ls_rjt_s *ls_rjt;
1528
1529 if (req_status != BFA_STATUS_OK) {
1530 bfa_trc(rport->fcs, req_status);
1531 rport->stats.adisc_failed++;
1532 bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1533 return;
1534 }
1535
1536 if (fc_adisc_rsp_parse((struct fc_adisc_s *)pld, rsp_len, rport->pwwn,
1537 rport->nwwn) == FC_PARSE_OK) {
1538 rport->stats.adisc_accs++;
1539 bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED);
1540 return;
1541 }
1542
1543 rport->stats.adisc_rejects++;
1544 ls_rjt = pld;
1545 bfa_trc(rport->fcs, ls_rjt->els_cmd.els_code);
1546 bfa_trc(rport->fcs, ls_rjt->reason_code);
1547 bfa_trc(rport->fcs, ls_rjt->reason_code_expl);
1548 bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1549}
1550
1551static void
1552bfa_fcs_rport_send_gidpn(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1553{
1554 struct bfa_fcs_rport_s *rport = rport_cbarg;
1555 struct bfa_fcs_port_s *port = rport->port;
1556 struct fchs_s fchs;
1557 struct bfa_fcxp_s *fcxp;
1558 int len;
1559
1560 bfa_trc(rport->fcs, rport->pid);
1561
1562 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
1563 if (!fcxp) {
1564 bfa_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1565 bfa_fcs_rport_send_gidpn, rport);
1566 return;
1567 }
1568 rport->fcxp = fcxp;
1569
1570 len = fc_gidpn_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1571 bfa_fcs_port_get_fcid(port), 0, rport->pwwn);
1572
1573 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1574 FC_CLASS_3, len, &fchs, bfa_fcs_rport_gidpn_response,
1575 (void *)rport, FC_MAX_PDUSZ, FC_RA_TOV);
1576
1577 bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
1578}
1579
1580static void
1581bfa_fcs_rport_gidpn_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
1582 bfa_status_t req_status, u32 rsp_len,
1583 u32 resid_len, struct fchs_s *rsp_fchs)
1584{
1585 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *)cbarg;
1586 struct bfa_fcs_rport_s *twin;
1587 struct list_head *qe;
1588 struct ct_hdr_s *cthdr;
1589 struct fcgs_gidpn_resp_s *gidpn_rsp;
1590
1591 bfa_trc(rport->fcs, rport->pwwn);
1592
1593 cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
1594 cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code);
1595
1596 if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
1597 /*
1598 * Check if the pid is the same as before.
1599 */
1600 gidpn_rsp = (struct fcgs_gidpn_resp_s *) (cthdr + 1);
1601
1602 if (gidpn_rsp->dap == rport->pid) {
1603 /*
1604 * Device is online
1605 */
1606 bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED);
1607 } else {
1608 /*
1609 * Device's PID has changed. We need to cleanup and
1610 * re-login. If there is another device with the the
1611 * newly discovered pid, send an scn notice so that its
1612 * new pid can be discovered.
1613 */
1614 list_for_each(qe, &rport->port->rport_q) {
1615 twin = (struct bfa_fcs_rport_s *)qe;
1616 if (twin == rport)
1617 continue;
1618 if (gidpn_rsp->dap == twin->pid) {
1619 bfa_trc(rport->fcs, twin->pid);
1620 bfa_trc(rport->fcs, rport->pid);
1621
1622 twin->pid = 0;
1623 bfa_sm_send_event(twin,
1624 RPSM_EVENT_ADDRESS_CHANGE);
1625 }
1626 }
1627 rport->pid = gidpn_rsp->dap;
1628 bfa_sm_send_event(rport, RPSM_EVENT_ADDRESS_CHANGE);
1629 }
1630 return;
1631 }
1632
1633 /*
1634 * Reject Response
1635 */
1636 switch (cthdr->reason_code) {
1637 case CT_RSN_LOGICAL_BUSY:
1638 /*
1639 * Need to retry
1640 */
1641 bfa_sm_send_event(rport, RPSM_EVENT_TIMEOUT);
1642 break;
1643
1644 case CT_RSN_UNABLE_TO_PERF:
1645 /*
1646 * device doesn't exist : Start timer to cleanup this later.
1647 */
1648 bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1649 break;
1650
1651 default:
1652 bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1653 break;
1654 }
1655}
1656
1657/**
1658 * Called to send a logout to the rport.
1659 */
1660static void
1661bfa_fcs_rport_send_logo(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1662{
1663 struct bfa_fcs_rport_s *rport = rport_cbarg;
1664 struct bfa_fcs_port_s *port;
1665 struct fchs_s fchs;
1666 struct bfa_fcxp_s *fcxp;
1667 u16 len;
1668
1669 bfa_trc(rport->fcs, rport->pid);
1670
1671 port = rport->port;
1672
1673 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
1674 if (!fcxp) {
1675 bfa_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1676 bfa_fcs_rport_send_logo, rport);
1677 return;
1678 }
1679 rport->fcxp = fcxp;
1680
1681 len = fc_logo_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
1682 bfa_fcs_port_get_fcid(port), 0,
1683 bfa_fcs_port_get_pwwn(port));
1684
1685 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1686 FC_CLASS_3, len, &fchs, NULL, rport, FC_MAX_PDUSZ,
1687 FC_ED_TOV);
1688
1689 rport->stats.logos++;
1690 bfa_fcxp_discard(rport->fcxp);
1691 bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
1692}
1693
1694/**
1695 * Send ACC for a LOGO received.
1696 */
1697static void
1698bfa_fcs_rport_send_logo_acc(void *rport_cbarg)
1699{
1700 struct bfa_fcs_rport_s *rport = rport_cbarg;
1701 struct bfa_fcs_port_s *port;
1702 struct fchs_s fchs;
1703 struct bfa_fcxp_s *fcxp;
1704 u16 len;
1705
1706 bfa_trc(rport->fcs, rport->pid);
1707
1708 port = rport->port;
1709
1710 fcxp = bfa_fcs_fcxp_alloc(port->fcs);
1711 if (!fcxp)
1712 return;
1713
1714 rport->stats.logo_rcvd++;
1715 len = fc_logo_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
1716 bfa_fcs_port_get_fcid(port), rport->reply_oxid);
1717
1718 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1719 FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
1720}
1721
1722/**
1723 * This routine will be called by bfa_timer on timer timeouts.
1724 *
1725 * param[in] rport - pointer to bfa_fcs_port_ns_t.
1726 * param[out] rport_status - pointer to return vport status in
1727 *
1728 * return
1729 * void
1730 *
1731* Special Considerations:
1732 *
1733 * note
1734 */
1735static void
1736bfa_fcs_rport_timeout(void *arg)
1737{
1738 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *)arg;
1739
1740 rport->stats.plogi_timeouts++;
1741 bfa_sm_send_event(rport, RPSM_EVENT_TIMEOUT);
1742}
1743
1744static void
1745bfa_fcs_rport_process_prli(struct bfa_fcs_rport_s *rport,
1746 struct fchs_s *rx_fchs, u16 len)
1747{
1748 struct bfa_fcxp_s *fcxp;
1749 struct fchs_s fchs;
1750 struct bfa_fcs_port_s *port = rport->port;
1751 struct fc_prli_s *prli;
1752
1753 bfa_trc(port->fcs, rx_fchs->s_id);
1754 bfa_trc(port->fcs, rx_fchs->d_id);
1755
1756 rport->stats.prli_rcvd++;
1757
1758 if (BFA_FCS_VPORT_IS_TARGET_MODE(port)) {
1759 /*
1760 * Target Mode : Let the fcptm handle it
1761 */
1762 bfa_fcs_tin_rx_prli(rport->tin, rx_fchs, len);
1763 return;
1764 }
1765
1766 /*
1767 * We are either in Initiator or ipfc Mode
1768 */
1769 prli = (struct fc_prli_s *) (rx_fchs + 1);
1770
1771 if (prli->parampage.servparams.initiator) {
1772 bfa_trc(rport->fcs, prli->parampage.type);
1773 rport->scsi_function = BFA_RPORT_INITIATOR;
1774 bfa_fcs_itnim_is_initiator(rport->itnim);
1775 } else {
1776 /*
1777 * @todo: PRLI from a target ?
1778 */
1779 bfa_trc(port->fcs, rx_fchs->s_id);
1780 rport->scsi_function = BFA_RPORT_TARGET;
1781 }
1782
1783 fcxp = bfa_fcs_fcxp_alloc(port->fcs);
1784 if (!fcxp)
1785 return;
1786
1787 len = fc_prli_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rx_fchs->s_id,
1788 bfa_fcs_port_get_fcid(port), rx_fchs->ox_id,
1789 port->port_cfg.roles);
1790
1791 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1792 FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
1793}
1794
1795static void
1796bfa_fcs_rport_process_rpsc(struct bfa_fcs_rport_s *rport,
1797 struct fchs_s *rx_fchs, u16 len)
1798{
1799 struct bfa_fcxp_s *fcxp;
1800 struct fchs_s fchs;
1801 struct bfa_fcs_port_s *port = rport->port;
1802 struct fc_rpsc_speed_info_s speeds;
1803 struct bfa_pport_attr_s pport_attr;
1804
1805 bfa_trc(port->fcs, rx_fchs->s_id);
1806 bfa_trc(port->fcs, rx_fchs->d_id);
1807
1808 rport->stats.rpsc_rcvd++;
1809 speeds.port_speed_cap =
1810 RPSC_SPEED_CAP_1G | RPSC_SPEED_CAP_2G | RPSC_SPEED_CAP_4G |
1811 RPSC_SPEED_CAP_8G;
1812
1813 /*
1814 * get curent speed from pport attributes from BFA
1815 */
1816 bfa_pport_get_attr(port->fcs->bfa, &pport_attr);
1817
1818 speeds.port_op_speed = fc_bfa_speed_to_rpsc_operspeed(pport_attr.speed);
1819
1820 fcxp = bfa_fcs_fcxp_alloc(port->fcs);
1821 if (!fcxp)
1822 return;
1823
1824 len = fc_rpsc_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rx_fchs->s_id,
1825 bfa_fcs_port_get_fcid(port), rx_fchs->ox_id,
1826 &speeds);
1827
1828 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1829 FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
1830}
1831
1832static void
1833bfa_fcs_rport_process_adisc(struct bfa_fcs_rport_s *rport,
1834 struct fchs_s *rx_fchs, u16 len)
1835{
1836 struct bfa_fcxp_s *fcxp;
1837 struct fchs_s fchs;
1838 struct bfa_fcs_port_s *port = rport->port;
1839 struct fc_adisc_s *adisc;
1840
1841 bfa_trc(port->fcs, rx_fchs->s_id);
1842 bfa_trc(port->fcs, rx_fchs->d_id);
1843
1844 rport->stats.adisc_rcvd++;
1845
1846 if (BFA_FCS_VPORT_IS_TARGET_MODE(port)) {
1847 /*
1848 * @todo : Target Mode handling
1849 */
1850 bfa_trc(port->fcs, rx_fchs->d_id);
1851 bfa_assert(0);
1852 return;
1853 }
1854
1855 adisc = (struct fc_adisc_s *) (rx_fchs + 1);
1856
1857 /*
1858 * Accept if the itnim for this rport is online. Else reject the ADISC
1859 */
1860 if (bfa_fcs_itnim_get_online_state(rport->itnim) == BFA_STATUS_OK) {
1861
1862 fcxp = bfa_fcs_fcxp_alloc(port->fcs);
1863 if (!fcxp)
1864 return;
1865
1866 len = fc_adisc_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1867 rx_fchs->s_id,
1868 bfa_fcs_port_get_fcid(port),
1869 rx_fchs->ox_id, port->port_cfg.pwwn,
1870 port->port_cfg.nwwn);
1871
1872 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag,
1873 BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
1874 FC_MAX_PDUSZ, 0);
1875 } else {
1876 rport->stats.adisc_rejected++;
1877 bfa_fcs_rport_send_ls_rjt(rport, rx_fchs,
1878 FC_LS_RJT_RSN_UNABLE_TO_PERF_CMD,
1879 FC_LS_RJT_EXP_LOGIN_REQUIRED);
1880 }
1881
1882}
1883
1884static void
1885bfa_fcs_rport_hal_online(struct bfa_fcs_rport_s *rport)
1886{
1887 struct bfa_fcs_port_s *port = rport->port;
1888 struct bfa_rport_info_s rport_info;
1889
1890 rport_info.pid = rport->pid;
1891 rport_info.local_pid = port->pid;
1892 rport_info.lp_tag = port->lp_tag;
1893 rport_info.vf_id = port->fabric->vf_id;
1894 rport_info.vf_en = port->fabric->is_vf;
1895 rport_info.fc_class = rport->fc_cos;
1896 rport_info.cisc = rport->cisc;
1897 rport_info.max_frmsz = rport->maxfrsize;
1898 bfa_rport_online(rport->bfa_rport, &rport_info);
1899}
1900
1901static void
1902bfa_fcs_rport_fc4_pause(struct bfa_fcs_rport_s *rport)
1903{
1904 if (bfa_fcs_port_is_initiator(rport->port))
1905 bfa_fcs_itnim_pause(rport->itnim);
1906
1907 if (bfa_fcs_port_is_target(rport->port))
1908 bfa_fcs_tin_pause(rport->tin);
1909}
1910
1911static void
1912bfa_fcs_rport_fc4_resume(struct bfa_fcs_rport_s *rport)
1913{
1914 if (bfa_fcs_port_is_initiator(rport->port))
1915 bfa_fcs_itnim_resume(rport->itnim);
1916
1917 if (bfa_fcs_port_is_target(rport->port))
1918 bfa_fcs_tin_resume(rport->tin);
1919}
1920
1921static struct bfa_fcs_rport_s *
1922bfa_fcs_rport_alloc(struct bfa_fcs_port_s *port, wwn_t pwwn, u32 rpid)
1923{
1924 struct bfa_fcs_s *fcs = port->fcs;
1925 struct bfa_fcs_rport_s *rport;
1926 struct bfad_rport_s *rport_drv;
1927
1928 /**
1929 * allocate rport
1930 */
1931 if (bfa_fcb_rport_alloc(fcs->bfad, &rport, &rport_drv)
1932 != BFA_STATUS_OK) {
1933 bfa_trc(fcs, rpid);
1934 return NULL;
1935 }
1936
1937 /*
1938 * Initialize r-port
1939 */
1940 rport->port = port;
1941 rport->fcs = fcs;
1942 rport->rp_drv = rport_drv;
1943 rport->pid = rpid;
1944 rport->pwwn = pwwn;
1945
1946 /**
1947 * allocate BFA rport
1948 */
1949 rport->bfa_rport = bfa_rport_create(port->fcs->bfa, rport);
1950 if (!rport->bfa_rport) {
1951 bfa_trc(fcs, rpid);
1952 kfree(rport_drv);
1953 return NULL;
1954 }
1955
1956 /**
1957 * allocate FC-4s
1958 */
1959 bfa_assert(bfa_fcs_port_is_initiator(port) ^
1960 bfa_fcs_port_is_target(port));
1961
1962 if (bfa_fcs_port_is_initiator(port)) {
1963 rport->itnim = bfa_fcs_itnim_create(rport);
1964 if (!rport->itnim) {
1965 bfa_trc(fcs, rpid);
1966 bfa_rport_delete(rport->bfa_rport);
1967 kfree(rport_drv);
1968 return NULL;
1969 }
1970 }
1971
1972 if (bfa_fcs_port_is_target(port)) {
1973 rport->tin = bfa_fcs_tin_create(rport);
1974 if (!rport->tin) {
1975 bfa_trc(fcs, rpid);
1976 bfa_rport_delete(rport->bfa_rport);
1977 kfree(rport_drv);
1978 return NULL;
1979 }
1980 }
1981
1982 bfa_fcs_port_add_rport(port, rport);
1983
1984 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1985
1986 /*
1987 * Initialize the Rport Features(RPF) Sub Module
1988 */
1989 if (!BFA_FCS_PID_IS_WKA(rport->pid))
1990 bfa_fcs_rpf_init(rport);
1991
1992 return rport;
1993}
1994
1995
1996static void
1997bfa_fcs_rport_free(struct bfa_fcs_rport_s *rport)
1998{
1999 struct bfa_fcs_port_s *port = rport->port;
2000
2001 /**
2002 * - delete FC-4s
2003 * - delete BFA rport
2004 * - remove from queue of rports
2005 */
2006 if (bfa_fcs_port_is_initiator(port))
2007 bfa_fcs_itnim_delete(rport->itnim);
2008
2009 if (bfa_fcs_port_is_target(port))
2010 bfa_fcs_tin_delete(rport->tin);
2011
2012 bfa_rport_delete(rport->bfa_rport);
2013 bfa_fcs_port_del_rport(port, rport);
2014 kfree(rport->rp_drv);
2015}
2016
2017static void
2018bfa_fcs_rport_aen_post(struct bfa_fcs_rport_s *rport,
2019 enum bfa_rport_aen_event event,
2020 struct bfa_rport_aen_data_s *data)
2021{
2022 union bfa_aen_data_u aen_data;
2023 struct bfa_log_mod_s *logmod = rport->fcs->logm;
2024 wwn_t lpwwn = bfa_fcs_port_get_pwwn(rport->port);
2025 wwn_t rpwwn = rport->pwwn;
2026 char lpwwn_ptr[BFA_STRING_32];
2027 char rpwwn_ptr[BFA_STRING_32];
2028 char *prio_str[] = { "unknown", "high", "medium", "low" };
2029
2030 wwn2str(lpwwn_ptr, lpwwn);
2031 wwn2str(rpwwn_ptr, rpwwn);
2032
2033 switch (event) {
2034 case BFA_RPORT_AEN_ONLINE:
2035 bfa_log(logmod, BFA_AEN_RPORT_ONLINE, rpwwn_ptr, lpwwn_ptr);
2036 break;
2037 case BFA_RPORT_AEN_OFFLINE:
2038 bfa_log(logmod, BFA_AEN_RPORT_OFFLINE, rpwwn_ptr, lpwwn_ptr);
2039 break;
2040 case BFA_RPORT_AEN_DISCONNECT:
2041 bfa_log(logmod, BFA_AEN_RPORT_DISCONNECT, rpwwn_ptr, lpwwn_ptr);
2042 break;
2043 case BFA_RPORT_AEN_QOS_PRIO:
2044 aen_data.rport.priv.qos = data->priv.qos;
2045 bfa_log(logmod, BFA_AEN_RPORT_QOS_PRIO,
2046 prio_str[aen_data.rport.priv.qos.qos_priority],
2047 rpwwn_ptr, lpwwn_ptr);
2048 break;
2049 case BFA_RPORT_AEN_QOS_FLOWID:
2050 aen_data.rport.priv.qos = data->priv.qos;
2051 bfa_log(logmod, BFA_AEN_RPORT_QOS_FLOWID,
2052 aen_data.rport.priv.qos.qos_flow_id, rpwwn_ptr,
2053 lpwwn_ptr);
2054 break;
2055 default:
2056 break;
2057 }
2058
2059 aen_data.rport.vf_id = rport->port->fabric->vf_id;
2060 aen_data.rport.ppwwn =
2061 bfa_fcs_port_get_pwwn(bfa_fcs_get_base_port(rport->fcs));
2062 aen_data.rport.lpwwn = lpwwn;
2063 aen_data.rport.rpwwn = rpwwn;
2064}
2065
2066static void
2067bfa_fcs_rport_online_action(struct bfa_fcs_rport_s *rport)
2068{
2069 struct bfa_fcs_port_s *port = rport->port;
2070
2071 rport->stats.onlines++;
2072
2073 if (bfa_fcs_port_is_initiator(port)) {
2074 bfa_fcs_itnim_rport_online(rport->itnim);
2075 if (!BFA_FCS_PID_IS_WKA(rport->pid))
2076 bfa_fcs_rpf_rport_online(rport);
2077 };
2078
2079 if (bfa_fcs_port_is_target(port))
2080 bfa_fcs_tin_rport_online(rport->tin);
2081
2082 /*
2083 * Don't post events for well known addresses
2084 */
2085 if (!BFA_FCS_PID_IS_WKA(rport->pid))
2086 bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_ONLINE, NULL);
2087}
2088
2089static void
2090bfa_fcs_rport_offline_action(struct bfa_fcs_rport_s *rport)
2091{
2092 struct bfa_fcs_port_s *port = rport->port;
2093
2094 rport->stats.offlines++;
2095
2096 /*
2097 * Don't post events for well known addresses
2098 */
2099 if (!BFA_FCS_PID_IS_WKA(rport->pid)) {
2100 if (bfa_fcs_port_is_online(rport->port) == BFA_TRUE) {
2101 bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_DISCONNECT,
2102 NULL);
2103 } else {
2104 bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_OFFLINE,
2105 NULL);
2106 }
2107 }
2108
2109 if (bfa_fcs_port_is_initiator(port)) {
2110 bfa_fcs_itnim_rport_offline(rport->itnim);
2111 if (!BFA_FCS_PID_IS_WKA(rport->pid))
2112 bfa_fcs_rpf_rport_offline(rport);
2113 }
2114
2115 if (bfa_fcs_port_is_target(port))
2116 bfa_fcs_tin_rport_offline(rport->tin);
2117}
2118
2119/**
2120 * Update rport parameters from PLOGI or PLOGI accept.
2121 */
2122static void
2123bfa_fcs_rport_update(struct bfa_fcs_rport_s *rport, struct fc_logi_s *plogi)
2124{
2125 struct bfa_fcs_port_s *port = rport->port;
2126
2127 /**
2128 * - port name
2129 * - node name
2130 */
2131 rport->pwwn = plogi->port_name;
2132 rport->nwwn = plogi->node_name;
2133
2134 /**
2135 * - class of service
2136 */
2137 rport->fc_cos = 0;
2138 if (plogi->class3.class_valid)
2139 rport->fc_cos = FC_CLASS_3;
2140
2141 if (plogi->class2.class_valid)
2142 rport->fc_cos |= FC_CLASS_2;
2143
2144 /**
2145 * - CISC
2146 * - MAX receive frame size
2147 */
2148 rport->cisc = plogi->csp.cisc;
2149 rport->maxfrsize = bfa_os_ntohs(plogi->class3.rxsz);
2150
2151 bfa_trc(port->fcs, bfa_os_ntohs(plogi->csp.bbcred));
2152 bfa_trc(port->fcs, port->fabric->bb_credit);
2153 /**
2154 * Direct Attach P2P mode :
2155 * This is to handle a bug (233476) in IBM targets in Direct Attach
2156 * Mode. Basically, in FLOGI Accept the target would have erroneously
2157 * set the BB Credit to the value used in the FLOGI sent by the HBA.
2158 * It uses the correct value (its own BB credit) in PLOGI.
2159 */
2160 if ((!bfa_fcs_fabric_is_switched(port->fabric))
2161 && (bfa_os_ntohs(plogi->csp.bbcred) < port->fabric->bb_credit)) {
2162
2163 bfa_trc(port->fcs, bfa_os_ntohs(plogi->csp.bbcred));
2164 bfa_trc(port->fcs, port->fabric->bb_credit);
2165
2166 port->fabric->bb_credit = bfa_os_ntohs(plogi->csp.bbcred);
2167 bfa_pport_set_tx_bbcredit(port->fcs->bfa,
2168 port->fabric->bb_credit);
2169 }
2170
2171}
2172
2173/**
2174 * Called to handle LOGO received from an existing remote port.
2175 */
2176static void
2177bfa_fcs_rport_process_logo(struct bfa_fcs_rport_s *rport, struct fchs_s *fchs)
2178{
2179 rport->reply_oxid = fchs->ox_id;
2180 bfa_trc(rport->fcs, rport->reply_oxid);
2181
2182 rport->stats.logo_rcvd++;
2183 bfa_sm_send_event(rport, RPSM_EVENT_LOGO_RCVD);
2184}
2185
2186
2187
2188/**
2189 * fcs_rport_public FCS rport public interfaces
2190 */
2191
2192/**
2193 * Called by bport/vport to create a remote port instance for a discovered
2194 * remote device.
2195 *
2196 * @param[in] port - base port or vport
2197 * @param[in] rpid - remote port ID
2198 *
2199 * @return None
2200 */
2201struct bfa_fcs_rport_s *
2202bfa_fcs_rport_create(struct bfa_fcs_port_s *port, u32 rpid)
2203{
2204 struct bfa_fcs_rport_s *rport;
2205
2206 bfa_trc(port->fcs, rpid);
2207 rport = bfa_fcs_rport_alloc(port, WWN_NULL, rpid);
2208 if (!rport)
2209 return NULL;
2210
2211 bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_SEND);
2212 return rport;
2213}
2214
2215/**
2216 * Called to create a rport for which only the wwn is known.
2217 *
2218 * @param[in] port - base port
2219 * @param[in] rpwwn - remote port wwn
2220 *
2221 * @return None
2222 */
2223struct bfa_fcs_rport_s *
2224bfa_fcs_rport_create_by_wwn(struct bfa_fcs_port_s *port, wwn_t rpwwn)
2225{
2226 struct bfa_fcs_rport_s *rport;
2227
2228 bfa_trc(port->fcs, rpwwn);
2229 rport = bfa_fcs_rport_alloc(port, rpwwn, 0);
2230 if (!rport)
2231 return NULL;
2232
2233 bfa_sm_send_event(rport, RPSM_EVENT_ADDRESS_DISC);
2234 return rport;
2235}
2236
2237/**
2238 * Called by bport in private loop topology to indicate that a
2239 * rport has been discovered and plogi has been completed.
2240 *
2241 * @param[in] port - base port or vport
2242 * @param[in] rpid - remote port ID
2243 */
2244void
2245bfa_fcs_rport_start(struct bfa_fcs_port_s *port, struct fchs_s *fchs,
2246 struct fc_logi_s *plogi)
2247{
2248 struct bfa_fcs_rport_s *rport;
2249
2250 rport = bfa_fcs_rport_alloc(port, WWN_NULL, fchs->s_id);
2251 if (!rport)
2252 return;
2253
2254 bfa_fcs_rport_update(rport, plogi);
2255
2256 bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_COMP);
2257}
2258
2259/**
2260 * Called by bport/vport to handle PLOGI received from a new remote port.
2261 * If an existing rport does a plogi, it will be handled separately.
2262 */
2263void
2264bfa_fcs_rport_plogi_create(struct bfa_fcs_port_s *port, struct fchs_s *fchs,
2265 struct fc_logi_s *plogi)
2266{
2267 struct bfa_fcs_rport_s *rport;
2268
2269 rport = bfa_fcs_rport_alloc(port, plogi->port_name, fchs->s_id);
2270 if (!rport)
2271 return;
2272
2273 bfa_fcs_rport_update(rport, plogi);
2274
2275 rport->reply_oxid = fchs->ox_id;
2276 bfa_trc(rport->fcs, rport->reply_oxid);
2277
2278 rport->stats.plogi_rcvd++;
2279 bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_RCVD);
2280}
2281
2282static int
2283wwn_compare(wwn_t wwn1, wwn_t wwn2)
2284{
2285 u8 *b1 = (u8 *) &wwn1;
2286 u8 *b2 = (u8 *) &wwn2;
2287 int i;
2288
2289 for (i = 0; i < sizeof(wwn_t); i++) {
2290 if (b1[i] < b2[i])
2291 return -1;
2292 if (b1[i] > b2[i])
2293 return 1;
2294 }
2295 return 0;
2296}
2297
2298/**
2299 * Called by bport/vport to handle PLOGI received from an existing
2300 * remote port.
2301 */
2302void
2303bfa_fcs_rport_plogi(struct bfa_fcs_rport_s *rport, struct fchs_s *rx_fchs,
2304 struct fc_logi_s *plogi)
2305{
2306 /**
2307 * @todo Handle P2P and initiator-initiator.
2308 */
2309
2310 bfa_fcs_rport_update(rport, plogi);
2311
2312 rport->reply_oxid = rx_fchs->ox_id;
2313 bfa_trc(rport->fcs, rport->reply_oxid);
2314
2315 /**
2316 * In Switched fabric topology,
2317 * PLOGI to each other. If our pwwn is smaller, ignore it,
2318 * if it is not a well known address.
2319 * If the link topology is N2N,
2320 * this Plogi should be accepted.
2321 */
2322 if ((wwn_compare(rport->port->port_cfg.pwwn, rport->pwwn) == -1)
2323 && (bfa_fcs_fabric_is_switched(rport->port->fabric))
2324 && (!BFA_FCS_PID_IS_WKA(rport->pid))) {
2325 bfa_trc(rport->fcs, rport->pid);
2326 return;
2327 }
2328
2329 rport->stats.plogi_rcvd++;
2330 bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_RCVD);
2331}
2332
2333/**
2334 * Called by bport/vport to delete a remote port instance.
2335 *
2336* Rport delete is called under the following conditions:
2337 * - vport is deleted
2338 * - vf is deleted
2339 * - explicit request from OS to delete rport (vmware)
2340 */
2341void
2342bfa_fcs_rport_delete(struct bfa_fcs_rport_s *rport)
2343{
2344 bfa_sm_send_event(rport, RPSM_EVENT_DELETE);
2345}
2346
2347/**
2348 * Called by bport/vport to when a target goes offline.
2349 *
2350 */
2351void
2352bfa_fcs_rport_offline(struct bfa_fcs_rport_s *rport)
2353{
2354 bfa_sm_send_event(rport, RPSM_EVENT_LOGO_IMP);
2355}
2356
2357/**
2358 * Called by bport in n2n when a target (attached port) becomes online.
2359 *
2360 */
2361void
2362bfa_fcs_rport_online(struct bfa_fcs_rport_s *rport)
2363{
2364 bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_SEND);
2365}
2366
2367/**
2368 * Called by bport/vport to notify SCN for the remote port
2369 */
2370void
2371bfa_fcs_rport_scn(struct bfa_fcs_rport_s *rport)
2372{
2373
2374 rport->stats.rscns++;
2375 bfa_sm_send_event(rport, RPSM_EVENT_SCN);
2376}
2377
2378/**
2379 * Called by fcpim to notify that the ITN cleanup is done.
2380 */
2381void
2382bfa_fcs_rport_itnim_ack(struct bfa_fcs_rport_s *rport)
2383{
2384 bfa_sm_send_event(rport, RPSM_EVENT_FC4_OFFLINE);
2385}
2386
2387/**
2388 * Called by fcptm to notify that the ITN cleanup is done.
2389 */
2390void
2391bfa_fcs_rport_tin_ack(struct bfa_fcs_rport_s *rport)
2392{
2393 bfa_sm_send_event(rport, RPSM_EVENT_FC4_OFFLINE);
2394}
2395
2396/**
2397 * This routine BFA callback for bfa_rport_online() call.
2398 *
2399 * param[in] cb_arg - rport struct.
2400 *
2401 * return
2402 * void
2403 *
2404* Special Considerations:
2405 *
2406 * note
2407 */
2408void
2409bfa_cb_rport_online(void *cbarg)
2410{
2411
2412 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *)cbarg;
2413
2414 bfa_trc(rport->fcs, rport->pwwn);
2415 bfa_sm_send_event(rport, RPSM_EVENT_HCB_ONLINE);
2416}
2417
2418/**
2419 * This routine BFA callback for bfa_rport_offline() call.
2420 *
2421 * param[in] rport -
2422 *
2423 * return
2424 * void
2425 *
2426 * Special Considerations:
2427 *
2428 * note
2429 */
2430void
2431bfa_cb_rport_offline(void *cbarg)
2432{
2433 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *)cbarg;
2434
2435 bfa_trc(rport->fcs, rport->pwwn);
2436 bfa_sm_send_event(rport, RPSM_EVENT_HCB_OFFLINE);
2437}
2438
2439/**
2440 * This routine is a static BFA callback when there is a QoS flow_id
2441 * change notification
2442 *
2443 * @param[in] rport -
2444 *
2445 * @return void
2446 *
2447 * Special Considerations:
2448 *
2449 * @note
2450 */
2451void
2452bfa_cb_rport_qos_scn_flowid(void *cbarg,
2453 struct bfa_rport_qos_attr_s old_qos_attr,
2454 struct bfa_rport_qos_attr_s new_qos_attr)
2455{
2456 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *)cbarg;
2457 struct bfa_rport_aen_data_s aen_data;
2458
2459 bfa_trc(rport->fcs, rport->pwwn);
2460 aen_data.priv.qos = new_qos_attr;
2461 bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_QOS_FLOWID, &aen_data);
2462}
2463
2464/**
2465 * This routine is a static BFA callback when there is a QoS priority
2466 * change notification
2467 *
2468 * @param[in] rport -
2469 *
2470 * @return void
2471 *
2472 * Special Considerations:
2473 *
2474 * @note
2475 */
2476void
2477bfa_cb_rport_qos_scn_prio(void *cbarg, struct bfa_rport_qos_attr_s old_qos_attr,
2478 struct bfa_rport_qos_attr_s new_qos_attr)
2479{
2480 struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *)cbarg;
2481 struct bfa_rport_aen_data_s aen_data;
2482
2483 bfa_trc(rport->fcs, rport->pwwn);
2484 aen_data.priv.qos = new_qos_attr;
2485 bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_QOS_PRIO, &aen_data);
2486}
2487
2488/**
2489 * Called to process any unsolicted frames from this remote port
2490 */
2491void
2492bfa_fcs_rport_logo_imp(struct bfa_fcs_rport_s *rport)
2493{
2494 bfa_sm_send_event(rport, RPSM_EVENT_LOGO_IMP);
2495}
2496
2497/**
2498 * Called to process any unsolicted frames from this remote port
2499 */
2500void
2501bfa_fcs_rport_uf_recv(struct bfa_fcs_rport_s *rport, struct fchs_s *fchs,
2502 u16 len)
2503{
2504 struct bfa_fcs_port_s *port = rport->port;
2505 struct fc_els_cmd_s *els_cmd;
2506
2507 bfa_trc(rport->fcs, fchs->s_id);
2508 bfa_trc(rport->fcs, fchs->d_id);
2509 bfa_trc(rport->fcs, fchs->type);
2510
2511 if (fchs->type != FC_TYPE_ELS)
2512 return;
2513
2514 els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
2515
2516 bfa_trc(rport->fcs, els_cmd->els_code);
2517
2518 switch (els_cmd->els_code) {
2519 case FC_ELS_LOGO:
2520 bfa_fcs_rport_process_logo(rport, fchs);
2521 break;
2522
2523 case FC_ELS_ADISC:
2524 bfa_fcs_rport_process_adisc(rport, fchs, len);
2525 break;
2526
2527 case FC_ELS_PRLO:
2528 if (bfa_fcs_port_is_initiator(port))
2529 bfa_fcs_fcpim_uf_recv(rport->itnim, fchs, len);
2530
2531 if (bfa_fcs_port_is_target(port))
2532 bfa_fcs_fcptm_uf_recv(rport->tin, fchs, len);
2533 break;
2534
2535 case FC_ELS_PRLI:
2536 bfa_fcs_rport_process_prli(rport, fchs, len);
2537 break;
2538
2539 case FC_ELS_RPSC:
2540 bfa_fcs_rport_process_rpsc(rport, fchs, len);
2541 break;
2542
2543 default:
2544 bfa_fcs_rport_send_ls_rjt(rport, fchs,
2545 FC_LS_RJT_RSN_CMD_NOT_SUPP,
2546 FC_LS_RJT_EXP_NO_ADDL_INFO);
2547 break;
2548 }
2549}
2550
2551/*
2552 * Send a LS reject
2553 */
2554static void
2555bfa_fcs_rport_send_ls_rjt(struct bfa_fcs_rport_s *rport, struct fchs_s *rx_fchs,
2556 u8 reason_code, u8 reason_code_expl)
2557{
2558 struct bfa_fcs_port_s *port = rport->port;
2559 struct fchs_s fchs;
2560 struct bfa_fcxp_s *fcxp;
2561 int len;
2562
2563 bfa_trc(rport->fcs, rx_fchs->s_id);
2564
2565 fcxp = bfa_fcs_fcxp_alloc(rport->fcs);
2566 if (!fcxp)
2567 return;
2568
2569 len = fc_ls_rjt_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rx_fchs->s_id,
2570 bfa_fcs_port_get_fcid(port), rx_fchs->ox_id,
2571 reason_code, reason_code_expl);
2572
2573 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
2574 FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
2575}
2576
2577/**
2578 * Module initialization
2579 */
2580void
2581bfa_fcs_rport_modinit(struct bfa_fcs_s *fcs)
2582{
2583}
2584
2585/**
2586 * Module cleanup
2587 */
2588void
2589bfa_fcs_rport_modexit(struct bfa_fcs_s *fcs)
2590{
2591 bfa_fcs_modexit_comp(fcs);
2592}
2593
2594/**
2595 * Return state of rport.
2596 */
2597int
2598bfa_fcs_rport_get_state(struct bfa_fcs_rport_s *rport)
2599{
2600 return bfa_sm_to_state(rport_sm_table, rport->sm);
2601}
2602
2603/**
2604 * Called by the Driver to set rport delete/ageout timeout
2605 *
2606 * param[in] rport timeout value in seconds.
2607 *
2608 * return None
2609 */
2610void
2611bfa_fcs_rport_set_del_timeout(u8 rport_tmo)
2612{
2613 /*
2614 * convert to Millisecs
2615 */
2616 if (rport_tmo > 0)
2617 bfa_fcs_rport_del_timeout = rport_tmo * 1000;
2618}
diff --git a/drivers/scsi/bfa/rport_api.c b/drivers/scsi/bfa/rport_api.c
new file mode 100644
index 000000000000..3dae1774181e
--- /dev/null
+++ b/drivers/scsi/bfa/rport_api.c
@@ -0,0 +1,180 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17#include <bfa.h>
18#include <bfa_svc.h>
19#include "fcs_vport.h"
20#include "fcs_lport.h"
21#include "fcs_rport.h"
22#include "fcs_trcmod.h"
23
24BFA_TRC_FILE(FCS, RPORT_API);
25
26/**
27 * rport_api.c Remote port implementation.
28 */
29
30/**
31 * fcs_rport_api FCS rport API.
32 */
33
34/**
35 * Direct API to add a target by port wwn. This interface is used, for
36 * example, by bios when target pwwn is known from boot lun configuration.
37 */
38bfa_status_t
39bfa_fcs_rport_add(struct bfa_fcs_port_s *port, wwn_t *pwwn,
40 struct bfa_fcs_rport_s *rport,
41 struct bfad_rport_s *rport_drv)
42{
43 bfa_trc(port->fcs, *pwwn);
44
45 return BFA_STATUS_OK;
46}
47
48/**
49 * Direct API to remove a target and its associated resources. This
50 * interface is used, for example, by vmware driver to remove target
51 * ports from the target list for a VM.
52 */
53bfa_status_t
54bfa_fcs_rport_remove(struct bfa_fcs_rport_s *rport_in)
55{
56
57 struct bfa_fcs_rport_s *rport;
58
59 bfa_trc(rport_in->fcs, rport_in->pwwn);
60
61 rport = bfa_fcs_port_get_rport_by_pwwn(rport_in->port, rport_in->pwwn);
62 if (rport == NULL) {
63 /*
64 * TBD Error handling
65 */
66 bfa_trc(rport_in->fcs, rport_in->pid);
67 return BFA_STATUS_UNKNOWN_RWWN;
68 }
69
70 /*
71 * TBD if this remote port is online, send a logo
72 */
73 return BFA_STATUS_OK;
74
75}
76
77/**
78 * Remote device status for display/debug.
79 */
80void
81bfa_fcs_rport_get_attr(struct bfa_fcs_rport_s *rport,
82 struct bfa_rport_attr_s *rport_attr)
83{
84 struct bfa_rport_qos_attr_s qos_attr;
85 struct bfa_fcs_port_s *port = rport->port;
86
87 bfa_os_memset(rport_attr, 0, sizeof(struct bfa_rport_attr_s));
88
89 rport_attr->pid = rport->pid;
90 rport_attr->pwwn = rport->pwwn;
91 rport_attr->nwwn = rport->nwwn;
92 rport_attr->cos_supported = rport->fc_cos;
93 rport_attr->df_sz = rport->maxfrsize;
94 rport_attr->state = bfa_fcs_rport_get_state(rport);
95 rport_attr->fc_cos = rport->fc_cos;
96 rport_attr->cisc = rport->cisc;
97 rport_attr->scsi_function = rport->scsi_function;
98 rport_attr->curr_speed = rport->rpf.rpsc_speed;
99 rport_attr->assigned_speed = rport->rpf.assigned_speed;
100
101 bfa_rport_get_qos_attr(rport->bfa_rport, &qos_attr);
102 rport_attr->qos_attr = qos_attr;
103
104 rport_attr->trl_enforced = BFA_FALSE;
105 if (bfa_pport_is_ratelim(port->fcs->bfa)) {
106 if ((rport->rpf.rpsc_speed == BFA_PPORT_SPEED_UNKNOWN) ||
107 (rport->rpf.rpsc_speed <
108 bfa_fcs_port_get_rport_max_speed(port)))
109 rport_attr->trl_enforced = BFA_TRUE;
110 }
111
112 /*
113 * TODO
114 * rport->symname
115 */
116}
117
118/**
119 * Per remote device statistics.
120 */
121void
122bfa_fcs_rport_get_stats(struct bfa_fcs_rport_s *rport,
123 struct bfa_rport_stats_s *stats)
124{
125 *stats = rport->stats;
126}
127
128void
129bfa_fcs_rport_clear_stats(struct bfa_fcs_rport_s *rport)
130{
131 bfa_os_memset((char *)&rport->stats, 0,
132 sizeof(struct bfa_rport_stats_s));
133}
134
135struct bfa_fcs_rport_s *
136bfa_fcs_rport_lookup(struct bfa_fcs_port_s *port, wwn_t rpwwn)
137{
138 struct bfa_fcs_rport_s *rport;
139
140 rport = bfa_fcs_port_get_rport_by_pwwn(port, rpwwn);
141 if (rport == NULL) {
142 /*
143 * TBD Error handling
144 */
145 }
146
147 return rport;
148}
149
150struct bfa_fcs_rport_s *
151bfa_fcs_rport_lookup_by_nwwn(struct bfa_fcs_port_s *port, wwn_t rnwwn)
152{
153 struct bfa_fcs_rport_s *rport;
154
155 rport = bfa_fcs_port_get_rport_by_nwwn(port, rnwwn);
156 if (rport == NULL) {
157 /*
158 * TBD Error handling
159 */
160 }
161
162 return rport;
163}
164
165/*
166 * This API is to set the Rport's speed. Should be used when RPSC is not
167 * supported by the rport.
168 */
169void
170bfa_fcs_rport_set_speed(struct bfa_fcs_rport_s *rport,
171 enum bfa_pport_speed speed)
172{
173 rport->rpf.assigned_speed = speed;
174
175 /* Set this speed in f/w only if the RPSC speed is not available */
176 if (rport->rpf.rpsc_speed == BFA_PPORT_SPEED_UNKNOWN)
177 bfa_rport_speed(rport->bfa_rport, speed);
178}
179
180
diff --git a/drivers/scsi/bfa/rport_ftrs.c b/drivers/scsi/bfa/rport_ftrs.c
new file mode 100644
index 000000000000..8a1f59d596c1
--- /dev/null
+++ b/drivers/scsi/bfa/rport_ftrs.c
@@ -0,0 +1,375 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * rport_ftrs.c Remote port features (RPF) implementation.
20 */
21
22#include <bfa.h>
23#include <bfa_svc.h>
24#include "fcbuild.h"
25#include "fcs_rport.h"
26#include "fcs_lport.h"
27#include "fcs_trcmod.h"
28#include "fcs_fcxp.h"
29#include "fcs.h"
30
31BFA_TRC_FILE(FCS, RPORT_FTRS);
32
33#define BFA_FCS_RPF_RETRIES (3)
34#define BFA_FCS_RPF_RETRY_TIMEOUT (1000) /* 1 sec (In millisecs) */
35
36static void bfa_fcs_rpf_send_rpsc2(void *rport_cbarg,
37 struct bfa_fcxp_s *fcxp_alloced);
38static void bfa_fcs_rpf_rpsc2_response(void *fcsarg,
39 struct bfa_fcxp_s *fcxp, void *cbarg,
40 bfa_status_t req_status, u32 rsp_len,
41 u32 resid_len,
42 struct fchs_s *rsp_fchs);
43static void bfa_fcs_rpf_timeout(void *arg);
44
45/**
46 * fcs_rport_ftrs_sm FCS rport state machine events
47 */
48
49enum rpf_event {
50 RPFSM_EVENT_RPORT_OFFLINE = 1, /* Rport offline */
51 RPFSM_EVENT_RPORT_ONLINE = 2, /* Rport online */
52 RPFSM_EVENT_FCXP_SENT = 3, /* Frame from has been sent */
53 RPFSM_EVENT_TIMEOUT = 4, /* Rport SM timeout event */
54 RPFSM_EVENT_RPSC_COMP = 5,
55 RPFSM_EVENT_RPSC_FAIL = 6,
56 RPFSM_EVENT_RPSC_ERROR = 7,
57};
58
59static void bfa_fcs_rpf_sm_uninit(struct bfa_fcs_rpf_s *rpf,
60 enum rpf_event event);
61static void bfa_fcs_rpf_sm_rpsc_sending(struct bfa_fcs_rpf_s *rpf,
62 enum rpf_event event);
63static void bfa_fcs_rpf_sm_rpsc(struct bfa_fcs_rpf_s *rpf,
64 enum rpf_event event);
65static void bfa_fcs_rpf_sm_rpsc_retry(struct bfa_fcs_rpf_s *rpf,
66 enum rpf_event event);
67static void bfa_fcs_rpf_sm_offline(struct bfa_fcs_rpf_s *rpf,
68 enum rpf_event event);
69static void bfa_fcs_rpf_sm_online(struct bfa_fcs_rpf_s *rpf,
70 enum rpf_event event);
71
72static void
73bfa_fcs_rpf_sm_uninit(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
74{
75 struct bfa_fcs_rport_s *rport = rpf->rport;
76
77 bfa_trc(rport->fcs, rport->pwwn);
78 bfa_trc(rport->fcs, rport->pid);
79 bfa_trc(rport->fcs, event);
80
81 switch (event) {
82 case RPFSM_EVENT_RPORT_ONLINE :
83 if (!BFA_FCS_PID_IS_WKA(rport->pid)) {
84 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending);
85 rpf->rpsc_retries = 0;
86 bfa_fcs_rpf_send_rpsc2(rpf, NULL);
87 break;
88 };
89
90 case RPFSM_EVENT_RPORT_OFFLINE :
91 break;
92
93 default:
94 bfa_assert(0);
95 }
96}
97
98static void
99bfa_fcs_rpf_sm_rpsc_sending(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
100{
101 struct bfa_fcs_rport_s *rport = rpf->rport;
102
103 bfa_trc(rport->fcs, event);
104
105 switch (event) {
106 case RPFSM_EVENT_FCXP_SENT:
107 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc);
108 break;
109
110 case RPFSM_EVENT_RPORT_OFFLINE :
111 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
112 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rpf->fcxp_wqe);
113 rpf->rpsc_retries = 0;
114 break;
115
116 default:
117 bfa_assert(0);
118 }
119}
120
121static void
122bfa_fcs_rpf_sm_rpsc(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
123{
124 struct bfa_fcs_rport_s *rport = rpf->rport;
125
126 bfa_trc(rport->fcs, rport->pid);
127 bfa_trc(rport->fcs, event);
128
129 switch (event) {
130 case RPFSM_EVENT_RPSC_COMP:
131 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online);
132 /* Update speed info in f/w via BFA */
133 if (rpf->rpsc_speed != BFA_PPORT_SPEED_UNKNOWN) {
134 bfa_rport_speed(rport->bfa_rport, rpf->rpsc_speed);
135 } else if (rpf->assigned_speed != BFA_PPORT_SPEED_UNKNOWN) {
136 bfa_rport_speed(rport->bfa_rport, rpf->assigned_speed);
137 }
138 break;
139
140 case RPFSM_EVENT_RPSC_FAIL:
141 /* RPSC not supported by rport */
142 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online);
143 break;
144
145 case RPFSM_EVENT_RPSC_ERROR:
146 /* need to retry...delayed a bit. */
147 if (rpf->rpsc_retries++ < BFA_FCS_RPF_RETRIES) {
148 bfa_timer_start(rport->fcs->bfa, &rpf->timer,
149 bfa_fcs_rpf_timeout, rpf,
150 BFA_FCS_RPF_RETRY_TIMEOUT);
151 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_retry);
152 } else {
153 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online);
154 }
155 break;
156
157 case RPFSM_EVENT_RPORT_OFFLINE :
158 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
159 bfa_fcxp_discard(rpf->fcxp);
160 rpf->rpsc_retries = 0;
161 break;
162
163 default:
164 bfa_assert(0);
165 }
166}
167
168static void
169bfa_fcs_rpf_sm_rpsc_retry(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
170{
171 struct bfa_fcs_rport_s *rport = rpf->rport;
172
173 bfa_trc(rport->fcs, rport->pid);
174 bfa_trc(rport->fcs, event);
175
176 switch (event) {
177 case RPFSM_EVENT_TIMEOUT :
178 /* re-send the RPSC */
179 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending);
180 bfa_fcs_rpf_send_rpsc2(rpf, NULL);
181 break;
182
183 case RPFSM_EVENT_RPORT_OFFLINE :
184 bfa_timer_stop(&rpf->timer);
185 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
186 rpf->rpsc_retries = 0;
187 break;
188
189 default:
190 bfa_assert(0);
191 }
192}
193
194static void
195bfa_fcs_rpf_sm_online(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
196{
197 struct bfa_fcs_rport_s *rport = rpf->rport;
198
199 bfa_trc(rport->fcs, rport->pwwn);
200 bfa_trc(rport->fcs, rport->pid);
201 bfa_trc(rport->fcs, event);
202
203 switch (event) {
204 case RPFSM_EVENT_RPORT_OFFLINE :
205 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
206 rpf->rpsc_retries = 0;
207 break;
208
209 default:
210 bfa_assert(0);
211 }
212}
213
214static void
215bfa_fcs_rpf_sm_offline(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
216{
217 struct bfa_fcs_rport_s *rport = rpf->rport;
218
219 bfa_trc(rport->fcs, rport->pwwn);
220 bfa_trc(rport->fcs, rport->pid);
221 bfa_trc(rport->fcs, event);
222
223 switch (event) {
224 case RPFSM_EVENT_RPORT_ONLINE :
225 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending);
226 bfa_fcs_rpf_send_rpsc2(rpf, NULL);
227 break;
228
229 case RPFSM_EVENT_RPORT_OFFLINE :
230 break;
231
232 default:
233 bfa_assert(0);
234 }
235}
236/**
237 * Called when Rport is created.
238 */
239void bfa_fcs_rpf_init(struct bfa_fcs_rport_s *rport)
240{
241 struct bfa_fcs_rpf_s *rpf = &rport->rpf;
242
243 bfa_trc(rport->fcs, rport->pid);
244 rpf->rport = rport;
245
246 bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_uninit);
247}
248
249/**
250 * Called when Rport becomes online
251 */
252void bfa_fcs_rpf_rport_online(struct bfa_fcs_rport_s *rport)
253{
254 bfa_trc(rport->fcs, rport->pid);
255
256 if (__fcs_min_cfg(rport->port->fcs))
257 return;
258
259 if (bfa_fcs_fabric_is_switched(rport->port->fabric))
260 bfa_sm_send_event(&rport->rpf, RPFSM_EVENT_RPORT_ONLINE);
261}
262
263/**
264 * Called when Rport becomes offline
265 */
266void bfa_fcs_rpf_rport_offline(struct bfa_fcs_rport_s *rport)
267{
268 bfa_trc(rport->fcs, rport->pid);
269
270 if (__fcs_min_cfg(rport->port->fcs))
271 return;
272
273 bfa_sm_send_event(&rport->rpf, RPFSM_EVENT_RPORT_OFFLINE);
274}
275
276static void
277bfa_fcs_rpf_timeout(void *arg)
278{
279 struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *) arg;
280 struct bfa_fcs_rport_s *rport = rpf->rport;
281
282 bfa_trc(rport->fcs, rport->pid);
283 bfa_sm_send_event(rpf, RPFSM_EVENT_TIMEOUT);
284}
285
286static void
287bfa_fcs_rpf_send_rpsc2(void *rpf_cbarg, struct bfa_fcxp_s *fcxp_alloced)
288{
289 struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *)rpf_cbarg;
290 struct bfa_fcs_rport_s *rport = rpf->rport;
291 struct bfa_fcs_port_s *port = rport->port;
292 struct fchs_s fchs;
293 int len;
294 struct bfa_fcxp_s *fcxp;
295
296 bfa_trc(rport->fcs, rport->pwwn);
297
298 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
299 if (!fcxp) {
300 bfa_fcxp_alloc_wait(port->fcs->bfa, &rpf->fcxp_wqe,
301 bfa_fcs_rpf_send_rpsc2, rpf);
302 return;
303 }
304 rpf->fcxp = fcxp;
305
306 len = fc_rpsc2_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
307 bfa_fcs_port_get_fcid(port), &rport->pid, 1);
308
309 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
310 FC_CLASS_3, len, &fchs, bfa_fcs_rpf_rpsc2_response,
311 rpf, FC_MAX_PDUSZ, FC_RA_TOV);
312 rport->stats.rpsc_sent++;
313 bfa_sm_send_event(rpf, RPFSM_EVENT_FCXP_SENT);
314
315}
316
317static void
318bfa_fcs_rpf_rpsc2_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
319 bfa_status_t req_status, u32 rsp_len,
320 u32 resid_len, struct fchs_s *rsp_fchs)
321{
322 struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *) cbarg;
323 struct bfa_fcs_rport_s *rport = rpf->rport;
324 struct fc_ls_rjt_s *ls_rjt;
325 struct fc_rpsc2_acc_s *rpsc2_acc;
326 u16 num_ents;
327
328 bfa_trc(rport->fcs, req_status);
329
330 if (req_status != BFA_STATUS_OK) {
331 bfa_trc(rport->fcs, req_status);
332 if (req_status == BFA_STATUS_ETIMER)
333 rport->stats.rpsc_failed++;
334 bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR);
335 return;
336 }
337
338 rpsc2_acc = (struct fc_rpsc2_acc_s *) BFA_FCXP_RSP_PLD(fcxp);
339 if (rpsc2_acc->els_cmd == FC_ELS_ACC) {
340 rport->stats.rpsc_accs++;
341 num_ents = bfa_os_ntohs(rpsc2_acc->num_pids);
342 bfa_trc(rport->fcs, num_ents);
343 if (num_ents > 0) {
344 bfa_assert(rpsc2_acc->port_info[0].pid != rport->pid);
345 bfa_trc(rport->fcs,
346 bfa_os_ntohs(rpsc2_acc->port_info[0].pid));
347 bfa_trc(rport->fcs,
348 bfa_os_ntohs(rpsc2_acc->port_info[0].speed));
349 bfa_trc(rport->fcs,
350 bfa_os_ntohs(rpsc2_acc->port_info[0].index));
351 bfa_trc(rport->fcs,
352 rpsc2_acc->port_info[0].type);
353
354 if (rpsc2_acc->port_info[0].speed == 0) {
355 bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR);
356 return;
357 }
358
359 rpf->rpsc_speed = fc_rpsc_operspeed_to_bfa_speed(
360 bfa_os_ntohs(rpsc2_acc->port_info[0].speed));
361
362 bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_COMP);
363 }
364 } else {
365 ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
366 bfa_trc(rport->fcs, ls_rjt->reason_code);
367 bfa_trc(rport->fcs, ls_rjt->reason_code_expl);
368 rport->stats.rpsc_rejects++;
369 if (ls_rjt->reason_code == FC_LS_RJT_RSN_CMD_NOT_SUPP) {
370 bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_FAIL);
371 } else {
372 bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR);
373 }
374 }
375}
diff --git a/drivers/scsi/bfa/scn.c b/drivers/scsi/bfa/scn.c
new file mode 100644
index 000000000000..bd4771ff62c8
--- /dev/null
+++ b/drivers/scsi/bfa/scn.c
@@ -0,0 +1,482 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18#include <bfa.h>
19#include <bfa_svc.h>
20#include "fcs_lport.h"
21#include "fcs_rport.h"
22#include "fcs_ms.h"
23#include "fcs_trcmod.h"
24#include "fcs_fcxp.h"
25#include "fcs.h"
26#include "lport_priv.h"
27
28BFA_TRC_FILE(FCS, SCN);
29
30#define FC_QOS_RSCN_EVENT 0x0c
31#define FC_FABRIC_NAME_RSCN_EVENT 0x0d
32
33/*
34 * forward declarations
35 */
36static void bfa_fcs_port_scn_send_scr(void *scn_cbarg,
37 struct bfa_fcxp_s *fcxp_alloced);
38static void bfa_fcs_port_scn_scr_response(void *fcsarg,
39 struct bfa_fcxp_s *fcxp,
40 void *cbarg,
41 bfa_status_t req_status,
42 u32 rsp_len,
43 u32 resid_len,
44 struct fchs_s *rsp_fchs);
45static void bfa_fcs_port_scn_send_ls_acc(struct bfa_fcs_port_s *port,
46 struct fchs_s *rx_fchs);
47static void bfa_fcs_port_scn_timeout(void *arg);
48
49/**
50 * fcs_scm_sm FCS SCN state machine
51 */
52
53/**
54 * VPort SCN State Machine events
55 */
56enum port_scn_event {
57 SCNSM_EVENT_PORT_ONLINE = 1,
58 SCNSM_EVENT_PORT_OFFLINE = 2,
59 SCNSM_EVENT_RSP_OK = 3,
60 SCNSM_EVENT_RSP_ERROR = 4,
61 SCNSM_EVENT_TIMEOUT = 5,
62 SCNSM_EVENT_SCR_SENT = 6,
63};
64
65static void bfa_fcs_port_scn_sm_offline(struct bfa_fcs_port_scn_s *scn,
66 enum port_scn_event event);
67static void bfa_fcs_port_scn_sm_sending_scr(struct bfa_fcs_port_scn_s *scn,
68 enum port_scn_event event);
69static void bfa_fcs_port_scn_sm_scr(struct bfa_fcs_port_scn_s *scn,
70 enum port_scn_event event);
71static void bfa_fcs_port_scn_sm_scr_retry(struct bfa_fcs_port_scn_s *scn,
72 enum port_scn_event event);
73static void bfa_fcs_port_scn_sm_online(struct bfa_fcs_port_scn_s *scn,
74 enum port_scn_event event);
75
76/**
77 * Starting state - awaiting link up.
78 */
79static void
80bfa_fcs_port_scn_sm_offline(struct bfa_fcs_port_scn_s *scn,
81 enum port_scn_event event)
82{
83 switch (event) {
84 case SCNSM_EVENT_PORT_ONLINE:
85 bfa_sm_set_state(scn, bfa_fcs_port_scn_sm_sending_scr);
86 bfa_fcs_port_scn_send_scr(scn, NULL);
87 break;
88
89 case SCNSM_EVENT_PORT_OFFLINE:
90 break;
91
92 default:
93 bfa_assert(0);
94 }
95}
96
97static void
98bfa_fcs_port_scn_sm_sending_scr(struct bfa_fcs_port_scn_s *scn,
99 enum port_scn_event event)
100{
101 switch (event) {
102 case SCNSM_EVENT_SCR_SENT:
103 bfa_sm_set_state(scn, bfa_fcs_port_scn_sm_scr);
104 break;
105
106 case SCNSM_EVENT_PORT_OFFLINE:
107 bfa_sm_set_state(scn, bfa_fcs_port_scn_sm_offline);
108 bfa_fcxp_walloc_cancel(scn->port->fcs->bfa, &scn->fcxp_wqe);
109 break;
110
111 default:
112 bfa_assert(0);
113 }
114}
115
116static void
117bfa_fcs_port_scn_sm_scr(struct bfa_fcs_port_scn_s *scn,
118 enum port_scn_event event)
119{
120 struct bfa_fcs_port_s *port = scn->port;
121
122 switch (event) {
123 case SCNSM_EVENT_RSP_OK:
124 bfa_sm_set_state(scn, bfa_fcs_port_scn_sm_online);
125 break;
126
127 case SCNSM_EVENT_RSP_ERROR:
128 bfa_sm_set_state(scn, bfa_fcs_port_scn_sm_scr_retry);
129 bfa_timer_start(port->fcs->bfa, &scn->timer,
130 bfa_fcs_port_scn_timeout, scn,
131 BFA_FCS_RETRY_TIMEOUT);
132 break;
133
134 case SCNSM_EVENT_PORT_OFFLINE:
135 bfa_sm_set_state(scn, bfa_fcs_port_scn_sm_offline);
136 bfa_fcxp_discard(scn->fcxp);
137 break;
138
139 default:
140 bfa_assert(0);
141 }
142}
143
144static void
145bfa_fcs_port_scn_sm_scr_retry(struct bfa_fcs_port_scn_s *scn,
146 enum port_scn_event event)
147{
148 switch (event) {
149 case SCNSM_EVENT_TIMEOUT:
150 bfa_sm_set_state(scn, bfa_fcs_port_scn_sm_sending_scr);
151 bfa_fcs_port_scn_send_scr(scn, NULL);
152 break;
153
154 case SCNSM_EVENT_PORT_OFFLINE:
155 bfa_sm_set_state(scn, bfa_fcs_port_scn_sm_offline);
156 bfa_timer_stop(&scn->timer);
157 break;
158
159 default:
160 bfa_assert(0);
161 }
162}
163
164static void
165bfa_fcs_port_scn_sm_online(struct bfa_fcs_port_scn_s *scn,
166 enum port_scn_event event)
167{
168 switch (event) {
169 case SCNSM_EVENT_PORT_OFFLINE:
170 bfa_sm_set_state(scn, bfa_fcs_port_scn_sm_offline);
171 break;
172
173 default:
174 bfa_assert(0);
175 }
176}
177
178
179
180/**
181 * fcs_scn_private FCS SCN private functions
182 */
183
184/**
185 * This routine will be called to send a SCR command.
186 */
187static void
188bfa_fcs_port_scn_send_scr(void *scn_cbarg, struct bfa_fcxp_s *fcxp_alloced)
189{
190 struct bfa_fcs_port_scn_s *scn = scn_cbarg;
191 struct bfa_fcs_port_s *port = scn->port;
192 struct fchs_s fchs;
193 int len;
194 struct bfa_fcxp_s *fcxp;
195
196 bfa_trc(port->fcs, port->pid);
197 bfa_trc(port->fcs, port->port_cfg.pwwn);
198
199 fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
200 if (!fcxp) {
201 bfa_fcxp_alloc_wait(port->fcs->bfa, &scn->fcxp_wqe,
202 bfa_fcs_port_scn_send_scr, scn);
203 return;
204 }
205 scn->fcxp = fcxp;
206
207 /*
208 * Handle VU registrations for Base port only
209 */
210 if ((!port->vport) && bfa_ioc_get_fcmode(&port->fcs->bfa->ioc)) {
211 len = fc_scr_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
212 bfa_lps_is_brcd_fabric(port->fabric->lps),
213 port->pid, 0);
214 } else {
215 len = fc_scr_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), BFA_FALSE,
216 port->pid, 0);
217 }
218
219 bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
220 FC_CLASS_3, len, &fchs, bfa_fcs_port_scn_scr_response,
221 (void *)scn, FC_MAX_PDUSZ, FC_RA_TOV);
222
223 bfa_sm_send_event(scn, SCNSM_EVENT_SCR_SENT);
224}
225
226static void
227bfa_fcs_port_scn_scr_response(void *fcsarg, struct bfa_fcxp_s *fcxp,
228 void *cbarg, bfa_status_t req_status,
229 u32 rsp_len, u32 resid_len,
230 struct fchs_s *rsp_fchs)
231{
232 struct bfa_fcs_port_scn_s *scn = (struct bfa_fcs_port_scn_s *)cbarg;
233 struct bfa_fcs_port_s *port = scn->port;
234 struct fc_els_cmd_s *els_cmd;
235 struct fc_ls_rjt_s *ls_rjt;
236
237 bfa_trc(port->fcs, port->port_cfg.pwwn);
238
239 /*
240 * Sanity Checks
241 */
242 if (req_status != BFA_STATUS_OK) {
243 bfa_trc(port->fcs, req_status);
244 bfa_sm_send_event(scn, SCNSM_EVENT_RSP_ERROR);
245 return;
246 }
247
248 els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp);
249
250 switch (els_cmd->els_code) {
251
252 case FC_ELS_ACC:
253 bfa_sm_send_event(scn, SCNSM_EVENT_RSP_OK);
254 break;
255
256 case FC_ELS_LS_RJT:
257
258 ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
259
260 bfa_trc(port->fcs, ls_rjt->reason_code);
261 bfa_trc(port->fcs, ls_rjt->reason_code_expl);
262
263 bfa_sm_send_event(scn, SCNSM_EVENT_RSP_ERROR);
264 break;
265
266 default:
267 bfa_sm_send_event(scn, SCNSM_EVENT_RSP_ERROR);
268 }
269}
270
271/*
272 * Send a LS Accept
273 */
274static void
275bfa_fcs_port_scn_send_ls_acc(struct bfa_fcs_port_s *port,
276 struct fchs_s *rx_fchs)
277{
278 struct fchs_s fchs;
279 struct bfa_fcxp_s *fcxp;
280 struct bfa_rport_s *bfa_rport = NULL;
281 int len;
282
283 bfa_trc(port->fcs, rx_fchs->s_id);
284
285 fcxp = bfa_fcs_fcxp_alloc(port->fcs);
286 if (!fcxp)
287 return;
288
289 len = fc_ls_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rx_fchs->s_id,
290 bfa_fcs_port_get_fcid(port), rx_fchs->ox_id);
291
292 bfa_fcxp_send(fcxp, bfa_rport, port->fabric->vf_id, port->lp_tag,
293 BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
294 FC_MAX_PDUSZ, 0);
295}
296
297/**
298 * This routine will be called by bfa_timer on timer timeouts.
299 *
300 * param[in] vport - pointer to bfa_fcs_port_t.
301 * param[out] vport_status - pointer to return vport status in
302 *
303 * return
304 * void
305 *
306* Special Considerations:
307 *
308 * note
309 */
310static void
311bfa_fcs_port_scn_timeout(void *arg)
312{
313 struct bfa_fcs_port_scn_s *scn = (struct bfa_fcs_port_scn_s *)arg;
314
315 bfa_sm_send_event(scn, SCNSM_EVENT_TIMEOUT);
316}
317
318
319
320/**
321 * fcs_scn_public FCS state change notification public interfaces
322 */
323
324/*
325 * Functions called by port/fab
326 */
327void
328bfa_fcs_port_scn_init(struct bfa_fcs_port_s *port)
329{
330 struct bfa_fcs_port_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port);
331
332 scn->port = port;
333 bfa_sm_set_state(scn, bfa_fcs_port_scn_sm_offline);
334}
335
336void
337bfa_fcs_port_scn_offline(struct bfa_fcs_port_s *port)
338{
339 struct bfa_fcs_port_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port);
340
341 scn->port = port;
342 bfa_sm_send_event(scn, SCNSM_EVENT_PORT_OFFLINE);
343}
344
345void
346bfa_fcs_port_scn_online(struct bfa_fcs_port_s *port)
347{
348 struct bfa_fcs_port_scn_s *scn = BFA_FCS_GET_SCN_FROM_PORT(port);
349
350 scn->port = port;
351 bfa_sm_send_event(scn, SCNSM_EVENT_PORT_ONLINE);
352}
353
354static void
355bfa_fcs_port_scn_portid_rscn(struct bfa_fcs_port_s *port, u32 rpid)
356{
357 struct bfa_fcs_rport_s *rport;
358
359 bfa_trc(port->fcs, rpid);
360
361 /**
362 * If this is an unknown device, then it just came online.
363 * Otherwise let rport handle the RSCN event.
364 */
365 rport = bfa_fcs_port_get_rport_by_pid(port, rpid);
366 if (rport == NULL) {
367 /*
368 * If min cfg mode is enabled, we donot need to
369 * discover any new rports.
370 */
371 if (!__fcs_min_cfg(port->fcs))
372 rport = bfa_fcs_rport_create(port, rpid);
373 } else {
374 bfa_fcs_rport_scn(rport);
375 }
376}
377
378/**
379 * rscn format based PID comparison
380 */
381#define __fc_pid_match(__c0, __c1, __fmt) \
382 (((__fmt) == FC_RSCN_FORMAT_FABRIC) || \
383 (((__fmt) == FC_RSCN_FORMAT_DOMAIN) && \
384 ((__c0)[0] == (__c1)[0])) || \
385 (((__fmt) == FC_RSCN_FORMAT_AREA) && \
386 ((__c0)[0] == (__c1)[0]) && \
387 ((__c0)[1] == (__c1)[1])))
388
389static void
390bfa_fcs_port_scn_multiport_rscn(struct bfa_fcs_port_s *port,
391 enum fc_rscn_format format, u32 rscn_pid)
392{
393 struct bfa_fcs_rport_s *rport;
394 struct list_head *qe, *qe_next;
395 u8 *c0, *c1;
396
397 bfa_trc(port->fcs, format);
398 bfa_trc(port->fcs, rscn_pid);
399
400 c0 = (u8 *) &rscn_pid;
401
402 list_for_each_safe(qe, qe_next, &port->rport_q) {
403 rport = (struct bfa_fcs_rport_s *)qe;
404 c1 = (u8 *) &rport->pid;
405 if (__fc_pid_match(c0, c1, format))
406 bfa_fcs_rport_scn(rport);
407 }
408}
409
410void
411bfa_fcs_port_scn_process_rscn(struct bfa_fcs_port_s *port, struct fchs_s *fchs,
412 u32 len)
413{
414 struct fc_rscn_pl_s *rscn = (struct fc_rscn_pl_s *) (fchs + 1);
415 int num_entries;
416 u32 rscn_pid;
417 bfa_boolean_t nsquery = BFA_FALSE;
418 int i = 0;
419
420 num_entries =
421 (bfa_os_ntohs(rscn->payldlen) -
422 sizeof(u32)) / sizeof(rscn->event[0]);
423
424 bfa_trc(port->fcs, num_entries);
425
426 port->stats.num_rscn++;
427
428 bfa_fcs_port_scn_send_ls_acc(port, fchs);
429
430 for (i = 0; i < num_entries; i++) {
431 rscn_pid = rscn->event[i].portid;
432
433 bfa_trc(port->fcs, rscn->event[i].format);
434 bfa_trc(port->fcs, rscn_pid);
435
436 switch (rscn->event[i].format) {
437 case FC_RSCN_FORMAT_PORTID:
438 if (rscn->event[i].qualifier == FC_QOS_RSCN_EVENT) {
439 /*
440 * Ignore this event. f/w would have processed
441 * it
442 */
443 bfa_trc(port->fcs, rscn_pid);
444 } else {
445 port->stats.num_portid_rscn++;
446 bfa_fcs_port_scn_portid_rscn(port, rscn_pid);
447 }
448 break;
449
450 case FC_RSCN_FORMAT_FABRIC:
451 if (rscn->event[i].qualifier ==
452 FC_FABRIC_NAME_RSCN_EVENT) {
453 bfa_fcs_port_ms_fabric_rscn(port);
454 break;
455 }
456 /*
457 * !!!!!!!!! Fall Through !!!!!!!!!!!!!
458 */
459
460 case FC_RSCN_FORMAT_AREA:
461 case FC_RSCN_FORMAT_DOMAIN:
462 nsquery = BFA_TRUE;
463 bfa_fcs_port_scn_multiport_rscn(port,
464 rscn->event[i].format,
465 rscn_pid);
466 break;
467
468 default:
469 bfa_assert(0);
470 nsquery = BFA_TRUE;
471 }
472 }
473
474 /**
475 * If any of area, domain or fabric RSCN is received, do a fresh discovery
476 * to find new devices.
477 */
478 if (nsquery)
479 bfa_fcs_port_ns_query(port);
480}
481
482
diff --git a/drivers/scsi/bfa/vfapi.c b/drivers/scsi/bfa/vfapi.c
new file mode 100644
index 000000000000..31d81fe2fc48
--- /dev/null
+++ b/drivers/scsi/bfa/vfapi.c
@@ -0,0 +1,292 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * vfapi.c Fabric module implementation.
20 */
21
22#include "fcs_fabric.h"
23#include "fcs_trcmod.h"
24
25BFA_TRC_FILE(FCS, VFAPI);
26
27/**
28 * fcs_vf_api virtual fabrics API
29 */
30
31/**
32 * Enable VF mode.
33 *
34 * @param[in] fcs fcs module instance
35 * @param[in] vf_id default vf_id of port, FC_VF_ID_NULL
36 * to use standard default vf_id of 1.
37 *
38 * @retval BFA_STATUS_OK vf mode is enabled
39 * @retval BFA_STATUS_BUSY Port is active. Port must be disabled
40 * before VF mode can be enabled.
41 */
42bfa_status_t
43bfa_fcs_vf_mode_enable(struct bfa_fcs_s *fcs, u16 vf_id)
44{
45 return BFA_STATUS_OK;
46}
47
48/**
49 * Disable VF mode.
50 *
51 * @param[in] fcs fcs module instance
52 *
53 * @retval BFA_STATUS_OK vf mode is disabled
54 * @retval BFA_STATUS_BUSY VFs are present and being used. All
55 * VFs must be deleted before disabling
56 * VF mode.
57 */
58bfa_status_t
59bfa_fcs_vf_mode_disable(struct bfa_fcs_s *fcs)
60{
61 return BFA_STATUS_OK;
62}
63
64/**
65 * Create a new VF instance.
66 *
67 * A new VF is created using the given VF configuration. A VF is identified
68 * by VF id. No duplicate VF creation is allowed with the same VF id. Once
69 * a VF is created, VF is automatically started after link initialization
70 * and EVFP exchange is completed.
71 *
72 * param[in] vf - FCS vf data structure. Memory is
73 * allocated by caller (driver)
74 * param[in] fcs - FCS module
75 * param[in] vf_cfg - VF configuration
76 * param[in] vf_drv - Opaque handle back to the driver's
77 * virtual vf structure
78 *
79 * retval BFA_STATUS_OK VF creation is successful
80 * retval BFA_STATUS_FAILED VF creation failed
81 * retval BFA_STATUS_EEXIST A VF exists with the given vf_id
82 */
83bfa_status_t
84bfa_fcs_vf_create(bfa_fcs_vf_t *vf, struct bfa_fcs_s *fcs, u16 vf_id,
85 struct bfa_port_cfg_s *port_cfg, struct bfad_vf_s *vf_drv)
86{
87 bfa_trc(fcs, vf_id);
88 return BFA_STATUS_OK;
89}
90
91/**
92 * Use this function to delete a BFA VF object. VF object should
93 * be stopped before this function call.
94 *
95 * param[in] vf - pointer to bfa_vf_t.
96 *
97 * retval BFA_STATUS_OK On vf deletion success
98 * retval BFA_STATUS_BUSY VF is not in a stopped state
99 * retval BFA_STATUS_INPROGRESS VF deletion in in progress
100 */
101bfa_status_t
102bfa_fcs_vf_delete(bfa_fcs_vf_t *vf)
103{
104 bfa_trc(vf->fcs, vf->vf_id);
105 return BFA_STATUS_OK;
106}
107
108/**
109 * Start participation in VF. This triggers login to the virtual fabric.
110 *
111 * param[in] vf - pointer to bfa_vf_t.
112 *
113 * return None
114 */
115void
116bfa_fcs_vf_start(bfa_fcs_vf_t *vf)
117{
118 bfa_trc(vf->fcs, vf->vf_id);
119}
120
121/**
122 * Logout with the virtual fabric.
123 *
124 * param[in] vf - pointer to bfa_vf_t.
125 *
126 * retval BFA_STATUS_OK On success.
127 * retval BFA_STATUS_INPROGRESS VF is being stopped.
128 */
129bfa_status_t
130bfa_fcs_vf_stop(bfa_fcs_vf_t *vf)
131{
132 bfa_trc(vf->fcs, vf->vf_id);
133 return BFA_STATUS_OK;
134}
135
136/**
137 * Returns attributes of the given VF.
138 *
139 * param[in] vf pointer to bfa_vf_t.
140 * param[out] vf_attr vf attributes returned
141 *
142 * return None
143 */
144void
145bfa_fcs_vf_get_attr(bfa_fcs_vf_t *vf, struct bfa_vf_attr_s *vf_attr)
146{
147 bfa_trc(vf->fcs, vf->vf_id);
148}
149
150/**
151 * Return statistics associated with the given vf.
152 *
153 * param[in] vf pointer to bfa_vf_t.
154 * param[out] vf_stats vf statistics returned
155 *
156 * @return None
157 */
158void
159bfa_fcs_vf_get_stats(bfa_fcs_vf_t *vf, struct bfa_vf_stats_s *vf_stats)
160{
161 bfa_os_memcpy(vf_stats, &vf->stats, sizeof(struct bfa_vf_stats_s));
162 return;
163}
164
165void
166/**
167 * clear statistics associated with the given vf.
168 *
169 * param[in] vf pointer to bfa_vf_t.
170 *
171 * @return None
172 */
173bfa_fcs_vf_clear_stats(bfa_fcs_vf_t *vf)
174{
175 bfa_os_memset(&vf->stats, 0, sizeof(struct bfa_vf_stats_s));
176 return;
177}
178
179/**
180 * Returns FCS vf structure for a given vf_id.
181 *
182 * param[in] vf_id - VF_ID
183 *
184 * return
185 * If lookup succeeds, retuns fcs vf object, otherwise returns NULL
186 */
187bfa_fcs_vf_t *
188bfa_fcs_vf_lookup(struct bfa_fcs_s *fcs, u16 vf_id)
189{
190 bfa_trc(fcs, vf_id);
191 if (vf_id == FC_VF_ID_NULL)
192 return (&fcs->fabric);
193
194 /**
195 * @todo vf support
196 */
197
198 return NULL;
199}
200
201/**
202 * Returns driver VF structure for a given FCS vf.
203 *
204 * param[in] vf - pointer to bfa_vf_t
205 *
206 * return Driver VF structure
207 */
208struct bfad_vf_s *
209bfa_fcs_vf_get_drv_vf(bfa_fcs_vf_t *vf)
210{
211 bfa_assert(vf);
212 bfa_trc(vf->fcs, vf->vf_id);
213 return vf->vf_drv;
214}
215
216/**
217 * Return the list of VFs configured.
218 *
219 * param[in] fcs fcs module instance
220 * param[out] vf_ids returned list of vf_ids
221 * param[in,out] nvfs in:size of vf_ids array,
222 * out:total elements present,
223 * actual elements returned is limited by the size
224 *
225 * return Driver VF structure
226 */
227void
228bfa_fcs_vf_list(struct bfa_fcs_s *fcs, u16 *vf_ids, int *nvfs)
229{
230 bfa_trc(fcs, *nvfs);
231}
232
233/**
234 * Return the list of all VFs visible from fabric.
235 *
236 * param[in] fcs fcs module instance
237 * param[out] vf_ids returned list of vf_ids
238 * param[in,out] nvfs in:size of vf_ids array,
239 * out:total elements present,
240 * actual elements returned is limited by the size
241 *
242 * return Driver VF structure
243 */
244void
245bfa_fcs_vf_list_all(struct bfa_fcs_s *fcs, u16 *vf_ids, int *nvfs)
246{
247 bfa_trc(fcs, *nvfs);
248}
249
250/**
251 * Return the list of local logical ports present in the given VF.
252 *
253 * param[in] vf vf for which logical ports are returned
254 * param[out] lpwwn returned logical port wwn list
255 * param[in,out] nlports in:size of lpwwn list;
256 * out:total elements present,
257 * actual elements returned is limited by the size
258 *
259 */
260void
261bfa_fcs_vf_get_ports(bfa_fcs_vf_t *vf, wwn_t lpwwn[], int *nlports)
262{
263 struct list_head *qe;
264 struct bfa_fcs_vport_s *vport;
265 int i;
266 struct bfa_fcs_s *fcs;
267
268 if (vf == NULL || lpwwn == NULL || *nlports == 0)
269 return;
270
271 fcs = vf->fcs;
272
273 bfa_trc(fcs, vf->vf_id);
274 bfa_trc(fcs, (u32) *nlports);
275
276 i = 0;
277 lpwwn[i++] = vf->bport.port_cfg.pwwn;
278
279 list_for_each(qe, &vf->vport_q) {
280 if (i >= *nlports)
281 break;
282
283 vport = (struct bfa_fcs_vport_s *) qe;
284 lpwwn[i++] = vport->lport.port_cfg.pwwn;
285 }
286
287 bfa_trc(fcs, i);
288 *nlports = i;
289 return;
290}
291
292
diff --git a/drivers/scsi/bfa/vport.c b/drivers/scsi/bfa/vport.c
new file mode 100644
index 000000000000..c10af06c5714
--- /dev/null
+++ b/drivers/scsi/bfa/vport.c
@@ -0,0 +1,891 @@
1/*
2 * Copyright (c) 2005-2009 Brocade Communications Systems, Inc.
3 * All rights reserved
4 * www.brocade.com
5 *
6 * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License (GPL) Version 2 as
10 * published by the Free Software Foundation
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 */
17
18/**
19 * bfa_fcs_vport.c FCS virtual port state machine
20 */
21
22#include <bfa.h>
23#include <bfa_svc.h>
24#include <fcbuild.h>
25#include "fcs_fabric.h"
26#include "fcs_lport.h"
27#include "fcs_vport.h"
28#include "fcs_trcmod.h"
29#include "fcs.h"
30#include <aen/bfa_aen_lport.h>
31
32BFA_TRC_FILE(FCS, VPORT);
33
34#define __vport_fcs(__vp) (__vp)->lport.fcs
35#define __vport_pwwn(__vp) (__vp)->lport.port_cfg.pwwn
36#define __vport_nwwn(__vp) (__vp)->lport.port_cfg.nwwn
37#define __vport_bfa(__vp) (__vp)->lport.fcs->bfa
38#define __vport_fcid(__vp) (__vp)->lport.pid
39#define __vport_fabric(__vp) (__vp)->lport.fabric
40#define __vport_vfid(__vp) (__vp)->lport.fabric->vf_id
41
42#define BFA_FCS_VPORT_MAX_RETRIES 5
43/*
44 * Forward declarations
45 */
46static void bfa_fcs_vport_do_fdisc(struct bfa_fcs_vport_s *vport);
47static void bfa_fcs_vport_timeout(void *vport_arg);
48static void bfa_fcs_vport_do_logo(struct bfa_fcs_vport_s *vport);
49static void bfa_fcs_vport_free(struct bfa_fcs_vport_s *vport);
50
51/**
52 * fcs_vport_sm FCS virtual port state machine
53 */
54
55/**
56 * VPort State Machine events
57 */
58enum bfa_fcs_vport_event {
59 BFA_FCS_VPORT_SM_CREATE = 1, /* vport create event */
60 BFA_FCS_VPORT_SM_DELETE = 2, /* vport delete event */
61 BFA_FCS_VPORT_SM_START = 3, /* vport start request */
62 BFA_FCS_VPORT_SM_STOP = 4, /* stop: unsupported */
63 BFA_FCS_VPORT_SM_ONLINE = 5, /* fabric online */
64 BFA_FCS_VPORT_SM_OFFLINE = 6, /* fabric offline event */
65 BFA_FCS_VPORT_SM_FRMSENT = 7, /* fdisc/logo sent events */
66 BFA_FCS_VPORT_SM_RSP_OK = 8, /* good response */
67 BFA_FCS_VPORT_SM_RSP_ERROR = 9, /* error/bad response */
68 BFA_FCS_VPORT_SM_TIMEOUT = 10, /* delay timer event */
69 BFA_FCS_VPORT_SM_DELCOMP = 11, /* lport delete completion */
70 BFA_FCS_VPORT_SM_RSP_DUP_WWN = 12, /* Dup wnn error */
71 BFA_FCS_VPORT_SM_RSP_FAILED = 13, /* non-retryable failure */
72};
73
74static void bfa_fcs_vport_sm_uninit(struct bfa_fcs_vport_s *vport,
75 enum bfa_fcs_vport_event event);
76static void bfa_fcs_vport_sm_created(struct bfa_fcs_vport_s *vport,
77 enum bfa_fcs_vport_event event);
78static void bfa_fcs_vport_sm_offline(struct bfa_fcs_vport_s *vport,
79 enum bfa_fcs_vport_event event);
80static void bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vport_s *vport,
81 enum bfa_fcs_vport_event event);
82static void bfa_fcs_vport_sm_fdisc_retry(struct bfa_fcs_vport_s *vport,
83 enum bfa_fcs_vport_event event);
84static void bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s *vport,
85 enum bfa_fcs_vport_event event);
86static void bfa_fcs_vport_sm_deleting(struct bfa_fcs_vport_s *vport,
87 enum bfa_fcs_vport_event event);
88static void bfa_fcs_vport_sm_cleanup(struct bfa_fcs_vport_s *vport,
89 enum bfa_fcs_vport_event event);
90static void bfa_fcs_vport_sm_logo(struct bfa_fcs_vport_s *vport,
91 enum bfa_fcs_vport_event event);
92static void bfa_fcs_vport_sm_error(struct bfa_fcs_vport_s *vport,
93 enum bfa_fcs_vport_event event);
94
95static struct bfa_sm_table_s vport_sm_table[] = {
96 {BFA_SM(bfa_fcs_vport_sm_uninit), BFA_FCS_VPORT_UNINIT},
97 {BFA_SM(bfa_fcs_vport_sm_created), BFA_FCS_VPORT_CREATED},
98 {BFA_SM(bfa_fcs_vport_sm_offline), BFA_FCS_VPORT_OFFLINE},
99 {BFA_SM(bfa_fcs_vport_sm_fdisc), BFA_FCS_VPORT_FDISC},
100 {BFA_SM(bfa_fcs_vport_sm_fdisc_retry), BFA_FCS_VPORT_FDISC_RETRY},
101 {BFA_SM(bfa_fcs_vport_sm_online), BFA_FCS_VPORT_ONLINE},
102 {BFA_SM(bfa_fcs_vport_sm_deleting), BFA_FCS_VPORT_DELETING},
103 {BFA_SM(bfa_fcs_vport_sm_cleanup), BFA_FCS_VPORT_CLEANUP},
104 {BFA_SM(bfa_fcs_vport_sm_logo), BFA_FCS_VPORT_LOGO},
105 {BFA_SM(bfa_fcs_vport_sm_error), BFA_FCS_VPORT_ERROR}
106};
107
108/**
109 * Beginning state.
110 */
111static void
112bfa_fcs_vport_sm_uninit(struct bfa_fcs_vport_s *vport,
113 enum bfa_fcs_vport_event event)
114{
115 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
116 bfa_trc(__vport_fcs(vport), event);
117
118 switch (event) {
119 case BFA_FCS_VPORT_SM_CREATE:
120 bfa_sm_set_state(vport, bfa_fcs_vport_sm_created);
121 bfa_fcs_fabric_addvport(__vport_fabric(vport), vport);
122 break;
123
124 default:
125 bfa_assert(0);
126 }
127}
128
129/**
130 * Created state - a start event is required to start up the state machine.
131 */
132static void
133bfa_fcs_vport_sm_created(struct bfa_fcs_vport_s *vport,
134 enum bfa_fcs_vport_event event)
135{
136 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
137 bfa_trc(__vport_fcs(vport), event);
138
139 switch (event) {
140 case BFA_FCS_VPORT_SM_START:
141 if (bfa_fcs_fabric_is_online(__vport_fabric(vport))
142 && bfa_fcs_fabric_npiv_capable(__vport_fabric(vport))) {
143 bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc);
144 bfa_fcs_vport_do_fdisc(vport);
145 } else {
146 /**
147 * Fabric is offline or not NPIV capable, stay in
148 * offline state.
149 */
150 vport->vport_stats.fab_no_npiv++;
151 bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
152 }
153 break;
154
155 case BFA_FCS_VPORT_SM_DELETE:
156 bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
157 bfa_fcs_port_delete(&vport->lport);
158 break;
159
160 case BFA_FCS_VPORT_SM_ONLINE:
161 case BFA_FCS_VPORT_SM_OFFLINE:
162 /**
163 * Ignore ONLINE/OFFLINE events from fabric till vport is started.
164 */
165 break;
166
167 default:
168 bfa_assert(0);
169 }
170}
171
172/**
173 * Offline state - awaiting ONLINE event from fabric SM.
174 */
175static void
176bfa_fcs_vport_sm_offline(struct bfa_fcs_vport_s *vport,
177 enum bfa_fcs_vport_event event)
178{
179 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
180 bfa_trc(__vport_fcs(vport), event);
181
182 switch (event) {
183 case BFA_FCS_VPORT_SM_DELETE:
184 bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
185 bfa_fcs_port_delete(&vport->lport);
186 break;
187
188 case BFA_FCS_VPORT_SM_ONLINE:
189 bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc);
190 vport->fdisc_retries = 0;
191 bfa_fcs_vport_do_fdisc(vport);
192 break;
193
194 case BFA_FCS_VPORT_SM_OFFLINE:
195 /*
196 * This can happen if the vport couldn't be initialzied due
197 * the fact that the npiv was not enabled on the switch. In
198 * that case we will put the vport in offline state. However,
199 * the link can go down and cause the this event to be sent when
200 * we are already offline. Ignore it.
201 */
202 break;
203
204 default:
205 bfa_assert(0);
206 }
207}
208
209/**
210 * FDISC is sent and awaiting reply from fabric.
211 */
212static void
213bfa_fcs_vport_sm_fdisc(struct bfa_fcs_vport_s *vport,
214 enum bfa_fcs_vport_event event)
215{
216 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
217 bfa_trc(__vport_fcs(vport), event);
218
219 switch (event) {
220 case BFA_FCS_VPORT_SM_DELETE:
221 bfa_sm_set_state(vport, bfa_fcs_vport_sm_logo);
222 bfa_lps_discard(vport->lps);
223 bfa_fcs_vport_do_logo(vport);
224 break;
225
226 case BFA_FCS_VPORT_SM_OFFLINE:
227 bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
228 bfa_lps_discard(vport->lps);
229 break;
230
231 case BFA_FCS_VPORT_SM_RSP_OK:
232 bfa_sm_set_state(vport, bfa_fcs_vport_sm_online);
233 bfa_fcs_port_online(&vport->lport);
234 break;
235
236 case BFA_FCS_VPORT_SM_RSP_ERROR:
237 bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc_retry);
238 bfa_timer_start(__vport_bfa(vport), &vport->timer,
239 bfa_fcs_vport_timeout, vport,
240 BFA_FCS_RETRY_TIMEOUT);
241 break;
242
243 case BFA_FCS_VPORT_SM_RSP_FAILED:
244 bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
245 break;
246
247 case BFA_FCS_VPORT_SM_RSP_DUP_WWN:
248 bfa_sm_set_state(vport, bfa_fcs_vport_sm_error);
249 break;
250
251 default:
252 bfa_assert(0);
253 }
254}
255
256/**
257 * FDISC attempt failed - a timer is active to retry FDISC.
258 */
259static void
260bfa_fcs_vport_sm_fdisc_retry(struct bfa_fcs_vport_s *vport,
261 enum bfa_fcs_vport_event event)
262{
263 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
264 bfa_trc(__vport_fcs(vport), event);
265
266 switch (event) {
267 case BFA_FCS_VPORT_SM_DELETE:
268 bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
269 bfa_timer_stop(&vport->timer);
270 bfa_fcs_port_delete(&vport->lport);
271 break;
272
273 case BFA_FCS_VPORT_SM_OFFLINE:
274 bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
275 bfa_timer_stop(&vport->timer);
276 break;
277
278 case BFA_FCS_VPORT_SM_TIMEOUT:
279 bfa_sm_set_state(vport, bfa_fcs_vport_sm_fdisc);
280 vport->vport_stats.fdisc_retries++;
281 vport->fdisc_retries++;
282 bfa_fcs_vport_do_fdisc(vport);
283 break;
284
285 default:
286 bfa_assert(0);
287 }
288}
289
290/**
291 * Vport is online (FDISC is complete).
292 */
293static void
294bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s *vport,
295 enum bfa_fcs_vport_event event)
296{
297 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
298 bfa_trc(__vport_fcs(vport), event);
299
300 switch (event) {
301 case BFA_FCS_VPORT_SM_DELETE:
302 bfa_sm_set_state(vport, bfa_fcs_vport_sm_deleting);
303 bfa_fcs_port_delete(&vport->lport);
304 break;
305
306 case BFA_FCS_VPORT_SM_OFFLINE:
307 bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline);
308 bfa_lps_discard(vport->lps);
309 bfa_fcs_port_offline(&vport->lport);
310 break;
311
312 default:
313 bfa_assert(0);
314 }
315}
316
317/**
318 * Vport is being deleted - awaiting lport delete completion to send
319 * LOGO to fabric.
320 */
321static void
322bfa_fcs_vport_sm_deleting(struct bfa_fcs_vport_s *vport,
323 enum bfa_fcs_vport_event event)
324{
325 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
326 bfa_trc(__vport_fcs(vport), event);
327
328 switch (event) {
329 case BFA_FCS_VPORT_SM_DELETE:
330 break;
331
332 case BFA_FCS_VPORT_SM_DELCOMP:
333 bfa_sm_set_state(vport, bfa_fcs_vport_sm_logo);
334 bfa_fcs_vport_do_logo(vport);
335 break;
336
337 case BFA_FCS_VPORT_SM_OFFLINE:
338 bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup);
339 break;
340
341 default:
342 bfa_assert(0);
343 }
344}
345
346/**
347 * Error State.
348 * This state will be set when the Vport Creation fails due to errors like
349 * Dup WWN. In this state only operation allowed is a Vport Delete.
350 */
351static void
352bfa_fcs_vport_sm_error(struct bfa_fcs_vport_s *vport,
353 enum bfa_fcs_vport_event event)
354{
355 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
356 bfa_trc(__vport_fcs(vport), event);
357
358 switch (event) {
359 case BFA_FCS_VPORT_SM_DELETE:
360 bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit);
361 bfa_fcs_vport_free(vport);
362 break;
363
364 default:
365 bfa_trc(__vport_fcs(vport), event);
366 }
367}
368
369/**
370 * Lport cleanup is in progress since vport is being deleted. Fabric is
371 * offline, so no LOGO is needed to complete vport deletion.
372 */
373static void
374bfa_fcs_vport_sm_cleanup(struct bfa_fcs_vport_s *vport,
375 enum bfa_fcs_vport_event event)
376{
377 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
378 bfa_trc(__vport_fcs(vport), event);
379
380 switch (event) {
381 case BFA_FCS_VPORT_SM_DELCOMP:
382 bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit);
383 bfa_fcs_vport_free(vport);
384 break;
385
386 case BFA_FCS_VPORT_SM_DELETE:
387 break;
388
389 default:
390 bfa_assert(0);
391 }
392}
393
394/**
395 * LOGO is sent to fabric. Vport delete is in progress. Lport delete cleanup
396 * is done.
397 */
398static void
399bfa_fcs_vport_sm_logo(struct bfa_fcs_vport_s *vport,
400 enum bfa_fcs_vport_event event)
401{
402 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
403 bfa_trc(__vport_fcs(vport), event);
404
405 switch (event) {
406 case BFA_FCS_VPORT_SM_OFFLINE:
407 bfa_lps_discard(vport->lps);
408 /*
409 * !!! fall through !!!
410 */
411
412 case BFA_FCS_VPORT_SM_RSP_OK:
413 case BFA_FCS_VPORT_SM_RSP_ERROR:
414 bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit);
415 bfa_fcs_vport_free(vport);
416 break;
417
418 case BFA_FCS_VPORT_SM_DELETE:
419 break;
420
421 default:
422 bfa_assert(0);
423 }
424}
425
426
427
428/**
429 * fcs_vport_private FCS virtual port private functions
430 */
431
432/**
433 * Send AEN notification
434 */
435static void
436bfa_fcs_vport_aen_post(bfa_fcs_lport_t *port, enum bfa_lport_aen_event event)
437{
438 union bfa_aen_data_u aen_data;
439 struct bfa_log_mod_s *logmod = port->fcs->logm;
440 enum bfa_port_role role = port->port_cfg.roles;
441 wwn_t lpwwn = bfa_fcs_port_get_pwwn(port);
442 char lpwwn_ptr[BFA_STRING_32];
443 char *role_str[BFA_PORT_ROLE_FCP_MAX / 2 + 1] =
444 { "Initiator", "Target", "IPFC" };
445
446 wwn2str(lpwwn_ptr, lpwwn);
447
448 bfa_assert(role <= BFA_PORT_ROLE_FCP_MAX);
449
450 switch (event) {
451 case BFA_LPORT_AEN_NPIV_DUP_WWN:
452 bfa_log(logmod, BFA_AEN_LPORT_NPIV_DUP_WWN, lpwwn_ptr,
453 role_str[role / 2]);
454 break;
455 case BFA_LPORT_AEN_NPIV_FABRIC_MAX:
456 bfa_log(logmod, BFA_AEN_LPORT_NPIV_FABRIC_MAX, lpwwn_ptr,
457 role_str[role / 2]);
458 break;
459 case BFA_LPORT_AEN_NPIV_UNKNOWN:
460 bfa_log(logmod, BFA_AEN_LPORT_NPIV_UNKNOWN, lpwwn_ptr,
461 role_str[role / 2]);
462 break;
463 default:
464 break;
465 }
466
467 aen_data.lport.vf_id = port->fabric->vf_id;
468 aen_data.lport.roles = role;
469 aen_data.lport.ppwwn =
470 bfa_fcs_port_get_pwwn(bfa_fcs_get_base_port(port->fcs));
471 aen_data.lport.lpwwn = lpwwn;
472}
473
474/**
475 * This routine will be called to send a FDISC command.
476 */
477static void
478bfa_fcs_vport_do_fdisc(struct bfa_fcs_vport_s *vport)
479{
480 bfa_lps_fdisc(vport->lps, vport,
481 bfa_pport_get_maxfrsize(__vport_bfa(vport)),
482 __vport_pwwn(vport), __vport_nwwn(vport));
483 vport->vport_stats.fdisc_sent++;
484}
485
486static void
487bfa_fcs_vport_fdisc_rejected(struct bfa_fcs_vport_s *vport)
488{
489 u8 lsrjt_rsn = bfa_lps_get_lsrjt_rsn(vport->lps);
490 u8 lsrjt_expl = bfa_lps_get_lsrjt_expl(vport->lps);
491
492 bfa_trc(__vport_fcs(vport), lsrjt_rsn);
493 bfa_trc(__vport_fcs(vport), lsrjt_expl);
494
495 /*
496 * For certain reason codes, we don't want to retry.
497 */
498 switch (bfa_lps_get_lsrjt_expl(vport->lps)) {
499 case FC_LS_RJT_EXP_INV_PORT_NAME: /* by brocade */
500 case FC_LS_RJT_EXP_INVALID_NPORT_ID: /* by Cisco */
501 if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES)
502 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
503 else {
504 bfa_fcs_vport_aen_post(&vport->lport,
505 BFA_LPORT_AEN_NPIV_DUP_WWN);
506 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_DUP_WWN);
507 }
508 break;
509
510 case FC_LS_RJT_EXP_INSUFF_RES:
511 /*
512 * This means max logins per port/switch setting on the
513 * switch was exceeded.
514 */
515 if (vport->fdisc_retries < BFA_FCS_VPORT_MAX_RETRIES)
516 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
517 else {
518 bfa_fcs_vport_aen_post(&vport->lport,
519 BFA_LPORT_AEN_NPIV_FABRIC_MAX);
520 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_FAILED);
521 }
522 break;
523
524 default:
525 if (vport->fdisc_retries == 0) /* Print only once */
526 bfa_fcs_vport_aen_post(&vport->lport,
527 BFA_LPORT_AEN_NPIV_UNKNOWN);
528 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
529 }
530}
531
532/**
533 * Called to send a logout to the fabric. Used when a V-Port is
534 * deleted/stopped.
535 */
536static void
537bfa_fcs_vport_do_logo(struct bfa_fcs_vport_s *vport)
538{
539 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
540
541 vport->vport_stats.logo_sent++;
542 bfa_lps_fdisclogo(vport->lps);
543}
544
545/**
546 * This routine will be called by bfa_timer on timer timeouts.
547 *
548 * param[in] vport - pointer to bfa_fcs_vport_t.
549 * param[out] vport_status - pointer to return vport status in
550 *
551 * return
552 * void
553 *
554* Special Considerations:
555 *
556 * note
557 */
558static void
559bfa_fcs_vport_timeout(void *vport_arg)
560{
561 struct bfa_fcs_vport_s *vport = (struct bfa_fcs_vport_s *)vport_arg;
562
563 vport->vport_stats.fdisc_timeouts++;
564 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_TIMEOUT);
565}
566
567static void
568bfa_fcs_vport_free(struct bfa_fcs_vport_s *vport)
569{
570 bfa_fcs_fabric_delvport(__vport_fabric(vport), vport);
571 bfa_fcb_vport_delete(vport->vport_drv);
572 bfa_lps_delete(vport->lps);
573}
574
575
576
577/**
578 * fcs_vport_public FCS virtual port public interfaces
579 */
580
581/**
582 * Online notification from fabric SM.
583 */
584void
585bfa_fcs_vport_online(struct bfa_fcs_vport_s *vport)
586{
587 vport->vport_stats.fab_online++;
588 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_ONLINE);
589}
590
591/**
592 * Offline notification from fabric SM.
593 */
594void
595bfa_fcs_vport_offline(struct bfa_fcs_vport_s *vport)
596{
597 vport->vport_stats.fab_offline++;
598 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_OFFLINE);
599}
600
601/**
602 * Cleanup notification from fabric SM on link timer expiry.
603 */
604void
605bfa_fcs_vport_cleanup(struct bfa_fcs_vport_s *vport)
606{
607 vport->vport_stats.fab_cleanup++;
608}
609
610/**
611 * Delete completion callback from associated lport
612 */
613void
614bfa_fcs_vport_delete_comp(struct bfa_fcs_vport_s *vport)
615{
616 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELCOMP);
617}
618
619/**
620 * Module initialization
621 */
622void
623bfa_fcs_vport_modinit(struct bfa_fcs_s *fcs)
624{
625}
626
627/**
628 * Module cleanup
629 */
630void
631bfa_fcs_vport_modexit(struct bfa_fcs_s *fcs)
632{
633 bfa_fcs_modexit_comp(fcs);
634}
635
636u32
637bfa_fcs_vport_get_max(struct bfa_fcs_s *fcs)
638{
639 struct bfa_ioc_attr_s ioc_attr;
640
641 bfa_get_attr(fcs->bfa, &ioc_attr);
642
643 if (ioc_attr.pci_attr.device_id == BFA_PCI_DEVICE_ID_CT)
644 return (BFA_FCS_MAX_VPORTS_SUPP_CT);
645 else
646 return (BFA_FCS_MAX_VPORTS_SUPP_CB);
647}
648
649
650
651/**
652 * fcs_vport_api Virtual port API
653 */
654
655/**
656 * Use this function to instantiate a new FCS vport object. This
657 * function will not trigger any HW initialization process (which will be
658 * done in vport_start() call)
659 *
660 * param[in] vport - pointer to bfa_fcs_vport_t. This space
661 * needs to be allocated by the driver.
662 * param[in] fcs - FCS instance
663 * param[in] vport_cfg - vport configuration
664 * param[in] vf_id - VF_ID if vport is created within a VF.
665 * FC_VF_ID_NULL to specify base fabric.
666 * param[in] vport_drv - Opaque handle back to the driver's vport
667 * structure
668 *
669 * retval BFA_STATUS_OK - on success.
670 * retval BFA_STATUS_FAILED - on failure.
671 */
672bfa_status_t
673bfa_fcs_vport_create(struct bfa_fcs_vport_s *vport, struct bfa_fcs_s *fcs,
674 u16 vf_id, struct bfa_port_cfg_s *vport_cfg,
675 struct bfad_vport_s *vport_drv)
676{
677 if (vport_cfg->pwwn == 0)
678 return (BFA_STATUS_INVALID_WWN);
679
680 if (bfa_fcs_port_get_pwwn(&fcs->fabric.bport) == vport_cfg->pwwn)
681 return BFA_STATUS_VPORT_WWN_BP;
682
683 if (bfa_fcs_vport_lookup(fcs, vf_id, vport_cfg->pwwn) != NULL)
684 return BFA_STATUS_VPORT_EXISTS;
685
686 if (bfa_fcs_fabric_vport_count(&fcs->fabric) ==
687 bfa_fcs_vport_get_max(fcs))
688 return BFA_STATUS_VPORT_MAX;
689
690 vport->lps = bfa_lps_alloc(fcs->bfa);
691 if (!vport->lps)
692 return BFA_STATUS_VPORT_MAX;
693
694 vport->vport_drv = vport_drv;
695 bfa_sm_set_state(vport, bfa_fcs_vport_sm_uninit);
696
697 bfa_fcs_lport_init(&vport->lport, fcs, vf_id, vport_cfg, vport);
698
699 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_CREATE);
700
701 return BFA_STATUS_OK;
702}
703
704/**
705 * Use this function initialize the vport.
706 *
707 * @param[in] vport - pointer to bfa_fcs_vport_t.
708 *
709 * @returns None
710 */
711bfa_status_t
712bfa_fcs_vport_start(struct bfa_fcs_vport_s *vport)
713{
714 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_START);
715
716 return BFA_STATUS_OK;
717}
718
719/**
720 * Use this function quiese the vport object. This function will return
721 * immediately, when the vport is actually stopped, the
722 * bfa_drv_vport_stop_cb() will be called.
723 *
724 * param[in] vport - pointer to bfa_fcs_vport_t.
725 *
726 * return None
727 */
728bfa_status_t
729bfa_fcs_vport_stop(struct bfa_fcs_vport_s *vport)
730{
731 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_STOP);
732
733 return BFA_STATUS_OK;
734}
735
736/**
737 * Use this function to delete a vport object. Fabric object should
738 * be stopped before this function call.
739 *
740 * param[in] vport - pointer to bfa_fcs_vport_t.
741 *
742 * return None
743 */
744bfa_status_t
745bfa_fcs_vport_delete(struct bfa_fcs_vport_s *vport)
746{
747 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELETE);
748
749 return BFA_STATUS_OK;
750}
751
752/**
753 * Use this function to get vport's current status info.
754 *
755 * param[in] vport pointer to bfa_fcs_vport_t.
756 * param[out] attr pointer to return vport attributes
757 *
758 * return None
759 */
760void
761bfa_fcs_vport_get_attr(struct bfa_fcs_vport_s *vport,
762 struct bfa_vport_attr_s *attr)
763{
764 if (vport == NULL || attr == NULL)
765 return;
766
767 bfa_os_memset(attr, 0, sizeof(struct bfa_vport_attr_s));
768
769 bfa_fcs_port_get_attr(&vport->lport, &attr->port_attr);
770 attr->vport_state = bfa_sm_to_state(vport_sm_table, vport->sm);
771}
772
773/**
774 * Use this function to get vport's statistics.
775 *
776 * param[in] vport pointer to bfa_fcs_vport_t.
777 * param[out] stats pointer to return vport statistics in
778 *
779 * return None
780 */
781void
782bfa_fcs_vport_get_stats(struct bfa_fcs_vport_s *vport,
783 struct bfa_vport_stats_s *stats)
784{
785 *stats = vport->vport_stats;
786}
787
788/**
789 * Use this function to clear vport's statistics.
790 *
791 * param[in] vport pointer to bfa_fcs_vport_t.
792 *
793 * return None
794 */
795void
796bfa_fcs_vport_clr_stats(struct bfa_fcs_vport_s *vport)
797{
798 bfa_os_memset(&vport->vport_stats, 0, sizeof(struct bfa_vport_stats_s));
799}
800
801/**
802 * Lookup a virtual port. Excludes base port from lookup.
803 */
804struct bfa_fcs_vport_s *
805bfa_fcs_vport_lookup(struct bfa_fcs_s *fcs, u16 vf_id, wwn_t vpwwn)
806{
807 struct bfa_fcs_vport_s *vport;
808 struct bfa_fcs_fabric_s *fabric;
809
810 bfa_trc(fcs, vf_id);
811 bfa_trc(fcs, vpwwn);
812
813 fabric = bfa_fcs_vf_lookup(fcs, vf_id);
814 if (!fabric) {
815 bfa_trc(fcs, vf_id);
816 return NULL;
817 }
818
819 vport = bfa_fcs_fabric_vport_lookup(fabric, vpwwn);
820 return vport;
821}
822
823/**
824 * FDISC Response
825 */
826void
827bfa_cb_lps_fdisc_comp(void *bfad, void *uarg, bfa_status_t status)
828{
829 struct bfa_fcs_vport_s *vport = uarg;
830
831 bfa_trc(__vport_fcs(vport), __vport_pwwn(vport));
832 bfa_trc(__vport_fcs(vport), status);
833
834 switch (status) {
835 case BFA_STATUS_OK:
836 /*
837 * Initialiaze the V-Port fields
838 */
839 __vport_fcid(vport) = bfa_lps_get_pid(vport->lps);
840 vport->vport_stats.fdisc_accepts++;
841 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_OK);
842 break;
843
844 case BFA_STATUS_INVALID_MAC:
845 /*
846 * Only for CNA
847 */
848 vport->vport_stats.fdisc_acc_bad++;
849 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
850
851 break;
852
853 case BFA_STATUS_EPROTOCOL:
854 switch (bfa_lps_get_extstatus(vport->lps)) {
855 case BFA_EPROTO_BAD_ACCEPT:
856 vport->vport_stats.fdisc_acc_bad++;
857 break;
858
859 case BFA_EPROTO_UNKNOWN_RSP:
860 vport->vport_stats.fdisc_unknown_rsp++;
861 break;
862
863 default:
864 break;
865 }
866
867 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
868 break;
869
870 case BFA_STATUS_FABRIC_RJT:
871 vport->vport_stats.fdisc_rejects++;
872 bfa_fcs_vport_fdisc_rejected(vport);
873 break;
874
875 default:
876 vport->vport_stats.fdisc_rsp_err++;
877 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_ERROR);
878 }
879}
880
881/**
882 * LOGO response
883 */
884void
885bfa_cb_lps_fdisclogo_comp(void *bfad, void *uarg)
886{
887 struct bfa_fcs_vport_s *vport = uarg;
888 bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_OK);
889}
890
891
diff --git a/drivers/scsi/bnx2i/bnx2i.h b/drivers/scsi/bnx2i/bnx2i.h
index d7576f28c6e9..5edde1a8c04d 100644
--- a/drivers/scsi/bnx2i/bnx2i.h
+++ b/drivers/scsi/bnx2i/bnx2i.h
@@ -100,6 +100,8 @@
100#define CTX_OFFSET 0x10000 100#define CTX_OFFSET 0x10000
101#define MAX_CID_CNT 0x4000 101#define MAX_CID_CNT 0x4000
102 102
103#define BNX2I_570X_PAGE_SIZE_DEFAULT 4096
104
103/* 5709 context registers */ 105/* 5709 context registers */
104#define BNX2_MQ_CONFIG2 0x00003d00 106#define BNX2_MQ_CONFIG2 0x00003d00
105#define BNX2_MQ_CONFIG2_CONT_SZ (0x7L<<4) 107#define BNX2_MQ_CONFIG2_CONT_SZ (0x7L<<4)
diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c
index 41e1b0e7e2ef..5c8d7630c13e 100644
--- a/drivers/scsi/bnx2i/bnx2i_hwi.c
+++ b/drivers/scsi/bnx2i/bnx2i_hwi.c
@@ -2386,7 +2386,7 @@ int bnx2i_map_ep_dbell_regs(struct bnx2i_endpoint *ep)
2386 ctx_sz = (config2 & BNX2_MQ_CONFIG2_CONT_SZ) >> 3; 2386 ctx_sz = (config2 & BNX2_MQ_CONFIG2_CONT_SZ) >> 3;
2387 if (ctx_sz) 2387 if (ctx_sz)
2388 reg_off = CTX_OFFSET + MAX_CID_CNT * MB_KERNEL_CTX_SIZE 2388 reg_off = CTX_OFFSET + MAX_CID_CNT * MB_KERNEL_CTX_SIZE
2389 + PAGE_SIZE * 2389 + BNX2I_570X_PAGE_SIZE_DEFAULT *
2390 (((cid_num - first_l4l5) / ctx_sz) + 256); 2390 (((cid_num - first_l4l5) / ctx_sz) + 256);
2391 else 2391 else
2392 reg_off = CTX_OFFSET + (MB_KERNEL_CTX_SIZE * cid_num); 2392 reg_off = CTX_OFFSET + (MB_KERNEL_CTX_SIZE * cid_num);
diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c
index 9a7ba71f1af4..cafb888c2376 100644
--- a/drivers/scsi/bnx2i/bnx2i_iscsi.c
+++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c
@@ -1243,7 +1243,7 @@ bnx2i_session_create(struct iscsi_endpoint *ep,
1243 cmds_max = BNX2I_SQ_WQES_MIN; 1243 cmds_max = BNX2I_SQ_WQES_MIN;
1244 1244
1245 cls_session = iscsi_session_setup(&bnx2i_iscsi_transport, shost, 1245 cls_session = iscsi_session_setup(&bnx2i_iscsi_transport, shost,
1246 cmds_max, sizeof(struct bnx2i_cmd), 1246 cmds_max, 0, sizeof(struct bnx2i_cmd),
1247 initial_cmdsn, ISCSI_MAX_TARGET); 1247 initial_cmdsn, ISCSI_MAX_TARGET);
1248 if (!cls_session) 1248 if (!cls_session)
1249 return NULL; 1249 return NULL;
diff --git a/drivers/scsi/cxgb3i/cxgb3i_iscsi.c b/drivers/scsi/cxgb3i/cxgb3i_iscsi.c
index c399f485aa7d..2631bddd255e 100644
--- a/drivers/scsi/cxgb3i/cxgb3i_iscsi.c
+++ b/drivers/scsi/cxgb3i/cxgb3i_iscsi.c
@@ -422,7 +422,7 @@ cxgb3i_session_create(struct iscsi_endpoint *ep, u16 cmds_max, u16 qdepth,
422 BUG_ON(hba != iscsi_host_priv(shost)); 422 BUG_ON(hba != iscsi_host_priv(shost));
423 423
424 cls_session = iscsi_session_setup(&cxgb3i_iscsi_transport, shost, 424 cls_session = iscsi_session_setup(&cxgb3i_iscsi_transport, shost,
425 cmds_max, 425 cmds_max, 0,
426 sizeof(struct iscsi_tcp_task) + 426 sizeof(struct iscsi_tcp_task) +
427 sizeof(struct cxgb3i_task_data), 427 sizeof(struct cxgb3i_task_data),
428 initial_cmdsn, ISCSI_MAX_TARGET); 428 initial_cmdsn, ISCSI_MAX_TARGET);
diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c
index 11c89311427e..268189d31d9c 100644
--- a/drivers/scsi/device_handler/scsi_dh_rdac.c
+++ b/drivers/scsi/device_handler/scsi_dh_rdac.c
@@ -500,8 +500,6 @@ static int mode_select_handle_sense(struct scsi_device *sdev,
500 if (!ret) 500 if (!ret)
501 goto done; 501 goto done;
502 502
503 err = SCSI_DH_OK;
504
505 switch (sense_hdr.sense_key) { 503 switch (sense_hdr.sense_key) {
506 case NO_SENSE: 504 case NO_SENSE:
507 case ABORTED_COMMAND: 505 case ABORTED_COMMAND:
diff --git a/drivers/scsi/hptiop.c b/drivers/scsi/hptiop.c
index c596ab5f05c3..a0e7e711ff9d 100644
--- a/drivers/scsi/hptiop.c
+++ b/drivers/scsi/hptiop.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * HighPoint RR3xxx/4xxx controller driver for Linux 2 * HighPoint RR3xxx/4xxx controller driver for Linux
3 * Copyright (C) 2006-2007 HighPoint Technologies, Inc. All Rights Reserved. 3 * Copyright (C) 2006-2009 HighPoint Technologies, Inc. All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify 5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by 6 * it under the terms of the GNU General Public License as published by
@@ -41,7 +41,7 @@ MODULE_DESCRIPTION("HighPoint RocketRAID 3xxx/4xxx Controller Driver");
41 41
42static char driver_name[] = "hptiop"; 42static char driver_name[] = "hptiop";
43static const char driver_name_long[] = "RocketRAID 3xxx/4xxx Controller driver"; 43static const char driver_name_long[] = "RocketRAID 3xxx/4xxx Controller driver";
44static const char driver_ver[] = "v1.3 (071203)"; 44static const char driver_ver[] = "v1.6 (090910)";
45 45
46static int iop_send_sync_msg(struct hptiop_hba *hba, u32 msg, u32 millisec); 46static int iop_send_sync_msg(struct hptiop_hba *hba, u32 msg, u32 millisec);
47static void hptiop_finish_scsi_req(struct hptiop_hba *hba, u32 tag, 47static void hptiop_finish_scsi_req(struct hptiop_hba *hba, u32 tag,
@@ -115,9 +115,13 @@ static void hptiop_drain_outbound_queue_itl(struct hptiop_hba *hba)
115static int iop_intr_itl(struct hptiop_hba *hba) 115static int iop_intr_itl(struct hptiop_hba *hba)
116{ 116{
117 struct hpt_iopmu_itl __iomem *iop = hba->u.itl.iop; 117 struct hpt_iopmu_itl __iomem *iop = hba->u.itl.iop;
118 void __iomem *plx = hba->u.itl.plx;
118 u32 status; 119 u32 status;
119 int ret = 0; 120 int ret = 0;
120 121
122 if (plx && readl(plx + 0x11C5C) & 0xf)
123 writel(1, plx + 0x11C60);
124
121 status = readl(&iop->outbound_intstatus); 125 status = readl(&iop->outbound_intstatus);
122 126
123 if (status & IOPMU_OUTBOUND_INT_MSG0) { 127 if (status & IOPMU_OUTBOUND_INT_MSG0) {
@@ -460,15 +464,25 @@ static void __iomem *hptiop_map_pci_bar(struct hptiop_hba *hba, int index)
460 464
461static int hptiop_map_pci_bar_itl(struct hptiop_hba *hba) 465static int hptiop_map_pci_bar_itl(struct hptiop_hba *hba)
462{ 466{
467 struct pci_dev *pcidev = hba->pcidev;
463 hba->u.itl.iop = hptiop_map_pci_bar(hba, 0); 468 hba->u.itl.iop = hptiop_map_pci_bar(hba, 0);
464 if (hba->u.itl.iop) 469 if (hba->u.itl.iop == NULL)
465 return 0;
466 else
467 return -1; 470 return -1;
471 if ((pcidev->device & 0xff00) == 0x4400) {
472 hba->u.itl.plx = hba->u.itl.iop;
473 hba->u.itl.iop = hptiop_map_pci_bar(hba, 2);
474 if (hba->u.itl.iop == NULL) {
475 iounmap(hba->u.itl.plx);
476 return -1;
477 }
478 }
479 return 0;
468} 480}
469 481
470static void hptiop_unmap_pci_bar_itl(struct hptiop_hba *hba) 482static void hptiop_unmap_pci_bar_itl(struct hptiop_hba *hba)
471{ 483{
484 if (hba->u.itl.plx)
485 iounmap(hba->u.itl.plx);
472 iounmap(hba->u.itl.iop); 486 iounmap(hba->u.itl.iop);
473} 487}
474 488
@@ -1239,22 +1253,23 @@ static struct hptiop_adapter_ops hptiop_mv_ops = {
1239static struct pci_device_id hptiop_id_table[] = { 1253static struct pci_device_id hptiop_id_table[] = {
1240 { PCI_VDEVICE(TTI, 0x3220), (kernel_ulong_t)&hptiop_itl_ops }, 1254 { PCI_VDEVICE(TTI, 0x3220), (kernel_ulong_t)&hptiop_itl_ops },
1241 { PCI_VDEVICE(TTI, 0x3320), (kernel_ulong_t)&hptiop_itl_ops }, 1255 { PCI_VDEVICE(TTI, 0x3320), (kernel_ulong_t)&hptiop_itl_ops },
1242 { PCI_VDEVICE(TTI, 0x3520), (kernel_ulong_t)&hptiop_itl_ops }, 1256 { PCI_VDEVICE(TTI, 0x3410), (kernel_ulong_t)&hptiop_itl_ops },
1243 { PCI_VDEVICE(TTI, 0x4320), (kernel_ulong_t)&hptiop_itl_ops },
1244 { PCI_VDEVICE(TTI, 0x3510), (kernel_ulong_t)&hptiop_itl_ops }, 1257 { PCI_VDEVICE(TTI, 0x3510), (kernel_ulong_t)&hptiop_itl_ops },
1245 { PCI_VDEVICE(TTI, 0x3511), (kernel_ulong_t)&hptiop_itl_ops }, 1258 { PCI_VDEVICE(TTI, 0x3511), (kernel_ulong_t)&hptiop_itl_ops },
1259 { PCI_VDEVICE(TTI, 0x3520), (kernel_ulong_t)&hptiop_itl_ops },
1246 { PCI_VDEVICE(TTI, 0x3521), (kernel_ulong_t)&hptiop_itl_ops }, 1260 { PCI_VDEVICE(TTI, 0x3521), (kernel_ulong_t)&hptiop_itl_ops },
1247 { PCI_VDEVICE(TTI, 0x3522), (kernel_ulong_t)&hptiop_itl_ops }, 1261 { PCI_VDEVICE(TTI, 0x3522), (kernel_ulong_t)&hptiop_itl_ops },
1248 { PCI_VDEVICE(TTI, 0x3410), (kernel_ulong_t)&hptiop_itl_ops },
1249 { PCI_VDEVICE(TTI, 0x3540), (kernel_ulong_t)&hptiop_itl_ops },
1250 { PCI_VDEVICE(TTI, 0x3530), (kernel_ulong_t)&hptiop_itl_ops }, 1262 { PCI_VDEVICE(TTI, 0x3530), (kernel_ulong_t)&hptiop_itl_ops },
1263 { PCI_VDEVICE(TTI, 0x3540), (kernel_ulong_t)&hptiop_itl_ops },
1251 { PCI_VDEVICE(TTI, 0x3560), (kernel_ulong_t)&hptiop_itl_ops }, 1264 { PCI_VDEVICE(TTI, 0x3560), (kernel_ulong_t)&hptiop_itl_ops },
1252 { PCI_VDEVICE(TTI, 0x4322), (kernel_ulong_t)&hptiop_itl_ops },
1253 { PCI_VDEVICE(TTI, 0x4321), (kernel_ulong_t)&hptiop_itl_ops },
1254 { PCI_VDEVICE(TTI, 0x4210), (kernel_ulong_t)&hptiop_itl_ops }, 1265 { PCI_VDEVICE(TTI, 0x4210), (kernel_ulong_t)&hptiop_itl_ops },
1255 { PCI_VDEVICE(TTI, 0x4211), (kernel_ulong_t)&hptiop_itl_ops }, 1266 { PCI_VDEVICE(TTI, 0x4211), (kernel_ulong_t)&hptiop_itl_ops },
1256 { PCI_VDEVICE(TTI, 0x4310), (kernel_ulong_t)&hptiop_itl_ops }, 1267 { PCI_VDEVICE(TTI, 0x4310), (kernel_ulong_t)&hptiop_itl_ops },
1257 { PCI_VDEVICE(TTI, 0x4311), (kernel_ulong_t)&hptiop_itl_ops }, 1268 { PCI_VDEVICE(TTI, 0x4311), (kernel_ulong_t)&hptiop_itl_ops },
1269 { PCI_VDEVICE(TTI, 0x4320), (kernel_ulong_t)&hptiop_itl_ops },
1270 { PCI_VDEVICE(TTI, 0x4321), (kernel_ulong_t)&hptiop_itl_ops },
1271 { PCI_VDEVICE(TTI, 0x4322), (kernel_ulong_t)&hptiop_itl_ops },
1272 { PCI_VDEVICE(TTI, 0x4400), (kernel_ulong_t)&hptiop_itl_ops },
1258 { PCI_VDEVICE(TTI, 0x3120), (kernel_ulong_t)&hptiop_mv_ops }, 1273 { PCI_VDEVICE(TTI, 0x3120), (kernel_ulong_t)&hptiop_mv_ops },
1259 { PCI_VDEVICE(TTI, 0x3122), (kernel_ulong_t)&hptiop_mv_ops }, 1274 { PCI_VDEVICE(TTI, 0x3122), (kernel_ulong_t)&hptiop_mv_ops },
1260 { PCI_VDEVICE(TTI, 0x3020), (kernel_ulong_t)&hptiop_mv_ops }, 1275 { PCI_VDEVICE(TTI, 0x3020), (kernel_ulong_t)&hptiop_mv_ops },
diff --git a/drivers/scsi/hptiop.h b/drivers/scsi/hptiop.h
index a0289f219752..0b871c0ae568 100644
--- a/drivers/scsi/hptiop.h
+++ b/drivers/scsi/hptiop.h
@@ -1,6 +1,6 @@
1/* 1/*
2 * HighPoint RR3xxx/4xxx controller driver for Linux 2 * HighPoint RR3xxx/4xxx controller driver for Linux
3 * Copyright (C) 2006-2007 HighPoint Technologies, Inc. All Rights Reserved. 3 * Copyright (C) 2006-2009 HighPoint Technologies, Inc. All Rights Reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify 5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by 6 * it under the terms of the GNU General Public License as published by
@@ -228,6 +228,7 @@ struct hptiop_hba {
228 union { 228 union {
229 struct { 229 struct {
230 struct hpt_iopmu_itl __iomem *iop; 230 struct hpt_iopmu_itl __iomem *iop;
231 void __iomem *plx;
231 } itl; 232 } itl;
232 struct { 233 struct {
233 struct hpt_iopmv_regs *regs; 234 struct hpt_iopmv_regs *regs;
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 2b1b834a098b..edc49ca49cea 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -811,7 +811,7 @@ iscsi_sw_tcp_session_create(struct iscsi_endpoint *ep, uint16_t cmds_max,
811 goto free_host; 811 goto free_host;
812 812
813 cls_session = iscsi_session_setup(&iscsi_sw_tcp_transport, shost, 813 cls_session = iscsi_session_setup(&iscsi_sw_tcp_transport, shost,
814 cmds_max, 814 cmds_max, 0,
815 sizeof(struct iscsi_tcp_task) + 815 sizeof(struct iscsi_tcp_task) +
816 sizeof(struct iscsi_sw_tcp_hdrbuf), 816 sizeof(struct iscsi_sw_tcp_hdrbuf),
817 initial_cmdsn, 0); 817 initial_cmdsn, 0);
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 8dc73c489a17..f1a4246f890c 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -2436,7 +2436,7 @@ static void iscsi_host_dec_session_cnt(struct Scsi_Host *shost)
2436 */ 2436 */
2437struct iscsi_cls_session * 2437struct iscsi_cls_session *
2438iscsi_session_setup(struct iscsi_transport *iscsit, struct Scsi_Host *shost, 2438iscsi_session_setup(struct iscsi_transport *iscsit, struct Scsi_Host *shost,
2439 uint16_t cmds_max, int cmd_task_size, 2439 uint16_t cmds_max, int dd_size, int cmd_task_size,
2440 uint32_t initial_cmdsn, unsigned int id) 2440 uint32_t initial_cmdsn, unsigned int id)
2441{ 2441{
2442 struct iscsi_host *ihost = shost_priv(shost); 2442 struct iscsi_host *ihost = shost_priv(shost);
@@ -2486,7 +2486,8 @@ iscsi_session_setup(struct iscsi_transport *iscsit, struct Scsi_Host *shost,
2486 scsi_cmds = total_cmds - ISCSI_MGMT_CMDS_MAX; 2486 scsi_cmds = total_cmds - ISCSI_MGMT_CMDS_MAX;
2487 2487
2488 cls_session = iscsi_alloc_session(shost, iscsit, 2488 cls_session = iscsi_alloc_session(shost, iscsit,
2489 sizeof(struct iscsi_session)); 2489 sizeof(struct iscsi_session) +
2490 dd_size);
2490 if (!cls_session) 2491 if (!cls_session)
2491 goto dec_session_count; 2492 goto dec_session_count;
2492 session = cls_session->dd_data; 2493 session = cls_session->dd_data;
@@ -2503,6 +2504,7 @@ iscsi_session_setup(struct iscsi_transport *iscsit, struct Scsi_Host *shost,
2503 session->max_cmdsn = initial_cmdsn + 1; 2504 session->max_cmdsn = initial_cmdsn + 1;
2504 session->max_r2t = 1; 2505 session->max_r2t = 1;
2505 session->tt = iscsit; 2506 session->tt = iscsit;
2507 session->dd_data = cls_session->dd_data + sizeof(*session);
2506 mutex_init(&session->eh_mutex); 2508 mutex_init(&session->eh_mutex);
2507 spin_lock_init(&session->lock); 2509 spin_lock_init(&session->lock);
2508 2510
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index 61d089703806..c88f59f0ce30 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -56,8 +56,6 @@ static char *dif_op_str[] = {
56 "SCSI_PROT_WRITE_INSERT", 56 "SCSI_PROT_WRITE_INSERT",
57 "SCSI_PROT_READ_PASS", 57 "SCSI_PROT_READ_PASS",
58 "SCSI_PROT_WRITE_PASS", 58 "SCSI_PROT_WRITE_PASS",
59 "SCSI_PROT_READ_CONVERT",
60 "SCSI_PROT_WRITE_CONVERT"
61}; 59};
62static void 60static void
63lpfc_release_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_scsi_buf *psb); 61lpfc_release_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_scsi_buf *psb);
@@ -1131,13 +1129,11 @@ lpfc_sc_to_sli_prof(struct scsi_cmnd *sc)
1131 ret_prof = LPFC_PROF_A1; 1129 ret_prof = LPFC_PROF_A1;
1132 break; 1130 break;
1133 1131
1134 case SCSI_PROT_READ_CONVERT: 1132 case SCSI_PROT_READ_PASS:
1135 case SCSI_PROT_WRITE_CONVERT: 1133 case SCSI_PROT_WRITE_PASS:
1136 ret_prof = LPFC_PROF_AST1; 1134 ret_prof = LPFC_PROF_AST1;
1137 break; 1135 break;
1138 1136
1139 case SCSI_PROT_READ_PASS:
1140 case SCSI_PROT_WRITE_PASS:
1141 case SCSI_PROT_NORMAL: 1137 case SCSI_PROT_NORMAL:
1142 default: 1138 default:
1143 printk(KERN_ERR "Bad op/guard:%d/%d combination\n", 1139 printk(KERN_ERR "Bad op/guard:%d/%d combination\n",
@@ -1157,8 +1153,6 @@ lpfc_sc_to_sli_prof(struct scsi_cmnd *sc)
1157 ret_prof = LPFC_PROF_C1; 1153 ret_prof = LPFC_PROF_C1;
1158 break; 1154 break;
1159 1155
1160 case SCSI_PROT_READ_CONVERT:
1161 case SCSI_PROT_WRITE_CONVERT:
1162 case SCSI_PROT_READ_INSERT: 1156 case SCSI_PROT_READ_INSERT:
1163 case SCSI_PROT_WRITE_STRIP: 1157 case SCSI_PROT_WRITE_STRIP:
1164 case SCSI_PROT_NORMAL: 1158 case SCSI_PROT_NORMAL:
@@ -1209,8 +1203,7 @@ lpfc_get_cmd_dif_parms(struct scsi_cmnd *sc, uint16_t *apptagmask,
1209 static int cnt; 1203 static int cnt;
1210 1204
1211 if (protcnt && (op == SCSI_PROT_WRITE_STRIP || 1205 if (protcnt && (op == SCSI_PROT_WRITE_STRIP ||
1212 op == SCSI_PROT_WRITE_PASS || 1206 op == SCSI_PROT_WRITE_PASS)) {
1213 op == SCSI_PROT_WRITE_CONVERT)) {
1214 1207
1215 cnt++; 1208 cnt++;
1216 spt = page_address(sg_page(scsi_prot_sglist(sc))) + 1209 spt = page_address(sg_page(scsi_prot_sglist(sc))) +
@@ -1501,8 +1494,6 @@ lpfc_prot_group_type(struct lpfc_hba *phba, struct scsi_cmnd *sc)
1501 case SCSI_PROT_WRITE_STRIP: 1494 case SCSI_PROT_WRITE_STRIP:
1502 case SCSI_PROT_READ_PASS: 1495 case SCSI_PROT_READ_PASS:
1503 case SCSI_PROT_WRITE_PASS: 1496 case SCSI_PROT_WRITE_PASS:
1504 case SCSI_PROT_WRITE_CONVERT:
1505 case SCSI_PROT_READ_CONVERT:
1506 ret = LPFC_PG_TYPE_DIF_BUF; 1497 ret = LPFC_PG_TYPE_DIF_BUF;
1507 break; 1498 break;
1508 default: 1499 default:
diff --git a/drivers/scsi/mpt2sas/Kconfig b/drivers/scsi/mpt2sas/Kconfig
index 4a86855c23b3..70c4c2467dd8 100644
--- a/drivers/scsi/mpt2sas/Kconfig
+++ b/drivers/scsi/mpt2sas/Kconfig
@@ -2,7 +2,7 @@
2# Kernel configuration file for the MPT2SAS 2# Kernel configuration file for the MPT2SAS
3# 3#
4# This code is based on drivers/scsi/mpt2sas/Kconfig 4# This code is based on drivers/scsi/mpt2sas/Kconfig
5# Copyright (C) 2007-2008 LSI Corporation 5# Copyright (C) 2007-2009 LSI Corporation
6# (mailto:DL-MPTFusionLinux@lsi.com) 6# (mailto:DL-MPTFusionLinux@lsi.com)
7 7
8# This program is free software; you can redistribute it and/or 8# This program is free software; you can redistribute it and/or
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2.h b/drivers/scsi/mpt2sas/mpi/mpi2.h
index 7bb2ece8b2e4..f9f6c0839276 100644
--- a/drivers/scsi/mpt2sas/mpi/mpi2.h
+++ b/drivers/scsi/mpt2sas/mpi/mpi2.h
@@ -8,7 +8,7 @@
8 * scatter/gather formats. 8 * scatter/gather formats.
9 * Creation Date: June 21, 2006 9 * Creation Date: June 21, 2006
10 * 10 *
11 * mpi2.h Version: 02.00.11 11 * mpi2.h Version: 02.00.12
12 * 12 *
13 * Version History 13 * Version History
14 * --------------- 14 * ---------------
@@ -45,6 +45,13 @@
45 * 10-02-08 02.00.10 Bumped MPI2_HEADER_VERSION_UNIT. 45 * 10-02-08 02.00.10 Bumped MPI2_HEADER_VERSION_UNIT.
46 * Moved LUN field defines from mpi2_init.h. 46 * Moved LUN field defines from mpi2_init.h.
47 * 01-19-09 02.00.11 Bumped MPI2_HEADER_VERSION_UNIT. 47 * 01-19-09 02.00.11 Bumped MPI2_HEADER_VERSION_UNIT.
48 * 05-06-09 02.00.12 Bumped MPI2_HEADER_VERSION_UNIT.
49 * In all request and reply descriptors, replaced VF_ID
50 * field with MSIxIndex field.
51 * Removed DevHandle field from
52 * MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR and made those
53 * bytes reserved.
54 * Added RAID Accelerator functionality.
48 * -------------------------------------------------------------------------- 55 * --------------------------------------------------------------------------
49 */ 56 */
50 57
@@ -70,7 +77,7 @@
70#define MPI2_VERSION_02_00 (0x0200) 77#define MPI2_VERSION_02_00 (0x0200)
71 78
72/* versioning for this MPI header set */ 79/* versioning for this MPI header set */
73#define MPI2_HEADER_VERSION_UNIT (0x0B) 80#define MPI2_HEADER_VERSION_UNIT (0x0C)
74#define MPI2_HEADER_VERSION_DEV (0x00) 81#define MPI2_HEADER_VERSION_DEV (0x00)
75#define MPI2_HEADER_VERSION_UNIT_MASK (0xFF00) 82#define MPI2_HEADER_VERSION_UNIT_MASK (0xFF00)
76#define MPI2_HEADER_VERSION_UNIT_SHIFT (8) 83#define MPI2_HEADER_VERSION_UNIT_SHIFT (8)
@@ -257,7 +264,7 @@ typedef volatile struct _MPI2_SYSTEM_INTERFACE_REGS
257typedef struct _MPI2_DEFAULT_REQUEST_DESCRIPTOR 264typedef struct _MPI2_DEFAULT_REQUEST_DESCRIPTOR
258{ 265{
259 U8 RequestFlags; /* 0x00 */ 266 U8 RequestFlags; /* 0x00 */
260 U8 VF_ID; /* 0x01 */ 267 U8 MSIxIndex; /* 0x01 */
261 U16 SMID; /* 0x02 */ 268 U16 SMID; /* 0x02 */
262 U16 LMID; /* 0x04 */ 269 U16 LMID; /* 0x04 */
263 U16 DescriptorTypeDependent; /* 0x06 */ 270 U16 DescriptorTypeDependent; /* 0x06 */
@@ -271,6 +278,7 @@ typedef struct _MPI2_DEFAULT_REQUEST_DESCRIPTOR
271#define MPI2_REQ_DESCRIPT_FLAGS_SCSI_TARGET (0x02) 278#define MPI2_REQ_DESCRIPT_FLAGS_SCSI_TARGET (0x02)
272#define MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY (0x06) 279#define MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY (0x06)
273#define MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE (0x08) 280#define MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE (0x08)
281#define MPI2_REQ_DESCRIPT_FLAGS_RAID_ACCELERATOR (0x0A)
274 282
275#define MPI2_REQ_DESCRIPT_FLAGS_IOC_FIFO_MARKER (0x01) 283#define MPI2_REQ_DESCRIPT_FLAGS_IOC_FIFO_MARKER (0x01)
276 284
@@ -279,7 +287,7 @@ typedef struct _MPI2_DEFAULT_REQUEST_DESCRIPTOR
279typedef struct _MPI2_HIGH_PRIORITY_REQUEST_DESCRIPTOR 287typedef struct _MPI2_HIGH_PRIORITY_REQUEST_DESCRIPTOR
280{ 288{
281 U8 RequestFlags; /* 0x00 */ 289 U8 RequestFlags; /* 0x00 */
282 U8 VF_ID; /* 0x01 */ 290 U8 MSIxIndex; /* 0x01 */
283 U16 SMID; /* 0x02 */ 291 U16 SMID; /* 0x02 */
284 U16 LMID; /* 0x04 */ 292 U16 LMID; /* 0x04 */
285 U16 Reserved1; /* 0x06 */ 293 U16 Reserved1; /* 0x06 */
@@ -293,7 +301,7 @@ typedef struct _MPI2_HIGH_PRIORITY_REQUEST_DESCRIPTOR
293typedef struct _MPI2_SCSI_IO_REQUEST_DESCRIPTOR 301typedef struct _MPI2_SCSI_IO_REQUEST_DESCRIPTOR
294{ 302{
295 U8 RequestFlags; /* 0x00 */ 303 U8 RequestFlags; /* 0x00 */
296 U8 VF_ID; /* 0x01 */ 304 U8 MSIxIndex; /* 0x01 */
297 U16 SMID; /* 0x02 */ 305 U16 SMID; /* 0x02 */
298 U16 LMID; /* 0x04 */ 306 U16 LMID; /* 0x04 */
299 U16 DevHandle; /* 0x06 */ 307 U16 DevHandle; /* 0x06 */
@@ -306,7 +314,7 @@ typedef struct _MPI2_SCSI_IO_REQUEST_DESCRIPTOR
306typedef struct _MPI2_SCSI_TARGET_REQUEST_DESCRIPTOR 314typedef struct _MPI2_SCSI_TARGET_REQUEST_DESCRIPTOR
307{ 315{
308 U8 RequestFlags; /* 0x00 */ 316 U8 RequestFlags; /* 0x00 */
309 U8 VF_ID; /* 0x01 */ 317 U8 MSIxIndex; /* 0x01 */
310 U16 SMID; /* 0x02 */ 318 U16 SMID; /* 0x02 */
311 U16 LMID; /* 0x04 */ 319 U16 LMID; /* 0x04 */
312 U16 IoIndex; /* 0x06 */ 320 U16 IoIndex; /* 0x06 */
@@ -315,14 +323,29 @@ typedef struct _MPI2_SCSI_TARGET_REQUEST_DESCRIPTOR
315 Mpi2SCSITargetRequestDescriptor_t, 323 Mpi2SCSITargetRequestDescriptor_t,
316 MPI2_POINTER pMpi2SCSITargetRequestDescriptor_t; 324 MPI2_POINTER pMpi2SCSITargetRequestDescriptor_t;
317 325
326
327/* RAID Accelerator Request Descriptor */
328typedef struct _MPI2_RAID_ACCEL_REQUEST_DESCRIPTOR {
329 U8 RequestFlags; /* 0x00 */
330 U8 MSIxIndex; /* 0x01 */
331 U16 SMID; /* 0x02 */
332 U16 LMID; /* 0x04 */
333 U16 Reserved; /* 0x06 */
334} MPI2_RAID_ACCEL_REQUEST_DESCRIPTOR,
335 MPI2_POINTER PTR_MPI2_RAID_ACCEL_REQUEST_DESCRIPTOR,
336 Mpi2RAIDAcceleratorRequestDescriptor_t,
337 MPI2_POINTER pMpi2RAIDAcceleratorRequestDescriptor_t;
338
339
318/* union of Request Descriptors */ 340/* union of Request Descriptors */
319typedef union _MPI2_REQUEST_DESCRIPTOR_UNION 341typedef union _MPI2_REQUEST_DESCRIPTOR_UNION
320{ 342{
321 MPI2_DEFAULT_REQUEST_DESCRIPTOR Default; 343 MPI2_DEFAULT_REQUEST_DESCRIPTOR Default;
322 MPI2_HIGH_PRIORITY_REQUEST_DESCRIPTOR HighPriority; 344 MPI2_HIGH_PRIORITY_REQUEST_DESCRIPTOR HighPriority;
323 MPI2_SCSI_IO_REQUEST_DESCRIPTOR SCSIIO; 345 MPI2_SCSI_IO_REQUEST_DESCRIPTOR SCSIIO;
324 MPI2_SCSI_TARGET_REQUEST_DESCRIPTOR SCSITarget; 346 MPI2_SCSI_TARGET_REQUEST_DESCRIPTOR SCSITarget;
325 U64 Words; 347 MPI2_RAID_ACCEL_REQUEST_DESCRIPTOR RAIDAccelerator;
348 U64 Words;
326} MPI2_REQUEST_DESCRIPTOR_UNION, MPI2_POINTER PTR_MPI2_REQUEST_DESCRIPTOR_UNION, 349} MPI2_REQUEST_DESCRIPTOR_UNION, MPI2_POINTER PTR_MPI2_REQUEST_DESCRIPTOR_UNION,
327 Mpi2RequestDescriptorUnion_t, MPI2_POINTER pMpi2RequestDescriptorUnion_t; 350 Mpi2RequestDescriptorUnion_t, MPI2_POINTER pMpi2RequestDescriptorUnion_t;
328 351
@@ -333,19 +356,20 @@ typedef union _MPI2_REQUEST_DESCRIPTOR_UNION
333typedef struct _MPI2_DEFAULT_REPLY_DESCRIPTOR 356typedef struct _MPI2_DEFAULT_REPLY_DESCRIPTOR
334{ 357{
335 U8 ReplyFlags; /* 0x00 */ 358 U8 ReplyFlags; /* 0x00 */
336 U8 VF_ID; /* 0x01 */ 359 U8 MSIxIndex; /* 0x01 */
337 U16 DescriptorTypeDependent1; /* 0x02 */ 360 U16 DescriptorTypeDependent1; /* 0x02 */
338 U32 DescriptorTypeDependent2; /* 0x04 */ 361 U32 DescriptorTypeDependent2; /* 0x04 */
339} MPI2_DEFAULT_REPLY_DESCRIPTOR, MPI2_POINTER PTR_MPI2_DEFAULT_REPLY_DESCRIPTOR, 362} MPI2_DEFAULT_REPLY_DESCRIPTOR, MPI2_POINTER PTR_MPI2_DEFAULT_REPLY_DESCRIPTOR,
340 Mpi2DefaultReplyDescriptor_t, MPI2_POINTER pMpi2DefaultReplyDescriptor_t; 363 Mpi2DefaultReplyDescriptor_t, MPI2_POINTER pMpi2DefaultReplyDescriptor_t;
341 364
342/* defines for the ReplyFlags field */ 365/* defines for the ReplyFlags field */
343#define MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK (0x0F) 366#define MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK (0x0F)
344#define MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS (0x00) 367#define MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS (0x00)
345#define MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY (0x01) 368#define MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY (0x01)
346#define MPI2_RPY_DESCRIPT_FLAGS_TARGETASSIST_SUCCESS (0x02) 369#define MPI2_RPY_DESCRIPT_FLAGS_TARGETASSIST_SUCCESS (0x02)
347#define MPI2_RPY_DESCRIPT_FLAGS_TARGET_COMMAND_BUFFER (0x03) 370#define MPI2_RPY_DESCRIPT_FLAGS_TARGET_COMMAND_BUFFER (0x03)
348#define MPI2_RPY_DESCRIPT_FLAGS_UNUSED (0x0F) 371#define MPI2_RPY_DESCRIPT_FLAGS_RAID_ACCELERATOR_SUCCESS (0x05)
372#define MPI2_RPY_DESCRIPT_FLAGS_UNUSED (0x0F)
349 373
350/* values for marking a reply descriptor as unused */ 374/* values for marking a reply descriptor as unused */
351#define MPI2_RPY_DESCRIPT_UNUSED_WORD0_MARK (0xFFFFFFFF) 375#define MPI2_RPY_DESCRIPT_UNUSED_WORD0_MARK (0xFFFFFFFF)
@@ -355,7 +379,7 @@ typedef struct _MPI2_DEFAULT_REPLY_DESCRIPTOR
355typedef struct _MPI2_ADDRESS_REPLY_DESCRIPTOR 379typedef struct _MPI2_ADDRESS_REPLY_DESCRIPTOR
356{ 380{
357 U8 ReplyFlags; /* 0x00 */ 381 U8 ReplyFlags; /* 0x00 */
358 U8 VF_ID; /* 0x01 */ 382 U8 MSIxIndex; /* 0x01 */
359 U16 SMID; /* 0x02 */ 383 U16 SMID; /* 0x02 */
360 U32 ReplyFrameAddress; /* 0x04 */ 384 U32 ReplyFrameAddress; /* 0x04 */
361} MPI2_ADDRESS_REPLY_DESCRIPTOR, MPI2_POINTER PTR_MPI2_ADDRESS_REPLY_DESCRIPTOR, 385} MPI2_ADDRESS_REPLY_DESCRIPTOR, MPI2_POINTER PTR_MPI2_ADDRESS_REPLY_DESCRIPTOR,
@@ -368,10 +392,10 @@ typedef struct _MPI2_ADDRESS_REPLY_DESCRIPTOR
368typedef struct _MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR 392typedef struct _MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR
369{ 393{
370 U8 ReplyFlags; /* 0x00 */ 394 U8 ReplyFlags; /* 0x00 */
371 U8 VF_ID; /* 0x01 */ 395 U8 MSIxIndex; /* 0x01 */
372 U16 SMID; /* 0x02 */ 396 U16 SMID; /* 0x02 */
373 U16 TaskTag; /* 0x04 */ 397 U16 TaskTag; /* 0x04 */
374 U16 DevHandle; /* 0x06 */ 398 U16 Reserved1; /* 0x06 */
375} MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR, 399} MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR,
376 MPI2_POINTER PTR_MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR, 400 MPI2_POINTER PTR_MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR,
377 Mpi2SCSIIOSuccessReplyDescriptor_t, 401 Mpi2SCSIIOSuccessReplyDescriptor_t,
@@ -382,7 +406,7 @@ typedef struct _MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR
382typedef struct _MPI2_TARGETASSIST_SUCCESS_REPLY_DESCRIPTOR 406typedef struct _MPI2_TARGETASSIST_SUCCESS_REPLY_DESCRIPTOR
383{ 407{
384 U8 ReplyFlags; /* 0x00 */ 408 U8 ReplyFlags; /* 0x00 */
385 U8 VF_ID; /* 0x01 */ 409 U8 MSIxIndex; /* 0x01 */
386 U16 SMID; /* 0x02 */ 410 U16 SMID; /* 0x02 */
387 U8 SequenceNumber; /* 0x04 */ 411 U8 SequenceNumber; /* 0x04 */
388 U8 Reserved1; /* 0x05 */ 412 U8 Reserved1; /* 0x05 */
@@ -397,7 +421,7 @@ typedef struct _MPI2_TARGETASSIST_SUCCESS_REPLY_DESCRIPTOR
397typedef struct _MPI2_TARGET_COMMAND_BUFFER_REPLY_DESCRIPTOR 421typedef struct _MPI2_TARGET_COMMAND_BUFFER_REPLY_DESCRIPTOR
398{ 422{
399 U8 ReplyFlags; /* 0x00 */ 423 U8 ReplyFlags; /* 0x00 */
400 U8 VF_ID; /* 0x01 */ 424 U8 MSIxIndex; /* 0x01 */
401 U8 VP_ID; /* 0x02 */ 425 U8 VP_ID; /* 0x02 */
402 U8 Flags; /* 0x03 */ 426 U8 Flags; /* 0x03 */
403 U16 InitiatorDevHandle; /* 0x04 */ 427 U16 InitiatorDevHandle; /* 0x04 */
@@ -411,15 +435,28 @@ typedef struct _MPI2_TARGET_COMMAND_BUFFER_REPLY_DESCRIPTOR
411#define MPI2_RPY_DESCRIPT_TCB_FLAGS_PHYNUM_MASK (0x3F) 435#define MPI2_RPY_DESCRIPT_TCB_FLAGS_PHYNUM_MASK (0x3F)
412 436
413 437
438/* RAID Accelerator Success Reply Descriptor */
439typedef struct _MPI2_RAID_ACCELERATOR_SUCCESS_REPLY_DESCRIPTOR {
440 U8 ReplyFlags; /* 0x00 */
441 U8 MSIxIndex; /* 0x01 */
442 U16 SMID; /* 0x02 */
443 U32 Reserved; /* 0x04 */
444} MPI2_RAID_ACCELERATOR_SUCCESS_REPLY_DESCRIPTOR,
445 MPI2_POINTER PTR_MPI2_RAID_ACCELERATOR_SUCCESS_REPLY_DESCRIPTOR,
446 Mpi2RAIDAcceleratorSuccessReplyDescriptor_t,
447 MPI2_POINTER pMpi2RAIDAcceleratorSuccessReplyDescriptor_t;
448
449
414/* union of Reply Descriptors */ 450/* union of Reply Descriptors */
415typedef union _MPI2_REPLY_DESCRIPTORS_UNION 451typedef union _MPI2_REPLY_DESCRIPTORS_UNION
416{ 452{
417 MPI2_DEFAULT_REPLY_DESCRIPTOR Default; 453 MPI2_DEFAULT_REPLY_DESCRIPTOR Default;
418 MPI2_ADDRESS_REPLY_DESCRIPTOR AddressReply; 454 MPI2_ADDRESS_REPLY_DESCRIPTOR AddressReply;
419 MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR SCSIIOSuccess; 455 MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR SCSIIOSuccess;
420 MPI2_TARGETASSIST_SUCCESS_REPLY_DESCRIPTOR TargetAssistSuccess; 456 MPI2_TARGETASSIST_SUCCESS_REPLY_DESCRIPTOR TargetAssistSuccess;
421 MPI2_TARGET_COMMAND_BUFFER_REPLY_DESCRIPTOR TargetCommandBuffer; 457 MPI2_TARGET_COMMAND_BUFFER_REPLY_DESCRIPTOR TargetCommandBuffer;
422 U64 Words; 458 MPI2_RAID_ACCELERATOR_SUCCESS_REPLY_DESCRIPTOR RAIDAcceleratorSuccess;
459 U64 Words;
423} MPI2_REPLY_DESCRIPTORS_UNION, MPI2_POINTER PTR_MPI2_REPLY_DESCRIPTORS_UNION, 460} MPI2_REPLY_DESCRIPTORS_UNION, MPI2_POINTER PTR_MPI2_REPLY_DESCRIPTORS_UNION,
424 Mpi2ReplyDescriptorsUnion_t, MPI2_POINTER pMpi2ReplyDescriptorsUnion_t; 461 Mpi2ReplyDescriptorsUnion_t, MPI2_POINTER pMpi2ReplyDescriptorsUnion_t;
425 462
@@ -458,6 +495,7 @@ typedef union _MPI2_REPLY_DESCRIPTORS_UNION
458#define MPI2_FUNCTION_DIAG_RELEASE (0x1E) /* Diagnostic Release */ 495#define MPI2_FUNCTION_DIAG_RELEASE (0x1E) /* Diagnostic Release */
459#define MPI2_FUNCTION_TARGET_CMD_BUF_BASE_POST (0x24) /* Target Command Buffer Post Base */ 496#define MPI2_FUNCTION_TARGET_CMD_BUF_BASE_POST (0x24) /* Target Command Buffer Post Base */
460#define MPI2_FUNCTION_TARGET_CMD_BUF_LIST_POST (0x25) /* Target Command Buffer Post List */ 497#define MPI2_FUNCTION_TARGET_CMD_BUF_LIST_POST (0x25) /* Target Command Buffer Post List */
498#define MPI2_FUNCTION_RAID_ACCELERATOR (0x2C) /* RAID Accelerator*/
461 499
462 500
463 501
@@ -555,12 +593,17 @@ typedef union _MPI2_REPLY_DESCRIPTORS_UNION
555 593
556#define MPI2_IOCSTATUS_DIAGNOSTIC_RELEASED (0x00A0) 594#define MPI2_IOCSTATUS_DIAGNOSTIC_RELEASED (0x00A0)
557 595
596/****************************************************************************
597* RAID Accelerator values
598****************************************************************************/
599
600#define MPI2_IOCSTATUS_RAID_ACCEL_ERROR (0x00B0)
558 601
559/**************************************************************************** 602/****************************************************************************
560* IOCStatus flag to indicate that log info is available 603* IOCStatus flag to indicate that log info is available
561****************************************************************************/ 604****************************************************************************/
562 605
563#define MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE (0x8000) 606#define MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE (0x8000)
564 607
565/**************************************************************************** 608/****************************************************************************
566* IOCLogInfo Types 609* IOCLogInfo Types
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h b/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h
index 2f27cf6d6c65..ab47c4679640 100644
--- a/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h
+++ b/drivers/scsi/mpt2sas/mpi/mpi2_cnfg.h
@@ -6,7 +6,7 @@
6 * Title: MPI Configuration messages and pages 6 * Title: MPI Configuration messages and pages
7 * Creation Date: November 10, 2006 7 * Creation Date: November 10, 2006
8 * 8 *
9 * mpi2_cnfg.h Version: 02.00.10 9 * mpi2_cnfg.h Version: 02.00.11
10 * 10 *
11 * Version History 11 * Version History
12 * --------------- 12 * ---------------
@@ -95,6 +95,11 @@
95 * Added MPI2_SAS_DEVICE0_ASTATUS_DEVICE_BLOCKED define. 95 * Added MPI2_SAS_DEVICE0_ASTATUS_DEVICE_BLOCKED define.
96 * Added PortGroups, DmaGroup, and ControlGroup fields to 96 * Added PortGroups, DmaGroup, and ControlGroup fields to
97 * SAS Device Page 0. 97 * SAS Device Page 0.
98 * 05-06-09 02.00.11 Added structures and defines for IO Unit Page 5 and IO
99 * Unit Page 6.
100 * Added expander reduced functionality data to SAS
101 * Expander Page 0.
102 * Added SAS PHY Page 2 and SAS PHY Page 3.
98 * -------------------------------------------------------------------------- 103 * --------------------------------------------------------------------------
99 */ 104 */
100 105
@@ -723,6 +728,65 @@ typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_3
723#define MPI2_IOUNITPAGE3_GPIO_SETTING_ON (0x0001) 728#define MPI2_IOUNITPAGE3_GPIO_SETTING_ON (0x0001)
724 729
725 730
731/* IO Unit Page 5 */
732
733/*
734 * Upper layer code (drivers, utilities, etc.) should leave this define set to
735 * one and check Header.PageLength or NumDmaEngines at runtime.
736 */
737#ifndef MPI2_IOUNITPAGE5_DMAENGINE_ENTRIES
738#define MPI2_IOUNITPAGE5_DMAENGINE_ENTRIES (1)
739#endif
740
741typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_5 {
742 MPI2_CONFIG_PAGE_HEADER Header; /* 0x00 */
743 U64 RaidAcceleratorBufferBaseAddress; /* 0x04 */
744 U64 RaidAcceleratorBufferSize; /* 0x0C */
745 U64 RaidAcceleratorControlBaseAddress; /* 0x14 */
746 U8 RAControlSize; /* 0x1C */
747 U8 NumDmaEngines; /* 0x1D */
748 U8 RAMinControlSize; /* 0x1E */
749 U8 RAMaxControlSize; /* 0x1F */
750 U32 Reserved1; /* 0x20 */
751 U32 Reserved2; /* 0x24 */
752 U32 Reserved3; /* 0x28 */
753 U32 DmaEngineCapabilities
754 [MPI2_IOUNITPAGE5_DMAENGINE_ENTRIES]; /* 0x2C */
755} MPI2_CONFIG_PAGE_IO_UNIT_5, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_IO_UNIT_5,
756 Mpi2IOUnitPage5_t, MPI2_POINTER pMpi2IOUnitPage5_t;
757
758#define MPI2_IOUNITPAGE5_PAGEVERSION (0x00)
759
760/* defines for IO Unit Page 5 DmaEngineCapabilities field */
761#define MPI2_IOUNITPAGE5_DMA_CAP_MASK_MAX_REQUESTS (0xFF00)
762#define MPI2_IOUNITPAGE5_DMA_CAP_SHIFT_MAX_REQUESTS (16)
763
764#define MPI2_IOUNITPAGE5_DMA_CAP_EEDP (0x0008)
765#define MPI2_IOUNITPAGE5_DMA_CAP_PARITY_GENERATION (0x0004)
766#define MPI2_IOUNITPAGE5_DMA_CAP_HASHING (0x0002)
767#define MPI2_IOUNITPAGE5_DMA_CAP_ENCRYPTION (0x0001)
768
769
770/* IO Unit Page 6 */
771
772typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_6 {
773 MPI2_CONFIG_PAGE_HEADER Header; /* 0x00 */
774 U16 Flags; /* 0x04 */
775 U8 RAHostControlSize; /* 0x06 */
776 U8 Reserved0; /* 0x07 */
777 U64 RaidAcceleratorHostControlBaseAddress; /* 0x08 */
778 U32 Reserved1; /* 0x10 */
779 U32 Reserved2; /* 0x14 */
780 U32 Reserved3; /* 0x18 */
781} MPI2_CONFIG_PAGE_IO_UNIT_6, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_IO_UNIT_6,
782 Mpi2IOUnitPage6_t, MPI2_POINTER pMpi2IOUnitPage6_t;
783
784#define MPI2_IOUNITPAGE6_PAGEVERSION (0x00)
785
786/* defines for IO Unit Page 6 Flags field */
787#define MPI2_IOUNITPAGE6_FLAGS_ENABLE_RAID_ACCELERATOR (0x0001)
788
789
726/**************************************************************************** 790/****************************************************************************
727* IOC Config Pages 791* IOC Config Pages
728****************************************************************************/ 792****************************************************************************/
@@ -1709,10 +1773,14 @@ typedef struct _MPI2_CONFIG_PAGE_EXPANDER_0
1709 U64 ActiveZoneManagerSASAddress;/* 0x2C */ 1773 U64 ActiveZoneManagerSASAddress;/* 0x2C */
1710 U16 ZoneLockInactivityLimit; /* 0x34 */ 1774 U16 ZoneLockInactivityLimit; /* 0x34 */
1711 U16 Reserved1; /* 0x36 */ 1775 U16 Reserved1; /* 0x36 */
1776 U8 TimeToReducedFunc; /* 0x38 */
1777 U8 InitialTimeToReducedFunc; /* 0x39 */
1778 U8 MaxReducedFuncTime; /* 0x3A */
1779 U8 Reserved2; /* 0x3B */
1712} MPI2_CONFIG_PAGE_EXPANDER_0, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_EXPANDER_0, 1780} MPI2_CONFIG_PAGE_EXPANDER_0, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_EXPANDER_0,
1713 Mpi2ExpanderPage0_t, MPI2_POINTER pMpi2ExpanderPage0_t; 1781 Mpi2ExpanderPage0_t, MPI2_POINTER pMpi2ExpanderPage0_t;
1714 1782
1715#define MPI2_SASEXPANDER0_PAGEVERSION (0x05) 1783#define MPI2_SASEXPANDER0_PAGEVERSION (0x06)
1716 1784
1717/* values for SAS Expander Page 0 DiscoveryStatus field */ 1785/* values for SAS Expander Page 0 DiscoveryStatus field */
1718#define MPI2_SAS_EXPANDER0_DS_MAX_ENCLOSURES_EXCEED (0x80000000) 1786#define MPI2_SAS_EXPANDER0_DS_MAX_ENCLOSURES_EXCEED (0x80000000)
@@ -1737,6 +1805,7 @@ typedef struct _MPI2_CONFIG_PAGE_EXPANDER_0
1737#define MPI2_SAS_EXPANDER0_DS_LOOP_DETECTED (0x00000001) 1805#define MPI2_SAS_EXPANDER0_DS_LOOP_DETECTED (0x00000001)
1738 1806
1739/* values for SAS Expander Page 0 Flags field */ 1807/* values for SAS Expander Page 0 Flags field */
1808#define MPI2_SAS_EXPANDER0_FLAGS_REDUCED_FUNCTIONALITY (0x2000)
1740#define MPI2_SAS_EXPANDER0_FLAGS_ZONE_LOCKED (0x1000) 1809#define MPI2_SAS_EXPANDER0_FLAGS_ZONE_LOCKED (0x1000)
1741#define MPI2_SAS_EXPANDER0_FLAGS_SUPPORTED_PHYSICAL_PRES (0x0800) 1810#define MPI2_SAS_EXPANDER0_FLAGS_SUPPORTED_PHYSICAL_PRES (0x0800)
1742#define MPI2_SAS_EXPANDER0_FLAGS_ASSERTED_PHYSICAL_PRES (0x0400) 1811#define MPI2_SAS_EXPANDER0_FLAGS_ASSERTED_PHYSICAL_PRES (0x0400)
@@ -1944,6 +2013,133 @@ typedef struct _MPI2_CONFIG_PAGE_SAS_PHY_1
1944#define MPI2_SASPHY1_PAGEVERSION (0x01) 2013#define MPI2_SASPHY1_PAGEVERSION (0x01)
1945 2014
1946 2015
2016/* SAS PHY Page 2 */
2017
2018typedef struct _MPI2_SASPHY2_PHY_EVENT {
2019 U8 PhyEventCode; /* 0x00 */
2020 U8 Reserved1; /* 0x01 */
2021 U16 Reserved2; /* 0x02 */
2022 U32 PhyEventInfo; /* 0x04 */
2023} MPI2_SASPHY2_PHY_EVENT, MPI2_POINTER PTR_MPI2_SASPHY2_PHY_EVENT,
2024 Mpi2SasPhy2PhyEvent_t, MPI2_POINTER pMpi2SasPhy2PhyEvent_t;
2025
2026/* use MPI2_SASPHY3_EVENT_CODE_ for the PhyEventCode field */
2027
2028
2029/*
2030 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
2031 * one and check Header.ExtPageLength or NumPhyEvents at runtime.
2032 */
2033#ifndef MPI2_SASPHY2_PHY_EVENT_MAX
2034#define MPI2_SASPHY2_PHY_EVENT_MAX (1)
2035#endif
2036
2037typedef struct _MPI2_CONFIG_PAGE_SAS_PHY_2 {
2038 MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /* 0x00 */
2039 U32 Reserved1; /* 0x08 */
2040 U8 NumPhyEvents; /* 0x0C */
2041 U8 Reserved2; /* 0x0D */
2042 U16 Reserved3; /* 0x0E */
2043 MPI2_SASPHY2_PHY_EVENT PhyEvent[MPI2_SASPHY2_PHY_EVENT_MAX];
2044 /* 0x10 */
2045} MPI2_CONFIG_PAGE_SAS_PHY_2, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_SAS_PHY_2,
2046 Mpi2SasPhyPage2_t, MPI2_POINTER pMpi2SasPhyPage2_t;
2047
2048#define MPI2_SASPHY2_PAGEVERSION (0x00)
2049
2050
2051/* SAS PHY Page 3 */
2052
2053typedef struct _MPI2_SASPHY3_PHY_EVENT_CONFIG {
2054 U8 PhyEventCode; /* 0x00 */
2055 U8 Reserved1; /* 0x01 */
2056 U16 Reserved2; /* 0x02 */
2057 U8 CounterType; /* 0x04 */
2058 U8 ThresholdWindow; /* 0x05 */
2059 U8 TimeUnits; /* 0x06 */
2060 U8 Reserved3; /* 0x07 */
2061 U32 EventThreshold; /* 0x08 */
2062 U16 ThresholdFlags; /* 0x0C */
2063 U16 Reserved4; /* 0x0E */
2064} MPI2_SASPHY3_PHY_EVENT_CONFIG, MPI2_POINTER PTR_MPI2_SASPHY3_PHY_EVENT_CONFIG,
2065 Mpi2SasPhy3PhyEventConfig_t, MPI2_POINTER pMpi2SasPhy3PhyEventConfig_t;
2066
2067/* values for PhyEventCode field */
2068#define MPI2_SASPHY3_EVENT_CODE_NO_EVENT (0x00)
2069#define MPI2_SASPHY3_EVENT_CODE_INVALID_DWORD (0x01)
2070#define MPI2_SASPHY3_EVENT_CODE_RUNNING_DISPARITY_ERROR (0x02)
2071#define MPI2_SASPHY3_EVENT_CODE_LOSS_DWORD_SYNC (0x03)
2072#define MPI2_SASPHY3_EVENT_CODE_PHY_RESET_PROBLEM (0x04)
2073#define MPI2_SASPHY3_EVENT_CODE_ELASTICITY_BUF_OVERFLOW (0x05)
2074#define MPI2_SASPHY3_EVENT_CODE_RX_ERROR (0x06)
2075#define MPI2_SASPHY3_EVENT_CODE_RX_ADDR_FRAME_ERROR (0x20)
2076#define MPI2_SASPHY3_EVENT_CODE_TX_AC_OPEN_REJECT (0x21)
2077#define MPI2_SASPHY3_EVENT_CODE_RX_AC_OPEN_REJECT (0x22)
2078#define MPI2_SASPHY3_EVENT_CODE_TX_RC_OPEN_REJECT (0x23)
2079#define MPI2_SASPHY3_EVENT_CODE_RX_RC_OPEN_REJECT (0x24)
2080#define MPI2_SASPHY3_EVENT_CODE_RX_AIP_PARTIAL_WAITING_ON (0x25)
2081#define MPI2_SASPHY3_EVENT_CODE_RX_AIP_CONNECT_WAITING_ON (0x26)
2082#define MPI2_SASPHY3_EVENT_CODE_TX_BREAK (0x27)
2083#define MPI2_SASPHY3_EVENT_CODE_RX_BREAK (0x28)
2084#define MPI2_SASPHY3_EVENT_CODE_BREAK_TIMEOUT (0x29)
2085#define MPI2_SASPHY3_EVENT_CODE_CONNECTION (0x2A)
2086#define MPI2_SASPHY3_EVENT_CODE_PEAKTX_PATHWAY_BLOCKED (0x2B)
2087#define MPI2_SASPHY3_EVENT_CODE_PEAKTX_ARB_WAIT_TIME (0x2C)
2088#define MPI2_SASPHY3_EVENT_CODE_PEAK_ARB_WAIT_TIME (0x2D)
2089#define MPI2_SASPHY3_EVENT_CODE_PEAK_CONNECT_TIME (0x2E)
2090#define MPI2_SASPHY3_EVENT_CODE_TX_SSP_FRAMES (0x40)
2091#define MPI2_SASPHY3_EVENT_CODE_RX_SSP_FRAMES (0x41)
2092#define MPI2_SASPHY3_EVENT_CODE_TX_SSP_ERROR_FRAMES (0x42)
2093#define MPI2_SASPHY3_EVENT_CODE_RX_SSP_ERROR_FRAMES (0x43)
2094#define MPI2_SASPHY3_EVENT_CODE_TX_CREDIT_BLOCKED (0x44)
2095#define MPI2_SASPHY3_EVENT_CODE_RX_CREDIT_BLOCKED (0x45)
2096#define MPI2_SASPHY3_EVENT_CODE_TX_SATA_FRAMES (0x50)
2097#define MPI2_SASPHY3_EVENT_CODE_RX_SATA_FRAMES (0x51)
2098#define MPI2_SASPHY3_EVENT_CODE_SATA_OVERFLOW (0x52)
2099#define MPI2_SASPHY3_EVENT_CODE_TX_SMP_FRAMES (0x60)
2100#define MPI2_SASPHY3_EVENT_CODE_RX_SMP_FRAMES (0x61)
2101#define MPI2_SASPHY3_EVENT_CODE_RX_SMP_ERROR_FRAMES (0x63)
2102#define MPI2_SASPHY3_EVENT_CODE_HOTPLUG_TIMEOUT (0xD0)
2103#define MPI2_SASPHY3_EVENT_CODE_MISALIGNED_MUX_PRIMITIVE (0xD1)
2104#define MPI2_SASPHY3_EVENT_CODE_RX_AIP (0xD2)
2105
2106/* values for the CounterType field */
2107#define MPI2_SASPHY3_COUNTER_TYPE_WRAPPING (0x00)
2108#define MPI2_SASPHY3_COUNTER_TYPE_SATURATING (0x01)
2109#define MPI2_SASPHY3_COUNTER_TYPE_PEAK_VALUE (0x02)
2110
2111/* values for the TimeUnits field */
2112#define MPI2_SASPHY3_TIME_UNITS_10_MICROSECONDS (0x00)
2113#define MPI2_SASPHY3_TIME_UNITS_100_MICROSECONDS (0x01)
2114#define MPI2_SASPHY3_TIME_UNITS_1_MILLISECOND (0x02)
2115#define MPI2_SASPHY3_TIME_UNITS_10_MILLISECONDS (0x03)
2116
2117/* values for the ThresholdFlags field */
2118#define MPI2_SASPHY3_TFLAGS_PHY_RESET (0x0002)
2119#define MPI2_SASPHY3_TFLAGS_EVENT_NOTIFY (0x0001)
2120
2121/*
2122 * Host code (drivers, BIOS, utilities, etc.) should leave this define set to
2123 * one and check Header.ExtPageLength or NumPhyEvents at runtime.
2124 */
2125#ifndef MPI2_SASPHY3_PHY_EVENT_MAX
2126#define MPI2_SASPHY3_PHY_EVENT_MAX (1)
2127#endif
2128
2129typedef struct _MPI2_CONFIG_PAGE_SAS_PHY_3 {
2130 MPI2_CONFIG_EXTENDED_PAGE_HEADER Header; /* 0x00 */
2131 U32 Reserved1; /* 0x08 */
2132 U8 NumPhyEvents; /* 0x0C */
2133 U8 Reserved2; /* 0x0D */
2134 U16 Reserved3; /* 0x0E */
2135 MPI2_SASPHY3_PHY_EVENT_CONFIG PhyEventConfig
2136 [MPI2_SASPHY3_PHY_EVENT_MAX]; /* 0x10 */
2137} MPI2_CONFIG_PAGE_SAS_PHY_3, MPI2_POINTER PTR_MPI2_CONFIG_PAGE_SAS_PHY_3,
2138 Mpi2SasPhyPage3_t, MPI2_POINTER pMpi2SasPhyPage3_t;
2139
2140#define MPI2_SASPHY3_PAGEVERSION (0x00)
2141
2142
1947/**************************************************************************** 2143/****************************************************************************
1948* SAS Port Config Pages 2144* SAS Port Config Pages
1949****************************************************************************/ 2145****************************************************************************/
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_history.txt b/drivers/scsi/mpt2sas/mpi/mpi2_history.txt
new file mode 100644
index 000000000000..65fcaa31cb30
--- /dev/null
+++ b/drivers/scsi/mpt2sas/mpi/mpi2_history.txt
@@ -0,0 +1,334 @@
1 ==============================
2 Fusion-MPT MPI 2.0 Header File Change History
3 ==============================
4
5 Copyright (c) 2000-2009 LSI Corporation.
6
7 ---------------------------------------
8 Header Set Release Version: 02.00.12
9 Header Set Release Date: 05-06-09
10 ---------------------------------------
11
12 Filename Current version Prior version
13 ---------- --------------- -------------
14 mpi2.h 02.00.12 02.00.11
15 mpi2_cnfg.h 02.00.11 02.00.10
16 mpi2_init.h 02.00.07 02.00.06
17 mpi2_ioc.h 02.00.11 02.00.10
18 mpi2_raid.h 02.00.03 02.00.03
19 mpi2_sas.h 02.00.02 02.00.02
20 mpi2_targ.h 02.00.03 02.00.03
21 mpi2_tool.h 02.00.03 02.00.02
22 mpi2_type.h 02.00.00 02.00.00
23 mpi2_ra.h 02.00.00
24 mpi2_history.txt 02.00.11 02.00.12
25
26
27 * Date Version Description
28 * -------- -------- ------------------------------------------------------
29
30mpi2.h
31 * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A.
32 * 06-04-07 02.00.01 Bumped MPI2_HEADER_VERSION_UNIT.
33 * 06-26-07 02.00.02 Bumped MPI2_HEADER_VERSION_UNIT.
34 * 08-31-07 02.00.03 Bumped MPI2_HEADER_VERSION_UNIT.
35 * Moved ReplyPostHostIndex register to offset 0x6C of the
36 * MPI2_SYSTEM_INTERFACE_REGS and modified the define for
37 * MPI2_REPLY_POST_HOST_INDEX_OFFSET.
38 * Added union of request descriptors.
39 * Added union of reply descriptors.
40 * 10-31-07 02.00.04 Bumped MPI2_HEADER_VERSION_UNIT.
41 * Added define for MPI2_VERSION_02_00.
42 * Fixed the size of the FunctionDependent5 field in the
43 * MPI2_DEFAULT_REPLY structure.
44 * 12-18-07 02.00.05 Bumped MPI2_HEADER_VERSION_UNIT.
45 * Removed the MPI-defined Fault Codes and extended the
46 * product specific codes up to 0xEFFF.
47 * Added a sixth key value for the WriteSequence register
48 * and changed the flush value to 0x0.
49 * Added message function codes for Diagnostic Buffer Post
50 * and Diagnsotic Release.
51 * New IOCStatus define: MPI2_IOCSTATUS_DIAGNOSTIC_RELEASED
52 * Moved MPI2_VERSION_UNION from mpi2_ioc.h.
53 * 02-29-08 02.00.06 Bumped MPI2_HEADER_VERSION_UNIT.
54 * 03-03-08 02.00.07 Bumped MPI2_HEADER_VERSION_UNIT.
55 * 05-21-08 02.00.08 Bumped MPI2_HEADER_VERSION_UNIT.
56 * Added #defines for marking a reply descriptor as unused.
57 * 06-27-08 02.00.09 Bumped MPI2_HEADER_VERSION_UNIT.
58 * 10-02-08 02.00.10 Bumped MPI2_HEADER_VERSION_UNIT.
59 * Moved LUN field defines from mpi2_init.h.
60 * 01-19-09 02.00.11 Bumped MPI2_HEADER_VERSION_UNIT.
61 * 05-06-09 02.00.12 Bumped MPI2_HEADER_VERSION_UNIT.
62 * In all request and reply descriptors, replaced VF_ID
63 * field with MSIxIndex field.
64 * Removed DevHandle field from
65 * MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR and made those
66 * bytes reserved.
67 * Added RAID Accelerator functionality.
68 * --------------------------------------------------------------------------
69
70mpi2_cnfg.h
71 * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A.
72 * 06-04-07 02.00.01 Added defines for SAS IO Unit Page 2 PhyFlags.
73 * Added Manufacturing Page 11.
74 * Added MPI2_SAS_EXPANDER0_FLAGS_CONNECTOR_END_DEVICE
75 * define.
76 * 06-26-07 02.00.02 Adding generic structure for product-specific
77 * Manufacturing pages: MPI2_CONFIG_PAGE_MANUFACTURING_PS.
78 * Rework of BIOS Page 2 configuration page.
79 * Fixed MPI2_BIOSPAGE2_BOOT_DEVICE to be a union of the
80 * forms.
81 * Added configuration pages IOC Page 8 and Driver
82 * Persistent Mapping Page 0.
83 * 08-31-07 02.00.03 Modified configuration pages dealing with Integrated
84 * RAID (Manufacturing Page 4, RAID Volume Pages 0 and 1,
85 * RAID Physical Disk Pages 0 and 1, RAID Configuration
86 * Page 0).
87 * Added new value for AccessStatus field of SAS Device
88 * Page 0 (_SATA_NEEDS_INITIALIZATION).
89 * 10-31-07 02.00.04 Added missing SEPDevHandle field to
90 * MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0.
91 * 12-18-07 02.00.05 Modified IO Unit Page 0 to use 32-bit version fields for
92 * NVDATA.
93 * Modified IOC Page 7 to use masks and added field for
94 * SASBroadcastPrimitiveMasks.
95 * Added MPI2_CONFIG_PAGE_BIOS_4.
96 * Added MPI2_CONFIG_PAGE_LOG_0.
97 * 02-29-08 02.00.06 Modified various names to make them 32-character unique.
98 * Added SAS Device IDs.
99 * Updated Integrated RAID configuration pages including
100 * Manufacturing Page 4, IOC Page 6, and RAID Configuration
101 * Page 0.
102 * 05-21-08 02.00.07 Added define MPI2_MANPAGE4_MIX_SSD_SAS_SATA.
103 * Added define MPI2_MANPAGE4_PHYSDISK_128MB_COERCION.
104 * Fixed define MPI2_IOCPAGE8_FLAGS_ENCLOSURE_SLOT_MAPPING.
105 * Added missing MaxNumRoutedSasAddresses field to
106 * MPI2_CONFIG_PAGE_EXPANDER_0.
107 * Added SAS Port Page 0.
108 * Modified structure layout for
109 * MPI2_CONFIG_PAGE_DRIVER_MAPPING_0.
110 * 06-27-08 02.00.08 Changed MPI2_CONFIG_PAGE_RD_PDISK_1 to use
111 * MPI2_RAID_PHYS_DISK1_PATH_MAX to size the array.
112 * 10-02-08 02.00.09 Changed MPI2_RAID_PGAD_CONFIGNUM_MASK from 0x0000FFFF
113 * to 0x000000FF.
114 * Added two new values for the Physical Disk Coercion Size
115 * bits in the Flags field of Manufacturing Page 4.
116 * Added product-specific Manufacturing pages 16 to 31.
117 * Modified Flags bits for controlling write cache on SATA
118 * drives in IO Unit Page 1.
119 * Added new bit to AdditionalControlFlags of SAS IO Unit
120 * Page 1 to control Invalid Topology Correction.
121 * Added SupportedPhysDisks field to RAID Volume Page 1 and
122 * added related defines.
123 * Added additional defines for RAID Volume Page 0
124 * VolumeStatusFlags field.
125 * Modified meaning of RAID Volume Page 0 VolumeSettings
126 * define for auto-configure of hot-swap drives.
127 * Added PhysDiskAttributes field (and related defines) to
128 * RAID Physical Disk Page 0.
129 * Added MPI2_SAS_PHYINFO_PHY_VACANT define.
130 * Added three new DiscoveryStatus bits for SAS IO Unit
131 * Page 0 and SAS Expander Page 0.
132 * Removed multiplexing information from SAS IO Unit pages.
133 * Added BootDeviceWaitTime field to SAS IO Unit Page 4.
134 * Removed Zone Address Resolved bit from PhyInfo and from
135 * Expander Page 0 Flags field.
136 * Added two new AccessStatus values to SAS Device Page 0
137 * for indicating routing problems. Added 3 reserved words
138 * to this page.
139 * 01-19-09 02.00.10 Fixed defines for GPIOVal field of IO Unit Page 3.
140 * Inserted missing reserved field into structure for IOC
141 * Page 6.
142 * Added more pending task bits to RAID Volume Page 0
143 * VolumeStatusFlags defines.
144 * Added MPI2_PHYSDISK0_STATUS_FLAG_NOT_CERTIFIED define.
145 * Added a new DiscoveryStatus bit for SAS IO Unit Page 0
146 * and SAS Expander Page 0 to flag a downstream initiator
147 * when in simplified routing mode.
148 * Removed SATA Init Failure defines for DiscoveryStatus
149 * fields of SAS IO Unit Page 0 and SAS Expander Page 0.
150 * Added MPI2_SAS_DEVICE0_ASTATUS_DEVICE_BLOCKED define.
151 * Added PortGroups, DmaGroup, and ControlGroup fields to
152 * SAS Device Page 0.
153 * 05-06-09 02.00.11 Added structures and defines for IO Unit Page 5 and IO
154 * Unit Page 6.
155 * Added expander reduced functionality data to SAS
156 * Expander Page 0.
157 * Added SAS PHY Page 2 and SAS PHY Page 3.
158 * --------------------------------------------------------------------------
159
160mpi2_init.h
161 * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A.
162 * 10-31-07 02.00.01 Fixed name for pMpi2SCSITaskManagementRequest_t.
163 * 12-18-07 02.00.02 Modified Task Management Target Reset Method defines.
164 * 02-29-08 02.00.03 Added Query Task Set and Query Unit Attention.
165 * 03-03-08 02.00.04 Fixed name of struct _MPI2_SCSI_TASK_MANAGE_REPLY.
166 * 05-21-08 02.00.05 Fixed typo in name of Mpi2SepRequest_t.
167 * 10-02-08 02.00.06 Removed Untagged and No Disconnect values from SCSI IO
168 * Control field Task Attribute flags.
169 * Moved LUN field defines to mpi2.h becasue they are
170 * common to many structures.
171 * 05-06-09 02.00.07 Changed task management type of Query Unit Attention to
172 * Query Asynchronous Event.
173 * Defined two new bits in the SlotStatus field of the SCSI
174 * Enclosure Processor Request and Reply.
175 * --------------------------------------------------------------------------
176
177mpi2_ioc.h
178 * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A.
179 * 06-04-07 02.00.01 In IOCFacts Reply structure, renamed MaxDevices to
180 * MaxTargets.
181 * Added TotalImageSize field to FWDownload Request.
182 * Added reserved words to FWUpload Request.
183 * 06-26-07 02.00.02 Added IR Configuration Change List Event.
184 * 08-31-07 02.00.03 Removed SystemReplyQueueDepth field from the IOCInit
185 * request and replaced it with
186 * ReplyDescriptorPostQueueDepth and ReplyFreeQueueDepth.
187 * Replaced the MinReplyQueueDepth field of the IOCFacts
188 * reply with MaxReplyDescriptorPostQueueDepth.
189 * Added MPI2_RDPQ_DEPTH_MIN define to specify the minimum
190 * depth for the Reply Descriptor Post Queue.
191 * Added SASAddress field to Initiator Device Table
192 * Overflow Event data.
193 * 10-31-07 02.00.04 Added ReasonCode MPI2_EVENT_SAS_INIT_RC_NOT_RESPONDING
194 * for SAS Initiator Device Status Change Event data.
195 * Modified Reason Code defines for SAS Topology Change
196 * List Event data, including adding a bit for PHY Vacant
197 * status, and adding a mask for the Reason Code.
198 * Added define for
199 * MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING.
200 * Added define for MPI2_EXT_IMAGE_TYPE_MEGARAID.
201 * 12-18-07 02.00.05 Added Boot Status defines for the IOCExceptions field of
202 * the IOCFacts Reply.
203 * Removed MPI2_IOCFACTS_CAPABILITY_EXTENDED_BUFFER define.
204 * Moved MPI2_VERSION_UNION to mpi2.h.
205 * Changed MPI2_EVENT_NOTIFICATION_REQUEST to use masks
206 * instead of enables, and added SASBroadcastPrimitiveMasks
207 * field.
208 * Added Log Entry Added Event and related structure.
209 * 02-29-08 02.00.06 Added define MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID.
210 * Removed define MPI2_IOCFACTS_PROTOCOL_SMP_TARGET.
211 * Added MaxVolumes and MaxPersistentEntries fields to
212 * IOCFacts reply.
213 * Added ProtocalFlags and IOCCapabilities fields to
214 * MPI2_FW_IMAGE_HEADER.
215 * Removed MPI2_PORTENABLE_FLAGS_ENABLE_SINGLE_PORT.
216 * 03-03-08 02.00.07 Fixed MPI2_FW_IMAGE_HEADER by changing Reserved26 to
217 * a U16 (from a U32).
218 * Removed extra 's' from EventMasks name.
219 * 06-27-08 02.00.08 Fixed an offset in a comment.
220 * 10-02-08 02.00.09 Removed SystemReplyFrameSize from MPI2_IOC_INIT_REQUEST.
221 * Removed CurReplyFrameSize from MPI2_IOC_FACTS_REPLY and
222 * renamed MinReplyFrameSize to ReplyFrameSize.
223 * Added MPI2_IOCFACTS_EXCEPT_IR_FOREIGN_CONFIG_MAX.
224 * Added two new RAIDOperation values for Integrated RAID
225 * Operations Status Event data.
226 * Added four new IR Configuration Change List Event data
227 * ReasonCode values.
228 * Added two new ReasonCode defines for SAS Device Status
229 * Change Event data.
230 * Added three new DiscoveryStatus bits for the SAS
231 * Discovery event data.
232 * Added Multiplexing Status Change bit to the PhyStatus
233 * field of the SAS Topology Change List event data.
234 * Removed define for MPI2_INIT_IMAGE_BOOTFLAGS_XMEMCOPY.
235 * BootFlags are now product-specific.
236 * Added defines for the indivdual signature bytes
237 * for MPI2_INIT_IMAGE_FOOTER.
238 * 01-19-09 02.00.10 Added MPI2_IOCFACTS_CAPABILITY_EVENT_REPLAY define.
239 * Added MPI2_EVENT_SAS_DISC_DS_DOWNSTREAM_INITIATOR
240 * define.
241 * Added MPI2_EVENT_SAS_DEV_STAT_RC_SATA_INIT_FAILURE
242 * define.
243 * Removed MPI2_EVENT_SAS_DISC_DS_SATA_INIT_FAILURE define.
244 * 05-06-09 02.00.11 Added MPI2_IOCFACTS_CAPABILITY_RAID_ACCELERATOR define.
245 * Added MPI2_IOCFACTS_CAPABILITY_MSI_X_INDEX define.
246 * Added two new reason codes for SAS Device Status Change
247 * Event.
248 * Added new event: SAS PHY Counter.
249 * --------------------------------------------------------------------------
250
251mpi2_raid.h
252 * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A.
253 * 08-31-07 02.00.01 Modifications to RAID Action request and reply,
254 * including the Actions and ActionData.
255 * 02-29-08 02.00.02 Added MPI2_RAID_ACTION_ADATA_DISABL_FULL_REBUILD.
256 * 05-21-08 02.00.03 Added MPI2_RAID_VOL_CREATION_NUM_PHYSDISKS so that
257 * the PhysDisk array in MPI2_RAID_VOLUME_CREATION_STRUCT
258 * can be sized by the build environment.
259 * --------------------------------------------------------------------------
260
261mpi2_sas.h
262 * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A.
263 * 06-26-07 02.00.01 Added Clear All Persistent Operation to SAS IO Unit
264 * Control Request.
265 * 10-02-08 02.00.02 Added Set IOC Parameter Operation to SAS IO Unit Control
266 * Request.
267 * --------------------------------------------------------------------------
268
269mpi2_targ.h
270 * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A.
271 * 08-31-07 02.00.01 Added Command Buffer Data Location Address Space bits to
272 * BufferPostFlags field of CommandBufferPostBase Request.
273 * 02-29-08 02.00.02 Modified various names to make them 32-character unique.
274 * 10-02-08 02.00.03 Removed NextCmdBufferOffset from
275 * MPI2_TARGET_CMD_BUF_POST_BASE_REQUEST.
276 * Target Status Send Request only takes a single SGE for
277 * response data.
278 * --------------------------------------------------------------------------
279
280mpi2_tool.h
281 * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A.
282 * 12-18-07 02.00.01 Added Diagnostic Buffer Post and Diagnostic Release
283 * structures and defines.
284 * 02-29-08 02.00.02 Modified various names to make them 32-character unique.
285 * 05-06-09 02.00.03 Added ISTWI Read Write Tool and Diagnostic CLI Tool.
286 * --------------------------------------------------------------------------
287
288mpi2_type.h
289 * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A.
290 * --------------------------------------------------------------------------
291
292mpi2_ra.h
293 * 05-06-09 02.00.00 Initial version.
294 * --------------------------------------------------------------------------
295
296mpi2_history.txt Parts list history
297
298Filename 02.00.12
299---------- --------
300mpi2.h 02.00.12
301mpi2_cnfg.h 02.00.11
302mpi2_init.h 02.00.07
303mpi2_ioc.h 02.00.11
304mpi2_raid.h 02.00.03
305mpi2_sas.h 02.00.02
306mpi2_targ.h 02.00.03
307mpi2_tool.h 02.00.03
308mpi2_type.h 02.00.00
309mpi2_ra.h 02.00.00
310
311Filename 02.00.11 02.00.10 02.00.09 02.00.08 02.00.07 02.00.06
312---------- -------- -------- -------- -------- -------- --------
313mpi2.h 02.00.11 02.00.10 02.00.09 02.00.08 02.00.07 02.00.06
314mpi2_cnfg.h 02.00.10 02.00.09 02.00.08 02.00.07 02.00.06 02.00.06
315mpi2_init.h 02.00.06 02.00.06 02.00.05 02.00.05 02.00.04 02.00.03
316mpi2_ioc.h 02.00.10 02.00.09 02.00.08 02.00.07 02.00.07 02.00.06
317mpi2_raid.h 02.00.03 02.00.03 02.00.03 02.00.03 02.00.02 02.00.02
318mpi2_sas.h 02.00.02 02.00.02 02.00.01 02.00.01 02.00.01 02.00.01
319mpi2_targ.h 02.00.03 02.00.03 02.00.02 02.00.02 02.00.02 02.00.02
320mpi2_tool.h 02.00.02 02.00.02 02.00.02 02.00.02 02.00.02 02.00.02
321mpi2_type.h 02.00.00 02.00.00 02.00.00 02.00.00 02.00.00 02.00.00
322
323Filename 02.00.05 02.00.04 02.00.03 02.00.02 02.00.01 02.00.00
324---------- -------- -------- -------- -------- -------- --------
325mpi2.h 02.00.05 02.00.04 02.00.03 02.00.02 02.00.01 02.00.00
326mpi2_cnfg.h 02.00.05 02.00.04 02.00.03 02.00.02 02.00.01 02.00.00
327mpi2_init.h 02.00.02 02.00.01 02.00.00 02.00.00 02.00.00 02.00.00
328mpi2_ioc.h 02.00.05 02.00.04 02.00.03 02.00.02 02.00.01 02.00.00
329mpi2_raid.h 02.00.01 02.00.01 02.00.01 02.00.00 02.00.00 02.00.00
330mpi2_sas.h 02.00.01 02.00.01 02.00.01 02.00.01 02.00.00 02.00.00
331mpi2_targ.h 02.00.01 02.00.01 02.00.01 02.00.00 02.00.00 02.00.00
332mpi2_tool.h 02.00.01 02.00.00 02.00.00 02.00.00 02.00.00 02.00.00
333mpi2_type.h 02.00.00 02.00.00 02.00.00 02.00.00 02.00.00 02.00.00
334
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_init.h b/drivers/scsi/mpt2sas/mpi/mpi2_init.h
index f1115f0f0eb2..563e56d2e945 100644
--- a/drivers/scsi/mpt2sas/mpi/mpi2_init.h
+++ b/drivers/scsi/mpt2sas/mpi/mpi2_init.h
@@ -1,12 +1,12 @@
1/* 1/*
2 * Copyright (c) 2000-2008 LSI Corporation. 2 * Copyright (c) 2000-2009 LSI Corporation.
3 * 3 *
4 * 4 *
5 * Name: mpi2_init.h 5 * Name: mpi2_init.h
6 * Title: MPI SCSI initiator mode messages and structures 6 * Title: MPI SCSI initiator mode messages and structures
7 * Creation Date: June 23, 2006 7 * Creation Date: June 23, 2006
8 * 8 *
9 * mpi2_init.h Version: 02.00.06 9 * mpi2_init.h Version: 02.00.07
10 * 10 *
11 * Version History 11 * Version History
12 * --------------- 12 * ---------------
@@ -23,6 +23,10 @@
23 * Control field Task Attribute flags. 23 * Control field Task Attribute flags.
24 * Moved LUN field defines to mpi2.h becasue they are 24 * Moved LUN field defines to mpi2.h becasue they are
25 * common to many structures. 25 * common to many structures.
26 * 05-06-09 02.00.07 Changed task management type of Query Unit Attention to
27 * Query Asynchronous Event.
28 * Defined two new bits in the SlotStatus field of the SCSI
29 * Enclosure Processor Request and Reply.
26 * -------------------------------------------------------------------------- 30 * --------------------------------------------------------------------------
27 */ 31 */
28 32
@@ -289,7 +293,11 @@ typedef struct _MPI2_SCSI_TASK_MANAGE_REQUEST
289#define MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK (0x07) 293#define MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK (0x07)
290#define MPI2_SCSITASKMGMT_TASKTYPE_CLR_ACA (0x08) 294#define MPI2_SCSITASKMGMT_TASKTYPE_CLR_ACA (0x08)
291#define MPI2_SCSITASKMGMT_TASKTYPE_QRY_TASK_SET (0x09) 295#define MPI2_SCSITASKMGMT_TASKTYPE_QRY_TASK_SET (0x09)
292#define MPI2_SCSITASKMGMT_TASKTYPE_QRY_UNIT_ATTENTION (0x0A) 296#define MPI2_SCSITASKMGMT_TASKTYPE_QRY_ASYNC_EVENT (0x0A)
297
298/* obsolete TaskType name */
299#define MPI2_SCSITASKMGMT_TASKTYPE_QRY_UNIT_ATTENTION \
300 (MPI2_SCSITASKMGMT_TASKTYPE_QRY_ASYNC_EVENT)
293 301
294/* MsgFlags bits */ 302/* MsgFlags bits */
295 303
@@ -375,6 +383,8 @@ typedef struct _MPI2_SEP_REQUEST
375#define MPI2_SEP_REQ_SLOTSTATUS_HOT_SPARE (0x00000100) 383#define MPI2_SEP_REQ_SLOTSTATUS_HOT_SPARE (0x00000100)
376#define MPI2_SEP_REQ_SLOTSTATUS_UNCONFIGURED (0x00000080) 384#define MPI2_SEP_REQ_SLOTSTATUS_UNCONFIGURED (0x00000080)
377#define MPI2_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT (0x00000040) 385#define MPI2_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT (0x00000040)
386#define MPI2_SEP_REQ_SLOTSTATUS_IN_CRITICAL_ARRAY (0x00000010)
387#define MPI2_SEP_REQ_SLOTSTATUS_IN_FAILED_ARRAY (0x00000008)
378#define MPI2_SEP_REQ_SLOTSTATUS_DEV_REBUILDING (0x00000004) 388#define MPI2_SEP_REQ_SLOTSTATUS_DEV_REBUILDING (0x00000004)
379#define MPI2_SEP_REQ_SLOTSTATUS_DEV_FAULTY (0x00000002) 389#define MPI2_SEP_REQ_SLOTSTATUS_DEV_FAULTY (0x00000002)
380#define MPI2_SEP_REQ_SLOTSTATUS_NO_ERROR (0x00000001) 390#define MPI2_SEP_REQ_SLOTSTATUS_NO_ERROR (0x00000001)
@@ -410,6 +420,8 @@ typedef struct _MPI2_SEP_REPLY
410#define MPI2_SEP_REPLY_SLOTSTATUS_HOT_SPARE (0x00000100) 420#define MPI2_SEP_REPLY_SLOTSTATUS_HOT_SPARE (0x00000100)
411#define MPI2_SEP_REPLY_SLOTSTATUS_UNCONFIGURED (0x00000080) 421#define MPI2_SEP_REPLY_SLOTSTATUS_UNCONFIGURED (0x00000080)
412#define MPI2_SEP_REPLY_SLOTSTATUS_PREDICTED_FAULT (0x00000040) 422#define MPI2_SEP_REPLY_SLOTSTATUS_PREDICTED_FAULT (0x00000040)
423#define MPI2_SEP_REPLY_SLOTSTATUS_IN_CRITICAL_ARRAY (0x00000010)
424#define MPI2_SEP_REPLY_SLOTSTATUS_IN_FAILED_ARRAY (0x00000008)
413#define MPI2_SEP_REPLY_SLOTSTATUS_DEV_REBUILDING (0x00000004) 425#define MPI2_SEP_REPLY_SLOTSTATUS_DEV_REBUILDING (0x00000004)
414#define MPI2_SEP_REPLY_SLOTSTATUS_DEV_FAULTY (0x00000002) 426#define MPI2_SEP_REPLY_SLOTSTATUS_DEV_FAULTY (0x00000002)
415#define MPI2_SEP_REPLY_SLOTSTATUS_NO_ERROR (0x00000001) 427#define MPI2_SEP_REPLY_SLOTSTATUS_NO_ERROR (0x00000001)
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h b/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h
index 8c5d81870c03..c294128bdeb4 100644
--- a/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h
+++ b/drivers/scsi/mpt2sas/mpi/mpi2_ioc.h
@@ -6,7 +6,7 @@
6 * Title: MPI IOC, Port, Event, FW Download, and FW Upload messages 6 * Title: MPI IOC, Port, Event, FW Download, and FW Upload messages
7 * Creation Date: October 11, 2006 7 * Creation Date: October 11, 2006
8 * 8 *
9 * mpi2_ioc.h Version: 02.00.10 9 * mpi2_ioc.h Version: 02.00.11
10 * 10 *
11 * Version History 11 * Version History
12 * --------------- 12 * ---------------
@@ -79,6 +79,11 @@
79 * Added MPI2_EVENT_SAS_DEV_STAT_RC_SATA_INIT_FAILURE 79 * Added MPI2_EVENT_SAS_DEV_STAT_RC_SATA_INIT_FAILURE
80 * define. 80 * define.
81 * Removed MPI2_EVENT_SAS_DISC_DS_SATA_INIT_FAILURE define. 81 * Removed MPI2_EVENT_SAS_DISC_DS_SATA_INIT_FAILURE define.
82 * 05-06-09 02.00.11 Added MPI2_IOCFACTS_CAPABILITY_RAID_ACCELERATOR define.
83 * Added MPI2_IOCFACTS_CAPABILITY_MSI_X_INDEX define.
84 * Added two new reason codes for SAS Device Status Change
85 * Event.
86 * Added new event: SAS PHY Counter.
82 * -------------------------------------------------------------------------- 87 * --------------------------------------------------------------------------
83 */ 88 */
84 89
@@ -261,6 +266,8 @@ typedef struct _MPI2_IOC_FACTS_REPLY
261/* ProductID field uses MPI2_FW_HEADER_PID_ */ 266/* ProductID field uses MPI2_FW_HEADER_PID_ */
262 267
263/* IOCCapabilities */ 268/* IOCCapabilities */
269#define MPI2_IOCFACTS_CAPABILITY_MSI_X_INDEX (0x00008000)
270#define MPI2_IOCFACTS_CAPABILITY_RAID_ACCELERATOR (0x00004000)
264#define MPI2_IOCFACTS_CAPABILITY_EVENT_REPLAY (0x00002000) 271#define MPI2_IOCFACTS_CAPABILITY_EVENT_REPLAY (0x00002000)
265#define MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID (0x00001000) 272#define MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID (0x00001000)
266#define MPI2_IOCFACTS_CAPABILITY_TLR (0x00000800) 273#define MPI2_IOCFACTS_CAPABILITY_TLR (0x00000800)
@@ -440,6 +447,7 @@ typedef struct _MPI2_EVENT_NOTIFICATION_REPLY
440#define MPI2_EVENT_IR_PHYSICAL_DISK (0x001F) 447#define MPI2_EVENT_IR_PHYSICAL_DISK (0x001F)
441#define MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST (0x0020) 448#define MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST (0x0020)
442#define MPI2_EVENT_LOG_ENTRY_ADDED (0x0021) 449#define MPI2_EVENT_LOG_ENTRY_ADDED (0x0021)
450#define MPI2_EVENT_SAS_PHY_COUNTER (0x0022)
443 451
444 452
445/* Log Entry Added Event data */ 453/* Log Entry Added Event data */
@@ -502,17 +510,19 @@ typedef struct _MPI2_EVENT_DATA_SAS_DEVICE_STATUS_CHANGE
502 MPI2_POINTER pMpi2EventDataSasDeviceStatusChange_t; 510 MPI2_POINTER pMpi2EventDataSasDeviceStatusChange_t;
503 511
504/* SAS Device Status Change Event data ReasonCode values */ 512/* SAS Device Status Change Event data ReasonCode values */
505#define MPI2_EVENT_SAS_DEV_STAT_RC_SMART_DATA (0x05) 513#define MPI2_EVENT_SAS_DEV_STAT_RC_SMART_DATA (0x05)
506#define MPI2_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED (0x07) 514#define MPI2_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED (0x07)
507#define MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET (0x08) 515#define MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET (0x08)
508#define MPI2_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL (0x09) 516#define MPI2_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL (0x09)
509#define MPI2_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL (0x0A) 517#define MPI2_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL (0x0A)
510#define MPI2_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL (0x0B) 518#define MPI2_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL (0x0B)
511#define MPI2_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL (0x0C) 519#define MPI2_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL (0x0C)
512#define MPI2_EVENT_SAS_DEV_STAT_RC_ASYNC_NOTIFICATION (0x0D) 520#define MPI2_EVENT_SAS_DEV_STAT_RC_ASYNC_NOTIFICATION (0x0D)
513#define MPI2_EVENT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET (0x0E) 521#define MPI2_EVENT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET (0x0E)
514#define MPI2_EVENT_SAS_DEV_STAT_RC_CMP_TASK_ABORT_INTERNAL (0x0F) 522#define MPI2_EVENT_SAS_DEV_STAT_RC_CMP_TASK_ABORT_INTERNAL (0x0F)
515#define MPI2_EVENT_SAS_DEV_STAT_RC_SATA_INIT_FAILURE (0x10) 523#define MPI2_EVENT_SAS_DEV_STAT_RC_SATA_INIT_FAILURE (0x10)
524#define MPI2_EVENT_SAS_DEV_STAT_RC_EXPANDER_REDUCED_FUNCTIONALITY (0x11)
525#define MPI2_EVENT_SAS_DEV_STAT_RC_CMP_EXPANDER_REDUCED_FUNCTIONALITY (0x12)
516 526
517 527
518/* Integrated RAID Operation Status Event data */ 528/* Integrated RAID Operation Status Event data */
@@ -822,6 +832,37 @@ typedef struct _MPI2_EVENT_DATA_SAS_ENCL_DEV_STATUS_CHANGE
822#define MPI2_EVENT_SAS_ENCL_RC_NOT_RESPONDING (0x02) 832#define MPI2_EVENT_SAS_ENCL_RC_NOT_RESPONDING (0x02)
823 833
824 834
835/* SAS PHY Counter Event data */
836
837typedef struct _MPI2_EVENT_DATA_SAS_PHY_COUNTER {
838 U64 TimeStamp; /* 0x00 */
839 U32 Reserved1; /* 0x08 */
840 U8 PhyEventCode; /* 0x0C */
841 U8 PhyNum; /* 0x0D */
842 U16 Reserved2; /* 0x0E */
843 U32 PhyEventInfo; /* 0x10 */
844 U8 CounterType; /* 0x14 */
845 U8 ThresholdWindow; /* 0x15 */
846 U8 TimeUnits; /* 0x16 */
847 U8 Reserved3; /* 0x17 */
848 U32 EventThreshold; /* 0x18 */
849 U16 ThresholdFlags; /* 0x1C */
850 U16 Reserved4; /* 0x1E */
851} MPI2_EVENT_DATA_SAS_PHY_COUNTER,
852 MPI2_POINTER PTR_MPI2_EVENT_DATA_SAS_PHY_COUNTER,
853 Mpi2EventDataSasPhyCounter_t, MPI2_POINTER pMpi2EventDataSasPhyCounter_t;
854
855/* use MPI2_SASPHY3_EVENT_CODE_ values from mpi2_cnfg.h for the
856 * PhyEventCode field
857 * use MPI2_SASPHY3_COUNTER_TYPE_ values from mpi2_cnfg.h for the
858 * CounterType field
859 * use MPI2_SASPHY3_TIME_UNITS_ values from mpi2_cnfg.h for the
860 * TimeUnits field
861 * use MPI2_SASPHY3_TFLAGS_ values from mpi2_cnfg.h for the
862 * ThresholdFlags field
863 * */
864
865
825/**************************************************************************** 866/****************************************************************************
826* EventAck message 867* EventAck message
827****************************************************************************/ 868****************************************************************************/
diff --git a/drivers/scsi/mpt2sas/mpi/mpi2_tool.h b/drivers/scsi/mpt2sas/mpi/mpi2_tool.h
index 2ff4e936bd39..007e950f7bfa 100644
--- a/drivers/scsi/mpt2sas/mpi/mpi2_tool.h
+++ b/drivers/scsi/mpt2sas/mpi/mpi2_tool.h
@@ -1,12 +1,12 @@
1/* 1/*
2 * Copyright (c) 2000-2008 LSI Corporation. 2 * Copyright (c) 2000-2009 LSI Corporation.
3 * 3 *
4 * 4 *
5 * Name: mpi2_tool.h 5 * Name: mpi2_tool.h
6 * Title: MPI diagnostic tool structures and definitions 6 * Title: MPI diagnostic tool structures and definitions
7 * Creation Date: March 26, 2007 7 * Creation Date: March 26, 2007
8 * 8 *
9 * mpi2_tool.h Version: 02.00.02 9 * mpi2_tool.h Version: 02.00.03
10 * 10 *
11 * Version History 11 * Version History
12 * --------------- 12 * ---------------
@@ -17,6 +17,7 @@
17 * 12-18-07 02.00.01 Added Diagnostic Buffer Post and Diagnostic Release 17 * 12-18-07 02.00.01 Added Diagnostic Buffer Post and Diagnostic Release
18 * structures and defines. 18 * structures and defines.
19 * 02-29-08 02.00.02 Modified various names to make them 32-character unique. 19 * 02-29-08 02.00.02 Modified various names to make them 32-character unique.
20 * 05-06-09 02.00.03 Added ISTWI Read Write Tool and Diagnostic CLI Tool.
20 * -------------------------------------------------------------------------- 21 * --------------------------------------------------------------------------
21 */ 22 */
22 23
@@ -32,7 +33,10 @@
32/* defines for the Tools */ 33/* defines for the Tools */
33#define MPI2_TOOLBOX_CLEAN_TOOL (0x00) 34#define MPI2_TOOLBOX_CLEAN_TOOL (0x00)
34#define MPI2_TOOLBOX_MEMORY_MOVE_TOOL (0x01) 35#define MPI2_TOOLBOX_MEMORY_MOVE_TOOL (0x01)
36#define MPI2_TOOLBOX_ISTWI_READ_WRITE_TOOL (0x03)
35#define MPI2_TOOLBOX_BEACON_TOOL (0x05) 37#define MPI2_TOOLBOX_BEACON_TOOL (0x05)
38#define MPI2_TOOLBOX_DIAGNOSTIC_CLI_TOOL (0x06)
39
36 40
37/**************************************************************************** 41/****************************************************************************
38* Toolbox reply 42* Toolbox reply
@@ -112,6 +116,77 @@ typedef struct _MPI2_TOOLBOX_MEM_MOVE_REQUEST
112 116
113 117
114/**************************************************************************** 118/****************************************************************************
119* Toolbox ISTWI Read Write Tool
120****************************************************************************/
121
122/* Toolbox ISTWI Read Write Tool request message */
123typedef struct _MPI2_TOOLBOX_ISTWI_READ_WRITE_REQUEST {
124 U8 Tool; /* 0x00 */
125 U8 Reserved1; /* 0x01 */
126 U8 ChainOffset; /* 0x02 */
127 U8 Function; /* 0x03 */
128 U16 Reserved2; /* 0x04 */
129 U8 Reserved3; /* 0x06 */
130 U8 MsgFlags; /* 0x07 */
131 U8 VP_ID; /* 0x08 */
132 U8 VF_ID; /* 0x09 */
133 U16 Reserved4; /* 0x0A */
134 U32 Reserved5; /* 0x0C */
135 U32 Reserved6; /* 0x10 */
136 U8 DevIndex; /* 0x14 */
137 U8 Action; /* 0x15 */
138 U8 SGLFlags; /* 0x16 */
139 U8 Reserved7; /* 0x17 */
140 U16 TxDataLength; /* 0x18 */
141 U16 RxDataLength; /* 0x1A */
142 U32 Reserved8; /* 0x1C */
143 U32 Reserved9; /* 0x20 */
144 U32 Reserved10; /* 0x24 */
145 U32 Reserved11; /* 0x28 */
146 U32 Reserved12; /* 0x2C */
147 MPI2_SGE_SIMPLE_UNION SGL; /* 0x30 */
148} MPI2_TOOLBOX_ISTWI_READ_WRITE_REQUEST,
149 MPI2_POINTER PTR_MPI2_TOOLBOX_ISTWI_READ_WRITE_REQUEST,
150 Mpi2ToolboxIstwiReadWriteRequest_t,
151 MPI2_POINTER pMpi2ToolboxIstwiReadWriteRequest_t;
152
153/* values for the Action field */
154#define MPI2_TOOL_ISTWI_ACTION_READ_DATA (0x01)
155#define MPI2_TOOL_ISTWI_ACTION_WRITE_DATA (0x02)
156#define MPI2_TOOL_ISTWI_ACTION_SEQUENCE (0x03)
157#define MPI2_TOOL_ISTWI_ACTION_RESERVE_BUS (0x10)
158#define MPI2_TOOL_ISTWI_ACTION_RELEASE_BUS (0x11)
159#define MPI2_TOOL_ISTWI_ACTION_RESET (0x12)
160
161/* values for SGLFlags field are in the SGL section of mpi2.h */
162
163
164/* Toolbox ISTWI Read Write Tool reply message */
165typedef struct _MPI2_TOOLBOX_ISTWI_REPLY {
166 U8 Tool; /* 0x00 */
167 U8 Reserved1; /* 0x01 */
168 U8 MsgLength; /* 0x02 */
169 U8 Function; /* 0x03 */
170 U16 Reserved2; /* 0x04 */
171 U8 Reserved3; /* 0x06 */
172 U8 MsgFlags; /* 0x07 */
173 U8 VP_ID; /* 0x08 */
174 U8 VF_ID; /* 0x09 */
175 U16 Reserved4; /* 0x0A */
176 U16 Reserved5; /* 0x0C */
177 U16 IOCStatus; /* 0x0E */
178 U32 IOCLogInfo; /* 0x10 */
179 U8 DevIndex; /* 0x14 */
180 U8 Action; /* 0x15 */
181 U8 IstwiStatus; /* 0x16 */
182 U8 Reserved6; /* 0x17 */
183 U16 TxDataCount; /* 0x18 */
184 U16 RxDataCount; /* 0x1A */
185} MPI2_TOOLBOX_ISTWI_REPLY, MPI2_POINTER PTR_MPI2_TOOLBOX_ISTWI_REPLY,
186 Mpi2ToolboxIstwiReply_t, MPI2_POINTER pMpi2ToolboxIstwiReply_t;
187
188
189/****************************************************************************
115* Toolbox Beacon Tool request 190* Toolbox Beacon Tool request
116****************************************************************************/ 191****************************************************************************/
117 192
@@ -139,6 +214,61 @@ typedef struct _MPI2_TOOLBOX_BEACON_REQUEST
139#define MPI2_TOOLBOX_FLAGS_BEACONMODE_ON (0x01) 214#define MPI2_TOOLBOX_FLAGS_BEACONMODE_ON (0x01)
140 215
141 216
217/****************************************************************************
218* Toolbox Diagnostic CLI Tool
219****************************************************************************/
220
221#define MPI2_TOOLBOX_DIAG_CLI_CMD_LENGTH (0x5C)
222
223/* Toolbox Diagnostic CLI Tool request message */
224typedef struct _MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST {
225 U8 Tool; /* 0x00 */
226 U8 Reserved1; /* 0x01 */
227 U8 ChainOffset; /* 0x02 */
228 U8 Function; /* 0x03 */
229 U16 Reserved2; /* 0x04 */
230 U8 Reserved3; /* 0x06 */
231 U8 MsgFlags; /* 0x07 */
232 U8 VP_ID; /* 0x08 */
233 U8 VF_ID; /* 0x09 */
234 U16 Reserved4; /* 0x0A */
235 U8 SGLFlags; /* 0x0C */
236 U8 Reserved5; /* 0x0D */
237 U16 Reserved6; /* 0x0E */
238 U32 DataLength; /* 0x10 */
239 U8 DiagnosticCliCommand
240 [MPI2_TOOLBOX_DIAG_CLI_CMD_LENGTH]; /* 0x14 */
241 MPI2_SGE_SIMPLE_UNION SGL; /* 0x70 */
242} MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST,
243 MPI2_POINTER PTR_MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST,
244 Mpi2ToolboxDiagnosticCliRequest_t,
245 MPI2_POINTER pMpi2ToolboxDiagnosticCliRequest_t;
246
247/* values for SGLFlags field are in the SGL section of mpi2.h */
248
249
250/* Toolbox Diagnostic CLI Tool reply message */
251typedef struct _MPI2_TOOLBOX_DIAGNOSTIC_CLI_REPLY {
252 U8 Tool; /* 0x00 */
253 U8 Reserved1; /* 0x01 */
254 U8 MsgLength; /* 0x02 */
255 U8 Function; /* 0x03 */
256 U16 Reserved2; /* 0x04 */
257 U8 Reserved3; /* 0x06 */
258 U8 MsgFlags; /* 0x07 */
259 U8 VP_ID; /* 0x08 */
260 U8 VF_ID; /* 0x09 */
261 U16 Reserved4; /* 0x0A */
262 U16 Reserved5; /* 0x0C */
263 U16 IOCStatus; /* 0x0E */
264 U32 IOCLogInfo; /* 0x10 */
265 U32 ReturnedDataLength; /* 0x14 */
266} MPI2_TOOLBOX_DIAGNOSTIC_CLI_REPLY,
267 MPI2_POINTER PTR_MPI2_TOOLBOX_DIAG_CLI_REPLY,
268 Mpi2ToolboxDiagnosticCliReply_t,
269 MPI2_POINTER pMpi2ToolboxDiagnosticCliReply_t;
270
271
142/***************************************************************************** 272/*****************************************************************************
143* 273*
144* Diagnostic Buffer Messages 274* Diagnostic Buffer Messages
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c
index d95d2f274cb3..670241efa4b5 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_base.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.c
@@ -3,7 +3,7 @@
3 * for access to MPT (Message Passing Technology) firmware. 3 * for access to MPT (Message Passing Technology) firmware.
4 * 4 *
5 * This code is based on drivers/scsi/mpt2sas/mpt2_base.c 5 * This code is based on drivers/scsi/mpt2sas/mpt2_base.c
6 * Copyright (C) 2007-2008 LSI Corporation 6 * Copyright (C) 2007-2009 LSI Corporation
7 * (mailto:DL-MPTFusionLinux@lsi.com) 7 * (mailto:DL-MPTFusionLinux@lsi.com)
8 * 8 *
9 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
@@ -63,7 +63,7 @@
63static MPT_CALLBACK mpt_callbacks[MPT_MAX_CALLBACKS]; 63static MPT_CALLBACK mpt_callbacks[MPT_MAX_CALLBACKS];
64 64
65#define FAULT_POLLING_INTERVAL 1000 /* in milliseconds */ 65#define FAULT_POLLING_INTERVAL 1000 /* in milliseconds */
66#define MPT2SAS_MAX_REQUEST_QUEUE 500 /* maximum controller queue depth */ 66#define MPT2SAS_MAX_REQUEST_QUEUE 600 /* maximum controller queue depth */
67 67
68static int max_queue_depth = -1; 68static int max_queue_depth = -1;
69module_param(max_queue_depth, int, 0); 69module_param(max_queue_depth, int, 0);
@@ -543,13 +543,13 @@ mpt2sas_base_fault_info(struct MPT2SAS_ADAPTER *ioc , u16 fault_code)
543 * _base_display_reply_info - 543 * _base_display_reply_info -
544 * @ioc: pointer to scsi command object 544 * @ioc: pointer to scsi command object
545 * @smid: system request message index 545 * @smid: system request message index
546 * @VF_ID: virtual function id 546 * @msix_index: MSIX table index supplied by the OS
547 * @reply: reply message frame(lower 32bit addr) 547 * @reply: reply message frame(lower 32bit addr)
548 * 548 *
549 * Return nothing. 549 * Return nothing.
550 */ 550 */
551static void 551static void
552_base_display_reply_info(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID, 552_base_display_reply_info(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
553 u32 reply) 553 u32 reply)
554{ 554{
555 MPI2DefaultReply_t *mpi_reply; 555 MPI2DefaultReply_t *mpi_reply;
@@ -572,22 +572,24 @@ _base_display_reply_info(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID,
572 * mpt2sas_base_done - base internal command completion routine 572 * mpt2sas_base_done - base internal command completion routine
573 * @ioc: pointer to scsi command object 573 * @ioc: pointer to scsi command object
574 * @smid: system request message index 574 * @smid: system request message index
575 * @VF_ID: virtual function id 575 * @msix_index: MSIX table index supplied by the OS
576 * @reply: reply message frame(lower 32bit addr) 576 * @reply: reply message frame(lower 32bit addr)
577 * 577 *
578 * Return nothing. 578 * Return 1 meaning mf should be freed from _base_interrupt
579 * 0 means the mf is freed from this function.
579 */ 580 */
580void 581u8
581mpt2sas_base_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID, u32 reply) 582mpt2sas_base_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
583 u32 reply)
582{ 584{
583 MPI2DefaultReply_t *mpi_reply; 585 MPI2DefaultReply_t *mpi_reply;
584 586
585 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); 587 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
586 if (mpi_reply && mpi_reply->Function == MPI2_FUNCTION_EVENT_ACK) 588 if (mpi_reply && mpi_reply->Function == MPI2_FUNCTION_EVENT_ACK)
587 return; 589 return 1;
588 590
589 if (ioc->base_cmds.status == MPT2_CMD_NOT_USED) 591 if (ioc->base_cmds.status == MPT2_CMD_NOT_USED)
590 return; 592 return 1;
591 593
592 ioc->base_cmds.status |= MPT2_CMD_COMPLETE; 594 ioc->base_cmds.status |= MPT2_CMD_COMPLETE;
593 if (mpi_reply) { 595 if (mpi_reply) {
@@ -596,18 +598,20 @@ mpt2sas_base_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID, u32 reply)
596 } 598 }
597 ioc->base_cmds.status &= ~MPT2_CMD_PENDING; 599 ioc->base_cmds.status &= ~MPT2_CMD_PENDING;
598 complete(&ioc->base_cmds.done); 600 complete(&ioc->base_cmds.done);
601 return 1;
599} 602}
600 603
601/** 604/**
602 * _base_async_event - main callback handler for firmware asyn events 605 * _base_async_event - main callback handler for firmware asyn events
603 * @ioc: pointer to scsi command object 606 * @ioc: pointer to scsi command object
604 * @VF_ID: virtual function id 607 * @msix_index: MSIX table index supplied by the OS
605 * @reply: reply message frame(lower 32bit addr) 608 * @reply: reply message frame(lower 32bit addr)
606 * 609 *
607 * Return nothing. 610 * Return 1 meaning mf should be freed from _base_interrupt
611 * 0 means the mf is freed from this function.
608 */ 612 */
609static void 613static u8
610_base_async_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, u32 reply) 614_base_async_event(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, u32 reply)
611{ 615{
612 Mpi2EventNotificationReply_t *mpi_reply; 616 Mpi2EventNotificationReply_t *mpi_reply;
613 Mpi2EventAckRequest_t *ack_request; 617 Mpi2EventAckRequest_t *ack_request;
@@ -615,9 +619,9 @@ _base_async_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, u32 reply)
615 619
616 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); 620 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
617 if (!mpi_reply) 621 if (!mpi_reply)
618 return; 622 return 1;
619 if (mpi_reply->Function != MPI2_FUNCTION_EVENT_NOTIFICATION) 623 if (mpi_reply->Function != MPI2_FUNCTION_EVENT_NOTIFICATION)
620 return; 624 return 1;
621#ifdef CONFIG_SCSI_MPT2SAS_LOGGING 625#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
622 _base_display_event_data(ioc, mpi_reply); 626 _base_display_event_data(ioc, mpi_reply);
623#endif 627#endif
@@ -635,16 +639,47 @@ _base_async_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, u32 reply)
635 ack_request->Function = MPI2_FUNCTION_EVENT_ACK; 639 ack_request->Function = MPI2_FUNCTION_EVENT_ACK;
636 ack_request->Event = mpi_reply->Event; 640 ack_request->Event = mpi_reply->Event;
637 ack_request->EventContext = mpi_reply->EventContext; 641 ack_request->EventContext = mpi_reply->EventContext;
638 ack_request->VF_ID = VF_ID; 642 ack_request->VF_ID = 0; /* TODO */
639 mpt2sas_base_put_smid_default(ioc, smid, VF_ID); 643 ack_request->VP_ID = 0;
644 mpt2sas_base_put_smid_default(ioc, smid);
640 645
641 out: 646 out:
642 647
643 /* scsih callback handler */ 648 /* scsih callback handler */
644 mpt2sas_scsih_event_callback(ioc, VF_ID, reply); 649 mpt2sas_scsih_event_callback(ioc, msix_index, reply);
645 650
646 /* ctl callback handler */ 651 /* ctl callback handler */
647 mpt2sas_ctl_event_callback(ioc, VF_ID, reply); 652 mpt2sas_ctl_event_callback(ioc, msix_index, reply);
653
654 return 1;
655}
656
657/**
658 * _base_get_cb_idx - obtain the callback index
659 * @ioc: per adapter object
660 * @smid: system request message index
661 *
662 * Return callback index.
663 */
664static u8
665_base_get_cb_idx(struct MPT2SAS_ADAPTER *ioc, u16 smid)
666{
667 int i;
668 u8 cb_idx = 0xFF;
669
670 if (smid >= ioc->hi_priority_smid) {
671 if (smid < ioc->internal_smid) {
672 i = smid - ioc->hi_priority_smid;
673 cb_idx = ioc->hpr_lookup[i].cb_idx;
674 } else {
675 i = smid - ioc->internal_smid;
676 cb_idx = ioc->internal_lookup[i].cb_idx;
677 }
678 } else {
679 i = smid - 1;
680 cb_idx = ioc->scsi_lookup[i].cb_idx;
681 }
682 return cb_idx;
648} 683}
649 684
650/** 685/**
@@ -680,7 +715,6 @@ _base_unmask_interrupts(struct MPT2SAS_ADAPTER *ioc)
680{ 715{
681 u32 him_register; 716 u32 him_register;
682 717
683 writel(0, &ioc->chip->HostInterruptStatus);
684 him_register = readl(&ioc->chip->HostInterruptMask); 718 him_register = readl(&ioc->chip->HostInterruptMask);
685 him_register &= ~MPI2_HIM_RIM; 719 him_register &= ~MPI2_HIM_RIM;
686 writel(him_register, &ioc->chip->HostInterruptMask); 720 writel(him_register, &ioc->chip->HostInterruptMask);
@@ -712,9 +746,10 @@ _base_interrupt(int irq, void *bus_id)
712 u16 smid; 746 u16 smid;
713 u8 cb_idx; 747 u8 cb_idx;
714 u32 reply; 748 u32 reply;
715 u8 VF_ID; 749 u8 msix_index;
716 struct MPT2SAS_ADAPTER *ioc = bus_id; 750 struct MPT2SAS_ADAPTER *ioc = bus_id;
717 Mpi2ReplyDescriptorsUnion_t *rpf; 751 Mpi2ReplyDescriptorsUnion_t *rpf;
752 u8 rc;
718 753
719 if (ioc->mask_interrupts) 754 if (ioc->mask_interrupts)
720 return IRQ_NONE; 755 return IRQ_NONE;
@@ -733,7 +768,7 @@ _base_interrupt(int irq, void *bus_id)
733 reply = 0; 768 reply = 0;
734 cb_idx = 0xFF; 769 cb_idx = 0xFF;
735 smid = le16_to_cpu(rpf->Default.DescriptorTypeDependent1); 770 smid = le16_to_cpu(rpf->Default.DescriptorTypeDependent1);
736 VF_ID = rpf->Default.VF_ID; 771 msix_index = rpf->Default.MSIxIndex;
737 if (request_desript_type == 772 if (request_desript_type ==
738 MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY) { 773 MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY) {
739 reply = le32_to_cpu 774 reply = le32_to_cpu
@@ -745,16 +780,18 @@ _base_interrupt(int irq, void *bus_id)
745 MPI2_RPY_DESCRIPT_FLAGS_TARGETASSIST_SUCCESS) 780 MPI2_RPY_DESCRIPT_FLAGS_TARGETASSIST_SUCCESS)
746 goto next; 781 goto next;
747 if (smid) 782 if (smid)
748 cb_idx = ioc->scsi_lookup[smid - 1].cb_idx; 783 cb_idx = _base_get_cb_idx(ioc, smid);
749 if (smid && cb_idx != 0xFF) { 784 if (smid && cb_idx != 0xFF) {
750 mpt_callbacks[cb_idx](ioc, smid, VF_ID, reply); 785 rc = mpt_callbacks[cb_idx](ioc, smid, msix_index,
786 reply);
751 if (reply) 787 if (reply)
752 _base_display_reply_info(ioc, smid, VF_ID, 788 _base_display_reply_info(ioc, smid, msix_index,
753 reply); 789 reply);
754 mpt2sas_base_free_smid(ioc, smid); 790 if (rc)
791 mpt2sas_base_free_smid(ioc, smid);
755 } 792 }
756 if (!smid) 793 if (!smid)
757 _base_async_event(ioc, VF_ID, reply); 794 _base_async_event(ioc, msix_index, reply);
758 795
759 /* reply free queue handling */ 796 /* reply free queue handling */
760 if (reply) { 797 if (reply) {
@@ -1191,19 +1228,6 @@ mpt2sas_base_map_resources(struct MPT2SAS_ADAPTER *ioc)
1191} 1228}
1192 1229
1193/** 1230/**
1194 * mpt2sas_base_get_msg_frame_dma - obtain request mf pointer phys addr
1195 * @ioc: per adapter object
1196 * @smid: system request message index(smid zero is invalid)
1197 *
1198 * Returns phys pointer to message frame.
1199 */
1200dma_addr_t
1201mpt2sas_base_get_msg_frame_dma(struct MPT2SAS_ADAPTER *ioc, u16 smid)
1202{
1203 return ioc->request_dma + (smid * ioc->request_sz);
1204}
1205
1206/**
1207 * mpt2sas_base_get_msg_frame - obtain request mf pointer 1231 * mpt2sas_base_get_msg_frame - obtain request mf pointer
1208 * @ioc: per adapter object 1232 * @ioc: per adapter object
1209 * @smid: system request message index(smid zero is invalid) 1233 * @smid: system request message index(smid zero is invalid)
@@ -1258,7 +1282,7 @@ mpt2sas_base_get_reply_virt_addr(struct MPT2SAS_ADAPTER *ioc, u32 phys_addr)
1258} 1282}
1259 1283
1260/** 1284/**
1261 * mpt2sas_base_get_smid - obtain a free smid 1285 * mpt2sas_base_get_smid - obtain a free smid from internal queue
1262 * @ioc: per adapter object 1286 * @ioc: per adapter object
1263 * @cb_idx: callback index 1287 * @cb_idx: callback index
1264 * 1288 *
@@ -1272,6 +1296,39 @@ mpt2sas_base_get_smid(struct MPT2SAS_ADAPTER *ioc, u8 cb_idx)
1272 u16 smid; 1296 u16 smid;
1273 1297
1274 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); 1298 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
1299 if (list_empty(&ioc->internal_free_list)) {
1300 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
1301 printk(MPT2SAS_ERR_FMT "%s: smid not available\n",
1302 ioc->name, __func__);
1303 return 0;
1304 }
1305
1306 request = list_entry(ioc->internal_free_list.next,
1307 struct request_tracker, tracker_list);
1308 request->cb_idx = cb_idx;
1309 smid = request->smid;
1310 list_del(&request->tracker_list);
1311 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
1312 return smid;
1313}
1314
1315/**
1316 * mpt2sas_base_get_smid_scsiio - obtain a free smid from scsiio queue
1317 * @ioc: per adapter object
1318 * @cb_idx: callback index
1319 * @scmd: pointer to scsi command object
1320 *
1321 * Returns smid (zero is invalid)
1322 */
1323u16
1324mpt2sas_base_get_smid_scsiio(struct MPT2SAS_ADAPTER *ioc, u8 cb_idx,
1325 struct scsi_cmnd *scmd)
1326{
1327 unsigned long flags;
1328 struct request_tracker *request;
1329 u16 smid;
1330
1331 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
1275 if (list_empty(&ioc->free_list)) { 1332 if (list_empty(&ioc->free_list)) {
1276 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); 1333 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
1277 printk(MPT2SAS_ERR_FMT "%s: smid not available\n", 1334 printk(MPT2SAS_ERR_FMT "%s: smid not available\n",
@@ -1281,6 +1338,36 @@ mpt2sas_base_get_smid(struct MPT2SAS_ADAPTER *ioc, u8 cb_idx)
1281 1338
1282 request = list_entry(ioc->free_list.next, 1339 request = list_entry(ioc->free_list.next,
1283 struct request_tracker, tracker_list); 1340 struct request_tracker, tracker_list);
1341 request->scmd = scmd;
1342 request->cb_idx = cb_idx;
1343 smid = request->smid;
1344 list_del(&request->tracker_list);
1345 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
1346 return smid;
1347}
1348
1349/**
1350 * mpt2sas_base_get_smid_hpr - obtain a free smid from hi-priority queue
1351 * @ioc: per adapter object
1352 * @cb_idx: callback index
1353 *
1354 * Returns smid (zero is invalid)
1355 */
1356u16
1357mpt2sas_base_get_smid_hpr(struct MPT2SAS_ADAPTER *ioc, u8 cb_idx)
1358{
1359 unsigned long flags;
1360 struct request_tracker *request;
1361 u16 smid;
1362
1363 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
1364 if (list_empty(&ioc->hpr_free_list)) {
1365 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
1366 return 0;
1367 }
1368
1369 request = list_entry(ioc->hpr_free_list.next,
1370 struct request_tracker, tracker_list);
1284 request->cb_idx = cb_idx; 1371 request->cb_idx = cb_idx;
1285 smid = request->smid; 1372 smid = request->smid;
1286 list_del(&request->tracker_list); 1373 list_del(&request->tracker_list);
@@ -1300,10 +1387,32 @@ void
1300mpt2sas_base_free_smid(struct MPT2SAS_ADAPTER *ioc, u16 smid) 1387mpt2sas_base_free_smid(struct MPT2SAS_ADAPTER *ioc, u16 smid)
1301{ 1388{
1302 unsigned long flags; 1389 unsigned long flags;
1390 int i;
1303 1391
1304 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); 1392 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
1305 ioc->scsi_lookup[smid - 1].cb_idx = 0xFF; 1393 if (smid >= ioc->hi_priority_smid) {
1306 list_add_tail(&ioc->scsi_lookup[smid - 1].tracker_list, 1394 if (smid < ioc->internal_smid) {
1395 /* hi-priority */
1396 i = smid - ioc->hi_priority_smid;
1397 ioc->hpr_lookup[i].cb_idx = 0xFF;
1398 list_add_tail(&ioc->hpr_lookup[i].tracker_list,
1399 &ioc->hpr_free_list);
1400 } else {
1401 /* internal queue */
1402 i = smid - ioc->internal_smid;
1403 ioc->internal_lookup[i].cb_idx = 0xFF;
1404 list_add_tail(&ioc->internal_lookup[i].tracker_list,
1405 &ioc->internal_free_list);
1406 }
1407 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
1408 return;
1409 }
1410
1411 /* scsiio queue */
1412 i = smid - 1;
1413 ioc->scsi_lookup[i].cb_idx = 0xFF;
1414 ioc->scsi_lookup[i].scmd = NULL;
1415 list_add_tail(&ioc->scsi_lookup[i].tracker_list,
1307 &ioc->free_list); 1416 &ioc->free_list);
1308 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); 1417 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
1309 1418
@@ -1352,21 +1461,19 @@ static inline void _base_writeq(__u64 b, volatile void __iomem *addr,
1352 * mpt2sas_base_put_smid_scsi_io - send SCSI_IO request to firmware 1461 * mpt2sas_base_put_smid_scsi_io - send SCSI_IO request to firmware
1353 * @ioc: per adapter object 1462 * @ioc: per adapter object
1354 * @smid: system request message index 1463 * @smid: system request message index
1355 * @vf_id: virtual function id
1356 * @handle: device handle 1464 * @handle: device handle
1357 * 1465 *
1358 * Return nothing. 1466 * Return nothing.
1359 */ 1467 */
1360void 1468void
1361mpt2sas_base_put_smid_scsi_io(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 vf_id, 1469mpt2sas_base_put_smid_scsi_io(struct MPT2SAS_ADAPTER *ioc, u16 smid, u16 handle)
1362 u16 handle)
1363{ 1470{
1364 Mpi2RequestDescriptorUnion_t descriptor; 1471 Mpi2RequestDescriptorUnion_t descriptor;
1365 u64 *request = (u64 *)&descriptor; 1472 u64 *request = (u64 *)&descriptor;
1366 1473
1367 1474
1368 descriptor.SCSIIO.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO; 1475 descriptor.SCSIIO.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO;
1369 descriptor.SCSIIO.VF_ID = vf_id; 1476 descriptor.SCSIIO.MSIxIndex = 0; /* TODO */
1370 descriptor.SCSIIO.SMID = cpu_to_le16(smid); 1477 descriptor.SCSIIO.SMID = cpu_to_le16(smid);
1371 descriptor.SCSIIO.DevHandle = cpu_to_le16(handle); 1478 descriptor.SCSIIO.DevHandle = cpu_to_le16(handle);
1372 descriptor.SCSIIO.LMID = 0; 1479 descriptor.SCSIIO.LMID = 0;
@@ -1379,20 +1486,18 @@ mpt2sas_base_put_smid_scsi_io(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 vf_id,
1379 * mpt2sas_base_put_smid_hi_priority - send Task Managment request to firmware 1486 * mpt2sas_base_put_smid_hi_priority - send Task Managment request to firmware
1380 * @ioc: per adapter object 1487 * @ioc: per adapter object
1381 * @smid: system request message index 1488 * @smid: system request message index
1382 * @vf_id: virtual function id
1383 * 1489 *
1384 * Return nothing. 1490 * Return nothing.
1385 */ 1491 */
1386void 1492void
1387mpt2sas_base_put_smid_hi_priority(struct MPT2SAS_ADAPTER *ioc, u16 smid, 1493mpt2sas_base_put_smid_hi_priority(struct MPT2SAS_ADAPTER *ioc, u16 smid)
1388 u8 vf_id)
1389{ 1494{
1390 Mpi2RequestDescriptorUnion_t descriptor; 1495 Mpi2RequestDescriptorUnion_t descriptor;
1391 u64 *request = (u64 *)&descriptor; 1496 u64 *request = (u64 *)&descriptor;
1392 1497
1393 descriptor.HighPriority.RequestFlags = 1498 descriptor.HighPriority.RequestFlags =
1394 MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY; 1499 MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY;
1395 descriptor.HighPriority.VF_ID = vf_id; 1500 descriptor.HighPriority.MSIxIndex = 0; /* TODO */
1396 descriptor.HighPriority.SMID = cpu_to_le16(smid); 1501 descriptor.HighPriority.SMID = cpu_to_le16(smid);
1397 descriptor.HighPriority.LMID = 0; 1502 descriptor.HighPriority.LMID = 0;
1398 descriptor.HighPriority.Reserved1 = 0; 1503 descriptor.HighPriority.Reserved1 = 0;
@@ -1404,18 +1509,17 @@ mpt2sas_base_put_smid_hi_priority(struct MPT2SAS_ADAPTER *ioc, u16 smid,
1404 * mpt2sas_base_put_smid_default - Default, primarily used for config pages 1509 * mpt2sas_base_put_smid_default - Default, primarily used for config pages
1405 * @ioc: per adapter object 1510 * @ioc: per adapter object
1406 * @smid: system request message index 1511 * @smid: system request message index
1407 * @vf_id: virtual function id
1408 * 1512 *
1409 * Return nothing. 1513 * Return nothing.
1410 */ 1514 */
1411void 1515void
1412mpt2sas_base_put_smid_default(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 vf_id) 1516mpt2sas_base_put_smid_default(struct MPT2SAS_ADAPTER *ioc, u16 smid)
1413{ 1517{
1414 Mpi2RequestDescriptorUnion_t descriptor; 1518 Mpi2RequestDescriptorUnion_t descriptor;
1415 u64 *request = (u64 *)&descriptor; 1519 u64 *request = (u64 *)&descriptor;
1416 1520
1417 descriptor.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; 1521 descriptor.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE;
1418 descriptor.Default.VF_ID = vf_id; 1522 descriptor.Default.MSIxIndex = 0; /* TODO */
1419 descriptor.Default.SMID = cpu_to_le16(smid); 1523 descriptor.Default.SMID = cpu_to_le16(smid);
1420 descriptor.Default.LMID = 0; 1524 descriptor.Default.LMID = 0;
1421 descriptor.Default.DescriptorTypeDependent = 0; 1525 descriptor.Default.DescriptorTypeDependent = 0;
@@ -1427,21 +1531,20 @@ mpt2sas_base_put_smid_default(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 vf_id)
1427 * mpt2sas_base_put_smid_target_assist - send Target Assist/Status to firmware 1531 * mpt2sas_base_put_smid_target_assist - send Target Assist/Status to firmware
1428 * @ioc: per adapter object 1532 * @ioc: per adapter object
1429 * @smid: system request message index 1533 * @smid: system request message index
1430 * @vf_id: virtual function id
1431 * @io_index: value used to track the IO 1534 * @io_index: value used to track the IO
1432 * 1535 *
1433 * Return nothing. 1536 * Return nothing.
1434 */ 1537 */
1435void 1538void
1436mpt2sas_base_put_smid_target_assist(struct MPT2SAS_ADAPTER *ioc, u16 smid, 1539mpt2sas_base_put_smid_target_assist(struct MPT2SAS_ADAPTER *ioc, u16 smid,
1437 u8 vf_id, u16 io_index) 1540 u16 io_index)
1438{ 1541{
1439 Mpi2RequestDescriptorUnion_t descriptor; 1542 Mpi2RequestDescriptorUnion_t descriptor;
1440 u64 *request = (u64 *)&descriptor; 1543 u64 *request = (u64 *)&descriptor;
1441 1544
1442 descriptor.SCSITarget.RequestFlags = 1545 descriptor.SCSITarget.RequestFlags =
1443 MPI2_REQ_DESCRIPT_FLAGS_SCSI_TARGET; 1546 MPI2_REQ_DESCRIPT_FLAGS_SCSI_TARGET;
1444 descriptor.SCSITarget.VF_ID = vf_id; 1547 descriptor.SCSITarget.MSIxIndex = 0; /* TODO */
1445 descriptor.SCSITarget.SMID = cpu_to_le16(smid); 1548 descriptor.SCSITarget.SMID = cpu_to_le16(smid);
1446 descriptor.SCSITarget.LMID = 0; 1549 descriptor.SCSITarget.LMID = 0;
1447 descriptor.SCSITarget.IoIndex = cpu_to_le16(io_index); 1550 descriptor.SCSITarget.IoIndex = cpu_to_le16(io_index);
@@ -1717,6 +1820,8 @@ _base_release_memory_pools(struct MPT2SAS_ADAPTER *ioc)
1717 } 1820 }
1718 1821
1719 kfree(ioc->scsi_lookup); 1822 kfree(ioc->scsi_lookup);
1823 kfree(ioc->hpr_lookup);
1824 kfree(ioc->internal_lookup);
1720} 1825}
1721 1826
1722 1827
@@ -1736,7 +1841,6 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
1736 u16 num_of_reply_frames; 1841 u16 num_of_reply_frames;
1737 u16 chains_needed_per_io; 1842 u16 chains_needed_per_io;
1738 u32 sz, total_sz; 1843 u32 sz, total_sz;
1739 u16 i;
1740 u32 retry_sz; 1844 u32 retry_sz;
1741 u16 max_request_credit; 1845 u16 max_request_credit;
1742 1846
@@ -1764,7 +1868,10 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
1764 MPT2SAS_MAX_REQUEST_QUEUE) ? MPT2SAS_MAX_REQUEST_QUEUE : 1868 MPT2SAS_MAX_REQUEST_QUEUE) ? MPT2SAS_MAX_REQUEST_QUEUE :
1765 facts->RequestCredit; 1869 facts->RequestCredit;
1766 } 1870 }
1767 ioc->request_depth = max_request_credit; 1871
1872 ioc->hba_queue_depth = max_request_credit;
1873 ioc->hi_priority_depth = facts->HighPriorityCredit;
1874 ioc->internal_depth = ioc->hi_priority_depth + 5;
1768 1875
1769 /* request frame size */ 1876 /* request frame size */
1770 ioc->request_sz = facts->IOCRequestFrameSize * 4; 1877 ioc->request_sz = facts->IOCRequestFrameSize * 4;
@@ -1802,7 +1909,7 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
1802 ioc->chains_needed_per_io = chains_needed_per_io; 1909 ioc->chains_needed_per_io = chains_needed_per_io;
1803 1910
1804 /* reply free queue sizing - taking into account for events */ 1911 /* reply free queue sizing - taking into account for events */
1805 num_of_reply_frames = ioc->request_depth + 32; 1912 num_of_reply_frames = ioc->hba_queue_depth + 32;
1806 1913
1807 /* number of replies frames can't be a multiple of 16 */ 1914 /* number of replies frames can't be a multiple of 16 */
1808 /* decrease number of reply frames by 1 */ 1915 /* decrease number of reply frames by 1 */
@@ -1823,7 +1930,7 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
1823 * frames 1930 * frames
1824 */ 1931 */
1825 1932
1826 queue_size = ioc->request_depth + num_of_reply_frames + 1; 1933 queue_size = ioc->hba_queue_depth + num_of_reply_frames + 1;
1827 /* round up to 16 byte boundary */ 1934 /* round up to 16 byte boundary */
1828 if (queue_size % 16) 1935 if (queue_size % 16)
1829 queue_size += 16 - (queue_size % 16); 1936 queue_size += 16 - (queue_size % 16);
@@ -1837,60 +1944,85 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
1837 if (queue_diff % 16) 1944 if (queue_diff % 16)
1838 queue_diff += 16 - (queue_diff % 16); 1945 queue_diff += 16 - (queue_diff % 16);
1839 1946
1840 /* adjust request_depth, reply_free_queue_depth, 1947 /* adjust hba_queue_depth, reply_free_queue_depth,
1841 * and queue_size 1948 * and queue_size
1842 */ 1949 */
1843 ioc->request_depth -= queue_diff; 1950 ioc->hba_queue_depth -= queue_diff;
1844 ioc->reply_free_queue_depth -= queue_diff; 1951 ioc->reply_free_queue_depth -= queue_diff;
1845 queue_size -= queue_diff; 1952 queue_size -= queue_diff;
1846 } 1953 }
1847 ioc->reply_post_queue_depth = queue_size; 1954 ioc->reply_post_queue_depth = queue_size;
1848 1955
1849 /* max scsi host queue depth */
1850 ioc->shost->can_queue = ioc->request_depth - INTERNAL_CMDS_COUNT;
1851 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "scsi host queue: depth"
1852 "(%d)\n", ioc->name, ioc->shost->can_queue));
1853
1854 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "scatter gather: " 1956 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "scatter gather: "
1855 "sge_in_main_msg(%d), sge_per_chain(%d), sge_per_io(%d), " 1957 "sge_in_main_msg(%d), sge_per_chain(%d), sge_per_io(%d), "
1856 "chains_per_io(%d)\n", ioc->name, ioc->max_sges_in_main_message, 1958 "chains_per_io(%d)\n", ioc->name, ioc->max_sges_in_main_message,
1857 ioc->max_sges_in_chain_message, ioc->shost->sg_tablesize, 1959 ioc->max_sges_in_chain_message, ioc->shost->sg_tablesize,
1858 ioc->chains_needed_per_io)); 1960 ioc->chains_needed_per_io));
1859 1961
1962 ioc->scsiio_depth = ioc->hba_queue_depth -
1963 ioc->hi_priority_depth - ioc->internal_depth;
1964
1965 /* set the scsi host can_queue depth
1966 * with some internal commands that could be outstanding
1967 */
1968 ioc->shost->can_queue = ioc->scsiio_depth - (2);
1969 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "scsi host: "
1970 "can_queue depth (%d)\n", ioc->name, ioc->shost->can_queue));
1971
1860 /* contiguous pool for request and chains, 16 byte align, one extra " 1972 /* contiguous pool for request and chains, 16 byte align, one extra "
1861 * "frame for smid=0 1973 * "frame for smid=0
1862 */ 1974 */
1863 ioc->chain_depth = ioc->chains_needed_per_io * ioc->request_depth; 1975 ioc->chain_depth = ioc->chains_needed_per_io * ioc->scsiio_depth;
1864 sz = ((ioc->request_depth + 1 + ioc->chain_depth) * ioc->request_sz); 1976 sz = ((ioc->scsiio_depth + 1 + ioc->chain_depth) * ioc->request_sz);
1977
1978 /* hi-priority queue */
1979 sz += (ioc->hi_priority_depth * ioc->request_sz);
1980
1981 /* internal queue */
1982 sz += (ioc->internal_depth * ioc->request_sz);
1865 1983
1866 ioc->request_dma_sz = sz; 1984 ioc->request_dma_sz = sz;
1867 ioc->request = pci_alloc_consistent(ioc->pdev, sz, &ioc->request_dma); 1985 ioc->request = pci_alloc_consistent(ioc->pdev, sz, &ioc->request_dma);
1868 if (!ioc->request) { 1986 if (!ioc->request) {
1869 printk(MPT2SAS_ERR_FMT "request pool: pci_alloc_consistent " 1987 printk(MPT2SAS_ERR_FMT "request pool: pci_alloc_consistent "
1870 "failed: req_depth(%d), chains_per_io(%d), frame_sz(%d), " 1988 "failed: hba_depth(%d), chains_per_io(%d), frame_sz(%d), "
1871 "total(%d kB)\n", ioc->name, ioc->request_depth, 1989 "total(%d kB)\n", ioc->name, ioc->hba_queue_depth,
1872 ioc->chains_needed_per_io, ioc->request_sz, sz/1024); 1990 ioc->chains_needed_per_io, ioc->request_sz, sz/1024);
1873 if (ioc->request_depth < MPT2SAS_SAS_QUEUE_DEPTH) 1991 if (ioc->scsiio_depth < MPT2SAS_SAS_QUEUE_DEPTH)
1874 goto out; 1992 goto out;
1875 retry_sz += 64; 1993 retry_sz += 64;
1876 ioc->request_depth = max_request_credit - retry_sz; 1994 ioc->hba_queue_depth = max_request_credit - retry_sz;
1877 goto retry_allocation; 1995 goto retry_allocation;
1878 } 1996 }
1879 1997
1880 if (retry_sz) 1998 if (retry_sz)
1881 printk(MPT2SAS_ERR_FMT "request pool: pci_alloc_consistent " 1999 printk(MPT2SAS_ERR_FMT "request pool: pci_alloc_consistent "
1882 "succeed: req_depth(%d), chains_per_io(%d), frame_sz(%d), " 2000 "succeed: hba_depth(%d), chains_per_io(%d), frame_sz(%d), "
1883 "total(%d kb)\n", ioc->name, ioc->request_depth, 2001 "total(%d kb)\n", ioc->name, ioc->hba_queue_depth,
1884 ioc->chains_needed_per_io, ioc->request_sz, sz/1024); 2002 ioc->chains_needed_per_io, ioc->request_sz, sz/1024);
1885 2003
1886 ioc->chain = ioc->request + ((ioc->request_depth + 1) * 2004
2005 /* hi-priority queue */
2006 ioc->hi_priority = ioc->request + ((ioc->scsiio_depth + 1) *
2007 ioc->request_sz);
2008 ioc->hi_priority_dma = ioc->request_dma + ((ioc->scsiio_depth + 1) *
2009 ioc->request_sz);
2010
2011 /* internal queue */
2012 ioc->internal = ioc->hi_priority + (ioc->hi_priority_depth *
2013 ioc->request_sz);
2014 ioc->internal_dma = ioc->hi_priority_dma + (ioc->hi_priority_depth *
2015 ioc->request_sz);
2016
2017 ioc->chain = ioc->internal + (ioc->internal_depth *
1887 ioc->request_sz); 2018 ioc->request_sz);
1888 ioc->chain_dma = ioc->request_dma + ((ioc->request_depth + 1) * 2019 ioc->chain_dma = ioc->internal_dma + (ioc->internal_depth *
1889 ioc->request_sz); 2020 ioc->request_sz);
2021
1890 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "request pool(0x%p): " 2022 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "request pool(0x%p): "
1891 "depth(%d), frame_size(%d), pool_size(%d kB)\n", ioc->name, 2023 "depth(%d), frame_size(%d), pool_size(%d kB)\n", ioc->name,
1892 ioc->request, ioc->request_depth, ioc->request_sz, 2024 ioc->request, ioc->hba_queue_depth, ioc->request_sz,
1893 ((ioc->request_depth + 1) * ioc->request_sz)/1024)); 2025 (ioc->hba_queue_depth * ioc->request_sz)/1024));
1894 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "chain pool(0x%p): depth" 2026 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "chain pool(0x%p): depth"
1895 "(%d), frame_size(%d), pool_size(%d kB)\n", ioc->name, ioc->chain, 2027 "(%d), frame_size(%d), pool_size(%d kB)\n", ioc->name, ioc->chain,
1896 ioc->chain_depth, ioc->request_sz, ((ioc->chain_depth * 2028 ioc->chain_depth, ioc->request_sz, ((ioc->chain_depth *
@@ -1899,7 +2031,7 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
1899 ioc->name, (unsigned long long) ioc->request_dma)); 2031 ioc->name, (unsigned long long) ioc->request_dma));
1900 total_sz += sz; 2032 total_sz += sz;
1901 2033
1902 ioc->scsi_lookup = kcalloc(ioc->request_depth, 2034 ioc->scsi_lookup = kcalloc(ioc->scsiio_depth,
1903 sizeof(struct request_tracker), GFP_KERNEL); 2035 sizeof(struct request_tracker), GFP_KERNEL);
1904 if (!ioc->scsi_lookup) { 2036 if (!ioc->scsi_lookup) {
1905 printk(MPT2SAS_ERR_FMT "scsi_lookup: kcalloc failed\n", 2037 printk(MPT2SAS_ERR_FMT "scsi_lookup: kcalloc failed\n",
@@ -1907,12 +2039,38 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
1907 goto out; 2039 goto out;
1908 } 2040 }
1909 2041
1910 /* initialize some bits */ 2042 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "scsiio(0x%p): "
1911 for (i = 0; i < ioc->request_depth; i++) 2043 "depth(%d)\n", ioc->name, ioc->request,
1912 ioc->scsi_lookup[i].smid = i + 1; 2044 ioc->scsiio_depth));
2045
2046 /* initialize hi-priority queue smid's */
2047 ioc->hpr_lookup = kcalloc(ioc->hi_priority_depth,
2048 sizeof(struct request_tracker), GFP_KERNEL);
2049 if (!ioc->hpr_lookup) {
2050 printk(MPT2SAS_ERR_FMT "hpr_lookup: kcalloc failed\n",
2051 ioc->name);
2052 goto out;
2053 }
2054 ioc->hi_priority_smid = ioc->scsiio_depth + 1;
2055 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "hi_priority(0x%p): "
2056 "depth(%d), start smid(%d)\n", ioc->name, ioc->hi_priority,
2057 ioc->hi_priority_depth, ioc->hi_priority_smid));
2058
2059 /* initialize internal queue smid's */
2060 ioc->internal_lookup = kcalloc(ioc->internal_depth,
2061 sizeof(struct request_tracker), GFP_KERNEL);
2062 if (!ioc->internal_lookup) {
2063 printk(MPT2SAS_ERR_FMT "internal_lookup: kcalloc failed\n",
2064 ioc->name);
2065 goto out;
2066 }
2067 ioc->internal_smid = ioc->hi_priority_smid + ioc->hi_priority_depth;
2068 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "internal(0x%p): "
2069 "depth(%d), start smid(%d)\n", ioc->name, ioc->internal,
2070 ioc->internal_depth, ioc->internal_smid));
1913 2071
1914 /* sense buffers, 4 byte align */ 2072 /* sense buffers, 4 byte align */
1915 sz = ioc->request_depth * SCSI_SENSE_BUFFERSIZE; 2073 sz = ioc->scsiio_depth * SCSI_SENSE_BUFFERSIZE;
1916 ioc->sense_dma_pool = pci_pool_create("sense pool", ioc->pdev, sz, 4, 2074 ioc->sense_dma_pool = pci_pool_create("sense pool", ioc->pdev, sz, 4,
1917 0); 2075 0);
1918 if (!ioc->sense_dma_pool) { 2076 if (!ioc->sense_dma_pool) {
@@ -1929,7 +2087,7 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
1929 } 2087 }
1930 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT 2088 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT
1931 "sense pool(0x%p): depth(%d), element_size(%d), pool_size" 2089 "sense pool(0x%p): depth(%d), element_size(%d), pool_size"
1932 "(%d kB)\n", ioc->name, ioc->sense, ioc->request_depth, 2090 "(%d kB)\n", ioc->name, ioc->sense, ioc->scsiio_depth,
1933 SCSI_SENSE_BUFFERSIZE, sz/1024)); 2091 SCSI_SENSE_BUFFERSIZE, sz/1024));
1934 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "sense_dma(0x%llx)\n", 2092 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "sense_dma(0x%llx)\n",
1935 ioc->name, (unsigned long long)ioc->sense_dma)); 2093 ioc->name, (unsigned long long)ioc->sense_dma));
@@ -2304,7 +2462,7 @@ _base_handshake_req_reply_wait(struct MPT2SAS_ADAPTER *ioc, int request_bytes,
2304 ((request_bytes/4)<<MPI2_DOORBELL_ADD_DWORDS_SHIFT)), 2462 ((request_bytes/4)<<MPI2_DOORBELL_ADD_DWORDS_SHIFT)),
2305 &ioc->chip->Doorbell); 2463 &ioc->chip->Doorbell);
2306 2464
2307 if ((_base_wait_for_doorbell_int(ioc, 5, sleep_flag))) { 2465 if ((_base_wait_for_doorbell_int(ioc, 5, NO_SLEEP))) {
2308 printk(MPT2SAS_ERR_FMT "doorbell handshake " 2466 printk(MPT2SAS_ERR_FMT "doorbell handshake "
2309 "int failed (line=%d)\n", ioc->name, __LINE__); 2467 "int failed (line=%d)\n", ioc->name, __LINE__);
2310 return -EFAULT; 2468 return -EFAULT;
@@ -2454,7 +2612,8 @@ mpt2sas_base_sas_iounit_control(struct MPT2SAS_ADAPTER *ioc,
2454 if (mpi_request->Operation == MPI2_SAS_OP_PHY_HARD_RESET || 2612 if (mpi_request->Operation == MPI2_SAS_OP_PHY_HARD_RESET ||
2455 mpi_request->Operation == MPI2_SAS_OP_PHY_LINK_RESET) 2613 mpi_request->Operation == MPI2_SAS_OP_PHY_LINK_RESET)
2456 ioc->ioc_link_reset_in_progress = 1; 2614 ioc->ioc_link_reset_in_progress = 1;
2457 mpt2sas_base_put_smid_default(ioc, smid, mpi_request->VF_ID); 2615 mpt2sas_base_put_smid_default(ioc, smid);
2616 init_completion(&ioc->base_cmds.done);
2458 timeleft = wait_for_completion_timeout(&ioc->base_cmds.done, 2617 timeleft = wait_for_completion_timeout(&ioc->base_cmds.done,
2459 msecs_to_jiffies(10000)); 2618 msecs_to_jiffies(10000));
2460 if ((mpi_request->Operation == MPI2_SAS_OP_PHY_HARD_RESET || 2619 if ((mpi_request->Operation == MPI2_SAS_OP_PHY_HARD_RESET ||
@@ -2555,7 +2714,8 @@ mpt2sas_base_scsi_enclosure_processor(struct MPT2SAS_ADAPTER *ioc,
2555 request = mpt2sas_base_get_msg_frame(ioc, smid); 2714 request = mpt2sas_base_get_msg_frame(ioc, smid);
2556 ioc->base_cmds.smid = smid; 2715 ioc->base_cmds.smid = smid;
2557 memcpy(request, mpi_request, sizeof(Mpi2SepReply_t)); 2716 memcpy(request, mpi_request, sizeof(Mpi2SepReply_t));
2558 mpt2sas_base_put_smid_default(ioc, smid, mpi_request->VF_ID); 2717 mpt2sas_base_put_smid_default(ioc, smid);
2718 init_completion(&ioc->base_cmds.done);
2559 timeleft = wait_for_completion_timeout(&ioc->base_cmds.done, 2719 timeleft = wait_for_completion_timeout(&ioc->base_cmds.done,
2560 msecs_to_jiffies(10000)); 2720 msecs_to_jiffies(10000));
2561 if (!(ioc->base_cmds.status & MPT2_CMD_COMPLETE)) { 2721 if (!(ioc->base_cmds.status & MPT2_CMD_COMPLETE)) {
@@ -2701,13 +2861,12 @@ _base_get_ioc_facts(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
2701/** 2861/**
2702 * _base_send_ioc_init - send ioc_init to firmware 2862 * _base_send_ioc_init - send ioc_init to firmware
2703 * @ioc: per adapter object 2863 * @ioc: per adapter object
2704 * @VF_ID: virtual function id
2705 * @sleep_flag: CAN_SLEEP or NO_SLEEP 2864 * @sleep_flag: CAN_SLEEP or NO_SLEEP
2706 * 2865 *
2707 * Returns 0 for success, non-zero for failure. 2866 * Returns 0 for success, non-zero for failure.
2708 */ 2867 */
2709static int 2868static int
2710_base_send_ioc_init(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, int sleep_flag) 2869_base_send_ioc_init(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
2711{ 2870{
2712 Mpi2IOCInitRequest_t mpi_request; 2871 Mpi2IOCInitRequest_t mpi_request;
2713 Mpi2IOCInitReply_t mpi_reply; 2872 Mpi2IOCInitReply_t mpi_reply;
@@ -2719,7 +2878,8 @@ _base_send_ioc_init(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, int sleep_flag)
2719 memset(&mpi_request, 0, sizeof(Mpi2IOCInitRequest_t)); 2878 memset(&mpi_request, 0, sizeof(Mpi2IOCInitRequest_t));
2720 mpi_request.Function = MPI2_FUNCTION_IOC_INIT; 2879 mpi_request.Function = MPI2_FUNCTION_IOC_INIT;
2721 mpi_request.WhoInit = MPI2_WHOINIT_HOST_DRIVER; 2880 mpi_request.WhoInit = MPI2_WHOINIT_HOST_DRIVER;
2722 mpi_request.VF_ID = VF_ID; 2881 mpi_request.VF_ID = 0; /* TODO */
2882 mpi_request.VP_ID = 0;
2723 mpi_request.MsgVersion = cpu_to_le16(MPI2_VERSION); 2883 mpi_request.MsgVersion = cpu_to_le16(MPI2_VERSION);
2724 mpi_request.HeaderVersion = cpu_to_le16(MPI2_HEADER_VERSION); 2884 mpi_request.HeaderVersion = cpu_to_le16(MPI2_HEADER_VERSION);
2725 2885
@@ -2795,13 +2955,12 @@ _base_send_ioc_init(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, int sleep_flag)
2795/** 2955/**
2796 * _base_send_port_enable - send port_enable(discovery stuff) to firmware 2956 * _base_send_port_enable - send port_enable(discovery stuff) to firmware
2797 * @ioc: per adapter object 2957 * @ioc: per adapter object
2798 * @VF_ID: virtual function id
2799 * @sleep_flag: CAN_SLEEP or NO_SLEEP 2958 * @sleep_flag: CAN_SLEEP or NO_SLEEP
2800 * 2959 *
2801 * Returns 0 for success, non-zero for failure. 2960 * Returns 0 for success, non-zero for failure.
2802 */ 2961 */
2803static int 2962static int
2804_base_send_port_enable(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, int sleep_flag) 2963_base_send_port_enable(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
2805{ 2964{
2806 Mpi2PortEnableRequest_t *mpi_request; 2965 Mpi2PortEnableRequest_t *mpi_request;
2807 u32 ioc_state; 2966 u32 ioc_state;
@@ -2829,9 +2988,11 @@ _base_send_port_enable(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, int sleep_flag)
2829 ioc->base_cmds.smid = smid; 2988 ioc->base_cmds.smid = smid;
2830 memset(mpi_request, 0, sizeof(Mpi2PortEnableRequest_t)); 2989 memset(mpi_request, 0, sizeof(Mpi2PortEnableRequest_t));
2831 mpi_request->Function = MPI2_FUNCTION_PORT_ENABLE; 2990 mpi_request->Function = MPI2_FUNCTION_PORT_ENABLE;
2832 mpi_request->VF_ID = VF_ID; 2991 mpi_request->VF_ID = 0; /* TODO */
2992 mpi_request->VP_ID = 0;
2833 2993
2834 mpt2sas_base_put_smid_default(ioc, smid, VF_ID); 2994 mpt2sas_base_put_smid_default(ioc, smid);
2995 init_completion(&ioc->base_cmds.done);
2835 timeleft = wait_for_completion_timeout(&ioc->base_cmds.done, 2996 timeleft = wait_for_completion_timeout(&ioc->base_cmds.done,
2836 300*HZ); 2997 300*HZ);
2837 if (!(ioc->base_cmds.status & MPT2_CMD_COMPLETE)) { 2998 if (!(ioc->base_cmds.status & MPT2_CMD_COMPLETE)) {
@@ -2892,13 +3053,12 @@ _base_unmask_events(struct MPT2SAS_ADAPTER *ioc, u16 event)
2892/** 3053/**
2893 * _base_event_notification - send event notification 3054 * _base_event_notification - send event notification
2894 * @ioc: per adapter object 3055 * @ioc: per adapter object
2895 * @VF_ID: virtual function id
2896 * @sleep_flag: CAN_SLEEP or NO_SLEEP 3056 * @sleep_flag: CAN_SLEEP or NO_SLEEP
2897 * 3057 *
2898 * Returns 0 for success, non-zero for failure. 3058 * Returns 0 for success, non-zero for failure.
2899 */ 3059 */
2900static int 3060static int
2901_base_event_notification(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, int sleep_flag) 3061_base_event_notification(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
2902{ 3062{
2903 Mpi2EventNotificationRequest_t *mpi_request; 3063 Mpi2EventNotificationRequest_t *mpi_request;
2904 unsigned long timeleft; 3064 unsigned long timeleft;
@@ -2926,11 +3086,13 @@ _base_event_notification(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, int sleep_flag)
2926 ioc->base_cmds.smid = smid; 3086 ioc->base_cmds.smid = smid;
2927 memset(mpi_request, 0, sizeof(Mpi2EventNotificationRequest_t)); 3087 memset(mpi_request, 0, sizeof(Mpi2EventNotificationRequest_t));
2928 mpi_request->Function = MPI2_FUNCTION_EVENT_NOTIFICATION; 3088 mpi_request->Function = MPI2_FUNCTION_EVENT_NOTIFICATION;
2929 mpi_request->VF_ID = VF_ID; 3089 mpi_request->VF_ID = 0; /* TODO */
3090 mpi_request->VP_ID = 0;
2930 for (i = 0; i < MPI2_EVENT_NOTIFY_EVENTMASK_WORDS; i++) 3091 for (i = 0; i < MPI2_EVENT_NOTIFY_EVENTMASK_WORDS; i++)
2931 mpi_request->EventMasks[i] = 3092 mpi_request->EventMasks[i] =
2932 le32_to_cpu(ioc->event_masks[i]); 3093 le32_to_cpu(ioc->event_masks[i]);
2933 mpt2sas_base_put_smid_default(ioc, smid, VF_ID); 3094 mpt2sas_base_put_smid_default(ioc, smid);
3095 init_completion(&ioc->base_cmds.done);
2934 timeleft = wait_for_completion_timeout(&ioc->base_cmds.done, 30*HZ); 3096 timeleft = wait_for_completion_timeout(&ioc->base_cmds.done, 30*HZ);
2935 if (!(ioc->base_cmds.status & MPT2_CMD_COMPLETE)) { 3097 if (!(ioc->base_cmds.status & MPT2_CMD_COMPLETE)) {
2936 printk(MPT2SAS_ERR_FMT "%s: timeout\n", 3098 printk(MPT2SAS_ERR_FMT "%s: timeout\n",
@@ -2981,7 +3143,7 @@ mpt2sas_base_validate_event_type(struct MPT2SAS_ADAPTER *ioc, u32 *event_type)
2981 return; 3143 return;
2982 3144
2983 mutex_lock(&ioc->base_cmds.mutex); 3145 mutex_lock(&ioc->base_cmds.mutex);
2984 _base_event_notification(ioc, 0, CAN_SLEEP); 3146 _base_event_notification(ioc, CAN_SLEEP);
2985 mutex_unlock(&ioc->base_cmds.mutex); 3147 mutex_unlock(&ioc->base_cmds.mutex);
2986} 3148}
2987 3149
@@ -3006,7 +3168,6 @@ _base_diag_reset(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
3006 3168
3007 drsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "clear interrupts\n", 3169 drsprintk(ioc, printk(MPT2SAS_DEBUG_FMT "clear interrupts\n",
3008 ioc->name)); 3170 ioc->name));
3009 writel(0, &ioc->chip->HostInterruptStatus);
3010 3171
3011 count = 0; 3172 count = 0;
3012 do { 3173 do {
@@ -3160,30 +3321,60 @@ _base_make_ioc_ready(struct MPT2SAS_ADAPTER *ioc, int sleep_flag,
3160/** 3321/**
3161 * _base_make_ioc_operational - put controller in OPERATIONAL state 3322 * _base_make_ioc_operational - put controller in OPERATIONAL state
3162 * @ioc: per adapter object 3323 * @ioc: per adapter object
3163 * @VF_ID: virtual function id
3164 * @sleep_flag: CAN_SLEEP or NO_SLEEP 3324 * @sleep_flag: CAN_SLEEP or NO_SLEEP
3165 * 3325 *
3166 * Returns 0 for success, non-zero for failure. 3326 * Returns 0 for success, non-zero for failure.
3167 */ 3327 */
3168static int 3328static int
3169_base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, 3329_base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
3170 int sleep_flag)
3171{ 3330{
3172 int r, i; 3331 int r, i;
3173 unsigned long flags; 3332 unsigned long flags;
3174 u32 reply_address; 3333 u32 reply_address;
3334 u16 smid;
3335 struct _tr_list *delayed_tr, *delayed_tr_next;
3175 3336
3176 dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name, 3337 dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
3177 __func__)); 3338 __func__));
3178 3339
3340 /* clean the delayed target reset list */
3341 list_for_each_entry_safe(delayed_tr, delayed_tr_next,
3342 &ioc->delayed_tr_list, list) {
3343 list_del(&delayed_tr->list);
3344 kfree(delayed_tr);
3345 }
3346
3179 /* initialize the scsi lookup free list */ 3347 /* initialize the scsi lookup free list */
3180 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); 3348 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
3181 INIT_LIST_HEAD(&ioc->free_list); 3349 INIT_LIST_HEAD(&ioc->free_list);
3182 for (i = 0; i < ioc->request_depth; i++) { 3350 smid = 1;
3351 for (i = 0; i < ioc->scsiio_depth; i++, smid++) {
3183 ioc->scsi_lookup[i].cb_idx = 0xFF; 3352 ioc->scsi_lookup[i].cb_idx = 0xFF;
3353 ioc->scsi_lookup[i].smid = smid;
3354 ioc->scsi_lookup[i].scmd = NULL;
3184 list_add_tail(&ioc->scsi_lookup[i].tracker_list, 3355 list_add_tail(&ioc->scsi_lookup[i].tracker_list,
3185 &ioc->free_list); 3356 &ioc->free_list);
3186 } 3357 }
3358
3359 /* hi-priority queue */
3360 INIT_LIST_HEAD(&ioc->hpr_free_list);
3361 smid = ioc->hi_priority_smid;
3362 for (i = 0; i < ioc->hi_priority_depth; i++, smid++) {
3363 ioc->hpr_lookup[i].cb_idx = 0xFF;
3364 ioc->hpr_lookup[i].smid = smid;
3365 list_add_tail(&ioc->hpr_lookup[i].tracker_list,
3366 &ioc->hpr_free_list);
3367 }
3368
3369 /* internal queue */
3370 INIT_LIST_HEAD(&ioc->internal_free_list);
3371 smid = ioc->internal_smid;
3372 for (i = 0; i < ioc->internal_depth; i++, smid++) {
3373 ioc->internal_lookup[i].cb_idx = 0xFF;
3374 ioc->internal_lookup[i].smid = smid;
3375 list_add_tail(&ioc->internal_lookup[i].tracker_list,
3376 &ioc->internal_free_list);
3377 }
3187 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); 3378 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
3188 3379
3189 /* initialize Reply Free Queue */ 3380 /* initialize Reply Free Queue */
@@ -3196,7 +3387,7 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,
3196 for (i = 0; i < ioc->reply_post_queue_depth; i++) 3387 for (i = 0; i < ioc->reply_post_queue_depth; i++)
3197 ioc->reply_post_free[i].Words = ULLONG_MAX; 3388 ioc->reply_post_free[i].Words = ULLONG_MAX;
3198 3389
3199 r = _base_send_ioc_init(ioc, VF_ID, sleep_flag); 3390 r = _base_send_ioc_init(ioc, sleep_flag);
3200 if (r) 3391 if (r)
3201 return r; 3392 return r;
3202 3393
@@ -3207,14 +3398,14 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,
3207 writel(0, &ioc->chip->ReplyPostHostIndex); 3398 writel(0, &ioc->chip->ReplyPostHostIndex);
3208 3399
3209 _base_unmask_interrupts(ioc); 3400 _base_unmask_interrupts(ioc);
3210 r = _base_event_notification(ioc, VF_ID, sleep_flag); 3401 r = _base_event_notification(ioc, sleep_flag);
3211 if (r) 3402 if (r)
3212 return r; 3403 return r;
3213 3404
3214 if (sleep_flag == CAN_SLEEP) 3405 if (sleep_flag == CAN_SLEEP)
3215 _base_static_config_pages(ioc); 3406 _base_static_config_pages(ioc);
3216 3407
3217 r = _base_send_port_enable(ioc, VF_ID, sleep_flag); 3408 r = _base_send_port_enable(ioc, sleep_flag);
3218 if (r) 3409 if (r)
3219 return r; 3410 return r;
3220 3411
@@ -3278,6 +3469,17 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
3278 if (r) 3469 if (r)
3279 goto out_free_resources; 3470 goto out_free_resources;
3280 3471
3472 ioc->pfacts = kcalloc(ioc->facts.NumberOfPorts,
3473 sizeof(Mpi2PortFactsReply_t), GFP_KERNEL);
3474 if (!ioc->pfacts)
3475 goto out_free_resources;
3476
3477 for (i = 0 ; i < ioc->facts.NumberOfPorts; i++) {
3478 r = _base_get_port_facts(ioc, i, CAN_SLEEP);
3479 if (r)
3480 goto out_free_resources;
3481 }
3482
3281 r = _base_allocate_memory_pools(ioc, CAN_SLEEP); 3483 r = _base_allocate_memory_pools(ioc, CAN_SLEEP);
3282 if (r) 3484 if (r)
3283 goto out_free_resources; 3485 goto out_free_resources;
@@ -3286,7 +3488,6 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
3286 3488
3287 /* base internal command bits */ 3489 /* base internal command bits */
3288 mutex_init(&ioc->base_cmds.mutex); 3490 mutex_init(&ioc->base_cmds.mutex);
3289 init_completion(&ioc->base_cmds.done);
3290 ioc->base_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); 3491 ioc->base_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL);
3291 ioc->base_cmds.status = MPT2_CMD_NOT_USED; 3492 ioc->base_cmds.status = MPT2_CMD_NOT_USED;
3292 3493
@@ -3294,7 +3495,6 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
3294 ioc->transport_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); 3495 ioc->transport_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL);
3295 ioc->transport_cmds.status = MPT2_CMD_NOT_USED; 3496 ioc->transport_cmds.status = MPT2_CMD_NOT_USED;
3296 mutex_init(&ioc->transport_cmds.mutex); 3497 mutex_init(&ioc->transport_cmds.mutex);
3297 init_completion(&ioc->transport_cmds.done);
3298 3498
3299 /* task management internal command bits */ 3499 /* task management internal command bits */
3300 ioc->tm_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); 3500 ioc->tm_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL);
@@ -3310,7 +3510,6 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
3310 ioc->ctl_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); 3510 ioc->ctl_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL);
3311 ioc->ctl_cmds.status = MPT2_CMD_NOT_USED; 3511 ioc->ctl_cmds.status = MPT2_CMD_NOT_USED;
3312 mutex_init(&ioc->ctl_cmds.mutex); 3512 mutex_init(&ioc->ctl_cmds.mutex);
3313 init_completion(&ioc->ctl_cmds.done);
3314 3513
3315 for (i = 0; i < MPI2_EVENT_NOTIFY_EVENTMASK_WORDS; i++) 3514 for (i = 0; i < MPI2_EVENT_NOTIFY_EVENTMASK_WORDS; i++)
3316 ioc->event_masks[i] = -1; 3515 ioc->event_masks[i] = -1;
@@ -3327,18 +3526,7 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
3327 _base_unmask_events(ioc, MPI2_EVENT_IR_OPERATION_STATUS); 3526 _base_unmask_events(ioc, MPI2_EVENT_IR_OPERATION_STATUS);
3328 _base_unmask_events(ioc, MPI2_EVENT_TASK_SET_FULL); 3527 _base_unmask_events(ioc, MPI2_EVENT_TASK_SET_FULL);
3329 _base_unmask_events(ioc, MPI2_EVENT_LOG_ENTRY_ADDED); 3528 _base_unmask_events(ioc, MPI2_EVENT_LOG_ENTRY_ADDED);
3330 3529 r = _base_make_ioc_operational(ioc, CAN_SLEEP);
3331 ioc->pfacts = kcalloc(ioc->facts.NumberOfPorts,
3332 sizeof(Mpi2PortFactsReply_t), GFP_KERNEL);
3333 if (!ioc->pfacts)
3334 goto out_free_resources;
3335
3336 for (i = 0 ; i < ioc->facts.NumberOfPorts; i++) {
3337 r = _base_get_port_facts(ioc, i, CAN_SLEEP);
3338 if (r)
3339 goto out_free_resources;
3340 }
3341 r = _base_make_ioc_operational(ioc, 0, CAN_SLEEP);
3342 if (r) 3530 if (r)
3343 goto out_free_resources; 3531 goto out_free_resources;
3344 3532
@@ -3466,7 +3654,7 @@ _wait_for_commands_to_complete(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
3466 3654
3467 /* pending command count */ 3655 /* pending command count */
3468 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); 3656 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
3469 for (i = 0; i < ioc->request_depth; i++) 3657 for (i = 0; i < ioc->scsiio_depth; i++)
3470 if (ioc->scsi_lookup[i].cb_idx != 0xFF) 3658 if (ioc->scsi_lookup[i].cb_idx != 0xFF)
3471 ioc->pending_io_count++; 3659 ioc->pending_io_count++;
3472 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); 3660 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
@@ -3490,7 +3678,7 @@ int
3490mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag, 3678mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag,
3491 enum reset_type type) 3679 enum reset_type type)
3492{ 3680{
3493 int r, i; 3681 int r;
3494 unsigned long flags; 3682 unsigned long flags;
3495 3683
3496 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: enter\n", ioc->name, 3684 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: enter\n", ioc->name,
@@ -3513,9 +3701,7 @@ mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag,
3513 if (r) 3701 if (r)
3514 goto out; 3702 goto out;
3515 _base_reset_handler(ioc, MPT2_IOC_AFTER_RESET); 3703 _base_reset_handler(ioc, MPT2_IOC_AFTER_RESET);
3516 for (i = 0 ; i < ioc->facts.NumberOfPorts; i++) 3704 r = _base_make_ioc_operational(ioc, sleep_flag);
3517 r = _base_make_ioc_operational(ioc, ioc->pfacts[i].VF_ID,
3518 sleep_flag);
3519 if (!r) 3705 if (!r)
3520 _base_reset_handler(ioc, MPT2_IOC_DONE_RESET); 3706 _base_reset_handler(ioc, MPT2_IOC_DONE_RESET);
3521 out: 3707 out:
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.h b/drivers/scsi/mpt2sas/mpt2sas_base.h
index 2faab1e690e9..0cf6bc236e4d 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_base.h
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.h
@@ -3,7 +3,7 @@
3 * for access to MPT (Message Passing Technology) firmware. 3 * for access to MPT (Message Passing Technology) firmware.
4 * 4 *
5 * This code is based on drivers/scsi/mpt2sas/mpt2_base.h 5 * This code is based on drivers/scsi/mpt2sas/mpt2_base.h
6 * Copyright (C) 2007-2008 LSI Corporation 6 * Copyright (C) 2007-2009 LSI Corporation
7 * (mailto:DL-MPTFusionLinux@lsi.com) 7 * (mailto:DL-MPTFusionLinux@lsi.com)
8 * 8 *
9 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
@@ -69,10 +69,10 @@
69#define MPT2SAS_DRIVER_NAME "mpt2sas" 69#define MPT2SAS_DRIVER_NAME "mpt2sas"
70#define MPT2SAS_AUTHOR "LSI Corporation <DL-MPTFusionLinux@lsi.com>" 70#define MPT2SAS_AUTHOR "LSI Corporation <DL-MPTFusionLinux@lsi.com>"
71#define MPT2SAS_DESCRIPTION "LSI MPT Fusion SAS 2.0 Device Driver" 71#define MPT2SAS_DESCRIPTION "LSI MPT Fusion SAS 2.0 Device Driver"
72#define MPT2SAS_DRIVER_VERSION "01.100.06.00" 72#define MPT2SAS_DRIVER_VERSION "02.100.03.00"
73#define MPT2SAS_MAJOR_VERSION 01 73#define MPT2SAS_MAJOR_VERSION 02
74#define MPT2SAS_MINOR_VERSION 100 74#define MPT2SAS_MINOR_VERSION 100
75#define MPT2SAS_BUILD_VERSION 06 75#define MPT2SAS_BUILD_VERSION 03
76#define MPT2SAS_RELEASE_VERSION 00 76#define MPT2SAS_RELEASE_VERSION 00
77 77
78/* 78/*
@@ -264,6 +264,13 @@ struct _internal_cmd {
264 * SAS Topology Structures 264 * SAS Topology Structures
265 */ 265 */
266 266
267#define MPTSAS_STATE_TR_SEND 0x0001
268#define MPTSAS_STATE_TR_COMPLETE 0x0002
269#define MPTSAS_STATE_CNTRL_SEND 0x0004
270#define MPTSAS_STATE_CNTRL_COMPLETE 0x0008
271
272#define MPT2SAS_REQ_SAS_CNTRL 0x0010
273
267/** 274/**
268 * struct _sas_device - attached device information 275 * struct _sas_device - attached device information
269 * @list: sas device list 276 * @list: sas device list
@@ -300,6 +307,7 @@ struct _sas_device {
300 u16 slot; 307 u16 slot;
301 u8 hidden_raid_component; 308 u8 hidden_raid_component;
302 u8 responding; 309 u8 responding;
310 u16 state;
303}; 311};
304 312
305/** 313/**
@@ -436,6 +444,17 @@ struct request_tracker {
436 struct list_head tracker_list; 444 struct list_head tracker_list;
437}; 445};
438 446
447/**
448 * struct _tr_list - target reset list
449 * @handle: device handle
450 * @state: state machine
451 */
452struct _tr_list {
453 struct list_head list;
454 u16 handle;
455 u16 state;
456};
457
439typedef void (*MPT_ADD_SGE)(void *paddr, u32 flags_length, dma_addr_t dma_addr); 458typedef void (*MPT_ADD_SGE)(void *paddr, u32 flags_length, dma_addr_t dma_addr);
440 459
441/** 460/**
@@ -510,8 +529,9 @@ typedef void (*MPT_ADD_SGE)(void *paddr, u32 flags_length, dma_addr_t dma_addr);
510 * @config_page_sz: config page size 529 * @config_page_sz: config page size
511 * @config_page: reserve memory for config page payload 530 * @config_page: reserve memory for config page payload
512 * @config_page_dma: 531 * @config_page_dma:
532 * @hba_queue_depth: hba request queue depth
513 * @sge_size: sg element size for either 32/64 bit 533 * @sge_size: sg element size for either 32/64 bit
514 * @request_depth: hba request queue depth 534 * @scsiio_depth: SCSI_IO queue depth
515 * @request_sz: per request frame size 535 * @request_sz: per request frame size
516 * @request: pool of request frames 536 * @request: pool of request frames
517 * @request_dma: 537 * @request_dma:
@@ -528,6 +548,18 @@ typedef void (*MPT_ADD_SGE)(void *paddr, u32 flags_length, dma_addr_t dma_addr);
528 * @chains_needed_per_io: max chains per io 548 * @chains_needed_per_io: max chains per io
529 * @chain_offset_value_for_main_message: location 1st sg in main 549 * @chain_offset_value_for_main_message: location 1st sg in main
530 * @chain_depth: total chains allocated 550 * @chain_depth: total chains allocated
551 * @hi_priority_smid:
552 * @hi_priority:
553 * @hi_priority_dma:
554 * @hi_priority_depth:
555 * @hpr_lookup:
556 * @hpr_free_list:
557 * @internal_smid:
558 * @internal:
559 * @internal_dma:
560 * @internal_depth:
561 * @internal_lookup:
562 * @internal_free_list:
531 * @sense: pool of sense 563 * @sense: pool of sense
532 * @sense_dma: 564 * @sense_dma:
533 * @sense_dma_pool: 565 * @sense_dma_pool:
@@ -597,6 +629,8 @@ struct MPT2SAS_ADAPTER {
597 u8 ctl_cb_idx; 629 u8 ctl_cb_idx;
598 u8 base_cb_idx; 630 u8 base_cb_idx;
599 u8 config_cb_idx; 631 u8 config_cb_idx;
632 u8 tm_tr_cb_idx;
633 u8 tm_sas_control_cb_idx;
600 struct _internal_cmd base_cmds; 634 struct _internal_cmd base_cmds;
601 struct _internal_cmd transport_cmds; 635 struct _internal_cmd transport_cmds;
602 struct _internal_cmd tm_cmds; 636 struct _internal_cmd tm_cmds;
@@ -643,9 +677,10 @@ struct MPT2SAS_ADAPTER {
643 void *config_page; 677 void *config_page;
644 dma_addr_t config_page_dma; 678 dma_addr_t config_page_dma;
645 679
646 /* request */ 680 /* scsiio request */
681 u16 hba_queue_depth;
647 u16 sge_size; 682 u16 sge_size;
648 u16 request_depth; 683 u16 scsiio_depth;
649 u16 request_sz; 684 u16 request_sz;
650 u8 *request; 685 u8 *request;
651 dma_addr_t request_dma; 686 dma_addr_t request_dma;
@@ -665,6 +700,22 @@ struct MPT2SAS_ADAPTER {
665 u16 chain_offset_value_for_main_message; 700 u16 chain_offset_value_for_main_message;
666 u16 chain_depth; 701 u16 chain_depth;
667 702
703 /* hi-priority queue */
704 u16 hi_priority_smid;
705 u8 *hi_priority;
706 dma_addr_t hi_priority_dma;
707 u16 hi_priority_depth;
708 struct request_tracker *hpr_lookup;
709 struct list_head hpr_free_list;
710
711 /* internal queue */
712 u16 internal_smid;
713 u8 *internal;
714 dma_addr_t internal_dma;
715 u16 internal_depth;
716 struct request_tracker *internal_lookup;
717 struct list_head internal_free_list;
718
668 /* sense */ 719 /* sense */
669 u8 *sense; 720 u8 *sense;
670 dma_addr_t sense_dma; 721 dma_addr_t sense_dma;
@@ -690,6 +741,8 @@ struct MPT2SAS_ADAPTER {
690 struct dma_pool *reply_post_free_dma_pool; 741 struct dma_pool *reply_post_free_dma_pool;
691 u32 reply_post_host_index; 742 u32 reply_post_host_index;
692 743
744 struct list_head delayed_tr_list;
745
693 /* diag buffer support */ 746 /* diag buffer support */
694 u8 *diag_buffer[MPI2_DIAG_BUF_TYPE_COUNT]; 747 u8 *diag_buffer[MPI2_DIAG_BUF_TYPE_COUNT];
695 u32 diag_buffer_sz[MPI2_DIAG_BUF_TYPE_COUNT]; 748 u32 diag_buffer_sz[MPI2_DIAG_BUF_TYPE_COUNT];
@@ -701,7 +754,7 @@ struct MPT2SAS_ADAPTER {
701 u32 diagnostic_flags[MPI2_DIAG_BUF_TYPE_COUNT]; 754 u32 diagnostic_flags[MPI2_DIAG_BUF_TYPE_COUNT];
702}; 755};
703 756
704typedef void (*MPT_CALLBACK)(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID, 757typedef u8 (*MPT_CALLBACK)(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
705 u32 reply); 758 u32 reply);
706 759
707 760
@@ -720,22 +773,28 @@ int mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag,
720void *mpt2sas_base_get_msg_frame(struct MPT2SAS_ADAPTER *ioc, u16 smid); 773void *mpt2sas_base_get_msg_frame(struct MPT2SAS_ADAPTER *ioc, u16 smid);
721void *mpt2sas_base_get_sense_buffer(struct MPT2SAS_ADAPTER *ioc, u16 smid); 774void *mpt2sas_base_get_sense_buffer(struct MPT2SAS_ADAPTER *ioc, u16 smid);
722void mpt2sas_base_build_zero_len_sge(struct MPT2SAS_ADAPTER *ioc, void *paddr); 775void mpt2sas_base_build_zero_len_sge(struct MPT2SAS_ADAPTER *ioc, void *paddr);
723dma_addr_t mpt2sas_base_get_msg_frame_dma(struct MPT2SAS_ADAPTER *ioc, u16 smid); 776dma_addr_t mpt2sas_base_get_sense_buffer_dma(struct MPT2SAS_ADAPTER *ioc,
724dma_addr_t mpt2sas_base_get_sense_buffer_dma(struct MPT2SAS_ADAPTER *ioc, u16 smid); 777 u16 smid);
778
779/* hi-priority queue */
780u16 mpt2sas_base_get_smid_hpr(struct MPT2SAS_ADAPTER *ioc, u8 cb_idx);
781u16 mpt2sas_base_get_smid_scsiio(struct MPT2SAS_ADAPTER *ioc, u8 cb_idx,
782 struct scsi_cmnd *scmd);
725 783
726u16 mpt2sas_base_get_smid(struct MPT2SAS_ADAPTER *ioc, u8 cb_idx); 784u16 mpt2sas_base_get_smid(struct MPT2SAS_ADAPTER *ioc, u8 cb_idx);
727void mpt2sas_base_free_smid(struct MPT2SAS_ADAPTER *ioc, u16 smid); 785void mpt2sas_base_free_smid(struct MPT2SAS_ADAPTER *ioc, u16 smid);
728void mpt2sas_base_put_smid_scsi_io(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 vf_id, 786void mpt2sas_base_put_smid_scsi_io(struct MPT2SAS_ADAPTER *ioc, u16 smid,
729 u16 handle); 787 u16 handle);
730void mpt2sas_base_put_smid_hi_priority(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 vf_id); 788void mpt2sas_base_put_smid_hi_priority(struct MPT2SAS_ADAPTER *ioc, u16 smid);
731void mpt2sas_base_put_smid_target_assist(struct MPT2SAS_ADAPTER *ioc, u16 smid, 789void mpt2sas_base_put_smid_target_assist(struct MPT2SAS_ADAPTER *ioc, u16 smid,
732 u8 vf_id, u16 io_index); 790 u16 io_index);
733void mpt2sas_base_put_smid_default(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 vf_id); 791void mpt2sas_base_put_smid_default(struct MPT2SAS_ADAPTER *ioc, u16 smid);
734void mpt2sas_base_initialize_callback_handler(void); 792void mpt2sas_base_initialize_callback_handler(void);
735u8 mpt2sas_base_register_callback_handler(MPT_CALLBACK cb_func); 793u8 mpt2sas_base_register_callback_handler(MPT_CALLBACK cb_func);
736void mpt2sas_base_release_callback_handler(u8 cb_idx); 794void mpt2sas_base_release_callback_handler(u8 cb_idx);
737 795
738void mpt2sas_base_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID, u32 reply); 796u8 mpt2sas_base_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
797 u32 reply);
739void *mpt2sas_base_get_reply_virt_addr(struct MPT2SAS_ADAPTER *ioc, u32 phys_addr); 798void *mpt2sas_base_get_reply_virt_addr(struct MPT2SAS_ADAPTER *ioc, u32 phys_addr);
740 799
741u32 mpt2sas_base_get_iocstate(struct MPT2SAS_ADAPTER *ioc, int cooked); 800u32 mpt2sas_base_get_iocstate(struct MPT2SAS_ADAPTER *ioc, int cooked);
@@ -749,6 +808,8 @@ int mpt2sas_base_scsi_enclosure_processor(struct MPT2SAS_ADAPTER *ioc,
749void mpt2sas_base_validate_event_type(struct MPT2SAS_ADAPTER *ioc, u32 *event_type); 808void mpt2sas_base_validate_event_type(struct MPT2SAS_ADAPTER *ioc, u32 *event_type);
750 809
751/* scsih shared API */ 810/* scsih shared API */
811u8 mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
812 u32 reply);
752void mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle, uint lun, 813void mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle, uint lun,
753 u8 type, u16 smid_task, ulong timeout); 814 u8 type, u16 smid_task, ulong timeout);
754void mpt2sas_scsih_set_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle); 815void mpt2sas_scsih_set_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle);
@@ -760,11 +821,11 @@ struct _sas_node *mpt2sas_scsih_expander_find_by_sas_address(struct MPT2SAS_ADAP
760struct _sas_device *mpt2sas_scsih_sas_device_find_by_sas_address( 821struct _sas_device *mpt2sas_scsih_sas_device_find_by_sas_address(
761 struct MPT2SAS_ADAPTER *ioc, u64 sas_address); 822 struct MPT2SAS_ADAPTER *ioc, u64 sas_address);
762 823
763void mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, u32 reply);
764void mpt2sas_scsih_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase); 824void mpt2sas_scsih_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase);
765 825
766/* config shared API */ 826/* config shared API */
767void mpt2sas_config_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID, u32 reply); 827u8 mpt2sas_config_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
828 u32 reply);
768int mpt2sas_config_get_number_hba_phys(struct MPT2SAS_ADAPTER *ioc, u8 *num_phys); 829int mpt2sas_config_get_number_hba_phys(struct MPT2SAS_ADAPTER *ioc, u8 *num_phys);
769int mpt2sas_config_get_manufacturing_pg0(struct MPT2SAS_ADAPTER *ioc, 830int mpt2sas_config_get_manufacturing_pg0(struct MPT2SAS_ADAPTER *ioc,
770 Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage0_t *config_page); 831 Mpi2ConfigReply_t *mpi_reply, Mpi2ManufacturingPage0_t *config_page);
@@ -817,14 +878,17 @@ extern struct device_attribute *mpt2sas_host_attrs[];
817extern struct device_attribute *mpt2sas_dev_attrs[]; 878extern struct device_attribute *mpt2sas_dev_attrs[];
818void mpt2sas_ctl_init(void); 879void mpt2sas_ctl_init(void);
819void mpt2sas_ctl_exit(void); 880void mpt2sas_ctl_exit(void);
820void mpt2sas_ctl_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID, u32 reply); 881u8 mpt2sas_ctl_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
882 u32 reply);
821void mpt2sas_ctl_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase); 883void mpt2sas_ctl_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase);
822void mpt2sas_ctl_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, u32 reply); 884u8 mpt2sas_ctl_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
885 u32 reply);
823void mpt2sas_ctl_add_to_event_log(struct MPT2SAS_ADAPTER *ioc, 886void mpt2sas_ctl_add_to_event_log(struct MPT2SAS_ADAPTER *ioc,
824 Mpi2EventNotificationReply_t *mpi_reply); 887 Mpi2EventNotificationReply_t *mpi_reply);
825 888
826/* transport shared API */ 889/* transport shared API */
827void mpt2sas_transport_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID, u32 reply); 890u8 mpt2sas_transport_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
891 u32 reply);
828struct _sas_port *mpt2sas_transport_port_add(struct MPT2SAS_ADAPTER *ioc, 892struct _sas_port *mpt2sas_transport_port_add(struct MPT2SAS_ADAPTER *ioc,
829 u16 handle, u16 parent_handle); 893 u16 handle, u16 parent_handle);
830void mpt2sas_transport_port_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address, 894void mpt2sas_transport_port_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
@@ -838,6 +902,8 @@ void mpt2sas_transport_update_links(struct MPT2SAS_ADAPTER *ioc, u16 handle,
838extern struct sas_function_template mpt2sas_transport_functions; 902extern struct sas_function_template mpt2sas_transport_functions;
839extern struct scsi_transport_template *mpt2sas_transport_template; 903extern struct scsi_transport_template *mpt2sas_transport_template;
840extern int scsi_internal_device_block(struct scsi_device *sdev); 904extern int scsi_internal_device_block(struct scsi_device *sdev);
905extern u8 mpt2sas_stm_zero_smid_handler(struct MPT2SAS_ADAPTER *ioc,
906 u8 msix_index, u32 reply);
841extern int scsi_internal_device_unblock(struct scsi_device *sdev); 907extern int scsi_internal_device_unblock(struct scsi_device *sdev);
842 908
843#endif /* MPT2SAS_BASE_H_INCLUDED */ 909#endif /* MPT2SAS_BASE_H_INCLUDED */
diff --git a/drivers/scsi/mpt2sas/mpt2sas_config.c b/drivers/scsi/mpt2sas/mpt2sas_config.c
index ab8c560865d8..594a389c6526 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_config.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_config.c
@@ -2,7 +2,7 @@
2 * This module provides common API for accessing firmware configuration pages 2 * This module provides common API for accessing firmware configuration pages
3 * 3 *
4 * This code is based on drivers/scsi/mpt2sas/mpt2_base.c 4 * This code is based on drivers/scsi/mpt2sas/mpt2_base.c
5 * Copyright (C) 2007-2008 LSI Corporation 5 * Copyright (C) 2007-2009 LSI Corporation
6 * (mailto:DL-MPTFusionLinux@lsi.com) 6 * (mailto:DL-MPTFusionLinux@lsi.com)
7 * 7 *
8 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
@@ -227,23 +227,25 @@ _config_free_config_dma_memory(struct MPT2SAS_ADAPTER *ioc,
227 * mpt2sas_config_done - config page completion routine 227 * mpt2sas_config_done - config page completion routine
228 * @ioc: per adapter object 228 * @ioc: per adapter object
229 * @smid: system request message index 229 * @smid: system request message index
230 * @VF_ID: virtual function id 230 * @msix_index: MSIX table index supplied by the OS
231 * @reply: reply message frame(lower 32bit addr) 231 * @reply: reply message frame(lower 32bit addr)
232 * Context: none. 232 * Context: none.
233 * 233 *
234 * The callback handler when using _config_request. 234 * The callback handler when using _config_request.
235 * 235 *
236 * Return nothing. 236 * Return 1 meaning mf should be freed from _base_interrupt
237 * 0 means the mf is freed from this function.
237 */ 238 */
238void 239u8
239mpt2sas_config_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID, u32 reply) 240mpt2sas_config_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
241 u32 reply)
240{ 242{
241 MPI2DefaultReply_t *mpi_reply; 243 MPI2DefaultReply_t *mpi_reply;
242 244
243 if (ioc->config_cmds.status == MPT2_CMD_NOT_USED) 245 if (ioc->config_cmds.status == MPT2_CMD_NOT_USED)
244 return; 246 return 1;
245 if (ioc->config_cmds.smid != smid) 247 if (ioc->config_cmds.smid != smid)
246 return; 248 return 1;
247 ioc->config_cmds.status |= MPT2_CMD_COMPLETE; 249 ioc->config_cmds.status |= MPT2_CMD_COMPLETE;
248 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); 250 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
249 if (mpi_reply) { 251 if (mpi_reply) {
@@ -257,6 +259,7 @@ mpt2sas_config_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID, u32 reply)
257#endif 259#endif
258 ioc->config_cmds.smid = USHORT_MAX; 260 ioc->config_cmds.smid = USHORT_MAX;
259 complete(&ioc->config_cmds.done); 261 complete(&ioc->config_cmds.done);
262 return 1;
260} 263}
261 264
262/** 265/**
@@ -303,6 +306,9 @@ _config_request(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigRequest_t
303 retry_count = 0; 306 retry_count = 0;
304 memset(&mem, 0, sizeof(struct config_request)); 307 memset(&mem, 0, sizeof(struct config_request));
305 308
309 mpi_request->VF_ID = 0; /* TODO */
310 mpi_request->VP_ID = 0;
311
306 if (config_page) { 312 if (config_page) {
307 mpi_request->Header.PageVersion = mpi_reply->Header.PageVersion; 313 mpi_request->Header.PageVersion = mpi_reply->Header.PageVersion;
308 mpi_request->Header.PageNumber = mpi_reply->Header.PageNumber; 314 mpi_request->Header.PageNumber = mpi_reply->Header.PageNumber;
@@ -380,7 +386,7 @@ _config_request(struct MPT2SAS_ADAPTER *ioc, Mpi2ConfigRequest_t
380 _config_display_some_debug(ioc, smid, "config_request", NULL); 386 _config_display_some_debug(ioc, smid, "config_request", NULL);
381#endif 387#endif
382 init_completion(&ioc->config_cmds.done); 388 init_completion(&ioc->config_cmds.done);
383 mpt2sas_base_put_smid_default(ioc, smid, config_request->VF_ID); 389 mpt2sas_base_put_smid_default(ioc, smid);
384 timeleft = wait_for_completion_timeout(&ioc->config_cmds.done, 390 timeleft = wait_for_completion_timeout(&ioc->config_cmds.done,
385 timeout*HZ); 391 timeout*HZ);
386 if (!(ioc->config_cmds.status & MPT2_CMD_COMPLETE)) { 392 if (!(ioc->config_cmds.status & MPT2_CMD_COMPLETE)) {
diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.c b/drivers/scsi/mpt2sas/mpt2sas_ctl.c
index c2a51018910f..57d724633906 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_ctl.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_ctl.c
@@ -3,7 +3,7 @@
3 * controllers 3 * controllers
4 * 4 *
5 * This code is based on drivers/scsi/mpt2sas/mpt2_ctl.c 5 * This code is based on drivers/scsi/mpt2sas/mpt2_ctl.c
6 * Copyright (C) 2007-2008 LSI Corporation 6 * Copyright (C) 2007-2009 LSI Corporation
7 * (mailto:DL-MPTFusionLinux@lsi.com) 7 * (mailto:DL-MPTFusionLinux@lsi.com)
8 * 8 *
9 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
@@ -219,23 +219,25 @@ _ctl_display_some_debug(struct MPT2SAS_ADAPTER *ioc, u16 smid,
219 * mpt2sas_ctl_done - ctl module completion routine 219 * mpt2sas_ctl_done - ctl module completion routine
220 * @ioc: per adapter object 220 * @ioc: per adapter object
221 * @smid: system request message index 221 * @smid: system request message index
222 * @VF_ID: virtual function id 222 * @msix_index: MSIX table index supplied by the OS
223 * @reply: reply message frame(lower 32bit addr) 223 * @reply: reply message frame(lower 32bit addr)
224 * Context: none. 224 * Context: none.
225 * 225 *
226 * The callback handler when using ioc->ctl_cb_idx. 226 * The callback handler when using ioc->ctl_cb_idx.
227 * 227 *
228 * Return nothing. 228 * Return 1 meaning mf should be freed from _base_interrupt
229 * 0 means the mf is freed from this function.
229 */ 230 */
230void 231u8
231mpt2sas_ctl_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID, u32 reply) 232mpt2sas_ctl_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
233 u32 reply)
232{ 234{
233 MPI2DefaultReply_t *mpi_reply; 235 MPI2DefaultReply_t *mpi_reply;
234 236
235 if (ioc->ctl_cmds.status == MPT2_CMD_NOT_USED) 237 if (ioc->ctl_cmds.status == MPT2_CMD_NOT_USED)
236 return; 238 return 1;
237 if (ioc->ctl_cmds.smid != smid) 239 if (ioc->ctl_cmds.smid != smid)
238 return; 240 return 1;
239 ioc->ctl_cmds.status |= MPT2_CMD_COMPLETE; 241 ioc->ctl_cmds.status |= MPT2_CMD_COMPLETE;
240 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); 242 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
241 if (mpi_reply) { 243 if (mpi_reply) {
@@ -247,6 +249,7 @@ mpt2sas_ctl_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID, u32 reply)
247#endif 249#endif
248 ioc->ctl_cmds.status &= ~MPT2_CMD_PENDING; 250 ioc->ctl_cmds.status &= ~MPT2_CMD_PENDING;
249 complete(&ioc->ctl_cmds.done); 251 complete(&ioc->ctl_cmds.done);
252 return 1;
250} 253}
251 254
252/** 255/**
@@ -328,22 +331,25 @@ mpt2sas_ctl_add_to_event_log(struct MPT2SAS_ADAPTER *ioc,
328/** 331/**
329 * mpt2sas_ctl_event_callback - firmware event handler (called at ISR time) 332 * mpt2sas_ctl_event_callback - firmware event handler (called at ISR time)
330 * @ioc: per adapter object 333 * @ioc: per adapter object
331 * @VF_ID: virtual function id 334 * @msix_index: MSIX table index supplied by the OS
332 * @reply: reply message frame(lower 32bit addr) 335 * @reply: reply message frame(lower 32bit addr)
333 * Context: interrupt. 336 * Context: interrupt.
334 * 337 *
335 * This function merely adds a new work task into ioc->firmware_event_thread. 338 * This function merely adds a new work task into ioc->firmware_event_thread.
336 * The tasks are worked from _firmware_event_work in user context. 339 * The tasks are worked from _firmware_event_work in user context.
337 * 340 *
338 * Return nothing. 341 * Return 1 meaning mf should be freed from _base_interrupt
342 * 0 means the mf is freed from this function.
339 */ 343 */
340void 344u8
341mpt2sas_ctl_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, u32 reply) 345mpt2sas_ctl_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
346 u32 reply)
342{ 347{
343 Mpi2EventNotificationReply_t *mpi_reply; 348 Mpi2EventNotificationReply_t *mpi_reply;
344 349
345 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); 350 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
346 mpt2sas_ctl_add_to_event_log(ioc, mpi_reply); 351 mpt2sas_ctl_add_to_event_log(ioc, mpi_reply);
352 return 1;
347} 353}
348 354
349/** 355/**
@@ -507,7 +513,7 @@ _ctl_set_task_mid(struct MPT2SAS_ADAPTER *ioc, struct mpt2_ioctl_command *karg,
507 513
508 handle = le16_to_cpu(tm_request->DevHandle); 514 handle = le16_to_cpu(tm_request->DevHandle);
509 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); 515 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
510 for (i = ioc->request_depth; i && !found; i--) { 516 for (i = ioc->scsiio_depth; i && !found; i--) {
511 scmd = ioc->scsi_lookup[i - 1].scmd; 517 scmd = ioc->scsi_lookup[i - 1].scmd;
512 if (scmd == NULL || scmd->device == NULL || 518 if (scmd == NULL || scmd->device == NULL ||
513 scmd->device->hostdata == NULL) 519 scmd->device->hostdata == NULL)
@@ -614,7 +620,7 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
614 printk(MPT2SAS_INFO_FMT "%s: ioc is operational\n", 620 printk(MPT2SAS_INFO_FMT "%s: ioc is operational\n",
615 ioc->name, __func__); 621 ioc->name, __func__);
616 622
617 smid = mpt2sas_base_get_smid(ioc, ioc->ctl_cb_idx); 623 smid = mpt2sas_base_get_smid_scsiio(ioc, ioc->ctl_cb_idx, NULL);
618 if (!smid) { 624 if (!smid) {
619 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n", 625 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
620 ioc->name, __func__); 626 ioc->name, __func__);
@@ -737,7 +743,7 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
737 (u32)mpt2sas_base_get_sense_buffer_dma(ioc, smid); 743 (u32)mpt2sas_base_get_sense_buffer_dma(ioc, smid);
738 priv_sense = mpt2sas_base_get_sense_buffer(ioc, smid); 744 priv_sense = mpt2sas_base_get_sense_buffer(ioc, smid);
739 memset(priv_sense, 0, SCSI_SENSE_BUFFERSIZE); 745 memset(priv_sense, 0, SCSI_SENSE_BUFFERSIZE);
740 mpt2sas_base_put_smid_scsi_io(ioc, smid, 0, 746 mpt2sas_base_put_smid_scsi_io(ioc, smid,
741 le16_to_cpu(mpi_request->FunctionDependent1)); 747 le16_to_cpu(mpi_request->FunctionDependent1));
742 break; 748 break;
743 } 749 }
@@ -759,8 +765,7 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
759 mutex_lock(&ioc->tm_cmds.mutex); 765 mutex_lock(&ioc->tm_cmds.mutex);
760 mpt2sas_scsih_set_tm_flag(ioc, le16_to_cpu( 766 mpt2sas_scsih_set_tm_flag(ioc, le16_to_cpu(
761 tm_request->DevHandle)); 767 tm_request->DevHandle));
762 mpt2sas_base_put_smid_hi_priority(ioc, smid, 768 mpt2sas_base_put_smid_hi_priority(ioc, smid);
763 mpi_request->VF_ID);
764 break; 769 break;
765 } 770 }
766 case MPI2_FUNCTION_SMP_PASSTHROUGH: 771 case MPI2_FUNCTION_SMP_PASSTHROUGH:
@@ -781,7 +786,7 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
781 ioc->ioc_link_reset_in_progress = 1; 786 ioc->ioc_link_reset_in_progress = 1;
782 ioc->ignore_loginfos = 1; 787 ioc->ignore_loginfos = 1;
783 } 788 }
784 mpt2sas_base_put_smid_default(ioc, smid, mpi_request->VF_ID); 789 mpt2sas_base_put_smid_default(ioc, smid);
785 break; 790 break;
786 } 791 }
787 case MPI2_FUNCTION_SAS_IO_UNIT_CONTROL: 792 case MPI2_FUNCTION_SAS_IO_UNIT_CONTROL:
@@ -795,11 +800,11 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
795 ioc->ioc_link_reset_in_progress = 1; 800 ioc->ioc_link_reset_in_progress = 1;
796 ioc->ignore_loginfos = 1; 801 ioc->ignore_loginfos = 1;
797 } 802 }
798 mpt2sas_base_put_smid_default(ioc, smid, mpi_request->VF_ID); 803 mpt2sas_base_put_smid_default(ioc, smid);
799 break; 804 break;
800 } 805 }
801 default: 806 default:
802 mpt2sas_base_put_smid_default(ioc, smid, mpi_request->VF_ID); 807 mpt2sas_base_put_smid_default(ioc, smid);
803 break; 808 break;
804 } 809 }
805 810
@@ -807,6 +812,7 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
807 timeout = MPT2_IOCTL_DEFAULT_TIMEOUT; 812 timeout = MPT2_IOCTL_DEFAULT_TIMEOUT;
808 else 813 else
809 timeout = karg.timeout; 814 timeout = karg.timeout;
815 init_completion(&ioc->ctl_cmds.done);
810 timeleft = wait_for_completion_timeout(&ioc->ctl_cmds.done, 816 timeleft = wait_for_completion_timeout(&ioc->ctl_cmds.done,
811 timeout*HZ); 817 timeout*HZ);
812 if (mpi_request->Function == MPI2_FUNCTION_SCSI_TASK_MGMT) { 818 if (mpi_request->Function == MPI2_FUNCTION_SCSI_TASK_MGMT) {
@@ -1371,6 +1377,8 @@ _ctl_diag_register(void __user *arg, enum block_state state)
1371 mpi_request->Flags = cpu_to_le32(karg.diagnostic_flags); 1377 mpi_request->Flags = cpu_to_le32(karg.diagnostic_flags);
1372 mpi_request->BufferAddress = cpu_to_le64(request_data_dma); 1378 mpi_request->BufferAddress = cpu_to_le64(request_data_dma);
1373 mpi_request->BufferLength = cpu_to_le32(request_data_sz); 1379 mpi_request->BufferLength = cpu_to_le32(request_data_sz);
1380 mpi_request->VF_ID = 0; /* TODO */
1381 mpi_request->VP_ID = 0;
1374 1382
1375 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: diag_buffer(0x%p), " 1383 dctlprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: diag_buffer(0x%p), "
1376 "dma(0x%llx), sz(%d)\n", ioc->name, __func__, request_data, 1384 "dma(0x%llx), sz(%d)\n", ioc->name, __func__, request_data,
@@ -1380,7 +1388,8 @@ _ctl_diag_register(void __user *arg, enum block_state state)
1380 mpi_request->ProductSpecific[i] = 1388 mpi_request->ProductSpecific[i] =
1381 cpu_to_le32(ioc->product_specific[buffer_type][i]); 1389 cpu_to_le32(ioc->product_specific[buffer_type][i]);
1382 1390
1383 mpt2sas_base_put_smid_default(ioc, smid, mpi_request->VF_ID); 1391 mpt2sas_base_put_smid_default(ioc, smid);
1392 init_completion(&ioc->ctl_cmds.done);
1384 timeleft = wait_for_completion_timeout(&ioc->ctl_cmds.done, 1393 timeleft = wait_for_completion_timeout(&ioc->ctl_cmds.done,
1385 MPT2_IOCTL_DEFAULT_TIMEOUT*HZ); 1394 MPT2_IOCTL_DEFAULT_TIMEOUT*HZ);
1386 1395
@@ -1643,8 +1652,11 @@ _ctl_send_release(struct MPT2SAS_ADAPTER *ioc, u8 buffer_type, u8 *issue_reset)
1643 1652
1644 mpi_request->Function = MPI2_FUNCTION_DIAG_RELEASE; 1653 mpi_request->Function = MPI2_FUNCTION_DIAG_RELEASE;
1645 mpi_request->BufferType = buffer_type; 1654 mpi_request->BufferType = buffer_type;
1655 mpi_request->VF_ID = 0; /* TODO */
1656 mpi_request->VP_ID = 0;
1646 1657
1647 mpt2sas_base_put_smid_default(ioc, smid, mpi_request->VF_ID); 1658 mpt2sas_base_put_smid_default(ioc, smid);
1659 init_completion(&ioc->ctl_cmds.done);
1648 timeleft = wait_for_completion_timeout(&ioc->ctl_cmds.done, 1660 timeleft = wait_for_completion_timeout(&ioc->ctl_cmds.done,
1649 MPT2_IOCTL_DEFAULT_TIMEOUT*HZ); 1661 MPT2_IOCTL_DEFAULT_TIMEOUT*HZ);
1650 1662
@@ -1902,8 +1914,11 @@ _ctl_diag_read_buffer(void __user *arg, enum block_state state)
1902 for (i = 0; i < MPT2_PRODUCT_SPECIFIC_DWORDS; i++) 1914 for (i = 0; i < MPT2_PRODUCT_SPECIFIC_DWORDS; i++)
1903 mpi_request->ProductSpecific[i] = 1915 mpi_request->ProductSpecific[i] =
1904 cpu_to_le32(ioc->product_specific[buffer_type][i]); 1916 cpu_to_le32(ioc->product_specific[buffer_type][i]);
1917 mpi_request->VF_ID = 0; /* TODO */
1918 mpi_request->VP_ID = 0;
1905 1919
1906 mpt2sas_base_put_smid_default(ioc, smid, mpi_request->VF_ID); 1920 mpt2sas_base_put_smid_default(ioc, smid);
1921 init_completion(&ioc->ctl_cmds.done);
1907 timeleft = wait_for_completion_timeout(&ioc->ctl_cmds.done, 1922 timeleft = wait_for_completion_timeout(&ioc->ctl_cmds.done,
1908 MPT2_IOCTL_DEFAULT_TIMEOUT*HZ); 1923 MPT2_IOCTL_DEFAULT_TIMEOUT*HZ);
1909 1924
@@ -2069,6 +2084,7 @@ static long
2069_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 2084_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
2070{ 2085{
2071 long ret; 2086 long ret;
2087
2072 lock_kernel(); 2088 lock_kernel();
2073 ret = _ctl_ioctl_main(file, cmd, (void __user *)arg); 2089 ret = _ctl_ioctl_main(file, cmd, (void __user *)arg);
2074 unlock_kernel(); 2090 unlock_kernel();
@@ -2143,6 +2159,7 @@ static long
2143_ctl_ioctl_compat(struct file *file, unsigned cmd, unsigned long arg) 2159_ctl_ioctl_compat(struct file *file, unsigned cmd, unsigned long arg)
2144{ 2160{
2145 long ret; 2161 long ret;
2162
2146 lock_kernel(); 2163 lock_kernel();
2147 if (cmd == MPT2COMMAND32) 2164 if (cmd == MPT2COMMAND32)
2148 ret = _ctl_compat_mpt_command(file, cmd, arg); 2165 ret = _ctl_compat_mpt_command(file, cmd, arg);
diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.h b/drivers/scsi/mpt2sas/mpt2sas_ctl.h
index 4da11435533f..211f296dd191 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_ctl.h
+++ b/drivers/scsi/mpt2sas/mpt2sas_ctl.h
@@ -3,7 +3,7 @@
3 * controllers 3 * controllers
4 * 4 *
5 * This code is based on drivers/scsi/mpt2sas/mpt2_ctl.h 5 * This code is based on drivers/scsi/mpt2sas/mpt2_ctl.h
6 * Copyright (C) 2007-2008 LSI Corporation 6 * Copyright (C) 2007-2009 LSI Corporation
7 * (mailto:DL-MPTFusionLinux@lsi.com) 7 * (mailto:DL-MPTFusionLinux@lsi.com)
8 * 8 *
9 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
diff --git a/drivers/scsi/mpt2sas/mpt2sas_debug.h b/drivers/scsi/mpt2sas/mpt2sas_debug.h
index ad325096e842..5308a25cb307 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_debug.h
+++ b/drivers/scsi/mpt2sas/mpt2sas_debug.h
@@ -2,7 +2,7 @@
2 * Logging Support for MPT (Message Passing Technology) based controllers 2 * Logging Support for MPT (Message Passing Technology) based controllers
3 * 3 *
4 * This code is based on drivers/scsi/mpt2sas/mpt2_debug.c 4 * This code is based on drivers/scsi/mpt2sas/mpt2_debug.c
5 * Copyright (C) 2007-2008 LSI Corporation 5 * Copyright (C) 2007-2009 LSI Corporation
6 * (mailto:DL-MPTFusionLinux@lsi.com) 6 * (mailto:DL-MPTFusionLinux@lsi.com)
7 * 7 *
8 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
index 774b34525bba..86ab32d7ab15 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
@@ -2,7 +2,7 @@
2 * Scsi Host Layer for MPT (Message Passing Technology) based controllers 2 * Scsi Host Layer for MPT (Message Passing Technology) based controllers
3 * 3 *
4 * This code is based on drivers/scsi/mpt2sas/mpt2_scsih.c 4 * This code is based on drivers/scsi/mpt2sas/mpt2_scsih.c
5 * Copyright (C) 2007-2008 LSI Corporation 5 * Copyright (C) 2007-2009 LSI Corporation
6 * (mailto:DL-MPTFusionLinux@lsi.com) 6 * (mailto:DL-MPTFusionLinux@lsi.com)
7 * 7 *
8 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
@@ -79,6 +79,9 @@ static u8 transport_cb_idx = -1;
79static u8 config_cb_idx = -1; 79static u8 config_cb_idx = -1;
80static int mpt_ids; 80static int mpt_ids;
81 81
82static u8 tm_tr_cb_idx = -1 ;
83static u8 tm_sas_control_cb_idx = -1;
84
82/* command line options */ 85/* command line options */
83static u32 logging_level; 86static u32 logging_level;
84MODULE_PARM_DESC(logging_level, " bits for enabling additional logging info " 87MODULE_PARM_DESC(logging_level, " bits for enabling additional logging info "
@@ -109,6 +112,7 @@ struct sense_info {
109 * @work: work object (ioc->fault_reset_work_q) 112 * @work: work object (ioc->fault_reset_work_q)
110 * @ioc: per adapter object 113 * @ioc: per adapter object
111 * @VF_ID: virtual function id 114 * @VF_ID: virtual function id
115 * @VP_ID: virtual port id
112 * @host_reset_handling: handling events during host reset 116 * @host_reset_handling: handling events during host reset
113 * @ignore: flag meaning this event has been marked to ignore 117 * @ignore: flag meaning this event has been marked to ignore
114 * @event: firmware event MPI2_EVENT_XXX defined in mpt2_ioc.h 118 * @event: firmware event MPI2_EVENT_XXX defined in mpt2_ioc.h
@@ -121,6 +125,7 @@ struct fw_event_work {
121 struct work_struct work; 125 struct work_struct work;
122 struct MPT2SAS_ADAPTER *ioc; 126 struct MPT2SAS_ADAPTER *ioc;
123 u8 VF_ID; 127 u8 VF_ID;
128 u8 VP_ID;
124 u8 host_reset_handling; 129 u8 host_reset_handling;
125 u8 ignore; 130 u8 ignore;
126 u16 event; 131 u16 event;
@@ -138,8 +143,10 @@ struct fw_event_work {
138 * @lun: lun number 143 * @lun: lun number
139 * @cdb_length: cdb length 144 * @cdb_length: cdb length
140 * @cdb: cdb contents 145 * @cdb: cdb contents
141 * @valid_reply: flag set for reply message
142 * @timeout: timeout for this command 146 * @timeout: timeout for this command
147 * @VF_ID: virtual function id
148 * @VP_ID: virtual port id
149 * @valid_reply: flag set for reply message
143 * @sense_length: sense length 150 * @sense_length: sense length
144 * @ioc_status: ioc status 151 * @ioc_status: ioc status
145 * @scsi_state: scsi state 152 * @scsi_state: scsi state
@@ -161,6 +168,8 @@ struct _scsi_io_transfer {
161 u8 cdb_length; 168 u8 cdb_length;
162 u8 cdb[32]; 169 u8 cdb[32];
163 u8 timeout; 170 u8 timeout;
171 u8 VF_ID;
172 u8 VP_ID;
164 u8 valid_reply; 173 u8 valid_reply;
165 /* the following bits are only valid when 'valid_reply = 1' */ 174 /* the following bits are only valid when 'valid_reply = 1' */
166 u32 sense_length; 175 u32 sense_length;
@@ -756,66 +765,16 @@ _scsih_is_end_device(u32 device_info)
756} 765}
757 766
758/** 767/**
759 * _scsih_scsi_lookup_get - returns scmd entry 768 * mptscsih_get_scsi_lookup - returns scmd entry
760 * @ioc: per adapter object 769 * @ioc: per adapter object
761 * @smid: system request message index 770 * @smid: system request message index
762 * Context: This function will acquire ioc->scsi_lookup_lock.
763 * 771 *
764 * Returns the smid stored scmd pointer. 772 * Returns the smid stored scmd pointer.
765 */ 773 */
766static struct scsi_cmnd * 774static struct scsi_cmnd *
767_scsih_scsi_lookup_get(struct MPT2SAS_ADAPTER *ioc, u16 smid) 775_scsih_scsi_lookup_get(struct MPT2SAS_ADAPTER *ioc, u16 smid)
768{ 776{
769 unsigned long flags; 777 return ioc->scsi_lookup[smid - 1].scmd;
770 struct scsi_cmnd *scmd;
771
772 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
773 scmd = ioc->scsi_lookup[smid - 1].scmd;
774 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
775 return scmd;
776}
777
778/**
779 * mptscsih_getclear_scsi_lookup - returns scmd entry
780 * @ioc: per adapter object
781 * @smid: system request message index
782 * Context: This function will acquire ioc->scsi_lookup_lock.
783 *
784 * Returns the smid stored scmd pointer, as well as clearing the scmd pointer.
785 */
786static struct scsi_cmnd *
787_scsih_scsi_lookup_getclear(struct MPT2SAS_ADAPTER *ioc, u16 smid)
788{
789 unsigned long flags;
790 struct scsi_cmnd *scmd;
791
792 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
793 scmd = ioc->scsi_lookup[smid - 1].scmd;
794 ioc->scsi_lookup[smid - 1].scmd = NULL;
795 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
796 return scmd;
797}
798
799/**
800 * _scsih_scsi_lookup_set - updates scmd entry in lookup
801 * @ioc: per adapter object
802 * @smid: system request message index
803 * @scmd: pointer to scsi command object
804 * Context: This function will acquire ioc->scsi_lookup_lock.
805 *
806 * This will save scmd pointer in the scsi_lookup array.
807 *
808 * Return nothing.
809 */
810static void
811_scsih_scsi_lookup_set(struct MPT2SAS_ADAPTER *ioc, u16 smid,
812 struct scsi_cmnd *scmd)
813{
814 unsigned long flags;
815
816 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
817 ioc->scsi_lookup[smid - 1].scmd = scmd;
818 spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
819} 778}
820 779
821/** 780/**
@@ -838,9 +797,9 @@ _scsih_scsi_lookup_find_by_scmd(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd
838 797
839 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); 798 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
840 smid = 0; 799 smid = 0;
841 for (i = 0; i < ioc->request_depth; i++) { 800 for (i = 0; i < ioc->scsiio_depth; i++) {
842 if (ioc->scsi_lookup[i].scmd == scmd) { 801 if (ioc->scsi_lookup[i].scmd == scmd) {
843 smid = i + 1; 802 smid = ioc->scsi_lookup[i].smid;
844 goto out; 803 goto out;
845 } 804 }
846 } 805 }
@@ -869,7 +828,7 @@ _scsih_scsi_lookup_find_by_target(struct MPT2SAS_ADAPTER *ioc, int id,
869 828
870 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); 829 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
871 found = 0; 830 found = 0;
872 for (i = 0 ; i < ioc->request_depth; i++) { 831 for (i = 0 ; i < ioc->scsiio_depth; i++) {
873 if (ioc->scsi_lookup[i].scmd && 832 if (ioc->scsi_lookup[i].scmd &&
874 (ioc->scsi_lookup[i].scmd->device->id == id && 833 (ioc->scsi_lookup[i].scmd->device->id == id &&
875 ioc->scsi_lookup[i].scmd->device->channel == channel)) { 834 ioc->scsi_lookup[i].scmd->device->channel == channel)) {
@@ -903,7 +862,7 @@ _scsih_scsi_lookup_find_by_lun(struct MPT2SAS_ADAPTER *ioc, int id,
903 862
904 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); 863 spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
905 found = 0; 864 found = 0;
906 for (i = 0 ; i < ioc->request_depth; i++) { 865 for (i = 0 ; i < ioc->scsiio_depth; i++) {
907 if (ioc->scsi_lookup[i].scmd && 866 if (ioc->scsi_lookup[i].scmd &&
908 (ioc->scsi_lookup[i].scmd->device->id == id && 867 (ioc->scsi_lookup[i].scmd->device->id == id &&
909 ioc->scsi_lookup[i].scmd->device->channel == channel && 868 ioc->scsi_lookup[i].scmd->device->channel == channel &&
@@ -1113,7 +1072,7 @@ _scsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
1113} 1072}
1114 1073
1115/** 1074/**
1116 * _scsih_change_queue_depth - changing device queue tag type 1075 * _scsih_change_queue_type - changing device queue tag type
1117 * @sdev: scsi device struct 1076 * @sdev: scsi device struct
1118 * @tag_type: requested tag type 1077 * @tag_type: requested tag type
1119 * 1078 *
@@ -1679,23 +1638,24 @@ _scsih_response_code(struct MPT2SAS_ADAPTER *ioc, u8 response_code)
1679 * _scsih_tm_done - tm completion routine 1638 * _scsih_tm_done - tm completion routine
1680 * @ioc: per adapter object 1639 * @ioc: per adapter object
1681 * @smid: system request message index 1640 * @smid: system request message index
1682 * @VF_ID: virtual function id 1641 * @msix_index: MSIX table index supplied by the OS
1683 * @reply: reply message frame(lower 32bit addr) 1642 * @reply: reply message frame(lower 32bit addr)
1684 * Context: none. 1643 * Context: none.
1685 * 1644 *
1686 * The callback handler when using scsih_issue_tm. 1645 * The callback handler when using scsih_issue_tm.
1687 * 1646 *
1688 * Return nothing. 1647 * Return 1 meaning mf should be freed from _base_interrupt
1648 * 0 means the mf is freed from this function.
1689 */ 1649 */
1690static void 1650static u8
1691_scsih_tm_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID, u32 reply) 1651_scsih_tm_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
1692{ 1652{
1693 MPI2DefaultReply_t *mpi_reply; 1653 MPI2DefaultReply_t *mpi_reply;
1694 1654
1695 if (ioc->tm_cmds.status == MPT2_CMD_NOT_USED) 1655 if (ioc->tm_cmds.status == MPT2_CMD_NOT_USED)
1696 return; 1656 return 1;
1697 if (ioc->tm_cmds.smid != smid) 1657 if (ioc->tm_cmds.smid != smid)
1698 return; 1658 return 1;
1699 ioc->tm_cmds.status |= MPT2_CMD_COMPLETE; 1659 ioc->tm_cmds.status |= MPT2_CMD_COMPLETE;
1700 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); 1660 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
1701 if (mpi_reply) { 1661 if (mpi_reply) {
@@ -1704,6 +1664,7 @@ _scsih_tm_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID, u32 reply)
1704 } 1664 }
1705 ioc->tm_cmds.status &= ~MPT2_CMD_PENDING; 1665 ioc->tm_cmds.status &= ~MPT2_CMD_PENDING;
1706 complete(&ioc->tm_cmds.done); 1666 complete(&ioc->tm_cmds.done);
1667 return 1;
1707} 1668}
1708 1669
1709/** 1670/**
@@ -1790,7 +1751,6 @@ mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle, uint lun,
1790 u16 smid = 0; 1751 u16 smid = 0;
1791 u32 ioc_state; 1752 u32 ioc_state;
1792 unsigned long timeleft; 1753 unsigned long timeleft;
1793 u8 VF_ID = 0;
1794 1754
1795 if (ioc->tm_cmds.status != MPT2_CMD_NOT_USED) { 1755 if (ioc->tm_cmds.status != MPT2_CMD_NOT_USED) {
1796 printk(MPT2SAS_INFO_FMT "%s: tm_cmd busy!!!\n", 1756 printk(MPT2SAS_INFO_FMT "%s: tm_cmd busy!!!\n",
@@ -1817,7 +1777,7 @@ mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle, uint lun,
1817 goto issue_host_reset; 1777 goto issue_host_reset;
1818 } 1778 }
1819 1779
1820 smid = mpt2sas_base_get_smid(ioc, ioc->tm_cb_idx); 1780 smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_cb_idx);
1821 if (!smid) { 1781 if (!smid) {
1822 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n", 1782 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
1823 ioc->name, __func__); 1783 ioc->name, __func__);
@@ -1825,7 +1785,8 @@ mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle, uint lun,
1825 } 1785 }
1826 1786
1827 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "sending tm: handle(0x%04x)," 1787 dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "sending tm: handle(0x%04x),"
1828 " task_type(0x%02x), smid(%d)\n", ioc->name, handle, type, smid)); 1788 " task_type(0x%02x), smid(%d)\n", ioc->name, handle, type,
1789 smid_task));
1829 ioc->tm_cmds.status = MPT2_CMD_PENDING; 1790 ioc->tm_cmds.status = MPT2_CMD_PENDING;
1830 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); 1791 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
1831 ioc->tm_cmds.smid = smid; 1792 ioc->tm_cmds.smid = smid;
@@ -1834,10 +1795,12 @@ mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle, uint lun,
1834 mpi_request->DevHandle = cpu_to_le16(handle); 1795 mpi_request->DevHandle = cpu_to_le16(handle);
1835 mpi_request->TaskType = type; 1796 mpi_request->TaskType = type;
1836 mpi_request->TaskMID = cpu_to_le16(smid_task); 1797 mpi_request->TaskMID = cpu_to_le16(smid_task);
1798 mpi_request->VP_ID = 0; /* TODO */
1799 mpi_request->VF_ID = 0;
1837 int_to_scsilun(lun, (struct scsi_lun *)mpi_request->LUN); 1800 int_to_scsilun(lun, (struct scsi_lun *)mpi_request->LUN);
1838 mpt2sas_scsih_set_tm_flag(ioc, handle); 1801 mpt2sas_scsih_set_tm_flag(ioc, handle);
1839 init_completion(&ioc->tm_cmds.done); 1802 init_completion(&ioc->tm_cmds.done);
1840 mpt2sas_base_put_smid_hi_priority(ioc, smid, VF_ID); 1803 mpt2sas_base_put_smid_hi_priority(ioc, smid);
1841 timeleft = wait_for_completion_timeout(&ioc->tm_cmds.done, timeout*HZ); 1804 timeleft = wait_for_completion_timeout(&ioc->tm_cmds.done, timeout*HZ);
1842 mpt2sas_scsih_clear_tm_flag(ioc, handle); 1805 mpt2sas_scsih_clear_tm_flag(ioc, handle);
1843 if (!(ioc->tm_cmds.status & MPT2_CMD_COMPLETE)) { 1806 if (!(ioc->tm_cmds.status & MPT2_CMD_COMPLETE)) {
@@ -2075,7 +2038,7 @@ _scsih_target_reset(struct scsi_cmnd *scmd)
2075} 2038}
2076 2039
2077/** 2040/**
2078 * _scsih_abort - eh threads main host reset routine 2041 * _scsih_host_reset - eh threads main host reset routine
2079 * @sdev: scsi device struct 2042 * @sdev: scsi device struct
2080 * 2043 *
2081 * Returns SUCCESS if command aborted else FAILED 2044 * Returns SUCCESS if command aborted else FAILED
@@ -2354,6 +2317,231 @@ _scsih_block_io_to_children_attached_directly(struct MPT2SAS_ADAPTER *ioc,
2354} 2317}
2355 2318
2356/** 2319/**
2320 * _scsih_tm_tr_send - send task management request
2321 * @ioc: per adapter object
2322 * @handle: device handle
2323 * Context: interrupt time.
2324 *
2325 * This code is to initiate the device removal handshake protocal
2326 * with controller firmware. This function will issue target reset
2327 * using high priority request queue. It will send a sas iounit
2328 * controll request (MPI2_SAS_OP_REMOVE_DEVICE) from this completion.
2329 *
2330 * This is designed to send muliple task management request at the same
2331 * time to the fifo. If the fifo is full, we will append the request,
2332 * and process it in a future completion.
2333 */
2334static void
2335_scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle)
2336{
2337 Mpi2SCSITaskManagementRequest_t *mpi_request;
2338 struct MPT2SAS_TARGET *sas_target_priv_data;
2339 u16 smid;
2340 struct _sas_device *sas_device;
2341 unsigned long flags;
2342 struct _tr_list *delayed_tr;
2343
2344 if (ioc->shost_recovery) {
2345 printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
2346 __func__, ioc->name);
2347 return;
2348 }
2349
2350 spin_lock_irqsave(&ioc->sas_device_lock, flags);
2351 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
2352 if (!sas_device) {
2353 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2354 printk(MPT2SAS_ERR_FMT "%s: failed finding sas_device\n",
2355 ioc->name, __func__);
2356 return;
2357 }
2358 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2359
2360 /* skip is hidden raid component */
2361 if (sas_device->hidden_raid_component)
2362 return;
2363
2364 smid = mpt2sas_base_get_smid_hpr(ioc, ioc->tm_tr_cb_idx);
2365 if (!smid) {
2366 delayed_tr = kzalloc(sizeof(*delayed_tr), GFP_ATOMIC);
2367 if (!delayed_tr)
2368 return;
2369 INIT_LIST_HEAD(&delayed_tr->list);
2370 delayed_tr->handle = handle;
2371 delayed_tr->state = MPT2SAS_REQ_SAS_CNTRL;
2372 list_add_tail(&delayed_tr->list,
2373 &ioc->delayed_tr_list);
2374 if (sas_device->starget)
2375 dewtprintk(ioc, starget_printk(KERN_INFO,
2376 sas_device->starget, "DELAYED:tr:handle(0x%04x), "
2377 "(open)\n", sas_device->handle));
2378 return;
2379 }
2380
2381 if (sas_device->starget && sas_device->starget->hostdata) {
2382 sas_target_priv_data = sas_device->starget->hostdata;
2383 sas_target_priv_data->tm_busy = 1;
2384 dewtprintk(ioc, starget_printk(KERN_INFO, sas_device->starget,
2385 "tr:handle(0x%04x), (open)\n", sas_device->handle));
2386 }
2387
2388 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
2389 memset(mpi_request, 0, sizeof(Mpi2SCSITaskManagementRequest_t));
2390 mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
2391 mpi_request->DevHandle = cpu_to_le16(handle);
2392 mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
2393 sas_device->state |= MPTSAS_STATE_TR_SEND;
2394 sas_device->state |= MPT2SAS_REQ_SAS_CNTRL;
2395 mpt2sas_base_put_smid_hi_priority(ioc, smid);
2396}
2397
2398
2399
2400/**
2401 * _scsih_sas_control_complete - completion routine
2402 * @ioc: per adapter object
2403 * @smid: system request message index
2404 * @msix_index: MSIX table index supplied by the OS
2405 * @reply: reply message frame(lower 32bit addr)
2406 * Context: interrupt time.
2407 *
2408 * This is the sas iounit controll completion routine.
2409 * This code is part of the code to initiate the device removal
2410 * handshake protocal with controller firmware.
2411 *
2412 * Return 1 meaning mf should be freed from _base_interrupt
2413 * 0 means the mf is freed from this function.
2414 */
2415static u8
2416_scsih_sas_control_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid,
2417 u8 msix_index, u32 reply)
2418{
2419 unsigned long flags;
2420 u16 handle;
2421 struct _sas_device *sas_device;
2422 Mpi2SasIoUnitControlReply_t *mpi_reply =
2423 mpt2sas_base_get_reply_virt_addr(ioc, reply);
2424
2425 handle = le16_to_cpu(mpi_reply->DevHandle);
2426
2427 spin_lock_irqsave(&ioc->sas_device_lock, flags);
2428 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
2429 if (!sas_device) {
2430 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2431 printk(MPT2SAS_ERR_FMT "%s: failed finding sas_device\n",
2432 ioc->name, __func__);
2433 return 1;
2434 }
2435 sas_device->state |= MPTSAS_STATE_CNTRL_COMPLETE;
2436 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2437
2438 if (sas_device->starget)
2439 dewtprintk(ioc, starget_printk(KERN_INFO, sas_device->starget,
2440 "sc_complete:handle(0x%04x), "
2441 "ioc_status(0x%04x), loginfo(0x%08x)\n",
2442 handle, le16_to_cpu(mpi_reply->IOCStatus),
2443 le32_to_cpu(mpi_reply->IOCLogInfo)));
2444 return 1;
2445}
2446
2447/**
2448 * _scsih_tm_tr_complete -
2449 * @ioc: per adapter object
2450 * @smid: system request message index
2451 * @msix_index: MSIX table index supplied by the OS
2452 * @reply: reply message frame(lower 32bit addr)
2453 * Context: interrupt time.
2454 *
2455 * This is the target reset completion routine.
2456 * This code is part of the code to initiate the device removal
2457 * handshake protocal with controller firmware.
2458 * It will send a sas iounit controll request (MPI2_SAS_OP_REMOVE_DEVICE)
2459 *
2460 * Return 1 meaning mf should be freed from _base_interrupt
2461 * 0 means the mf is freed from this function.
2462 */
2463static u8
2464_scsih_tm_tr_complete(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
2465 u32 reply)
2466{
2467 unsigned long flags;
2468 u16 handle;
2469 struct _sas_device *sas_device;
2470 Mpi2SCSITaskManagementReply_t *mpi_reply =
2471 mpt2sas_base_get_reply_virt_addr(ioc, reply);
2472 Mpi2SasIoUnitControlRequest_t *mpi_request;
2473 u16 smid_sas_ctrl;
2474 struct MPT2SAS_TARGET *sas_target_priv_data;
2475 struct _tr_list *delayed_tr;
2476 u8 rc;
2477
2478 handle = le16_to_cpu(mpi_reply->DevHandle);
2479 spin_lock_irqsave(&ioc->sas_device_lock, flags);
2480 sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
2481 if (!sas_device) {
2482 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2483 printk(MPT2SAS_ERR_FMT "%s: failed finding sas_device\n",
2484 ioc->name, __func__);
2485 return 1;
2486 }
2487 sas_device->state |= MPTSAS_STATE_TR_COMPLETE;
2488 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
2489
2490 if (sas_device->starget)
2491 dewtprintk(ioc, starget_printk(KERN_INFO, sas_device->starget,
2492 "tr_complete:handle(0x%04x), (%s) ioc_status(0x%04x), "
2493 "loginfo(0x%08x), completed(%d)\n",
2494 sas_device->handle, (sas_device->state &
2495 MPT2SAS_REQ_SAS_CNTRL) ? "open" : "active",
2496 le16_to_cpu(mpi_reply->IOCStatus),
2497 le32_to_cpu(mpi_reply->IOCLogInfo),
2498 le32_to_cpu(mpi_reply->TerminationCount)));
2499
2500 if (sas_device->starget && sas_device->starget->hostdata) {
2501 sas_target_priv_data = sas_device->starget->hostdata;
2502 sas_target_priv_data->tm_busy = 0;
2503 }
2504
2505 if (!list_empty(&ioc->delayed_tr_list)) {
2506 delayed_tr = list_entry(ioc->delayed_tr_list.next,
2507 struct _tr_list, list);
2508 mpt2sas_base_free_smid(ioc, smid);
2509 if (delayed_tr->state & MPT2SAS_REQ_SAS_CNTRL)
2510 _scsih_tm_tr_send(ioc, delayed_tr->handle);
2511 list_del(&delayed_tr->list);
2512 kfree(delayed_tr);
2513 rc = 0; /* tells base_interrupt not to free mf */
2514 } else
2515 rc = 1;
2516
2517
2518 if (!(sas_device->state & MPT2SAS_REQ_SAS_CNTRL))
2519 return rc;
2520
2521 if (ioc->shost_recovery) {
2522 printk(MPT2SAS_INFO_FMT "%s: host reset in progress!\n",
2523 __func__, ioc->name);
2524 return rc;
2525 }
2526
2527 smid_sas_ctrl = mpt2sas_base_get_smid(ioc, ioc->tm_sas_control_cb_idx);
2528 if (!smid_sas_ctrl) {
2529 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
2530 ioc->name, __func__);
2531 return rc;
2532 }
2533
2534 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid_sas_ctrl);
2535 memset(mpi_request, 0, sizeof(Mpi2SasIoUnitControlRequest_t));
2536 mpi_request->Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL;
2537 mpi_request->Operation = MPI2_SAS_OP_REMOVE_DEVICE;
2538 mpi_request->DevHandle = mpi_reply->DevHandle;
2539 sas_device->state |= MPTSAS_STATE_CNTRL_SEND;
2540 mpt2sas_base_put_smid_default(ioc, smid_sas_ctrl);
2541 return rc;
2542}
2543
2544/**
2357 * _scsih_check_topo_delete_events - sanity check on topo events 2545 * _scsih_check_topo_delete_events - sanity check on topo events
2358 * @ioc: per adapter object 2546 * @ioc: per adapter object
2359 * @event_data: the event data payload 2547 * @event_data: the event data payload
@@ -2375,6 +2563,21 @@ _scsih_check_topo_delete_events(struct MPT2SAS_ADAPTER *ioc,
2375 u16 expander_handle; 2563 u16 expander_handle;
2376 struct _sas_node *sas_expander; 2564 struct _sas_node *sas_expander;
2377 unsigned long flags; 2565 unsigned long flags;
2566 int i, reason_code;
2567 u16 handle;
2568
2569 for (i = 0 ; i < event_data->NumEntries; i++) {
2570 if (event_data->PHY[i].PhyStatus &
2571 MPI2_EVENT_SAS_TOPO_PHYSTATUS_VACANT)
2572 continue;
2573 handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle);
2574 if (!handle)
2575 continue;
2576 reason_code = event_data->PHY[i].PhyStatus &
2577 MPI2_EVENT_SAS_TOPO_RC_MASK;
2578 if (reason_code == MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING)
2579 _scsih_tm_tr_send(ioc, handle);
2580 }
2378 2581
2379 expander_handle = le16_to_cpu(event_data->ExpanderDevHandle); 2582 expander_handle = le16_to_cpu(event_data->ExpanderDevHandle);
2380 if (expander_handle < ioc->sas_hba.num_phys) { 2583 if (expander_handle < ioc->sas_hba.num_phys) {
@@ -2433,8 +2636,8 @@ _scsih_flush_running_cmds(struct MPT2SAS_ADAPTER *ioc)
2433 u16 smid; 2636 u16 smid;
2434 u16 count = 0; 2637 u16 count = 0;
2435 2638
2436 for (smid = 1; smid <= ioc->request_depth; smid++) { 2639 for (smid = 1; smid <= ioc->scsiio_depth; smid++) {
2437 scmd = _scsih_scsi_lookup_getclear(ioc, smid); 2640 scmd = _scsih_scsi_lookup_get(ioc, smid);
2438 if (!scmd) 2641 if (!scmd)
2439 continue; 2642 continue;
2440 count++; 2643 count++;
@@ -2616,7 +2819,7 @@ _scsih_qcmd(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
2616 if ((sas_device_priv_data->flags & MPT_DEVICE_TLR_ON)) 2819 if ((sas_device_priv_data->flags & MPT_DEVICE_TLR_ON))
2617 mpi_control |= MPI2_SCSIIO_CONTROL_TLR_ON; 2820 mpi_control |= MPI2_SCSIIO_CONTROL_TLR_ON;
2618 2821
2619 smid = mpt2sas_base_get_smid(ioc, ioc->scsi_io_cb_idx); 2822 smid = mpt2sas_base_get_smid_scsiio(ioc, ioc->scsi_io_cb_idx, scmd);
2620 if (!smid) { 2823 if (!smid) {
2621 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n", 2824 printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
2622 ioc->name, __func__); 2825 ioc->name, __func__);
@@ -2643,7 +2846,8 @@ _scsih_qcmd(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
2643 mpi_request->SGLOffset0 = offsetof(Mpi2SCSIIORequest_t, SGL) / 4; 2846 mpi_request->SGLOffset0 = offsetof(Mpi2SCSIIORequest_t, SGL) / 4;
2644 mpi_request->SGLFlags = cpu_to_le16(MPI2_SCSIIO_SGLFLAGS_TYPE_MPI + 2847 mpi_request->SGLFlags = cpu_to_le16(MPI2_SCSIIO_SGLFLAGS_TYPE_MPI +
2645 MPI2_SCSIIO_SGLFLAGS_SYSTEM_ADDR); 2848 MPI2_SCSIIO_SGLFLAGS_SYSTEM_ADDR);
2646 2849 mpi_request->VF_ID = 0; /* TODO */
2850 mpi_request->VP_ID = 0;
2647 int_to_scsilun(sas_device_priv_data->lun, (struct scsi_lun *) 2851 int_to_scsilun(sas_device_priv_data->lun, (struct scsi_lun *)
2648 mpi_request->LUN); 2852 mpi_request->LUN);
2649 memcpy(mpi_request->CDB.CDB32, scmd->cmnd, scmd->cmd_len); 2853 memcpy(mpi_request->CDB.CDB32, scmd->cmnd, scmd->cmd_len);
@@ -2657,8 +2861,7 @@ _scsih_qcmd(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
2657 } 2861 }
2658 } 2862 }
2659 2863
2660 _scsih_scsi_lookup_set(ioc, smid, scmd); 2864 mpt2sas_base_put_smid_scsi_io(ioc, smid,
2661 mpt2sas_base_put_smid_scsi_io(ioc, smid, 0,
2662 sas_device_priv_data->sas_target->handle); 2865 sas_device_priv_data->sas_target->handle);
2663 return 0; 2866 return 0;
2664 2867
@@ -2954,15 +3157,16 @@ _scsih_smart_predicted_fault(struct MPT2SAS_ADAPTER *ioc, u16 handle)
2954 * _scsih_io_done - scsi request callback 3157 * _scsih_io_done - scsi request callback
2955 * @ioc: per adapter object 3158 * @ioc: per adapter object
2956 * @smid: system request message index 3159 * @smid: system request message index
2957 * @VF_ID: virtual function id 3160 * @msix_index: MSIX table index supplied by the OS
2958 * @reply: reply message frame(lower 32bit addr) 3161 * @reply: reply message frame(lower 32bit addr)
2959 * 3162 *
2960 * Callback handler when using scsih_qcmd. 3163 * Callback handler when using _scsih_qcmd.
2961 * 3164 *
2962 * Return nothing. 3165 * Return 1 meaning mf should be freed from _base_interrupt
3166 * 0 means the mf is freed from this function.
2963 */ 3167 */
2964static void 3168static u8
2965_scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID, u32 reply) 3169_scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
2966{ 3170{
2967 Mpi2SCSIIORequest_t *mpi_request; 3171 Mpi2SCSIIORequest_t *mpi_request;
2968 Mpi2SCSIIOReply_t *mpi_reply; 3172 Mpi2SCSIIOReply_t *mpi_reply;
@@ -2976,9 +3180,9 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID, u32 reply)
2976 u32 response_code; 3180 u32 response_code;
2977 3181
2978 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); 3182 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
2979 scmd = _scsih_scsi_lookup_getclear(ioc, smid); 3183 scmd = _scsih_scsi_lookup_get(ioc, smid);
2980 if (scmd == NULL) 3184 if (scmd == NULL)
2981 return; 3185 return 1;
2982 3186
2983 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid); 3187 mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
2984 3188
@@ -3134,6 +3338,7 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID, u32 reply)
3134 out: 3338 out:
3135 scsi_dma_unmap(scmd); 3339 scsi_dma_unmap(scmd);
3136 scmd->scsi_done(scmd); 3340 scmd->scsi_done(scmd);
3341 return 1;
3137} 3342}
3138 3343
3139/** 3344/**
@@ -3398,9 +3603,8 @@ _scsih_expander_add(struct MPT2SAS_ADAPTER *ioc, u16 handle)
3398 } 3603 }
3399 } 3604 }
3400 3605
3401 sas_address = le64_to_cpu(expander_pg0.SASAddress);
3402
3403 spin_lock_irqsave(&ioc->sas_node_lock, flags); 3606 spin_lock_irqsave(&ioc->sas_node_lock, flags);
3607 sas_address = le64_to_cpu(expander_pg0.SASAddress);
3404 sas_expander = mpt2sas_scsih_expander_find_by_sas_address(ioc, 3608 sas_expander = mpt2sas_scsih_expander_find_by_sas_address(ioc,
3405 sas_address); 3609 sas_address);
3406 spin_unlock_irqrestore(&ioc->sas_node_lock, flags); 3610 spin_unlock_irqrestore(&ioc->sas_node_lock, flags);
@@ -3666,6 +3870,12 @@ _scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, u16 handle)
3666 if (ioc->remove_host) 3870 if (ioc->remove_host)
3667 goto out; 3871 goto out;
3668 3872
3873 if ((sas_device->state & MPTSAS_STATE_TR_COMPLETE)) {
3874 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "\tskip "
3875 "target_reset handle(0x%04x)\n", ioc->name, handle));
3876 goto skip_tr;
3877 }
3878
3669 /* Target Reset to flush out all the outstanding IO */ 3879 /* Target Reset to flush out all the outstanding IO */
3670 device_handle = (sas_device->hidden_raid_component) ? 3880 device_handle = (sas_device->hidden_raid_component) ?
3671 sas_device->volume_handle : handle; 3881 sas_device->volume_handle : handle;
@@ -3682,6 +3892,13 @@ _scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, u16 handle)
3682 if (ioc->shost_recovery) 3892 if (ioc->shost_recovery)
3683 goto out; 3893 goto out;
3684 } 3894 }
3895 skip_tr:
3896
3897 if ((sas_device->state & MPTSAS_STATE_CNTRL_COMPLETE)) {
3898 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "\tskip "
3899 "sas_cntrl handle(0x%04x)\n", ioc->name, handle));
3900 goto out;
3901 }
3685 3902
3686 /* SAS_IO_UNIT_CNTR - send REMOVE_DEVICE */ 3903 /* SAS_IO_UNIT_CNTR - send REMOVE_DEVICE */
3687 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "sas_iounit: handle" 3904 dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "sas_iounit: handle"
@@ -3690,7 +3907,8 @@ _scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, u16 handle)
3690 mpi_request.Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL; 3907 mpi_request.Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL;
3691 mpi_request.Operation = MPI2_SAS_OP_REMOVE_DEVICE; 3908 mpi_request.Operation = MPI2_SAS_OP_REMOVE_DEVICE;
3692 mpi_request.DevHandle = handle; 3909 mpi_request.DevHandle = handle;
3693 mpi_request.VF_ID = 0; 3910 mpi_request.VF_ID = 0; /* TODO */
3911 mpi_request.VP_ID = 0;
3694 if ((mpt2sas_base_sas_iounit_control(ioc, &mpi_reply, 3912 if ((mpt2sas_base_sas_iounit_control(ioc, &mpi_reply,
3695 &mpi_request)) != 0) { 3913 &mpi_request)) != 0) {
3696 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 3914 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
@@ -3800,15 +4018,12 @@ _scsih_sas_topology_change_event_debug(struct MPT2SAS_ADAPTER *ioc,
3800/** 4018/**
3801 * _scsih_sas_topology_change_event - handle topology changes 4019 * _scsih_sas_topology_change_event - handle topology changes
3802 * @ioc: per adapter object 4020 * @ioc: per adapter object
3803 * @VF_ID: 4021 * @fw_event: The fw_event_work object
3804 * @event_data: event data payload
3805 * fw_event:
3806 * Context: user. 4022 * Context: user.
3807 * 4023 *
3808 */ 4024 */
3809static void 4025static void
3810_scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, 4026_scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,
3811 Mpi2EventDataSasTopologyChangeList_t *event_data,
3812 struct fw_event_work *fw_event) 4027 struct fw_event_work *fw_event)
3813{ 4028{
3814 int i; 4029 int i;
@@ -3818,6 +4033,7 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,
3818 struct _sas_node *sas_expander; 4033 struct _sas_node *sas_expander;
3819 unsigned long flags; 4034 unsigned long flags;
3820 u8 link_rate_; 4035 u8 link_rate_;
4036 Mpi2EventDataSasTopologyChangeList_t *event_data = fw_event->event_data;
3821 4037
3822#ifdef CONFIG_SCSI_MPT2SAS_LOGGING 4038#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
3823 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) 4039 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
@@ -3851,15 +4067,16 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,
3851 } 4067 }
3852 if (ioc->shost_recovery) 4068 if (ioc->shost_recovery)
3853 return; 4069 return;
3854 if (event_data->PHY[i].PhyStatus & 4070 phy_number = event_data->StartPhyNum + i;
3855 MPI2_EVENT_SAS_TOPO_PHYSTATUS_VACANT) 4071 reason_code = event_data->PHY[i].PhyStatus &
4072 MPI2_EVENT_SAS_TOPO_RC_MASK;
4073 if ((event_data->PHY[i].PhyStatus &
4074 MPI2_EVENT_SAS_TOPO_PHYSTATUS_VACANT) && (reason_code !=
4075 MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING))
3856 continue; 4076 continue;
3857 handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle); 4077 handle = le16_to_cpu(event_data->PHY[i].AttachedDevHandle);
3858 if (!handle) 4078 if (!handle)
3859 continue; 4079 continue;
3860 phy_number = event_data->StartPhyNum + i;
3861 reason_code = event_data->PHY[i].PhyStatus &
3862 MPI2_EVENT_SAS_TOPO_RC_MASK;
3863 link_rate_ = event_data->PHY[i].LinkRate >> 4; 4080 link_rate_ = event_data->PHY[i].LinkRate >> 4;
3864 switch (reason_code) { 4081 switch (reason_code) {
3865 case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED: 4082 case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED:
@@ -3971,19 +4188,19 @@ _scsih_sas_device_status_change_event_debug(struct MPT2SAS_ADAPTER *ioc,
3971/** 4188/**
3972 * _scsih_sas_device_status_change_event - handle device status change 4189 * _scsih_sas_device_status_change_event - handle device status change
3973 * @ioc: per adapter object 4190 * @ioc: per adapter object
3974 * @VF_ID: 4191 * @fw_event: The fw_event_work object
3975 * @event_data: event data payload
3976 * Context: user. 4192 * Context: user.
3977 * 4193 *
3978 * Return nothing. 4194 * Return nothing.
3979 */ 4195 */
3980static void 4196static void
3981_scsih_sas_device_status_change_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, 4197_scsih_sas_device_status_change_event(struct MPT2SAS_ADAPTER *ioc,
3982 Mpi2EventDataSasDeviceStatusChange_t *event_data) 4198 struct fw_event_work *fw_event)
3983{ 4199{
3984#ifdef CONFIG_SCSI_MPT2SAS_LOGGING 4200#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
3985 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) 4201 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
3986 _scsih_sas_device_status_change_event_debug(ioc, event_data); 4202 _scsih_sas_device_status_change_event_debug(ioc,
4203 fw_event->event_data);
3987#endif 4204#endif
3988} 4205}
3989 4206
@@ -4026,34 +4243,33 @@ _scsih_sas_enclosure_dev_status_change_event_debug(struct MPT2SAS_ADAPTER *ioc,
4026/** 4243/**
4027 * _scsih_sas_enclosure_dev_status_change_event - handle enclosure events 4244 * _scsih_sas_enclosure_dev_status_change_event - handle enclosure events
4028 * @ioc: per adapter object 4245 * @ioc: per adapter object
4029 * @VF_ID: 4246 * @fw_event: The fw_event_work object
4030 * @event_data: event data payload
4031 * Context: user. 4247 * Context: user.
4032 * 4248 *
4033 * Return nothing. 4249 * Return nothing.
4034 */ 4250 */
4035static void 4251static void
4036_scsih_sas_enclosure_dev_status_change_event(struct MPT2SAS_ADAPTER *ioc, 4252_scsih_sas_enclosure_dev_status_change_event(struct MPT2SAS_ADAPTER *ioc,
4037 u8 VF_ID, Mpi2EventDataSasEnclDevStatusChange_t *event_data) 4253 struct fw_event_work *fw_event)
4038{ 4254{
4039#ifdef CONFIG_SCSI_MPT2SAS_LOGGING 4255#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
4040 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) 4256 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
4041 _scsih_sas_enclosure_dev_status_change_event_debug(ioc, 4257 _scsih_sas_enclosure_dev_status_change_event_debug(ioc,
4042 event_data); 4258 fw_event->event_data);
4043#endif 4259#endif
4044} 4260}
4045 4261
4046/** 4262/**
4047 * _scsih_sas_broadcast_primative_event - handle broadcast events 4263 * _scsih_sas_broadcast_primative_event - handle broadcast events
4048 * @ioc: per adapter object 4264 * @ioc: per adapter object
4049 * @event_data: event data payload 4265 * @fw_event: The fw_event_work object
4050 * Context: user. 4266 * Context: user.
4051 * 4267 *
4052 * Return nothing. 4268 * Return nothing.
4053 */ 4269 */
4054static void 4270static void
4055_scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, 4271_scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc,
4056 Mpi2EventDataSasBroadcastPrimitive_t *event_data) 4272 struct fw_event_work *fw_event)
4057{ 4273{
4058 struct scsi_cmnd *scmd; 4274 struct scsi_cmnd *scmd;
4059 u16 smid, handle; 4275 u16 smid, handle;
@@ -4062,11 +4278,12 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,
4062 u32 termination_count; 4278 u32 termination_count;
4063 u32 query_count; 4279 u32 query_count;
4064 Mpi2SCSITaskManagementReply_t *mpi_reply; 4280 Mpi2SCSITaskManagementReply_t *mpi_reply;
4065 4281#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
4282 Mpi2EventDataSasBroadcastPrimitive_t *event_data = fw_event->event_data;
4283#endif
4066 dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "broadcast primative: " 4284 dewtprintk(ioc, printk(MPT2SAS_DEBUG_FMT "broadcast primative: "
4067 "phy number(%d), width(%d)\n", ioc->name, event_data->PhyNum, 4285 "phy number(%d), width(%d)\n", ioc->name, event_data->PhyNum,
4068 event_data->PortWidth)); 4286 event_data->PortWidth));
4069
4070 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: enter\n", ioc->name, 4287 dtmprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s: enter\n", ioc->name,
4071 __func__)); 4288 __func__));
4072 4289
@@ -4074,7 +4291,7 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,
4074 termination_count = 0; 4291 termination_count = 0;
4075 query_count = 0; 4292 query_count = 0;
4076 mpi_reply = ioc->tm_cmds.reply; 4293 mpi_reply = ioc->tm_cmds.reply;
4077 for (smid = 1; smid <= ioc->request_depth; smid++) { 4294 for (smid = 1; smid <= ioc->scsiio_depth; smid++) {
4078 scmd = _scsih_scsi_lookup_get(ioc, smid); 4295 scmd = _scsih_scsi_lookup_get(ioc, smid);
4079 if (!scmd) 4296 if (!scmd)
4080 continue; 4297 continue;
@@ -4121,23 +4338,25 @@ _scsih_sas_broadcast_primative_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,
4121/** 4338/**
4122 * _scsih_sas_discovery_event - handle discovery events 4339 * _scsih_sas_discovery_event - handle discovery events
4123 * @ioc: per adapter object 4340 * @ioc: per adapter object
4124 * @event_data: event data payload 4341 * @fw_event: The fw_event_work object
4125 * Context: user. 4342 * Context: user.
4126 * 4343 *
4127 * Return nothing. 4344 * Return nothing.
4128 */ 4345 */
4129static void 4346static void
4130_scsih_sas_discovery_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, 4347_scsih_sas_discovery_event(struct MPT2SAS_ADAPTER *ioc,
4131 Mpi2EventDataSasDiscovery_t *event_data) 4348 struct fw_event_work *fw_event)
4132{ 4349{
4350 Mpi2EventDataSasDiscovery_t *event_data = fw_event->event_data;
4351
4133#ifdef CONFIG_SCSI_MPT2SAS_LOGGING 4352#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
4134 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) { 4353 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) {
4135 printk(MPT2SAS_DEBUG_FMT "discovery event: (%s)", ioc->name, 4354 printk(MPT2SAS_DEBUG_FMT "discovery event: (%s)", ioc->name,
4136 (event_data->ReasonCode == MPI2_EVENT_SAS_DISC_RC_STARTED) ? 4355 (event_data->ReasonCode == MPI2_EVENT_SAS_DISC_RC_STARTED) ?
4137 "start" : "stop"); 4356 "start" : "stop");
4138 if (event_data->DiscoveryStatus) 4357 if (event_data->DiscoveryStatus)
4139 printk(MPT2SAS_DEBUG_FMT ", discovery_status(0x%08x)", 4358 printk("discovery_status(0x%08x)",
4140 ioc->name, le32_to_cpu(event_data->DiscoveryStatus)); 4359 le32_to_cpu(event_data->DiscoveryStatus));
4141 printk("\n"); 4360 printk("\n");
4142 } 4361 }
4143#endif 4362#endif
@@ -4488,19 +4707,19 @@ _scsih_sas_ir_config_change_event_debug(struct MPT2SAS_ADAPTER *ioc,
4488/** 4707/**
4489 * _scsih_sas_ir_config_change_event - handle ir configuration change events 4708 * _scsih_sas_ir_config_change_event - handle ir configuration change events
4490 * @ioc: per adapter object 4709 * @ioc: per adapter object
4491 * @VF_ID: 4710 * @fw_event: The fw_event_work object
4492 * @event_data: event data payload
4493 * Context: user. 4711 * Context: user.
4494 * 4712 *
4495 * Return nothing. 4713 * Return nothing.
4496 */ 4714 */
4497static void 4715static void
4498_scsih_sas_ir_config_change_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, 4716_scsih_sas_ir_config_change_event(struct MPT2SAS_ADAPTER *ioc,
4499 Mpi2EventDataIrConfigChangeList_t *event_data) 4717 struct fw_event_work *fw_event)
4500{ 4718{
4501 Mpi2EventIrConfigElement_t *element; 4719 Mpi2EventIrConfigElement_t *element;
4502 int i; 4720 int i;
4503 u8 foreign_config; 4721 u8 foreign_config;
4722 Mpi2EventDataIrConfigChangeList_t *event_data = fw_event->event_data;
4504 4723
4505#ifdef CONFIG_SCSI_MPT2SAS_LOGGING 4724#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
4506 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) 4725 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
@@ -4543,14 +4762,14 @@ _scsih_sas_ir_config_change_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,
4543/** 4762/**
4544 * _scsih_sas_ir_volume_event - IR volume event 4763 * _scsih_sas_ir_volume_event - IR volume event
4545 * @ioc: per adapter object 4764 * @ioc: per adapter object
4546 * @event_data: event data payload 4765 * @fw_event: The fw_event_work object
4547 * Context: user. 4766 * Context: user.
4548 * 4767 *
4549 * Return nothing. 4768 * Return nothing.
4550 */ 4769 */
4551static void 4770static void
4552_scsih_sas_ir_volume_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, 4771_scsih_sas_ir_volume_event(struct MPT2SAS_ADAPTER *ioc,
4553 Mpi2EventDataIrVolume_t *event_data) 4772 struct fw_event_work *fw_event)
4554{ 4773{
4555 u64 wwid; 4774 u64 wwid;
4556 unsigned long flags; 4775 unsigned long flags;
@@ -4559,6 +4778,7 @@ _scsih_sas_ir_volume_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,
4559 u32 state; 4778 u32 state;
4560 int rc; 4779 int rc;
4561 struct MPT2SAS_TARGET *sas_target_priv_data; 4780 struct MPT2SAS_TARGET *sas_target_priv_data;
4781 Mpi2EventDataIrVolume_t *event_data = fw_event->event_data;
4562 4782
4563 if (event_data->ReasonCode != MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED) 4783 if (event_data->ReasonCode != MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED)
4564 return; 4784 return;
@@ -4628,14 +4848,14 @@ _scsih_sas_ir_volume_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,
4628/** 4848/**
4629 * _scsih_sas_ir_physical_disk_event - PD event 4849 * _scsih_sas_ir_physical_disk_event - PD event
4630 * @ioc: per adapter object 4850 * @ioc: per adapter object
4631 * @event_data: event data payload 4851 * @fw_event: The fw_event_work object
4632 * Context: user. 4852 * Context: user.
4633 * 4853 *
4634 * Return nothing. 4854 * Return nothing.
4635 */ 4855 */
4636static void 4856static void
4637_scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, 4857_scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc,
4638 Mpi2EventDataIrPhysicalDisk_t *event_data) 4858 struct fw_event_work *fw_event)
4639{ 4859{
4640 u16 handle; 4860 u16 handle;
4641 u32 state; 4861 u32 state;
@@ -4644,6 +4864,7 @@ _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,
4644 Mpi2ConfigReply_t mpi_reply; 4864 Mpi2ConfigReply_t mpi_reply;
4645 Mpi2SasDevicePage0_t sas_device_pg0; 4865 Mpi2SasDevicePage0_t sas_device_pg0;
4646 u32 ioc_status; 4866 u32 ioc_status;
4867 Mpi2EventDataIrPhysicalDisk_t *event_data = fw_event->event_data;
4647 4868
4648 if (event_data->ReasonCode != MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED) 4869 if (event_data->ReasonCode != MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED)
4649 return; 4870 return;
@@ -4743,33 +4964,33 @@ _scsih_sas_ir_operation_status_event_debug(struct MPT2SAS_ADAPTER *ioc,
4743/** 4964/**
4744 * _scsih_sas_ir_operation_status_event - handle RAID operation events 4965 * _scsih_sas_ir_operation_status_event - handle RAID operation events
4745 * @ioc: per adapter object 4966 * @ioc: per adapter object
4746 * @VF_ID: 4967 * @fw_event: The fw_event_work object
4747 * @event_data: event data payload
4748 * Context: user. 4968 * Context: user.
4749 * 4969 *
4750 * Return nothing. 4970 * Return nothing.
4751 */ 4971 */
4752static void 4972static void
4753_scsih_sas_ir_operation_status_event(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, 4973_scsih_sas_ir_operation_status_event(struct MPT2SAS_ADAPTER *ioc,
4754 Mpi2EventDataIrOperationStatus_t *event_data) 4974 struct fw_event_work *fw_event)
4755{ 4975{
4756#ifdef CONFIG_SCSI_MPT2SAS_LOGGING 4976#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
4757 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) 4977 if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
4758 _scsih_sas_ir_operation_status_event_debug(ioc, event_data); 4978 _scsih_sas_ir_operation_status_event_debug(ioc,
4979 fw_event->event_data);
4759#endif 4980#endif
4760} 4981}
4761 4982
4762/** 4983/**
4763 * _scsih_task_set_full - handle task set full 4984 * _scsih_task_set_full - handle task set full
4764 * @ioc: per adapter object 4985 * @ioc: per adapter object
4765 * @event_data: event data payload 4986 * @fw_event: The fw_event_work object
4766 * Context: user. 4987 * Context: user.
4767 * 4988 *
4768 * Throttle back qdepth. 4989 * Throttle back qdepth.
4769 */ 4990 */
4770static void 4991static void
4771_scsih_task_set_full(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, 4992_scsih_task_set_full(struct MPT2SAS_ADAPTER *ioc, struct fw_event_work
4772 Mpi2EventDataTaskSetFull_t *event_data) 4993 *fw_event)
4773{ 4994{
4774 unsigned long flags; 4995 unsigned long flags;
4775 struct _sas_device *sas_device; 4996 struct _sas_device *sas_device;
@@ -4780,6 +5001,7 @@ _scsih_task_set_full(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,
4780 u16 handle; 5001 u16 handle;
4781 int id, channel; 5002 int id, channel;
4782 u64 sas_address; 5003 u64 sas_address;
5004 Mpi2EventDataTaskSetFull_t *event_data = fw_event->event_data;
4783 5005
4784 current_depth = le16_to_cpu(event_data->CurrentDepth); 5006 current_depth = le16_to_cpu(event_data->CurrentDepth);
4785 handle = le16_to_cpu(event_data->DevHandle); 5007 handle = le16_to_cpu(event_data->DevHandle);
@@ -4868,6 +5090,10 @@ _scsih_mark_responding_sas_device(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
4868 if (sas_device->sas_address == sas_address && 5090 if (sas_device->sas_address == sas_address &&
4869 sas_device->slot == slot && sas_device->starget) { 5091 sas_device->slot == slot && sas_device->starget) {
4870 sas_device->responding = 1; 5092 sas_device->responding = 1;
5093 sas_device->state = 0;
5094 starget = sas_device->starget;
5095 sas_target_priv_data = starget->hostdata;
5096 sas_target_priv_data->tm_busy = 0;
4871 starget_printk(KERN_INFO, sas_device->starget, 5097 starget_printk(KERN_INFO, sas_device->starget,
4872 "handle(0x%04x), sas_addr(0x%016llx), enclosure " 5098 "handle(0x%04x), sas_addr(0x%016llx), enclosure "
4873 "logical id(0x%016llx), slot(%d)\n", handle, 5099 "logical id(0x%016llx), slot(%d)\n", handle,
@@ -4880,8 +5106,6 @@ _scsih_mark_responding_sas_device(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
4880 printk(KERN_INFO "\thandle changed from(0x%04x)!!!\n", 5106 printk(KERN_INFO "\thandle changed from(0x%04x)!!!\n",
4881 sas_device->handle); 5107 sas_device->handle);
4882 sas_device->handle = handle; 5108 sas_device->handle = handle;
4883 starget = sas_device->starget;
4884 sas_target_priv_data = starget->hostdata;
4885 sas_target_priv_data->handle = handle; 5109 sas_target_priv_data->handle = handle;
4886 goto out; 5110 goto out;
4887 } 5111 }
@@ -5227,44 +5451,38 @@ _firmware_event_work(struct work_struct *work)
5227 5451
5228 switch (fw_event->event) { 5452 switch (fw_event->event) {
5229 case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST: 5453 case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
5230 _scsih_sas_topology_change_event(ioc, fw_event->VF_ID, 5454 _scsih_sas_topology_change_event(ioc, fw_event);
5231 fw_event->event_data, fw_event);
5232 break; 5455 break;
5233 case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE: 5456 case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE:
5234 _scsih_sas_device_status_change_event(ioc, fw_event->VF_ID, 5457 _scsih_sas_device_status_change_event(ioc,
5235 fw_event->event_data); 5458 fw_event);
5236 break; 5459 break;
5237 case MPI2_EVENT_SAS_DISCOVERY: 5460 case MPI2_EVENT_SAS_DISCOVERY:
5238 _scsih_sas_discovery_event(ioc, fw_event->VF_ID, 5461 _scsih_sas_discovery_event(ioc,
5239 fw_event->event_data); 5462 fw_event);
5240 break; 5463 break;
5241 case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE: 5464 case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE:
5242 _scsih_sas_broadcast_primative_event(ioc, fw_event->VF_ID, 5465 _scsih_sas_broadcast_primative_event(ioc,
5243 fw_event->event_data); 5466 fw_event);
5244 break; 5467 break;
5245 case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE: 5468 case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE:
5246 _scsih_sas_enclosure_dev_status_change_event(ioc, 5469 _scsih_sas_enclosure_dev_status_change_event(ioc,
5247 fw_event->VF_ID, fw_event->event_data); 5470 fw_event);
5248 break; 5471 break;
5249 case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST: 5472 case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST:
5250 _scsih_sas_ir_config_change_event(ioc, fw_event->VF_ID, 5473 _scsih_sas_ir_config_change_event(ioc, fw_event);
5251 fw_event->event_data);
5252 break; 5474 break;
5253 case MPI2_EVENT_IR_VOLUME: 5475 case MPI2_EVENT_IR_VOLUME:
5254 _scsih_sas_ir_volume_event(ioc, fw_event->VF_ID, 5476 _scsih_sas_ir_volume_event(ioc, fw_event);
5255 fw_event->event_data);
5256 break; 5477 break;
5257 case MPI2_EVENT_IR_PHYSICAL_DISK: 5478 case MPI2_EVENT_IR_PHYSICAL_DISK:
5258 _scsih_sas_ir_physical_disk_event(ioc, fw_event->VF_ID, 5479 _scsih_sas_ir_physical_disk_event(ioc, fw_event);
5259 fw_event->event_data);
5260 break; 5480 break;
5261 case MPI2_EVENT_IR_OPERATION_STATUS: 5481 case MPI2_EVENT_IR_OPERATION_STATUS:
5262 _scsih_sas_ir_operation_status_event(ioc, fw_event->VF_ID, 5482 _scsih_sas_ir_operation_status_event(ioc, fw_event);
5263 fw_event->event_data);
5264 break; 5483 break;
5265 case MPI2_EVENT_TASK_SET_FULL: 5484 case MPI2_EVENT_TASK_SET_FULL:
5266 _scsih_task_set_full(ioc, fw_event->VF_ID, 5485 _scsih_task_set_full(ioc, fw_event);
5267 fw_event->event_data);
5268 break; 5486 break;
5269 } 5487 }
5270 _scsih_fw_event_free(ioc, fw_event); 5488 _scsih_fw_event_free(ioc, fw_event);
@@ -5273,17 +5491,19 @@ _firmware_event_work(struct work_struct *work)
5273/** 5491/**
5274 * mpt2sas_scsih_event_callback - firmware event handler (called at ISR time) 5492 * mpt2sas_scsih_event_callback - firmware event handler (called at ISR time)
5275 * @ioc: per adapter object 5493 * @ioc: per adapter object
5276 * @VF_ID: virtual function id 5494 * @msix_index: MSIX table index supplied by the OS
5277 * @reply: reply message frame(lower 32bit addr) 5495 * @reply: reply message frame(lower 32bit addr)
5278 * Context: interrupt. 5496 * Context: interrupt.
5279 * 5497 *
5280 * This function merely adds a new work task into ioc->firmware_event_thread. 5498 * This function merely adds a new work task into ioc->firmware_event_thread.
5281 * The tasks are worked from _firmware_event_work in user context. 5499 * The tasks are worked from _firmware_event_work in user context.
5282 * 5500 *
5283 * Return nothing. 5501 * Return 1 meaning mf should be freed from _base_interrupt
5502 * 0 means the mf is freed from this function.
5284 */ 5503 */
5285void 5504u8
5286mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, u32 reply) 5505mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
5506 u32 reply)
5287{ 5507{
5288 struct fw_event_work *fw_event; 5508 struct fw_event_work *fw_event;
5289 Mpi2EventNotificationReply_t *mpi_reply; 5509 Mpi2EventNotificationReply_t *mpi_reply;
@@ -5294,11 +5514,11 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, u32 reply)
5294 spin_lock_irqsave(&ioc->fw_event_lock, flags); 5514 spin_lock_irqsave(&ioc->fw_event_lock, flags);
5295 if (ioc->fw_events_off || ioc->remove_host) { 5515 if (ioc->fw_events_off || ioc->remove_host) {
5296 spin_unlock_irqrestore(&ioc->fw_event_lock, flags); 5516 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
5297 return; 5517 return 1;
5298 } 5518 }
5299 spin_unlock_irqrestore(&ioc->fw_event_lock, flags); 5519 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
5300 5520
5301 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); 5521 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
5302 event = le16_to_cpu(mpi_reply->Event); 5522 event = le16_to_cpu(mpi_reply->Event);
5303 5523
5304 switch (event) { 5524 switch (event) {
@@ -5312,7 +5532,7 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, u32 reply)
5312 if (baen_data->Primitive != 5532 if (baen_data->Primitive !=
5313 MPI2_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT || 5533 MPI2_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT ||
5314 ioc->broadcast_aen_busy) 5534 ioc->broadcast_aen_busy)
5315 return; 5535 return 1;
5316 ioc->broadcast_aen_busy = 1; 5536 ioc->broadcast_aen_busy = 1;
5317 break; 5537 break;
5318 } 5538 }
@@ -5334,14 +5554,14 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, u32 reply)
5334 break; 5554 break;
5335 5555
5336 default: /* ignore the rest */ 5556 default: /* ignore the rest */
5337 return; 5557 return 1;
5338 } 5558 }
5339 5559
5340 fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC); 5560 fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC);
5341 if (!fw_event) { 5561 if (!fw_event) {
5342 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 5562 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
5343 ioc->name, __FILE__, __LINE__, __func__); 5563 ioc->name, __FILE__, __LINE__, __func__);
5344 return; 5564 return 1;
5345 } 5565 }
5346 fw_event->event_data = 5566 fw_event->event_data =
5347 kzalloc(mpi_reply->EventDataLength*4, GFP_ATOMIC); 5567 kzalloc(mpi_reply->EventDataLength*4, GFP_ATOMIC);
@@ -5349,15 +5569,17 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID, u32 reply)
5349 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 5569 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
5350 ioc->name, __FILE__, __LINE__, __func__); 5570 ioc->name, __FILE__, __LINE__, __func__);
5351 kfree(fw_event); 5571 kfree(fw_event);
5352 return; 5572 return 1;
5353 } 5573 }
5354 5574
5355 memcpy(fw_event->event_data, mpi_reply->EventData, 5575 memcpy(fw_event->event_data, mpi_reply->EventData,
5356 mpi_reply->EventDataLength*4); 5576 mpi_reply->EventDataLength*4);
5357 fw_event->ioc = ioc; 5577 fw_event->ioc = ioc;
5358 fw_event->VF_ID = VF_ID; 5578 fw_event->VF_ID = mpi_reply->VF_ID;
5579 fw_event->VP_ID = mpi_reply->VP_ID;
5359 fw_event->event = event; 5580 fw_event->event = event;
5360 _scsih_fw_event_add(ioc, fw_event); 5581 _scsih_fw_event_add(ioc, fw_event);
5582 return 1;
5361} 5583}
5362 5584
5363/* shost template */ 5585/* shost template */
@@ -5617,7 +5839,7 @@ _scsih_probe_raid(struct MPT2SAS_ADAPTER *ioc)
5617} 5839}
5618 5840
5619/** 5841/**
5620 * _scsih_probe_sas - reporting raid volumes to sas transport 5842 * _scsih_probe_sas - reporting sas devices to sas transport
5621 * @ioc: per adapter object 5843 * @ioc: per adapter object
5622 * 5844 *
5623 * Called during initial loading of the driver. 5845 * Called during initial loading of the driver.
@@ -5714,6 +5936,8 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
5714 ioc->base_cb_idx = base_cb_idx; 5936 ioc->base_cb_idx = base_cb_idx;
5715 ioc->transport_cb_idx = transport_cb_idx; 5937 ioc->transport_cb_idx = transport_cb_idx;
5716 ioc->config_cb_idx = config_cb_idx; 5938 ioc->config_cb_idx = config_cb_idx;
5939 ioc->tm_tr_cb_idx = tm_tr_cb_idx;
5940 ioc->tm_sas_control_cb_idx = tm_sas_control_cb_idx;
5717 ioc->logging_level = logging_level; 5941 ioc->logging_level = logging_level;
5718 /* misc semaphores and spin locks */ 5942 /* misc semaphores and spin locks */
5719 spin_lock_init(&ioc->ioc_reset_in_progress_lock); 5943 spin_lock_init(&ioc->ioc_reset_in_progress_lock);
@@ -5729,6 +5953,7 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
5729 INIT_LIST_HEAD(&ioc->fw_event_list); 5953 INIT_LIST_HEAD(&ioc->fw_event_list);
5730 INIT_LIST_HEAD(&ioc->raid_device_list); 5954 INIT_LIST_HEAD(&ioc->raid_device_list);
5731 INIT_LIST_HEAD(&ioc->sas_hba.sas_port_list); 5955 INIT_LIST_HEAD(&ioc->sas_hba.sas_port_list);
5956 INIT_LIST_HEAD(&ioc->delayed_tr_list);
5732 5957
5733 /* init shost parameters */ 5958 /* init shost parameters */
5734 shost->max_cmd_len = 16; 5959 shost->max_cmd_len = 16;
@@ -5745,6 +5970,7 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
5745 5970
5746 scsi_host_set_prot(shost, SHOST_DIF_TYPE1_PROTECTION 5971 scsi_host_set_prot(shost, SHOST_DIF_TYPE1_PROTECTION
5747 | SHOST_DIF_TYPE3_PROTECTION); 5972 | SHOST_DIF_TYPE3_PROTECTION);
5973 scsi_host_set_guard(shost, SHOST_DIX_GUARD_CRC);
5748 5974
5749 /* event thread */ 5975 /* event thread */
5750 snprintf(ioc->firmware_event_name, sizeof(ioc->firmware_event_name), 5976 snprintf(ioc->firmware_event_name, sizeof(ioc->firmware_event_name),
@@ -5894,6 +6120,11 @@ _scsih_init(void)
5894 /* ctl module callback handler */ 6120 /* ctl module callback handler */
5895 ctl_cb_idx = mpt2sas_base_register_callback_handler(mpt2sas_ctl_done); 6121 ctl_cb_idx = mpt2sas_base_register_callback_handler(mpt2sas_ctl_done);
5896 6122
6123 tm_tr_cb_idx = mpt2sas_base_register_callback_handler(
6124 _scsih_tm_tr_complete);
6125 tm_sas_control_cb_idx = mpt2sas_base_register_callback_handler(
6126 _scsih_sas_control_complete);
6127
5897 mpt2sas_ctl_init(); 6128 mpt2sas_ctl_init();
5898 6129
5899 error = pci_register_driver(&scsih_driver); 6130 error = pci_register_driver(&scsih_driver);
@@ -5924,6 +6155,9 @@ _scsih_exit(void)
5924 mpt2sas_base_release_callback_handler(config_cb_idx); 6155 mpt2sas_base_release_callback_handler(config_cb_idx);
5925 mpt2sas_base_release_callback_handler(ctl_cb_idx); 6156 mpt2sas_base_release_callback_handler(ctl_cb_idx);
5926 6157
6158 mpt2sas_base_release_callback_handler(tm_tr_cb_idx);
6159 mpt2sas_base_release_callback_handler(tm_sas_control_cb_idx);
6160
5927 mpt2sas_ctl_exit(); 6161 mpt2sas_ctl_exit();
5928} 6162}
5929 6163
diff --git a/drivers/scsi/mpt2sas/mpt2sas_transport.c b/drivers/scsi/mpt2sas/mpt2sas_transport.c
index 742324a0a11e..eb98188c7f3f 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_transport.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_transport.c
@@ -2,7 +2,7 @@
2 * SAS Transport Layer for MPT (Message Passing Technology) based controllers 2 * SAS Transport Layer for MPT (Message Passing Technology) based controllers
3 * 3 *
4 * This code is based on drivers/scsi/mpt2sas/mpt2_transport.c 4 * This code is based on drivers/scsi/mpt2sas/mpt2_transport.c
5 * Copyright (C) 2007-2008 LSI Corporation 5 * Copyright (C) 2007-2009 LSI Corporation
6 * (mailto:DL-MPTFusionLinux@lsi.com) 6 * (mailto:DL-MPTFusionLinux@lsi.com)
7 * 7 *
8 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
@@ -212,25 +212,26 @@ _transport_set_identify(struct MPT2SAS_ADAPTER *ioc, u16 handle,
212 * mpt2sas_transport_done - internal transport layer callback handler. 212 * mpt2sas_transport_done - internal transport layer callback handler.
213 * @ioc: per adapter object 213 * @ioc: per adapter object
214 * @smid: system request message index 214 * @smid: system request message index
215 * @VF_ID: virtual function id 215 * @msix_index: MSIX table index supplied by the OS
216 * @reply: reply message frame(lower 32bit addr) 216 * @reply: reply message frame(lower 32bit addr)
217 * 217 *
218 * Callback handler when sending internal generated transport cmds. 218 * Callback handler when sending internal generated transport cmds.
219 * The callback index passed is `ioc->transport_cb_idx` 219 * The callback index passed is `ioc->transport_cb_idx`
220 * 220 *
221 * Return nothing. 221 * Return 1 meaning mf should be freed from _base_interrupt
222 * 0 means the mf is freed from this function.
222 */ 223 */
223void 224u8
224mpt2sas_transport_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID, 225mpt2sas_transport_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
225 u32 reply) 226 u32 reply)
226{ 227{
227 MPI2DefaultReply_t *mpi_reply; 228 MPI2DefaultReply_t *mpi_reply;
228 229
229 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); 230 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
230 if (ioc->transport_cmds.status == MPT2_CMD_NOT_USED) 231 if (ioc->transport_cmds.status == MPT2_CMD_NOT_USED)
231 return; 232 return 1;
232 if (ioc->transport_cmds.smid != smid) 233 if (ioc->transport_cmds.smid != smid)
233 return; 234 return 1;
234 ioc->transport_cmds.status |= MPT2_CMD_COMPLETE; 235 ioc->transport_cmds.status |= MPT2_CMD_COMPLETE;
235 if (mpi_reply) { 236 if (mpi_reply) {
236 memcpy(ioc->transport_cmds.reply, mpi_reply, 237 memcpy(ioc->transport_cmds.reply, mpi_reply,
@@ -239,6 +240,7 @@ mpt2sas_transport_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID,
239 } 240 }
240 ioc->transport_cmds.status &= ~MPT2_CMD_PENDING; 241 ioc->transport_cmds.status &= ~MPT2_CMD_PENDING;
241 complete(&ioc->transport_cmds.done); 242 complete(&ioc->transport_cmds.done);
243 return 1;
242} 244}
243 245
244/* report manufacture request structure */ 246/* report manufacture request structure */
@@ -369,6 +371,8 @@ _transport_expander_report_manufacture(struct MPT2SAS_ADAPTER *ioc,
369 memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t)); 371 memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t));
370 mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH; 372 mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
371 mpi_request->PhysicalPort = 0xFF; 373 mpi_request->PhysicalPort = 0xFF;
374 mpi_request->VF_ID = 0; /* TODO */
375 mpi_request->VP_ID = 0;
372 sas_address_le = (u64 *)&mpi_request->SASAddress; 376 sas_address_le = (u64 *)&mpi_request->SASAddress;
373 *sas_address_le = cpu_to_le64(sas_address); 377 *sas_address_le = cpu_to_le64(sas_address);
374 mpi_request->RequestDataLength = sizeof(struct rep_manu_request); 378 mpi_request->RequestDataLength = sizeof(struct rep_manu_request);
@@ -396,7 +400,8 @@ _transport_expander_report_manufacture(struct MPT2SAS_ADAPTER *ioc,
396 dtransportprintk(ioc, printk(MPT2SAS_DEBUG_FMT "report_manufacture - " 400 dtransportprintk(ioc, printk(MPT2SAS_DEBUG_FMT "report_manufacture - "
397 "send to sas_addr(0x%016llx)\n", ioc->name, 401 "send to sas_addr(0x%016llx)\n", ioc->name,
398 (unsigned long long)sas_address)); 402 (unsigned long long)sas_address));
399 mpt2sas_base_put_smid_default(ioc, smid, 0 /* VF_ID */); 403 mpt2sas_base_put_smid_default(ioc, smid);
404 init_completion(&ioc->transport_cmds.done);
400 timeleft = wait_for_completion_timeout(&ioc->transport_cmds.done, 405 timeleft = wait_for_completion_timeout(&ioc->transport_cmds.done,
401 10*HZ); 406 10*HZ);
402 407
@@ -1106,6 +1111,8 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
1106 memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t)); 1111 memset(mpi_request, 0, sizeof(Mpi2SmpPassthroughRequest_t));
1107 mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH; 1112 mpi_request->Function = MPI2_FUNCTION_SMP_PASSTHROUGH;
1108 mpi_request->PhysicalPort = 0xFF; 1113 mpi_request->PhysicalPort = 0xFF;
1114 mpi_request->VF_ID = 0; /* TODO */
1115 mpi_request->VP_ID = 0;
1109 *((u64 *)&mpi_request->SASAddress) = (rphy) ? 1116 *((u64 *)&mpi_request->SASAddress) = (rphy) ?
1110 cpu_to_le64(rphy->identify.sas_address) : 1117 cpu_to_le64(rphy->identify.sas_address) :
1111 cpu_to_le64(ioc->sas_hba.sas_address); 1118 cpu_to_le64(ioc->sas_hba.sas_address);
@@ -1147,7 +1154,8 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
1147 dtransportprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s - " 1154 dtransportprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s - "
1148 "sending smp request\n", ioc->name, __func__)); 1155 "sending smp request\n", ioc->name, __func__));
1149 1156
1150 mpt2sas_base_put_smid_default(ioc, smid, 0 /* VF_ID */); 1157 mpt2sas_base_put_smid_default(ioc, smid);
1158 init_completion(&ioc->transport_cmds.done);
1151 timeleft = wait_for_completion_timeout(&ioc->transport_cmds.done, 1159 timeleft = wait_for_completion_timeout(&ioc->transport_cmds.done,
1152 10*HZ); 1160 10*HZ);
1153 1161
diff --git a/drivers/scsi/mvsas/mv_defs.h b/drivers/scsi/mvsas/mv_defs.h
index f8cb9defb961..1849da1f030d 100644
--- a/drivers/scsi/mvsas/mv_defs.h
+++ b/drivers/scsi/mvsas/mv_defs.h
@@ -25,6 +25,8 @@
25#ifndef _MV_DEFS_H_ 25#ifndef _MV_DEFS_H_
26#define _MV_DEFS_H_ 26#define _MV_DEFS_H_
27 27
28#define PCI_DEVICE_ID_ARECA_1300 0x1300
29#define PCI_DEVICE_ID_ARECA_1320 0x1320
28 30
29enum chip_flavors { 31enum chip_flavors {
30 chip_6320, 32 chip_6320,
@@ -32,6 +34,8 @@ enum chip_flavors {
32 chip_6485, 34 chip_6485,
33 chip_9480, 35 chip_9480,
34 chip_9180, 36 chip_9180,
37 chip_1300,
38 chip_1320
35}; 39};
36 40
37/* driver compile-time configuration */ 41/* driver compile-time configuration */
diff --git a/drivers/scsi/mvsas/mv_init.c b/drivers/scsi/mvsas/mv_init.c
index 8646a19f999d..c790d45876c4 100644
--- a/drivers/scsi/mvsas/mv_init.c
+++ b/drivers/scsi/mvsas/mv_init.c
@@ -32,6 +32,8 @@ static const struct mvs_chip_info mvs_chips[] = {
32 [chip_6485] = { 1, 8, 0x800, 33, 32, 10, &mvs_64xx_dispatch, }, 32 [chip_6485] = { 1, 8, 0x800, 33, 32, 10, &mvs_64xx_dispatch, },
33 [chip_9180] = { 2, 4, 0x800, 17, 64, 9, &mvs_94xx_dispatch, }, 33 [chip_9180] = { 2, 4, 0x800, 17, 64, 9, &mvs_94xx_dispatch, },
34 [chip_9480] = { 2, 4, 0x800, 17, 64, 9, &mvs_94xx_dispatch, }, 34 [chip_9480] = { 2, 4, 0x800, 17, 64, 9, &mvs_94xx_dispatch, },
35 [chip_1300] = { 1, 4, 0x400, 17, 16, 9, &mvs_64xx_dispatch, },
36 [chip_1320] = { 2, 4, 0x800, 17, 64, 9, &mvs_94xx_dispatch, },
35}; 37};
36 38
37#define SOC_SAS_NUM 2 39#define SOC_SAS_NUM 2
@@ -653,6 +655,8 @@ static struct pci_device_id __devinitdata mvs_pci_table[] = {
653 { PCI_VDEVICE(MARVELL, 0x6485), chip_6485 }, 655 { PCI_VDEVICE(MARVELL, 0x6485), chip_6485 },
654 { PCI_VDEVICE(MARVELL, 0x9480), chip_9480 }, 656 { PCI_VDEVICE(MARVELL, 0x9480), chip_9480 },
655 { PCI_VDEVICE(MARVELL, 0x9180), chip_9180 }, 657 { PCI_VDEVICE(MARVELL, 0x9180), chip_9180 },
658 { PCI_VDEVICE(ARECA, PCI_DEVICE_ID_ARECA_1300), chip_1300 },
659 { PCI_VDEVICE(ARECA, PCI_DEVICE_ID_ARECA_1320), chip_1320 },
656 660
657 { } /* terminate list */ 661 { } /* terminate list */
658}; 662};
diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c
index 4302f06e4ec9..f7c70e2a8224 100644
--- a/drivers/scsi/pmcraid.c
+++ b/drivers/scsi/pmcraid.c
@@ -46,6 +46,7 @@
46#include <linux/mutex.h> 46#include <linux/mutex.h>
47#include <scsi/scsi.h> 47#include <scsi/scsi.h>
48#include <scsi/scsi_host.h> 48#include <scsi/scsi_host.h>
49#include <scsi/scsi_device.h>
49#include <scsi/scsi_tcq.h> 50#include <scsi/scsi_tcq.h>
50#include <scsi/scsi_eh.h> 51#include <scsi/scsi_eh.h>
51#include <scsi/scsi_cmnd.h> 52#include <scsi/scsi_cmnd.h>
@@ -684,7 +685,7 @@ static void pmcraid_timeout_handler(struct pmcraid_cmd *cmd)
684 struct pmcraid_instance *pinstance = cmd->drv_inst; 685 struct pmcraid_instance *pinstance = cmd->drv_inst;
685 unsigned long lock_flags; 686 unsigned long lock_flags;
686 687
687 dev_err(&pinstance->pdev->dev, 688 dev_info(&pinstance->pdev->dev,
688 "Adapter being reset due to command timeout.\n"); 689 "Adapter being reset due to command timeout.\n");
689 690
690 /* Command timeouts result in hard reset sequence. The command that got 691 /* Command timeouts result in hard reset sequence. The command that got
@@ -815,8 +816,9 @@ static void pmcraid_erp_done(struct pmcraid_cmd *cmd)
815 816
816 if (PMCRAID_IOASC_SENSE_KEY(ioasc) > 0) { 817 if (PMCRAID_IOASC_SENSE_KEY(ioasc) > 0) {
817 scsi_cmd->result |= (DID_ERROR << 16); 818 scsi_cmd->result |= (DID_ERROR << 16);
818 pmcraid_err("command CDB[0] = %x failed with IOASC: 0x%08X\n", 819 scmd_printk(KERN_INFO, scsi_cmd,
819 cmd->ioa_cb->ioarcb.cdb[0], ioasc); 820 "command CDB[0] = %x failed with IOASC: 0x%08X\n",
821 cmd->ioa_cb->ioarcb.cdb[0], ioasc);
820 } 822 }
821 823
822 /* if we had allocated sense buffers for request sense, copy the sense 824 /* if we had allocated sense buffers for request sense, copy the sense
@@ -1541,13 +1543,13 @@ static void pmcraid_handle_error_log(struct pmcraid_instance *pinstance)
1541 1543
1542 if (pinstance->ldn.hcam->notification_lost == 1544 if (pinstance->ldn.hcam->notification_lost ==
1543 HOSTRCB_NOTIFICATIONS_LOST) 1545 HOSTRCB_NOTIFICATIONS_LOST)
1544 dev_err(&pinstance->pdev->dev, "Error notifications lost\n"); 1546 dev_info(&pinstance->pdev->dev, "Error notifications lost\n");
1545 1547
1546 ioasc = le32_to_cpu(hcam_ldn->error_log.fd_ioasc); 1548 ioasc = le32_to_cpu(hcam_ldn->error_log.fd_ioasc);
1547 1549
1548 if (ioasc == PMCRAID_IOASC_UA_BUS_WAS_RESET || 1550 if (ioasc == PMCRAID_IOASC_UA_BUS_WAS_RESET ||
1549 ioasc == PMCRAID_IOASC_UA_BUS_WAS_RESET_BY_OTHER) { 1551 ioasc == PMCRAID_IOASC_UA_BUS_WAS_RESET_BY_OTHER) {
1550 dev_err(&pinstance->pdev->dev, 1552 dev_info(&pinstance->pdev->dev,
1551 "UnitAttention due to IOA Bus Reset\n"); 1553 "UnitAttention due to IOA Bus Reset\n");
1552 scsi_report_bus_reset( 1554 scsi_report_bus_reset(
1553 pinstance->host, 1555 pinstance->host,
@@ -1584,7 +1586,7 @@ static void pmcraid_process_ccn(struct pmcraid_cmd *cmd)
1584 atomic_read(&pinstance->ccn.ignore) == 1) { 1586 atomic_read(&pinstance->ccn.ignore) == 1) {
1585 return; 1587 return;
1586 } else if (ioasc) { 1588 } else if (ioasc) {
1587 dev_err(&pinstance->pdev->dev, 1589 dev_info(&pinstance->pdev->dev,
1588 "Host RCB (CCN) failed with IOASC: 0x%08X\n", ioasc); 1590 "Host RCB (CCN) failed with IOASC: 0x%08X\n", ioasc);
1589 spin_lock_irqsave(pinstance->host->host_lock, lock_flags); 1591 spin_lock_irqsave(pinstance->host->host_lock, lock_flags);
1590 pmcraid_send_hcam(pinstance, PMCRAID_HCAM_CODE_CONFIG_CHANGE); 1592 pmcraid_send_hcam(pinstance, PMCRAID_HCAM_CODE_CONFIG_CHANGE);
@@ -1634,7 +1636,7 @@ static void pmcraid_process_ldn(struct pmcraid_cmd *cmd)
1634 return; 1636 return;
1635 } 1637 }
1636 } else { 1638 } else {
1637 dev_err(&pinstance->pdev->dev, 1639 dev_info(&pinstance->pdev->dev,
1638 "Host RCB(LDN) failed with IOASC: 0x%08X\n", ioasc); 1640 "Host RCB(LDN) failed with IOASC: 0x%08X\n", ioasc);
1639 } 1641 }
1640 /* send netlink message for HCAM notification if enabled */ 1642 /* send netlink message for HCAM notification if enabled */
@@ -1822,7 +1824,6 @@ static void pmcraid_fail_outstanding_cmds(struct pmcraid_instance *pinstance)
1822 scsi_dma_unmap(scsi_cmd); 1824 scsi_dma_unmap(scsi_cmd);
1823 pmcraid_return_cmd(cmd); 1825 pmcraid_return_cmd(cmd);
1824 1826
1825
1826 pmcraid_info("failing(%d) CDB[0] = %x result: %x\n", 1827 pmcraid_info("failing(%d) CDB[0] = %x result: %x\n",
1827 le32_to_cpu(resp) >> 2, 1828 le32_to_cpu(resp) >> 2,
1828 cmd->ioa_cb->ioarcb.cdb[0], 1829 cmd->ioa_cb->ioarcb.cdb[0],
@@ -2514,7 +2515,8 @@ static int pmcraid_reset_device(
2514 res = scsi_cmd->device->hostdata; 2515 res = scsi_cmd->device->hostdata;
2515 2516
2516 if (!res) { 2517 if (!res) {
2517 pmcraid_err("reset_device: NULL resource pointer\n"); 2518 sdev_printk(KERN_ERR, scsi_cmd->device,
2519 "reset_device: NULL resource pointer\n");
2518 return FAILED; 2520 return FAILED;
2519 } 2521 }
2520 2522
@@ -2752,8 +2754,8 @@ static int pmcraid_eh_abort_handler(struct scsi_cmnd *scsi_cmd)
2752 pinstance = 2754 pinstance =
2753 (struct pmcraid_instance *)scsi_cmd->device->host->hostdata; 2755 (struct pmcraid_instance *)scsi_cmd->device->host->hostdata;
2754 2756
2755 dev_err(&pinstance->pdev->dev, 2757 scmd_printk(KERN_INFO, scsi_cmd,
2756 "I/O command timed out, aborting it.\n"); 2758 "I/O command timed out, aborting it.\n");
2757 2759
2758 res = scsi_cmd->device->hostdata; 2760 res = scsi_cmd->device->hostdata;
2759 2761
@@ -2824,7 +2826,8 @@ static int pmcraid_eh_abort_handler(struct scsi_cmnd *scsi_cmd)
2824 */ 2826 */
2825static int pmcraid_eh_device_reset_handler(struct scsi_cmnd *scmd) 2827static int pmcraid_eh_device_reset_handler(struct scsi_cmnd *scmd)
2826{ 2828{
2827 pmcraid_err("Doing device reset due to an I/O command timeout.\n"); 2829 scmd_printk(KERN_INFO, scmd,
2830 "resetting device due to an I/O command timeout.\n");
2828 return pmcraid_reset_device(scmd, 2831 return pmcraid_reset_device(scmd,
2829 PMCRAID_INTERNAL_TIMEOUT, 2832 PMCRAID_INTERNAL_TIMEOUT,
2830 RESET_DEVICE_LUN); 2833 RESET_DEVICE_LUN);
@@ -2832,7 +2835,8 @@ static int pmcraid_eh_device_reset_handler(struct scsi_cmnd *scmd)
2832 2835
2833static int pmcraid_eh_bus_reset_handler(struct scsi_cmnd *scmd) 2836static int pmcraid_eh_bus_reset_handler(struct scsi_cmnd *scmd)
2834{ 2837{
2835 pmcraid_err("Doing bus reset due to an I/O command timeout.\n"); 2838 scmd_printk(KERN_INFO, scmd,
2839 "Doing bus reset due to an I/O command timeout.\n");
2836 return pmcraid_reset_device(scmd, 2840 return pmcraid_reset_device(scmd,
2837 PMCRAID_RESET_BUS_TIMEOUT, 2841 PMCRAID_RESET_BUS_TIMEOUT,
2838 RESET_DEVICE_BUS); 2842 RESET_DEVICE_BUS);
@@ -2840,7 +2844,8 @@ static int pmcraid_eh_bus_reset_handler(struct scsi_cmnd *scmd)
2840 2844
2841static int pmcraid_eh_target_reset_handler(struct scsi_cmnd *scmd) 2845static int pmcraid_eh_target_reset_handler(struct scsi_cmnd *scmd)
2842{ 2846{
2843 pmcraid_err("Doing target reset due to an I/O command timeout.\n"); 2847 scmd_printk(KERN_INFO, scmd,
2848 "Doing target reset due to an I/O command timeout.\n");
2844 return pmcraid_reset_device(scmd, 2849 return pmcraid_reset_device(scmd,
2845 PMCRAID_INTERNAL_TIMEOUT, 2850 PMCRAID_INTERNAL_TIMEOUT,
2846 RESET_DEVICE_TARGET); 2851 RESET_DEVICE_TARGET);
@@ -2988,11 +2993,11 @@ static int pmcraid_build_ioadl(
2988 nseg = scsi_dma_map(scsi_cmd); 2993 nseg = scsi_dma_map(scsi_cmd);
2989 2994
2990 if (nseg < 0) { 2995 if (nseg < 0) {
2991 dev_err(&pinstance->pdev->dev, "scsi_map_dma failed!\n"); 2996 scmd_printk(KERN_ERR, scsi_cmd, "scsi_map_dma failed!\n");
2992 return -1; 2997 return -1;
2993 } else if (nseg > PMCRAID_MAX_IOADLS) { 2998 } else if (nseg > PMCRAID_MAX_IOADLS) {
2994 scsi_dma_unmap(scsi_cmd); 2999 scsi_dma_unmap(scsi_cmd);
2995 dev_err(&pinstance->pdev->dev, 3000 scmd_printk(KERN_ERR, scsi_cmd,
2996 "sg count is (%d) more than allowed!\n", nseg); 3001 "sg count is (%d) more than allowed!\n", nseg);
2997 return -1; 3002 return -1;
2998 } 3003 }
@@ -5040,7 +5045,7 @@ static int pmcraid_resume(struct pci_dev *pdev)
5040 rc = pci_enable_device(pdev); 5045 rc = pci_enable_device(pdev);
5041 5046
5042 if (rc) { 5047 if (rc) {
5043 pmcraid_err("pmcraid: Enable device failed\n"); 5048 dev_err(&pdev->dev, "resume: Enable device failed\n");
5044 return rc; 5049 return rc;
5045 } 5050 }
5046 5051
@@ -5054,7 +5059,7 @@ static int pmcraid_resume(struct pci_dev *pdev)
5054 rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); 5059 rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
5055 5060
5056 if (rc != 0) { 5061 if (rc != 0) {
5057 dev_err(&pdev->dev, "Failed to set PCI DMA mask\n"); 5062 dev_err(&pdev->dev, "resume: Failed to set PCI DMA mask\n");
5058 goto disable_device; 5063 goto disable_device;
5059 } 5064 }
5060 5065
@@ -5063,7 +5068,8 @@ static int pmcraid_resume(struct pci_dev *pdev)
5063 rc = pmcraid_register_interrupt_handler(pinstance); 5068 rc = pmcraid_register_interrupt_handler(pinstance);
5064 5069
5065 if (rc) { 5070 if (rc) {
5066 pmcraid_err("resume: couldn't register interrupt handlers\n"); 5071 dev_err(&pdev->dev,
5072 "resume: couldn't register interrupt handlers\n");
5067 rc = -ENODEV; 5073 rc = -ENODEV;
5068 goto release_host; 5074 goto release_host;
5069 } 5075 }
@@ -5080,7 +5086,7 @@ static int pmcraid_resume(struct pci_dev *pdev)
5080 * state. 5086 * state.
5081 */ 5087 */
5082 if (pmcraid_reset_bringup(pinstance)) { 5088 if (pmcraid_reset_bringup(pinstance)) {
5083 pmcraid_err("couldn't initialize IOA \n"); 5089 dev_err(&pdev->dev, "couldn't initialize IOA \n");
5084 rc = -ENODEV; 5090 rc = -ENODEV;
5085 goto release_tasklets; 5091 goto release_tasklets;
5086 } 5092 }
@@ -5187,7 +5193,7 @@ static void pmcraid_init_res_table(struct pmcraid_cmd *cmd)
5187 LIST_HEAD(old_res); 5193 LIST_HEAD(old_res);
5188 5194
5189 if (pinstance->cfg_table->flags & MICROCODE_UPDATE_REQUIRED) 5195 if (pinstance->cfg_table->flags & MICROCODE_UPDATE_REQUIRED)
5190 dev_err(&pinstance->pdev->dev, "Require microcode download\n"); 5196 pmcraid_err("IOA requires microcode download\n");
5191 5197
5192 /* resource list is protected by pinstance->resource_lock. 5198 /* resource list is protected by pinstance->resource_lock.
5193 * init_res_table can be called from probe (user-thread) or runtime 5199 * init_res_table can be called from probe (user-thread) or runtime
@@ -5224,8 +5230,7 @@ static void pmcraid_init_res_table(struct pmcraid_cmd *cmd)
5224 if (!found) { 5230 if (!found) {
5225 5231
5226 if (list_empty(&pinstance->free_res_q)) { 5232 if (list_empty(&pinstance->free_res_q)) {
5227 dev_err(&pinstance->pdev->dev, 5233 pmcraid_err("Too many devices attached\n");
5228 "Too many devices attached\n");
5229 break; 5234 break;
5230 } 5235 }
5231 5236
@@ -5442,7 +5447,7 @@ static int __devinit pmcraid_probe(
5442 rc = pmcraid_register_interrupt_handler(pinstance); 5447 rc = pmcraid_register_interrupt_handler(pinstance);
5443 5448
5444 if (rc) { 5449 if (rc) {
5445 pmcraid_err("couldn't register interrupt handler\n"); 5450 dev_err(&pdev->dev, "couldn't register interrupt handler\n");
5446 goto out_scsi_host_put; 5451 goto out_scsi_host_put;
5447 } 5452 }
5448 5453
@@ -5466,7 +5471,7 @@ static int __devinit pmcraid_probe(
5466 */ 5471 */
5467 pmcraid_info("starting IOA initialization sequence\n"); 5472 pmcraid_info("starting IOA initialization sequence\n");
5468 if (pmcraid_reset_bringup(pinstance)) { 5473 if (pmcraid_reset_bringup(pinstance)) {
5469 pmcraid_err("couldn't initialize IOA \n"); 5474 dev_err(&pdev->dev, "couldn't initialize IOA \n");
5470 rc = 1; 5475 rc = 1;
5471 goto out_release_bufs; 5476 goto out_release_bufs;
5472 } 5477 }
@@ -5534,7 +5539,6 @@ static struct pci_driver pmcraid_driver = {
5534 .shutdown = pmcraid_shutdown 5539 .shutdown = pmcraid_shutdown
5535}; 5540};
5536 5541
5537
5538/** 5542/**
5539 * pmcraid_init - module load entry point 5543 * pmcraid_init - module load entry point
5540 */ 5544 */
@@ -5566,7 +5570,6 @@ static int __init pmcraid_init(void)
5566 goto out_unreg_chrdev; 5570 goto out_unreg_chrdev;
5567 } 5571 }
5568 5572
5569
5570 error = pmcraid_netlink_init(); 5573 error = pmcraid_netlink_init();
5571 5574
5572 if (error) 5575 if (error)
@@ -5584,6 +5587,7 @@ static int __init pmcraid_init(void)
5584 5587
5585out_unreg_chrdev: 5588out_unreg_chrdev:
5586 unregister_chrdev_region(MKDEV(pmcraid_major, 0), PMCRAID_MAX_ADAPTERS); 5589 unregister_chrdev_region(MKDEV(pmcraid_major, 0), PMCRAID_MAX_ADAPTERS);
5590
5587out_init: 5591out_init:
5588 return error; 5592 return error;
5589} 5593}
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c
index 42b799abba57..e07b3617f019 100644
--- a/drivers/scsi/qla2xxx/qla_mid.c
+++ b/drivers/scsi/qla2xxx/qla_mid.c
@@ -568,7 +568,7 @@ qla25xx_create_req_que(struct qla_hw_data *ha, uint16_t options,
568 if (req == NULL) { 568 if (req == NULL) {
569 qla_printk(KERN_WARNING, ha, "could not allocate memory" 569 qla_printk(KERN_WARNING, ha, "could not allocate memory"
570 "for request que\n"); 570 "for request que\n");
571 goto que_failed; 571 goto failed;
572 } 572 }
573 573
574 req->length = REQUEST_ENTRY_CNT_24XX; 574 req->length = REQUEST_ENTRY_CNT_24XX;
@@ -632,6 +632,7 @@ qla25xx_create_req_que(struct qla_hw_data *ha, uint16_t options,
632 632
633que_failed: 633que_failed:
634 qla25xx_free_req_que(base_vha, req); 634 qla25xx_free_req_que(base_vha, req);
635failed:
635 return 0; 636 return 0;
636} 637}
637 638
@@ -659,7 +660,7 @@ qla25xx_create_rsp_que(struct qla_hw_data *ha, uint16_t options,
659 if (rsp == NULL) { 660 if (rsp == NULL) {
660 qla_printk(KERN_WARNING, ha, "could not allocate memory for" 661 qla_printk(KERN_WARNING, ha, "could not allocate memory for"
661 " response que\n"); 662 " response que\n");
662 goto que_failed; 663 goto failed;
663 } 664 }
664 665
665 rsp->length = RESPONSE_ENTRY_CNT_MQ; 666 rsp->length = RESPONSE_ENTRY_CNT_MQ;
@@ -728,6 +729,7 @@ qla25xx_create_rsp_que(struct qla_hw_data *ha, uint16_t options,
728 729
729que_failed: 730que_failed:
730 qla25xx_free_rsp_que(base_vha, rsp); 731 qla25xx_free_rsp_que(base_vha, rsp);
732failed:
731 return 0; 733 return 0;
732} 734}
733 735
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index b6e03074cb8f..dd098cad337b 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -241,10 +241,7 @@ scsi_host_alloc_command(struct Scsi_Host *shost, gfp_t gfp_mask)
241 */ 241 */
242struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *shost, gfp_t gfp_mask) 242struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *shost, gfp_t gfp_mask)
243{ 243{
244 struct scsi_cmnd *cmd; 244 struct scsi_cmnd *cmd = scsi_host_alloc_command(shost, gfp_mask);
245 unsigned char *buf;
246
247 cmd = scsi_host_alloc_command(shost, gfp_mask);
248 245
249 if (unlikely(!cmd)) { 246 if (unlikely(!cmd)) {
250 unsigned long flags; 247 unsigned long flags;
@@ -258,9 +255,15 @@ struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *shost, gfp_t gfp_mask)
258 spin_unlock_irqrestore(&shost->free_list_lock, flags); 255 spin_unlock_irqrestore(&shost->free_list_lock, flags);
259 256
260 if (cmd) { 257 if (cmd) {
258 void *buf, *prot;
259
261 buf = cmd->sense_buffer; 260 buf = cmd->sense_buffer;
261 prot = cmd->prot_sdb;
262
262 memset(cmd, 0, sizeof(*cmd)); 263 memset(cmd, 0, sizeof(*cmd));
264
263 cmd->sense_buffer = buf; 265 cmd->sense_buffer = buf;
266 cmd->prot_sdb = prot;
264 } 267 }
265 } 268 }
266 269
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index fb9af207d61d..c4103bef41b5 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -50,6 +50,7 @@
50#include <scsi/scsi_host.h> 50#include <scsi/scsi_host.h>
51#include <scsi/scsicam.h> 51#include <scsi/scsicam.h>
52#include <scsi/scsi_eh.h> 52#include <scsi/scsi_eh.h>
53#include <scsi/scsi_dbg.h>
53 54
54#include "sd.h" 55#include "sd.h"
55#include "scsi_logging.h" 56#include "scsi_logging.h"
@@ -64,6 +65,7 @@ static const char * scsi_debug_version_date = "20070104";
64#define PARAMETER_LIST_LENGTH_ERR 0x1a 65#define PARAMETER_LIST_LENGTH_ERR 0x1a
65#define INVALID_OPCODE 0x20 66#define INVALID_OPCODE 0x20
66#define ADDR_OUT_OF_RANGE 0x21 67#define ADDR_OUT_OF_RANGE 0x21
68#define INVALID_COMMAND_OPCODE 0x20
67#define INVALID_FIELD_IN_CDB 0x24 69#define INVALID_FIELD_IN_CDB 0x24
68#define INVALID_FIELD_IN_PARAM_LIST 0x26 70#define INVALID_FIELD_IN_PARAM_LIST 0x26
69#define POWERON_RESET 0x29 71#define POWERON_RESET 0x29
@@ -180,7 +182,7 @@ static int sdebug_sectors_per; /* sectors per cylinder */
180#define SDEBUG_SENSE_LEN 32 182#define SDEBUG_SENSE_LEN 32
181 183
182#define SCSI_DEBUG_CANQUEUE 255 184#define SCSI_DEBUG_CANQUEUE 255
183#define SCSI_DEBUG_MAX_CMD_LEN 16 185#define SCSI_DEBUG_MAX_CMD_LEN 32
184 186
185struct sdebug_dev_info { 187struct sdebug_dev_info {
186 struct list_head dev_list; 188 struct list_head dev_list;
@@ -296,9 +298,25 @@ static void mk_sense_buffer(struct sdebug_dev_info *devip, int key,
296} 298}
297 299
298static void get_data_transfer_info(unsigned char *cmd, 300static void get_data_transfer_info(unsigned char *cmd,
299 unsigned long long *lba, unsigned int *num) 301 unsigned long long *lba, unsigned int *num,
302 u32 *ei_lba)
300{ 303{
304 *ei_lba = 0;
305
301 switch (*cmd) { 306 switch (*cmd) {
307 case VARIABLE_LENGTH_CMD:
308 *lba = (u64)cmd[19] | (u64)cmd[18] << 8 |
309 (u64)cmd[17] << 16 | (u64)cmd[16] << 24 |
310 (u64)cmd[15] << 32 | (u64)cmd[14] << 40 |
311 (u64)cmd[13] << 48 | (u64)cmd[12] << 56;
312
313 *ei_lba = (u32)cmd[23] | (u32)cmd[22] << 8 |
314 (u32)cmd[21] << 16 | (u32)cmd[20] << 24;
315
316 *num = (u32)cmd[31] | (u32)cmd[30] << 8 | (u32)cmd[29] << 16 |
317 (u32)cmd[28] << 24;
318 break;
319
302 case WRITE_16: 320 case WRITE_16:
303 case READ_16: 321 case READ_16:
304 *lba = (u64)cmd[9] | (u64)cmd[8] << 8 | 322 *lba = (u64)cmd[9] | (u64)cmd[8] << 8 |
@@ -1589,7 +1607,7 @@ static int do_device_access(struct scsi_cmnd *scmd,
1589} 1607}
1590 1608
1591static int prot_verify_read(struct scsi_cmnd *SCpnt, sector_t start_sec, 1609static int prot_verify_read(struct scsi_cmnd *SCpnt, sector_t start_sec,
1592 unsigned int sectors) 1610 unsigned int sectors, u32 ei_lba)
1593{ 1611{
1594 unsigned int i, resid; 1612 unsigned int i, resid;
1595 struct scatterlist *psgl; 1613 struct scatterlist *psgl;
@@ -1636,13 +1654,23 @@ static int prot_verify_read(struct scsi_cmnd *SCpnt, sector_t start_sec,
1636 return 0x01; 1654 return 0x01;
1637 } 1655 }
1638 1656
1639 if (scsi_debug_dif != SD_DIF_TYPE3_PROTECTION && 1657 if (scsi_debug_dif == SD_DIF_TYPE1_PROTECTION &&
1640 be32_to_cpu(sdt[i].ref_tag) != (sector & 0xffffffff)) { 1658 be32_to_cpu(sdt[i].ref_tag) != (sector & 0xffffffff)) {
1641 printk(KERN_ERR "%s: REF check failed on sector %lu\n", 1659 printk(KERN_ERR "%s: REF check failed on sector %lu\n",
1642 __func__, (unsigned long)sector); 1660 __func__, (unsigned long)sector);
1643 dif_errors++; 1661 dif_errors++;
1644 return 0x03; 1662 return 0x03;
1645 } 1663 }
1664
1665 if (scsi_debug_dif == SD_DIF_TYPE2_PROTECTION &&
1666 be32_to_cpu(sdt[i].ref_tag) != ei_lba) {
1667 printk(KERN_ERR "%s: REF check failed on sector %lu\n",
1668 __func__, (unsigned long)sector);
1669 dif_errors++;
1670 return 0x03;
1671 }
1672
1673 ei_lba++;
1646 } 1674 }
1647 1675
1648 resid = sectors * 8; /* Bytes of protection data to copy into sgl */ 1676 resid = sectors * 8; /* Bytes of protection data to copy into sgl */
@@ -1670,7 +1698,8 @@ static int prot_verify_read(struct scsi_cmnd *SCpnt, sector_t start_sec,
1670} 1698}
1671 1699
1672static int resp_read(struct scsi_cmnd *SCpnt, unsigned long long lba, 1700static int resp_read(struct scsi_cmnd *SCpnt, unsigned long long lba,
1673 unsigned int num, struct sdebug_dev_info *devip) 1701 unsigned int num, struct sdebug_dev_info *devip,
1702 u32 ei_lba)
1674{ 1703{
1675 unsigned long iflags; 1704 unsigned long iflags;
1676 int ret; 1705 int ret;
@@ -1699,7 +1728,7 @@ static int resp_read(struct scsi_cmnd *SCpnt, unsigned long long lba,
1699 1728
1700 /* DIX + T10 DIF */ 1729 /* DIX + T10 DIF */
1701 if (scsi_debug_dix && scsi_prot_sg_count(SCpnt)) { 1730 if (scsi_debug_dix && scsi_prot_sg_count(SCpnt)) {
1702 int prot_ret = prot_verify_read(SCpnt, lba, num); 1731 int prot_ret = prot_verify_read(SCpnt, lba, num, ei_lba);
1703 1732
1704 if (prot_ret) { 1733 if (prot_ret) {
1705 mk_sense_buffer(devip, ABORTED_COMMAND, 0x10, prot_ret); 1734 mk_sense_buffer(devip, ABORTED_COMMAND, 0x10, prot_ret);
@@ -1735,7 +1764,7 @@ void dump_sector(unsigned char *buf, int len)
1735} 1764}
1736 1765
1737static int prot_verify_write(struct scsi_cmnd *SCpnt, sector_t start_sec, 1766static int prot_verify_write(struct scsi_cmnd *SCpnt, sector_t start_sec,
1738 unsigned int sectors) 1767 unsigned int sectors, u32 ei_lba)
1739{ 1768{
1740 int i, j, ret; 1769 int i, j, ret;
1741 struct sd_dif_tuple *sdt; 1770 struct sd_dif_tuple *sdt;
@@ -1749,11 +1778,6 @@ static int prot_verify_write(struct scsi_cmnd *SCpnt, sector_t start_sec,
1749 1778
1750 sector = do_div(tmp_sec, sdebug_store_sectors); 1779 sector = do_div(tmp_sec, sdebug_store_sectors);
1751 1780
1752 if (((SCpnt->cmnd[1] >> 5) & 7) != 1) {
1753 printk(KERN_WARNING "scsi_debug: WRPROTECT != 1\n");
1754 return 0;
1755 }
1756
1757 BUG_ON(scsi_sg_count(SCpnt) == 0); 1781 BUG_ON(scsi_sg_count(SCpnt) == 0);
1758 BUG_ON(scsi_prot_sg_count(SCpnt) == 0); 1782 BUG_ON(scsi_prot_sg_count(SCpnt) == 0);
1759 1783
@@ -1808,7 +1832,7 @@ static int prot_verify_write(struct scsi_cmnd *SCpnt, sector_t start_sec,
1808 goto out; 1832 goto out;
1809 } 1833 }
1810 1834
1811 if (scsi_debug_dif != SD_DIF_TYPE3_PROTECTION && 1835 if (scsi_debug_dif == SD_DIF_TYPE1_PROTECTION &&
1812 be32_to_cpu(sdt->ref_tag) 1836 be32_to_cpu(sdt->ref_tag)
1813 != (start_sec & 0xffffffff)) { 1837 != (start_sec & 0xffffffff)) {
1814 printk(KERN_ERR 1838 printk(KERN_ERR
@@ -1819,6 +1843,16 @@ static int prot_verify_write(struct scsi_cmnd *SCpnt, sector_t start_sec,
1819 goto out; 1843 goto out;
1820 } 1844 }
1821 1845
1846 if (scsi_debug_dif == SD_DIF_TYPE2_PROTECTION &&
1847 be32_to_cpu(sdt->ref_tag) != ei_lba) {
1848 printk(KERN_ERR
1849 "%s: REF check failed on sector %lu\n",
1850 __func__, (unsigned long)sector);
1851 ret = 0x03;
1852 dump_sector(daddr, scsi_debug_sector_size);
1853 goto out;
1854 }
1855
1822 /* Would be great to copy this in bigger 1856 /* Would be great to copy this in bigger
1823 * chunks. However, for the sake of 1857 * chunks. However, for the sake of
1824 * correctness we need to verify each sector 1858 * correctness we need to verify each sector
@@ -1832,6 +1866,7 @@ static int prot_verify_write(struct scsi_cmnd *SCpnt, sector_t start_sec,
1832 sector = 0; /* Force wrap */ 1866 sector = 0; /* Force wrap */
1833 1867
1834 start_sec++; 1868 start_sec++;
1869 ei_lba++;
1835 daddr += scsi_debug_sector_size; 1870 daddr += scsi_debug_sector_size;
1836 ppage_offset += sizeof(struct sd_dif_tuple); 1871 ppage_offset += sizeof(struct sd_dif_tuple);
1837 } 1872 }
@@ -1853,7 +1888,8 @@ out:
1853} 1888}
1854 1889
1855static int resp_write(struct scsi_cmnd *SCpnt, unsigned long long lba, 1890static int resp_write(struct scsi_cmnd *SCpnt, unsigned long long lba,
1856 unsigned int num, struct sdebug_dev_info *devip) 1891 unsigned int num, struct sdebug_dev_info *devip,
1892 u32 ei_lba)
1857{ 1893{
1858 unsigned long iflags; 1894 unsigned long iflags;
1859 int ret; 1895 int ret;
@@ -1864,7 +1900,7 @@ static int resp_write(struct scsi_cmnd *SCpnt, unsigned long long lba,
1864 1900
1865 /* DIX + T10 DIF */ 1901 /* DIX + T10 DIF */
1866 if (scsi_debug_dix && scsi_prot_sg_count(SCpnt)) { 1902 if (scsi_debug_dix && scsi_prot_sg_count(SCpnt)) {
1867 int prot_ret = prot_verify_write(SCpnt, lba, num); 1903 int prot_ret = prot_verify_write(SCpnt, lba, num, ei_lba);
1868 1904
1869 if (prot_ret) { 1905 if (prot_ret) {
1870 mk_sense_buffer(devip, ILLEGAL_REQUEST, 0x10, prot_ret); 1906 mk_sense_buffer(devip, ILLEGAL_REQUEST, 0x10, prot_ret);
@@ -2872,11 +2908,12 @@ static int __init scsi_debug_init(void)
2872 2908
2873 case SD_DIF_TYPE0_PROTECTION: 2909 case SD_DIF_TYPE0_PROTECTION:
2874 case SD_DIF_TYPE1_PROTECTION: 2910 case SD_DIF_TYPE1_PROTECTION:
2911 case SD_DIF_TYPE2_PROTECTION:
2875 case SD_DIF_TYPE3_PROTECTION: 2912 case SD_DIF_TYPE3_PROTECTION:
2876 break; 2913 break;
2877 2914
2878 default: 2915 default:
2879 printk(KERN_ERR "scsi_debug_init: dif must be 0, 1 or 3\n"); 2916 printk(KERN_ERR "scsi_debug_init: dif must be 0, 1, 2 or 3\n");
2880 return -EINVAL; 2917 return -EINVAL;
2881 } 2918 }
2882 2919
@@ -3121,6 +3158,7 @@ int scsi_debug_queuecommand(struct scsi_cmnd *SCpnt, done_funct_t done)
3121 int len, k; 3158 int len, k;
3122 unsigned int num; 3159 unsigned int num;
3123 unsigned long long lba; 3160 unsigned long long lba;
3161 u32 ei_lba;
3124 int errsts = 0; 3162 int errsts = 0;
3125 int target = SCpnt->device->id; 3163 int target = SCpnt->device->id;
3126 struct sdebug_dev_info *devip = NULL; 3164 struct sdebug_dev_info *devip = NULL;
@@ -3254,14 +3292,30 @@ int scsi_debug_queuecommand(struct scsi_cmnd *SCpnt, done_funct_t done)
3254 case READ_16: 3292 case READ_16:
3255 case READ_12: 3293 case READ_12:
3256 case READ_10: 3294 case READ_10:
3295 /* READ{10,12,16} and DIF Type 2 are natural enemies */
3296 if (scsi_debug_dif == SD_DIF_TYPE2_PROTECTION &&
3297 cmd[1] & 0xe0) {
3298 mk_sense_buffer(devip, ILLEGAL_REQUEST,
3299 INVALID_COMMAND_OPCODE, 0);
3300 errsts = check_condition_result;
3301 break;
3302 }
3303
3304 if ((scsi_debug_dif == SD_DIF_TYPE1_PROTECTION ||
3305 scsi_debug_dif == SD_DIF_TYPE3_PROTECTION) &&
3306 (cmd[1] & 0xe0) == 0)
3307 printk(KERN_ERR "Unprotected RD/WR to DIF device\n");
3308
3309 /* fall through */
3257 case READ_6: 3310 case READ_6:
3311read:
3258 errsts = check_readiness(SCpnt, 0, devip); 3312 errsts = check_readiness(SCpnt, 0, devip);
3259 if (errsts) 3313 if (errsts)
3260 break; 3314 break;
3261 if (scsi_debug_fake_rw) 3315 if (scsi_debug_fake_rw)
3262 break; 3316 break;
3263 get_data_transfer_info(cmd, &lba, &num); 3317 get_data_transfer_info(cmd, &lba, &num, &ei_lba);
3264 errsts = resp_read(SCpnt, lba, num, devip); 3318 errsts = resp_read(SCpnt, lba, num, devip, ei_lba);
3265 if (inj_recovered && (0 == errsts)) { 3319 if (inj_recovered && (0 == errsts)) {
3266 mk_sense_buffer(devip, RECOVERED_ERROR, 3320 mk_sense_buffer(devip, RECOVERED_ERROR,
3267 THRESHOLD_EXCEEDED, 0); 3321 THRESHOLD_EXCEEDED, 0);
@@ -3288,14 +3342,30 @@ int scsi_debug_queuecommand(struct scsi_cmnd *SCpnt, done_funct_t done)
3288 case WRITE_16: 3342 case WRITE_16:
3289 case WRITE_12: 3343 case WRITE_12:
3290 case WRITE_10: 3344 case WRITE_10:
3345 /* WRITE{10,12,16} and DIF Type 2 are natural enemies */
3346 if (scsi_debug_dif == SD_DIF_TYPE2_PROTECTION &&
3347 cmd[1] & 0xe0) {
3348 mk_sense_buffer(devip, ILLEGAL_REQUEST,
3349 INVALID_COMMAND_OPCODE, 0);
3350 errsts = check_condition_result;
3351 break;
3352 }
3353
3354 if ((scsi_debug_dif == SD_DIF_TYPE1_PROTECTION ||
3355 scsi_debug_dif == SD_DIF_TYPE3_PROTECTION) &&
3356 (cmd[1] & 0xe0) == 0)
3357 printk(KERN_ERR "Unprotected RD/WR to DIF device\n");
3358
3359 /* fall through */
3291 case WRITE_6: 3360 case WRITE_6:
3361write:
3292 errsts = check_readiness(SCpnt, 0, devip); 3362 errsts = check_readiness(SCpnt, 0, devip);
3293 if (errsts) 3363 if (errsts)
3294 break; 3364 break;
3295 if (scsi_debug_fake_rw) 3365 if (scsi_debug_fake_rw)
3296 break; 3366 break;
3297 get_data_transfer_info(cmd, &lba, &num); 3367 get_data_transfer_info(cmd, &lba, &num, &ei_lba);
3298 errsts = resp_write(SCpnt, lba, num, devip); 3368 errsts = resp_write(SCpnt, lba, num, devip, ei_lba);
3299 if (inj_recovered && (0 == errsts)) { 3369 if (inj_recovered && (0 == errsts)) {
3300 mk_sense_buffer(devip, RECOVERED_ERROR, 3370 mk_sense_buffer(devip, RECOVERED_ERROR,
3301 THRESHOLD_EXCEEDED, 0); 3371 THRESHOLD_EXCEEDED, 0);
@@ -3341,15 +3411,38 @@ int scsi_debug_queuecommand(struct scsi_cmnd *SCpnt, done_funct_t done)
3341 break; 3411 break;
3342 if (scsi_debug_fake_rw) 3412 if (scsi_debug_fake_rw)
3343 break; 3413 break;
3344 get_data_transfer_info(cmd, &lba, &num); 3414 get_data_transfer_info(cmd, &lba, &num, &ei_lba);
3345 errsts = resp_read(SCpnt, lba, num, devip); 3415 errsts = resp_read(SCpnt, lba, num, devip, ei_lba);
3346 if (errsts) 3416 if (errsts)
3347 break; 3417 break;
3348 errsts = resp_write(SCpnt, lba, num, devip); 3418 errsts = resp_write(SCpnt, lba, num, devip, ei_lba);
3349 if (errsts) 3419 if (errsts)
3350 break; 3420 break;
3351 errsts = resp_xdwriteread(SCpnt, lba, num, devip); 3421 errsts = resp_xdwriteread(SCpnt, lba, num, devip);
3352 break; 3422 break;
3423 case VARIABLE_LENGTH_CMD:
3424 if (scsi_debug_dif == SD_DIF_TYPE2_PROTECTION) {
3425
3426 if ((cmd[10] & 0xe0) == 0)
3427 printk(KERN_ERR
3428 "Unprotected RD/WR to DIF device\n");
3429
3430 if (cmd[9] == READ_32) {
3431 BUG_ON(SCpnt->cmd_len < 32);
3432 goto read;
3433 }
3434
3435 if (cmd[9] == WRITE_32) {
3436 BUG_ON(SCpnt->cmd_len < 32);
3437 goto write;
3438 }
3439 }
3440
3441 mk_sense_buffer(devip, ILLEGAL_REQUEST,
3442 INVALID_FIELD_IN_CDB, 0);
3443 errsts = check_condition_result;
3444 break;
3445
3353 default: 3446 default:
3354 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) 3447 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
3355 printk(KERN_INFO "scsi_debug: Opcode: 0x%x not " 3448 printk(KERN_INFO "scsi_debug: Opcode: 0x%x not "
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 877204daf549..1b0060b791e8 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -725,6 +725,9 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd,
725 case NEEDS_RETRY: 725 case NEEDS_RETRY:
726 case FAILED: 726 case FAILED:
727 break; 727 break;
728 case ADD_TO_MLQUEUE:
729 rtn = NEEDS_RETRY;
730 break;
728 default: 731 default:
729 rtn = FAILED; 732 rtn = FAILED;
730 break; 733 break;
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index b98885de6876..a67fed10598a 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -3586,6 +3586,7 @@ enum fc_dispatch_result {
3586 3586
3587/** 3587/**
3588 * fc_bsg_host_dispatch - process fc host bsg requests and dispatch to LLDD 3588 * fc_bsg_host_dispatch - process fc host bsg requests and dispatch to LLDD
3589 * @q: fc host request queue
3589 * @shost: scsi host rport attached to 3590 * @shost: scsi host rport attached to
3590 * @job: bsg job to be processed 3591 * @job: bsg job to be processed
3591 */ 3592 */
@@ -3693,6 +3694,7 @@ fc_bsg_goose_queue(struct fc_rport *rport)
3693 3694
3694/** 3695/**
3695 * fc_bsg_rport_dispatch - process rport bsg requests and dispatch to LLDD 3696 * fc_bsg_rport_dispatch - process rport bsg requests and dispatch to LLDD
3697 * @q: rport request queue
3696 * @shost: scsi host rport attached to 3698 * @shost: scsi host rport attached to
3697 * @rport: rport request destined to 3699 * @rport: rport request destined to
3698 * @job: bsg job to be processed 3700 * @job: bsg job to be processed
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 8dd96dcd716c..9093c7261f33 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -116,6 +116,9 @@ static DEFINE_IDA(sd_index_ida);
116 * object after last put) */ 116 * object after last put) */
117static DEFINE_MUTEX(sd_ref_mutex); 117static DEFINE_MUTEX(sd_ref_mutex);
118 118
119struct kmem_cache *sd_cdb_cache;
120mempool_t *sd_cdb_pool;
121
119static const char *sd_cache_types[] = { 122static const char *sd_cache_types[] = {
120 "write through", "none", "write back", 123 "write through", "none", "write back",
121 "write back, no read (daft)" 124 "write back, no read (daft)"
@@ -370,6 +373,31 @@ static void scsi_disk_put(struct scsi_disk *sdkp)
370 mutex_unlock(&sd_ref_mutex); 373 mutex_unlock(&sd_ref_mutex);
371} 374}
372 375
376static void sd_prot_op(struct scsi_cmnd *scmd, unsigned int dif)
377{
378 unsigned int prot_op = SCSI_PROT_NORMAL;
379 unsigned int dix = scsi_prot_sg_count(scmd);
380
381 if (scmd->sc_data_direction == DMA_FROM_DEVICE) {
382 if (dif && dix)
383 prot_op = SCSI_PROT_READ_PASS;
384 else if (dif && !dix)
385 prot_op = SCSI_PROT_READ_STRIP;
386 else if (!dif && dix)
387 prot_op = SCSI_PROT_READ_INSERT;
388 } else {
389 if (dif && dix)
390 prot_op = SCSI_PROT_WRITE_PASS;
391 else if (dif && !dix)
392 prot_op = SCSI_PROT_WRITE_INSERT;
393 else if (!dif && dix)
394 prot_op = SCSI_PROT_WRITE_STRIP;
395 }
396
397 scsi_set_prot_op(scmd, prot_op);
398 scsi_set_prot_type(scmd, dif);
399}
400
373/** 401/**
374 * sd_init_command - build a scsi (read or write) command from 402 * sd_init_command - build a scsi (read or write) command from
375 * information in the request structure. 403 * information in the request structure.
@@ -388,6 +416,7 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq)
388 sector_t threshold; 416 sector_t threshold;
389 unsigned int this_count = blk_rq_sectors(rq); 417 unsigned int this_count = blk_rq_sectors(rq);
390 int ret, host_dif; 418 int ret, host_dif;
419 unsigned char protect;
391 420
392 if (rq->cmd_type == REQ_TYPE_BLOCK_PC) { 421 if (rq->cmd_type == REQ_TYPE_BLOCK_PC) {
393 ret = scsi_setup_blk_pc_cmnd(sdp, rq); 422 ret = scsi_setup_blk_pc_cmnd(sdp, rq);
@@ -520,13 +549,49 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq)
520 /* Set RDPROTECT/WRPROTECT if disk is formatted with DIF */ 549 /* Set RDPROTECT/WRPROTECT if disk is formatted with DIF */
521 host_dif = scsi_host_dif_capable(sdp->host, sdkp->protection_type); 550 host_dif = scsi_host_dif_capable(sdp->host, sdkp->protection_type);
522 if (host_dif) 551 if (host_dif)
523 SCpnt->cmnd[1] = 1 << 5; 552 protect = 1 << 5;
524 else 553 else
525 SCpnt->cmnd[1] = 0; 554 protect = 0;
526 555
527 if (block > 0xffffffff) { 556 if (host_dif == SD_DIF_TYPE2_PROTECTION) {
557 SCpnt->cmnd = mempool_alloc(sd_cdb_pool, GFP_ATOMIC);
558
559 if (unlikely(SCpnt->cmnd == NULL)) {
560 ret = BLKPREP_DEFER;
561 goto out;
562 }
563
564 SCpnt->cmd_len = SD_EXT_CDB_SIZE;
565 memset(SCpnt->cmnd, 0, SCpnt->cmd_len);
566 SCpnt->cmnd[0] = VARIABLE_LENGTH_CMD;
567 SCpnt->cmnd[7] = 0x18;
568 SCpnt->cmnd[9] = (rq_data_dir(rq) == READ) ? READ_32 : WRITE_32;
569 SCpnt->cmnd[10] = protect | (blk_fua_rq(rq) ? 0x8 : 0);
570
571 /* LBA */
572 SCpnt->cmnd[12] = sizeof(block) > 4 ? (unsigned char) (block >> 56) & 0xff : 0;
573 SCpnt->cmnd[13] = sizeof(block) > 4 ? (unsigned char) (block >> 48) & 0xff : 0;
574 SCpnt->cmnd[14] = sizeof(block) > 4 ? (unsigned char) (block >> 40) & 0xff : 0;
575 SCpnt->cmnd[15] = sizeof(block) > 4 ? (unsigned char) (block >> 32) & 0xff : 0;
576 SCpnt->cmnd[16] = (unsigned char) (block >> 24) & 0xff;
577 SCpnt->cmnd[17] = (unsigned char) (block >> 16) & 0xff;
578 SCpnt->cmnd[18] = (unsigned char) (block >> 8) & 0xff;
579 SCpnt->cmnd[19] = (unsigned char) block & 0xff;
580
581 /* Expected Indirect LBA */
582 SCpnt->cmnd[20] = (unsigned char) (block >> 24) & 0xff;
583 SCpnt->cmnd[21] = (unsigned char) (block >> 16) & 0xff;
584 SCpnt->cmnd[22] = (unsigned char) (block >> 8) & 0xff;
585 SCpnt->cmnd[23] = (unsigned char) block & 0xff;
586
587 /* Transfer length */
588 SCpnt->cmnd[28] = (unsigned char) (this_count >> 24) & 0xff;
589 SCpnt->cmnd[29] = (unsigned char) (this_count >> 16) & 0xff;
590 SCpnt->cmnd[30] = (unsigned char) (this_count >> 8) & 0xff;
591 SCpnt->cmnd[31] = (unsigned char) this_count & 0xff;
592 } else if (block > 0xffffffff) {
528 SCpnt->cmnd[0] += READ_16 - READ_6; 593 SCpnt->cmnd[0] += READ_16 - READ_6;
529 SCpnt->cmnd[1] |= blk_fua_rq(rq) ? 0x8 : 0; 594 SCpnt->cmnd[1] = protect | (blk_fua_rq(rq) ? 0x8 : 0);
530 SCpnt->cmnd[2] = sizeof(block) > 4 ? (unsigned char) (block >> 56) & 0xff : 0; 595 SCpnt->cmnd[2] = sizeof(block) > 4 ? (unsigned char) (block >> 56) & 0xff : 0;
531 SCpnt->cmnd[3] = sizeof(block) > 4 ? (unsigned char) (block >> 48) & 0xff : 0; 596 SCpnt->cmnd[3] = sizeof(block) > 4 ? (unsigned char) (block >> 48) & 0xff : 0;
532 SCpnt->cmnd[4] = sizeof(block) > 4 ? (unsigned char) (block >> 40) & 0xff : 0; 597 SCpnt->cmnd[4] = sizeof(block) > 4 ? (unsigned char) (block >> 40) & 0xff : 0;
@@ -547,7 +612,7 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq)
547 this_count = 0xffff; 612 this_count = 0xffff;
548 613
549 SCpnt->cmnd[0] += READ_10 - READ_6; 614 SCpnt->cmnd[0] += READ_10 - READ_6;
550 SCpnt->cmnd[1] |= blk_fua_rq(rq) ? 0x8 : 0; 615 SCpnt->cmnd[1] = protect | (blk_fua_rq(rq) ? 0x8 : 0);
551 SCpnt->cmnd[2] = (unsigned char) (block >> 24) & 0xff; 616 SCpnt->cmnd[2] = (unsigned char) (block >> 24) & 0xff;
552 SCpnt->cmnd[3] = (unsigned char) (block >> 16) & 0xff; 617 SCpnt->cmnd[3] = (unsigned char) (block >> 16) & 0xff;
553 SCpnt->cmnd[4] = (unsigned char) (block >> 8) & 0xff; 618 SCpnt->cmnd[4] = (unsigned char) (block >> 8) & 0xff;
@@ -578,8 +643,7 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq)
578 643
579 /* If DIF or DIX is enabled, tell HBA how to handle request */ 644 /* If DIF or DIX is enabled, tell HBA how to handle request */
580 if (host_dif || scsi_prot_sg_count(SCpnt)) 645 if (host_dif || scsi_prot_sg_count(SCpnt))
581 sd_dif_op(SCpnt, host_dif, scsi_prot_sg_count(SCpnt), 646 sd_prot_op(SCpnt, host_dif);
582 sdkp->protection_type);
583 647
584 /* 648 /*
585 * We shouldn't disconnect in the middle of a sector, so with a dumb 649 * We shouldn't disconnect in the middle of a sector, so with a dumb
@@ -1023,6 +1087,7 @@ static int sd_done(struct scsi_cmnd *SCpnt)
1023 int result = SCpnt->result; 1087 int result = SCpnt->result;
1024 unsigned int good_bytes = result ? 0 : scsi_bufflen(SCpnt); 1088 unsigned int good_bytes = result ? 0 : scsi_bufflen(SCpnt);
1025 struct scsi_sense_hdr sshdr; 1089 struct scsi_sense_hdr sshdr;
1090 struct scsi_disk *sdkp = scsi_disk(SCpnt->request->rq_disk);
1026 int sense_valid = 0; 1091 int sense_valid = 0;
1027 int sense_deferred = 0; 1092 int sense_deferred = 0;
1028 1093
@@ -1084,6 +1149,10 @@ static int sd_done(struct scsi_cmnd *SCpnt)
1084 if (rq_data_dir(SCpnt->request) == READ && scsi_prot_sg_count(SCpnt)) 1149 if (rq_data_dir(SCpnt->request) == READ && scsi_prot_sg_count(SCpnt))
1085 sd_dif_complete(SCpnt, good_bytes); 1150 sd_dif_complete(SCpnt, good_bytes);
1086 1151
1152 if (scsi_host_dif_capable(sdkp->device->host, sdkp->protection_type)
1153 == SD_DIF_TYPE2_PROTECTION && SCpnt->cmnd != SCpnt->request->cmd)
1154 mempool_free(SCpnt->cmnd, sd_cdb_pool);
1155
1087 return good_bytes; 1156 return good_bytes;
1088} 1157}
1089 1158
@@ -1238,34 +1307,28 @@ void sd_read_protection_type(struct scsi_disk *sdkp, unsigned char *buffer)
1238 u8 type; 1307 u8 type;
1239 1308
1240 if (scsi_device_protection(sdp) == 0 || (buffer[12] & 1) == 0) 1309 if (scsi_device_protection(sdp) == 0 || (buffer[12] & 1) == 0)
1241 type = 0; 1310 return;
1242 else
1243 type = ((buffer[12] >> 1) & 7) + 1; /* P_TYPE 0 = Type 1 */
1244 1311
1245 sdkp->protection_type = type; 1312 type = ((buffer[12] >> 1) & 7) + 1; /* P_TYPE 0 = Type 1 */
1246 1313
1247 switch (type) { 1314 if (type == sdkp->protection_type || !sdkp->first_scan)
1248 case SD_DIF_TYPE0_PROTECTION: 1315 return;
1249 case SD_DIF_TYPE1_PROTECTION:
1250 case SD_DIF_TYPE3_PROTECTION:
1251 break;
1252 1316
1253 case SD_DIF_TYPE2_PROTECTION: 1317 sdkp->protection_type = type;
1254 sd_printk(KERN_ERR, sdkp, "formatted with DIF Type 2 " \
1255 "protection which is currently unsupported. " \
1256 "Disabling disk!\n");
1257 goto disable;
1258 1318
1259 default: 1319 if (type > SD_DIF_TYPE3_PROTECTION) {
1260 sd_printk(KERN_ERR, sdkp, "formatted with unknown " \ 1320 sd_printk(KERN_ERR, sdkp, "formatted with unsupported " \
1261 "protection type %d. Disabling disk!\n", type); 1321 "protection type %u. Disabling disk!\n", type);
1262 goto disable; 1322 sdkp->capacity = 0;
1323 return;
1263 } 1324 }
1264 1325
1265 return; 1326 if (scsi_host_dif_capable(sdp->host, type))
1266 1327 sd_printk(KERN_NOTICE, sdkp,
1267disable: 1328 "Enabling DIF Type %u protection\n", type);
1268 sdkp->capacity = 0; 1329 else
1330 sd_printk(KERN_NOTICE, sdkp,
1331 "Disabling DIF Type %u protection\n", type);
1269} 1332}
1270 1333
1271static void read_capacity_error(struct scsi_disk *sdkp, struct scsi_device *sdp, 1334static void read_capacity_error(struct scsi_disk *sdkp, struct scsi_device *sdp,
@@ -2300,8 +2363,24 @@ static int __init init_sd(void)
2300 if (err) 2363 if (err)
2301 goto err_out_class; 2364 goto err_out_class;
2302 2365
2366 sd_cdb_cache = kmem_cache_create("sd_ext_cdb", SD_EXT_CDB_SIZE,
2367 0, 0, NULL);
2368 if (!sd_cdb_cache) {
2369 printk(KERN_ERR "sd: can't init extended cdb cache\n");
2370 goto err_out_class;
2371 }
2372
2373 sd_cdb_pool = mempool_create_slab_pool(SD_MEMPOOL_SIZE, sd_cdb_cache);
2374 if (!sd_cdb_pool) {
2375 printk(KERN_ERR "sd: can't init extended cdb pool\n");
2376 goto err_out_cache;
2377 }
2378
2303 return 0; 2379 return 0;
2304 2380
2381err_out_cache:
2382 kmem_cache_destroy(sd_cdb_cache);
2383
2305err_out_class: 2384err_out_class:
2306 class_unregister(&sd_disk_class); 2385 class_unregister(&sd_disk_class);
2307err_out: 2386err_out:
@@ -2321,6 +2400,9 @@ static void __exit exit_sd(void)
2321 2400
2322 SCSI_LOG_HLQUEUE(3, printk("exit_sd: exiting sd driver\n")); 2401 SCSI_LOG_HLQUEUE(3, printk("exit_sd: exiting sd driver\n"));
2323 2402
2403 mempool_destroy(sd_cdb_pool);
2404 kmem_cache_destroy(sd_cdb_cache);
2405
2324 scsi_unregister_driver(&sd_template.gendrv); 2406 scsi_unregister_driver(&sd_template.gendrv);
2325 class_unregister(&sd_disk_class); 2407 class_unregister(&sd_disk_class);
2326 2408
diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h
index 8474b5bad3fe..e374804d26fb 100644
--- a/drivers/scsi/sd.h
+++ b/drivers/scsi/sd.h
@@ -37,6 +37,11 @@
37 */ 37 */
38#define SD_LAST_BUGGY_SECTORS 8 38#define SD_LAST_BUGGY_SECTORS 8
39 39
40enum {
41 SD_EXT_CDB_SIZE = 32, /* Extended CDB size */
42 SD_MEMPOOL_SIZE = 2, /* CDB pool size */
43};
44
40struct scsi_disk { 45struct scsi_disk {
41 struct scsi_driver *driver; /* always &sd_template */ 46 struct scsi_driver *driver; /* always &sd_template */
42 struct scsi_device *device; 47 struct scsi_device *device;
@@ -101,16 +106,12 @@ struct sd_dif_tuple {
101 106
102#ifdef CONFIG_BLK_DEV_INTEGRITY 107#ifdef CONFIG_BLK_DEV_INTEGRITY
103 108
104extern void sd_dif_op(struct scsi_cmnd *, unsigned int, unsigned int, unsigned int);
105extern void sd_dif_config_host(struct scsi_disk *); 109extern void sd_dif_config_host(struct scsi_disk *);
106extern int sd_dif_prepare(struct request *rq, sector_t, unsigned int); 110extern int sd_dif_prepare(struct request *rq, sector_t, unsigned int);
107extern void sd_dif_complete(struct scsi_cmnd *, unsigned int); 111extern void sd_dif_complete(struct scsi_cmnd *, unsigned int);
108 112
109#else /* CONFIG_BLK_DEV_INTEGRITY */ 113#else /* CONFIG_BLK_DEV_INTEGRITY */
110 114
111static inline void sd_dif_op(struct scsi_cmnd *cmd, unsigned int a, unsigned int b, unsigned int c)
112{
113}
114static inline void sd_dif_config_host(struct scsi_disk *disk) 115static inline void sd_dif_config_host(struct scsi_disk *disk)
115{ 116{
116} 117}
diff --git a/drivers/scsi/sd_dif.c b/drivers/scsi/sd_dif.c
index 82f14a9482d0..88da97745710 100644
--- a/drivers/scsi/sd_dif.c
+++ b/drivers/scsi/sd_dif.c
@@ -320,15 +320,6 @@ void sd_dif_config_host(struct scsi_disk *sdkp)
320 dif = 0; dix = 1; 320 dif = 0; dix = 1;
321 } 321 }
322 322
323 if (type) {
324 if (dif)
325 sd_printk(KERN_NOTICE, sdkp,
326 "Enabling DIF Type %d protection\n", type);
327 else
328 sd_printk(KERN_NOTICE, sdkp,
329 "Disabling DIF Type %d protection\n", type);
330 }
331
332 if (!dix) 323 if (!dix)
333 return; 324 return;
334 325
@@ -360,62 +351,6 @@ void sd_dif_config_host(struct scsi_disk *sdkp)
360} 351}
361 352
362/* 353/*
363 * DIF DMA operation magic decoder ring.
364 */
365void sd_dif_op(struct scsi_cmnd *scmd, unsigned int dif, unsigned int dix, unsigned int type)
366{
367 int csum_convert, prot_op;
368
369 prot_op = 0;
370
371 /* Convert checksum? */
372 if (scsi_host_get_guard(scmd->device->host) != SHOST_DIX_GUARD_CRC)
373 csum_convert = 1;
374 else
375 csum_convert = 0;
376
377 BUG_ON(dif && (scmd->cmnd[0] == READ_6 || scmd->cmnd[0] == WRITE_6));
378
379 switch (scmd->cmnd[0]) {
380 case READ_6:
381 case READ_10:
382 case READ_12:
383 case READ_16:
384 if (dif && dix)
385 if (csum_convert)
386 prot_op = SCSI_PROT_READ_CONVERT;
387 else
388 prot_op = SCSI_PROT_READ_PASS;
389 else if (dif && !dix)
390 prot_op = SCSI_PROT_READ_STRIP;
391 else if (!dif && dix)
392 prot_op = SCSI_PROT_READ_INSERT;
393
394 break;
395
396 case WRITE_6:
397 case WRITE_10:
398 case WRITE_12:
399 case WRITE_16:
400 if (dif && dix)
401 if (csum_convert)
402 prot_op = SCSI_PROT_WRITE_CONVERT;
403 else
404 prot_op = SCSI_PROT_WRITE_PASS;
405 else if (dif && !dix)
406 prot_op = SCSI_PROT_WRITE_INSERT;
407 else if (!dif && dix)
408 prot_op = SCSI_PROT_WRITE_STRIP;
409
410 break;
411 }
412
413 scsi_set_prot_op(scmd, prot_op);
414 if (dif)
415 scsi_set_prot_type(scmd, type);
416}
417
418/*
419 * The virtual start sector is the one that was originally submitted 354 * The virtual start sector is the one that was originally submitted
420 * by the block layer. Due to partitioning, MD/DM cloning, etc. the 355 * by the block layer. Due to partitioning, MD/DM cloning, etc. the
421 * actual physical start sector is likely to be different. Remap 356 * actual physical start sector is likely to be different. Remap
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 0cb049f5cc56..040f751809ea 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1317,7 +1317,7 @@ static void sg_rq_end_io(struct request *rq, int uptodate)
1317 } 1317 }
1318} 1318}
1319 1319
1320static struct file_operations sg_fops = { 1320static const struct file_operations sg_fops = {
1321 .owner = THIS_MODULE, 1321 .owner = THIS_MODULE,
1322 .read = sg_read, 1322 .read = sg_read,
1323 .write = sg_write, 1323 .write = sg_write,
@@ -1708,11 +1708,6 @@ static int sg_finish_rem_req(Sg_request * srp)
1708 Sg_scatter_hold *req_schp = &srp->data; 1708 Sg_scatter_hold *req_schp = &srp->data;
1709 1709
1710 SCSI_LOG_TIMEOUT(4, printk("sg_finish_rem_req: res_used=%d\n", (int) srp->res_used)); 1710 SCSI_LOG_TIMEOUT(4, printk("sg_finish_rem_req: res_used=%d\n", (int) srp->res_used));
1711 if (srp->res_used)
1712 sg_unlink_reserve(sfp, srp);
1713 else
1714 sg_remove_scat(req_schp);
1715
1716 if (srp->rq) { 1711 if (srp->rq) {
1717 if (srp->bio) 1712 if (srp->bio)
1718 ret = blk_rq_unmap_user(srp->bio); 1713 ret = blk_rq_unmap_user(srp->bio);
@@ -1720,6 +1715,11 @@ static int sg_finish_rem_req(Sg_request * srp)
1720 blk_put_request(srp->rq); 1715 blk_put_request(srp->rq);
1721 } 1716 }
1722 1717
1718 if (srp->res_used)
1719 sg_unlink_reserve(sfp, srp);
1720 else
1721 sg_remove_scat(req_schp);
1722
1723 sg_remove_request(sfp, srp); 1723 sg_remove_request(sfp, srp);
1724 1724
1725 return ret; 1725 return ret;
@@ -2194,9 +2194,11 @@ static int sg_proc_seq_show_int(struct seq_file *s, void *v);
2194static int sg_proc_single_open_adio(struct inode *inode, struct file *file); 2194static int sg_proc_single_open_adio(struct inode *inode, struct file *file);
2195static ssize_t sg_proc_write_adio(struct file *filp, const char __user *buffer, 2195static ssize_t sg_proc_write_adio(struct file *filp, const char __user *buffer,
2196 size_t count, loff_t *off); 2196 size_t count, loff_t *off);
2197static struct file_operations adio_fops = { 2197static const struct file_operations adio_fops = {
2198 /* .owner, .read and .llseek added in sg_proc_init() */ 2198 .owner = THIS_MODULE,
2199 .open = sg_proc_single_open_adio, 2199 .open = sg_proc_single_open_adio,
2200 .read = seq_read,
2201 .llseek = seq_lseek,
2200 .write = sg_proc_write_adio, 2202 .write = sg_proc_write_adio,
2201 .release = single_release, 2203 .release = single_release,
2202}; 2204};
@@ -2204,23 +2206,32 @@ static struct file_operations adio_fops = {
2204static int sg_proc_single_open_dressz(struct inode *inode, struct file *file); 2206static int sg_proc_single_open_dressz(struct inode *inode, struct file *file);
2205static ssize_t sg_proc_write_dressz(struct file *filp, 2207static ssize_t sg_proc_write_dressz(struct file *filp,
2206 const char __user *buffer, size_t count, loff_t *off); 2208 const char __user *buffer, size_t count, loff_t *off);
2207static struct file_operations dressz_fops = { 2209static const struct file_operations dressz_fops = {
2210 .owner = THIS_MODULE,
2208 .open = sg_proc_single_open_dressz, 2211 .open = sg_proc_single_open_dressz,
2212 .read = seq_read,
2213 .llseek = seq_lseek,
2209 .write = sg_proc_write_dressz, 2214 .write = sg_proc_write_dressz,
2210 .release = single_release, 2215 .release = single_release,
2211}; 2216};
2212 2217
2213static int sg_proc_seq_show_version(struct seq_file *s, void *v); 2218static int sg_proc_seq_show_version(struct seq_file *s, void *v);
2214static int sg_proc_single_open_version(struct inode *inode, struct file *file); 2219static int sg_proc_single_open_version(struct inode *inode, struct file *file);
2215static struct file_operations version_fops = { 2220static const struct file_operations version_fops = {
2221 .owner = THIS_MODULE,
2216 .open = sg_proc_single_open_version, 2222 .open = sg_proc_single_open_version,
2223 .read = seq_read,
2224 .llseek = seq_lseek,
2217 .release = single_release, 2225 .release = single_release,
2218}; 2226};
2219 2227
2220static int sg_proc_seq_show_devhdr(struct seq_file *s, void *v); 2228static int sg_proc_seq_show_devhdr(struct seq_file *s, void *v);
2221static int sg_proc_single_open_devhdr(struct inode *inode, struct file *file); 2229static int sg_proc_single_open_devhdr(struct inode *inode, struct file *file);
2222static struct file_operations devhdr_fops = { 2230static const struct file_operations devhdr_fops = {
2231 .owner = THIS_MODULE,
2223 .open = sg_proc_single_open_devhdr, 2232 .open = sg_proc_single_open_devhdr,
2233 .read = seq_read,
2234 .llseek = seq_lseek,
2224 .release = single_release, 2235 .release = single_release,
2225}; 2236};
2226 2237
@@ -2229,8 +2240,11 @@ static int sg_proc_open_dev(struct inode *inode, struct file *file);
2229static void * dev_seq_start(struct seq_file *s, loff_t *pos); 2240static void * dev_seq_start(struct seq_file *s, loff_t *pos);
2230static void * dev_seq_next(struct seq_file *s, void *v, loff_t *pos); 2241static void * dev_seq_next(struct seq_file *s, void *v, loff_t *pos);
2231static void dev_seq_stop(struct seq_file *s, void *v); 2242static void dev_seq_stop(struct seq_file *s, void *v);
2232static struct file_operations dev_fops = { 2243static const struct file_operations dev_fops = {
2244 .owner = THIS_MODULE,
2233 .open = sg_proc_open_dev, 2245 .open = sg_proc_open_dev,
2246 .read = seq_read,
2247 .llseek = seq_lseek,
2234 .release = seq_release, 2248 .release = seq_release,
2235}; 2249};
2236static const struct seq_operations dev_seq_ops = { 2250static const struct seq_operations dev_seq_ops = {
@@ -2242,8 +2256,11 @@ static const struct seq_operations dev_seq_ops = {
2242 2256
2243static int sg_proc_seq_show_devstrs(struct seq_file *s, void *v); 2257static int sg_proc_seq_show_devstrs(struct seq_file *s, void *v);
2244static int sg_proc_open_devstrs(struct inode *inode, struct file *file); 2258static int sg_proc_open_devstrs(struct inode *inode, struct file *file);
2245static struct file_operations devstrs_fops = { 2259static const struct file_operations devstrs_fops = {
2260 .owner = THIS_MODULE,
2246 .open = sg_proc_open_devstrs, 2261 .open = sg_proc_open_devstrs,
2262 .read = seq_read,
2263 .llseek = seq_lseek,
2247 .release = seq_release, 2264 .release = seq_release,
2248}; 2265};
2249static const struct seq_operations devstrs_seq_ops = { 2266static const struct seq_operations devstrs_seq_ops = {
@@ -2255,8 +2272,11 @@ static const struct seq_operations devstrs_seq_ops = {
2255 2272
2256static int sg_proc_seq_show_debug(struct seq_file *s, void *v); 2273static int sg_proc_seq_show_debug(struct seq_file *s, void *v);
2257static int sg_proc_open_debug(struct inode *inode, struct file *file); 2274static int sg_proc_open_debug(struct inode *inode, struct file *file);
2258static struct file_operations debug_fops = { 2275static const struct file_operations debug_fops = {
2276 .owner = THIS_MODULE,
2259 .open = sg_proc_open_debug, 2277 .open = sg_proc_open_debug,
2278 .read = seq_read,
2279 .llseek = seq_lseek,
2260 .release = seq_release, 2280 .release = seq_release,
2261}; 2281};
2262static const struct seq_operations debug_seq_ops = { 2282static const struct seq_operations debug_seq_ops = {
@@ -2269,7 +2289,7 @@ static const struct seq_operations debug_seq_ops = {
2269 2289
2270struct sg_proc_leaf { 2290struct sg_proc_leaf {
2271 const char * name; 2291 const char * name;
2272 struct file_operations * fops; 2292 const struct file_operations * fops;
2273}; 2293};
2274 2294
2275static struct sg_proc_leaf sg_proc_leaf_arr[] = { 2295static struct sg_proc_leaf sg_proc_leaf_arr[] = {
@@ -2295,9 +2315,6 @@ sg_proc_init(void)
2295 for (k = 0; k < num_leaves; ++k) { 2315 for (k = 0; k < num_leaves; ++k) {
2296 leaf = &sg_proc_leaf_arr[k]; 2316 leaf = &sg_proc_leaf_arr[k];
2297 mask = leaf->fops->write ? S_IRUGO | S_IWUSR : S_IRUGO; 2317 mask = leaf->fops->write ? S_IRUGO | S_IWUSR : S_IRUGO;
2298 leaf->fops->owner = THIS_MODULE;
2299 leaf->fops->read = seq_read;
2300 leaf->fops->llseek = seq_lseek;
2301 proc_create(leaf->name, mask, sg_proc_sgp, leaf->fops); 2318 proc_create(leaf->name, mask, sg_proc_sgp, leaf->fops);
2302 } 2319 }
2303 return 0; 2320 return 0;
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index eb61f7a70e1d..d6f340f48a3b 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -684,14 +684,20 @@ static void get_sectorsize(struct scsi_cd *cd)
684 cd->capacity = 0x1fffff; 684 cd->capacity = 0x1fffff;
685 sector_size = 2048; /* A guess, just in case */ 685 sector_size = 2048; /* A guess, just in case */
686 } else { 686 } else {
687#if 0 687 long last_written;
688 if (cdrom_get_last_written(&cd->cdi, 688
689 &cd->capacity)) 689 cd->capacity = 1 + ((buffer[0] << 24) | (buffer[1] << 16) |
690#endif 690 (buffer[2] << 8) | buffer[3]);
691 cd->capacity = 1 + ((buffer[0] << 24) | 691 /*
692 (buffer[1] << 16) | 692 * READ_CAPACITY doesn't return the correct size on
693 (buffer[2] << 8) | 693 * certain UDF media. If last_written is larger, use
694 buffer[3]); 694 * it instead.
695 *
696 * http://bugzilla.kernel.org/show_bug.cgi?id=9668
697 */
698 if (!cdrom_get_last_written(&cd->cdi, &last_written))
699 cd->capacity = max_t(long, cd->capacity, last_written);
700
695 sector_size = (buffer[4] << 24) | 701 sector_size = (buffer[4] << 24) |
696 (buffer[5] << 16) | (buffer[6] << 8) | buffer[7]; 702 (buffer[5] << 16) | (buffer[6] << 8) | buffer[7];
697 switch (sector_size) { 703 switch (sector_size) {
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index b33d04250bbc..12d58a7ed6bc 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -2859,11 +2859,8 @@ static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned lon
2859 ioctl_result = st_int_ioctl(STp, MTBSF, 1); 2859 ioctl_result = st_int_ioctl(STp, MTBSF, 1);
2860 2860
2861 if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) { 2861 if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) {
2862 int old_block_size = STp->block_size;
2863 STp->block_size = arg & MT_ST_BLKSIZE_MASK; 2862 STp->block_size = arg & MT_ST_BLKSIZE_MASK;
2864 if (STp->block_size != 0) { 2863 if (STp->block_size != 0) {
2865 if (old_block_size == 0)
2866 normalize_buffer(STp->buffer);
2867 (STp->buffer)->buffer_blocks = 2864 (STp->buffer)->buffer_blocks =
2868 (STp->buffer)->buffer_size / STp->block_size; 2865 (STp->buffer)->buffer_size / STp->block_size;
2869 } 2866 }
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 2209620d2349..b1ae774016f1 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -64,6 +64,8 @@ static int serial_index(struct uart_port *port)
64 return (serial8250_reg.minor - 64) + port->line; 64 return (serial8250_reg.minor - 64) + port->line;
65} 65}
66 66
67static unsigned int skip_txen_test; /* force skip of txen test at init time */
68
67/* 69/*
68 * Debugging. 70 * Debugging.
69 */ 71 */
@@ -2108,7 +2110,7 @@ static int serial8250_startup(struct uart_port *port)
2108 is variable. So, let's just don't test if we receive 2110 is variable. So, let's just don't test if we receive
2109 TX irq. This way, we'll never enable UART_BUG_TXEN. 2111 TX irq. This way, we'll never enable UART_BUG_TXEN.
2110 */ 2112 */
2111 if (up->port.flags & UPF_NO_TXEN_TEST) 2113 if (skip_txen_test || up->port.flags & UPF_NO_TXEN_TEST)
2112 goto dont_test_tx_en; 2114 goto dont_test_tx_en;
2113 2115
2114 /* 2116 /*
@@ -3248,6 +3250,9 @@ MODULE_PARM_DESC(share_irqs, "Share IRQs with other non-8250/16x50 devices"
3248module_param(nr_uarts, uint, 0644); 3250module_param(nr_uarts, uint, 0644);
3249MODULE_PARM_DESC(nr_uarts, "Maximum number of UARTs supported. (1-" __MODULE_STRING(CONFIG_SERIAL_8250_NR_UARTS) ")"); 3251MODULE_PARM_DESC(nr_uarts, "Maximum number of UARTs supported. (1-" __MODULE_STRING(CONFIG_SERIAL_8250_NR_UARTS) ")");
3250 3252
3253module_param(skip_txen_test, uint, 0644);
3254MODULE_PARM_DESC(skip_txen_test, "Skip checking for the TXEN bug at init time");
3255
3251#ifdef CONFIG_SERIAL_8250_RSA 3256#ifdef CONFIG_SERIAL_8250_RSA
3252module_param_array(probe_rsa, ulong, &probe_rsa_count, 0444); 3257module_param_array(probe_rsa, ulong, &probe_rsa_count, 0444);
3253MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA"); 3258MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA");
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 03422ce878cf..e52257257279 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -862,7 +862,7 @@ config SERIAL_IMX_CONSOLE
862 862
863config SERIAL_UARTLITE 863config SERIAL_UARTLITE
864 tristate "Xilinx uartlite serial port support" 864 tristate "Xilinx uartlite serial port support"
865 depends on PPC32 || MICROBLAZE 865 depends on PPC32 || MICROBLAZE || MFD_TIMBERDALE
866 select SERIAL_CORE 866 select SERIAL_CORE
867 help 867 help
868 Say Y here if you want to use the Xilinx uartlite serial controller. 868 Say Y here if you want to use the Xilinx uartlite serial controller.
@@ -1458,4 +1458,23 @@ config SERIAL_TIMBERDALE
1458 ---help--- 1458 ---help---
1459 Add support for UART controller on timberdale. 1459 Add support for UART controller on timberdale.
1460 1460
1461config SERIAL_BCM63XX
1462 tristate "bcm63xx serial port support"
1463 select SERIAL_CORE
1464 depends on BCM63XX
1465 help
1466 If you have a bcm63xx CPU, you can enable its onboard
1467 serial port by enabling this options.
1468
1469 To compile this driver as a module, choose M here: the
1470 module will be called bcm963xx_uart.
1471
1472config SERIAL_BCM63XX_CONSOLE
1473 bool "Console on bcm63xx serial port"
1474 depends on SERIAL_BCM63XX=y
1475 select SERIAL_CORE_CONSOLE
1476 help
1477 If you have enabled the serial port on the bcm63xx CPU
1478 you can make it the console by answering Y to this option.
1479
1461endmenu 1480endmenu
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 97f6fcc8b432..d21d5dd5d048 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o
34obj-$(CONFIG_SERIAL_PXA) += pxa.o 34obj-$(CONFIG_SERIAL_PXA) += pxa.o
35obj-$(CONFIG_SERIAL_PNX8XXX) += pnx8xxx_uart.o 35obj-$(CONFIG_SERIAL_PNX8XXX) += pnx8xxx_uart.o
36obj-$(CONFIG_SERIAL_SA1100) += sa1100.o 36obj-$(CONFIG_SERIAL_SA1100) += sa1100.o
37obj-$(CONFIG_SERIAL_BCM63XX) += bcm63xx_uart.o
37obj-$(CONFIG_SERIAL_BFIN) += bfin_5xx.o 38obj-$(CONFIG_SERIAL_BFIN) += bfin_5xx.o
38obj-$(CONFIG_SERIAL_BFIN_SPORT) += bfin_sport_uart.o 39obj-$(CONFIG_SERIAL_BFIN_SPORT) += bfin_sport_uart.o
39obj-$(CONFIG_SERIAL_SAMSUNG) += samsung.o 40obj-$(CONFIG_SERIAL_SAMSUNG) += samsung.o
diff --git a/drivers/serial/bcm63xx_uart.c b/drivers/serial/bcm63xx_uart.c
new file mode 100644
index 000000000000..beddaa6e9069
--- /dev/null
+++ b/drivers/serial/bcm63xx_uart.c
@@ -0,0 +1,890 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Derived from many drivers using generic_serial interface.
7 *
8 * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
9 *
10 * Serial driver for BCM63xx integrated UART.
11 *
12 * Hardware flow control was _not_ tested since I only have RX/TX on
13 * my board.
14 */
15
16#if defined(CONFIG_SERIAL_BCM63XX_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
17#define SUPPORT_SYSRQ
18#endif
19
20#include <linux/kernel.h>
21#include <linux/platform_device.h>
22#include <linux/init.h>
23#include <linux/delay.h>
24#include <linux/module.h>
25#include <linux/console.h>
26#include <linux/clk.h>
27#include <linux/tty.h>
28#include <linux/tty_flip.h>
29#include <linux/sysrq.h>
30#include <linux/serial.h>
31#include <linux/serial_core.h>
32
33#include <bcm63xx_clk.h>
34#include <bcm63xx_irq.h>
35#include <bcm63xx_regs.h>
36#include <bcm63xx_io.h>
37
38#define BCM63XX_NR_UARTS 1
39
40static struct uart_port ports[BCM63XX_NR_UARTS];
41
42/*
43 * rx interrupt mask / stat
44 *
45 * mask:
46 * - rx fifo full
47 * - rx fifo above threshold
48 * - rx fifo not empty for too long
49 */
50#define UART_RX_INT_MASK (UART_IR_MASK(UART_IR_RXOVER) | \
51 UART_IR_MASK(UART_IR_RXTHRESH) | \
52 UART_IR_MASK(UART_IR_RXTIMEOUT))
53
54#define UART_RX_INT_STAT (UART_IR_STAT(UART_IR_RXOVER) | \
55 UART_IR_STAT(UART_IR_RXTHRESH) | \
56 UART_IR_STAT(UART_IR_RXTIMEOUT))
57
58/*
59 * tx interrupt mask / stat
60 *
61 * mask:
62 * - tx fifo empty
63 * - tx fifo below threshold
64 */
65#define UART_TX_INT_MASK (UART_IR_MASK(UART_IR_TXEMPTY) | \
66 UART_IR_MASK(UART_IR_TXTRESH))
67
68#define UART_TX_INT_STAT (UART_IR_STAT(UART_IR_TXEMPTY) | \
69 UART_IR_STAT(UART_IR_TXTRESH))
70
71/*
72 * external input interrupt
73 *
74 * mask: any edge on CTS, DCD
75 */
76#define UART_EXTINP_INT_MASK (UART_EXTINP_IRMASK(UART_EXTINP_IR_CTS) | \
77 UART_EXTINP_IRMASK(UART_EXTINP_IR_DCD))
78
79/*
80 * handy uart register accessor
81 */
82static inline unsigned int bcm_uart_readl(struct uart_port *port,
83 unsigned int offset)
84{
85 return bcm_readl(port->membase + offset);
86}
87
88static inline void bcm_uart_writel(struct uart_port *port,
89 unsigned int value, unsigned int offset)
90{
91 bcm_writel(value, port->membase + offset);
92}
93
94/*
95 * serial core request to check if uart tx fifo is empty
96 */
97static unsigned int bcm_uart_tx_empty(struct uart_port *port)
98{
99 unsigned int val;
100
101 val = bcm_uart_readl(port, UART_IR_REG);
102 return (val & UART_IR_STAT(UART_IR_TXEMPTY)) ? 1 : 0;
103}
104
105/*
106 * serial core request to set RTS and DTR pin state and loopback mode
107 */
108static void bcm_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
109{
110 unsigned int val;
111
112 val = bcm_uart_readl(port, UART_MCTL_REG);
113 val &= ~(UART_MCTL_DTR_MASK | UART_MCTL_RTS_MASK);
114 /* invert of written value is reflected on the pin */
115 if (!(mctrl & TIOCM_DTR))
116 val |= UART_MCTL_DTR_MASK;
117 if (!(mctrl & TIOCM_RTS))
118 val |= UART_MCTL_RTS_MASK;
119 bcm_uart_writel(port, val, UART_MCTL_REG);
120
121 val = bcm_uart_readl(port, UART_CTL_REG);
122 if (mctrl & TIOCM_LOOP)
123 val |= UART_CTL_LOOPBACK_MASK;
124 else
125 val &= ~UART_CTL_LOOPBACK_MASK;
126 bcm_uart_writel(port, val, UART_CTL_REG);
127}
128
129/*
130 * serial core request to return RI, CTS, DCD and DSR pin state
131 */
132static unsigned int bcm_uart_get_mctrl(struct uart_port *port)
133{
134 unsigned int val, mctrl;
135
136 mctrl = 0;
137 val = bcm_uart_readl(port, UART_EXTINP_REG);
138 if (val & UART_EXTINP_RI_MASK)
139 mctrl |= TIOCM_RI;
140 if (val & UART_EXTINP_CTS_MASK)
141 mctrl |= TIOCM_CTS;
142 if (val & UART_EXTINP_DCD_MASK)
143 mctrl |= TIOCM_CD;
144 if (val & UART_EXTINP_DSR_MASK)
145 mctrl |= TIOCM_DSR;
146 return mctrl;
147}
148
149/*
150 * serial core request to disable tx ASAP (used for flow control)
151 */
152static void bcm_uart_stop_tx(struct uart_port *port)
153{
154 unsigned int val;
155
156 val = bcm_uart_readl(port, UART_CTL_REG);
157 val &= ~(UART_CTL_TXEN_MASK);
158 bcm_uart_writel(port, val, UART_CTL_REG);
159
160 val = bcm_uart_readl(port, UART_IR_REG);
161 val &= ~UART_TX_INT_MASK;
162 bcm_uart_writel(port, val, UART_IR_REG);
163}
164
165/*
166 * serial core request to (re)enable tx
167 */
168static void bcm_uart_start_tx(struct uart_port *port)
169{
170 unsigned int val;
171
172 val = bcm_uart_readl(port, UART_IR_REG);
173 val |= UART_TX_INT_MASK;
174 bcm_uart_writel(port, val, UART_IR_REG);
175
176 val = bcm_uart_readl(port, UART_CTL_REG);
177 val |= UART_CTL_TXEN_MASK;
178 bcm_uart_writel(port, val, UART_CTL_REG);
179}
180
181/*
182 * serial core request to stop rx, called before port shutdown
183 */
184static void bcm_uart_stop_rx(struct uart_port *port)
185{
186 unsigned int val;
187
188 val = bcm_uart_readl(port, UART_IR_REG);
189 val &= ~UART_RX_INT_MASK;
190 bcm_uart_writel(port, val, UART_IR_REG);
191}
192
193/*
194 * serial core request to enable modem status interrupt reporting
195 */
196static void bcm_uart_enable_ms(struct uart_port *port)
197{
198 unsigned int val;
199
200 val = bcm_uart_readl(port, UART_IR_REG);
201 val |= UART_IR_MASK(UART_IR_EXTIP);
202 bcm_uart_writel(port, val, UART_IR_REG);
203}
204
205/*
206 * serial core request to start/stop emitting break char
207 */
208static void bcm_uart_break_ctl(struct uart_port *port, int ctl)
209{
210 unsigned long flags;
211 unsigned int val;
212
213 spin_lock_irqsave(&port->lock, flags);
214
215 val = bcm_uart_readl(port, UART_CTL_REG);
216 if (ctl)
217 val |= UART_CTL_XMITBRK_MASK;
218 else
219 val &= ~UART_CTL_XMITBRK_MASK;
220 bcm_uart_writel(port, val, UART_CTL_REG);
221
222 spin_unlock_irqrestore(&port->lock, flags);
223}
224
225/*
226 * return port type in string format
227 */
228static const char *bcm_uart_type(struct uart_port *port)
229{
230 return (port->type == PORT_BCM63XX) ? "bcm63xx_uart" : NULL;
231}
232
233/*
234 * read all chars in rx fifo and send them to core
235 */
236static void bcm_uart_do_rx(struct uart_port *port)
237{
238 struct tty_struct *tty;
239 unsigned int max_count;
240
241 /* limit number of char read in interrupt, should not be
242 * higher than fifo size anyway since we're much faster than
243 * serial port */
244 max_count = 32;
245 tty = port->info->port.tty;
246 do {
247 unsigned int iestat, c, cstat;
248 char flag;
249
250 /* get overrun/fifo empty information from ier
251 * register */
252 iestat = bcm_uart_readl(port, UART_IR_REG);
253 if (!(iestat & UART_IR_STAT(UART_IR_RXNOTEMPTY)))
254 break;
255
256 cstat = c = bcm_uart_readl(port, UART_FIFO_REG);
257 port->icount.rx++;
258 flag = TTY_NORMAL;
259 c &= 0xff;
260
261 if (unlikely((cstat & UART_FIFO_ANYERR_MASK))) {
262 /* do stats first */
263 if (cstat & UART_FIFO_BRKDET_MASK) {
264 port->icount.brk++;
265 if (uart_handle_break(port))
266 continue;
267 }
268
269 if (cstat & UART_FIFO_PARERR_MASK)
270 port->icount.parity++;
271 if (cstat & UART_FIFO_FRAMEERR_MASK)
272 port->icount.frame++;
273
274 /* update flag wrt read_status_mask */
275 cstat &= port->read_status_mask;
276 if (cstat & UART_FIFO_BRKDET_MASK)
277 flag = TTY_BREAK;
278 if (cstat & UART_FIFO_FRAMEERR_MASK)
279 flag = TTY_FRAME;
280 if (cstat & UART_FIFO_PARERR_MASK)
281 flag = TTY_PARITY;
282 }
283
284 if (uart_handle_sysrq_char(port, c))
285 continue;
286
287 if (unlikely(iestat & UART_IR_STAT(UART_IR_RXOVER))) {
288 port->icount.overrun++;
289 tty_insert_flip_char(tty, 0, TTY_OVERRUN);
290 }
291
292 if ((cstat & port->ignore_status_mask) == 0)
293 tty_insert_flip_char(tty, c, flag);
294
295 } while (--max_count);
296
297 tty_flip_buffer_push(tty);
298}
299
300/*
301 * fill tx fifo with chars to send, stop when fifo is about to be full
302 * or when all chars have been sent.
303 */
304static void bcm_uart_do_tx(struct uart_port *port)
305{
306 struct circ_buf *xmit;
307 unsigned int val, max_count;
308
309 if (port->x_char) {
310 bcm_uart_writel(port, port->x_char, UART_FIFO_REG);
311 port->icount.tx++;
312 port->x_char = 0;
313 return;
314 }
315
316 if (uart_tx_stopped(port)) {
317 bcm_uart_stop_tx(port);
318 return;
319 }
320
321 xmit = &port->info->xmit;
322 if (uart_circ_empty(xmit))
323 goto txq_empty;
324
325 val = bcm_uart_readl(port, UART_MCTL_REG);
326 val = (val & UART_MCTL_TXFIFOFILL_MASK) >> UART_MCTL_TXFIFOFILL_SHIFT;
327 max_count = port->fifosize - val;
328
329 while (max_count--) {
330 unsigned int c;
331
332 c = xmit->buf[xmit->tail];
333 bcm_uart_writel(port, c, UART_FIFO_REG);
334 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
335 port->icount.tx++;
336 if (uart_circ_empty(xmit))
337 break;
338 }
339
340 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
341 uart_write_wakeup(port);
342
343 if (uart_circ_empty(xmit))
344 goto txq_empty;
345 return;
346
347txq_empty:
348 /* nothing to send, disable transmit interrupt */
349 val = bcm_uart_readl(port, UART_IR_REG);
350 val &= ~UART_TX_INT_MASK;
351 bcm_uart_writel(port, val, UART_IR_REG);
352 return;
353}
354
355/*
356 * process uart interrupt
357 */
358static irqreturn_t bcm_uart_interrupt(int irq, void *dev_id)
359{
360 struct uart_port *port;
361 unsigned int irqstat;
362
363 port = dev_id;
364 spin_lock(&port->lock);
365
366 irqstat = bcm_uart_readl(port, UART_IR_REG);
367 if (irqstat & UART_RX_INT_STAT)
368 bcm_uart_do_rx(port);
369
370 if (irqstat & UART_TX_INT_STAT)
371 bcm_uart_do_tx(port);
372
373 if (irqstat & UART_IR_MASK(UART_IR_EXTIP)) {
374 unsigned int estat;
375
376 estat = bcm_uart_readl(port, UART_EXTINP_REG);
377 if (estat & UART_EXTINP_IRSTAT(UART_EXTINP_IR_CTS))
378 uart_handle_cts_change(port,
379 estat & UART_EXTINP_CTS_MASK);
380 if (estat & UART_EXTINP_IRSTAT(UART_EXTINP_IR_DCD))
381 uart_handle_dcd_change(port,
382 estat & UART_EXTINP_DCD_MASK);
383 }
384
385 spin_unlock(&port->lock);
386 return IRQ_HANDLED;
387}
388
389/*
390 * enable rx & tx operation on uart
391 */
392static void bcm_uart_enable(struct uart_port *port)
393{
394 unsigned int val;
395
396 val = bcm_uart_readl(port, UART_CTL_REG);
397 val |= (UART_CTL_BRGEN_MASK | UART_CTL_TXEN_MASK | UART_CTL_RXEN_MASK);
398 bcm_uart_writel(port, val, UART_CTL_REG);
399}
400
401/*
402 * disable rx & tx operation on uart
403 */
404static void bcm_uart_disable(struct uart_port *port)
405{
406 unsigned int val;
407
408 val = bcm_uart_readl(port, UART_CTL_REG);
409 val &= ~(UART_CTL_BRGEN_MASK | UART_CTL_TXEN_MASK |
410 UART_CTL_RXEN_MASK);
411 bcm_uart_writel(port, val, UART_CTL_REG);
412}
413
414/*
415 * clear all unread data in rx fifo and unsent data in tx fifo
416 */
417static void bcm_uart_flush(struct uart_port *port)
418{
419 unsigned int val;
420
421 /* empty rx and tx fifo */
422 val = bcm_uart_readl(port, UART_CTL_REG);
423 val |= UART_CTL_RSTRXFIFO_MASK | UART_CTL_RSTTXFIFO_MASK;
424 bcm_uart_writel(port, val, UART_CTL_REG);
425
426 /* read any pending char to make sure all irq status are
427 * cleared */
428 (void)bcm_uart_readl(port, UART_FIFO_REG);
429}
430
431/*
432 * serial core request to initialize uart and start rx operation
433 */
434static int bcm_uart_startup(struct uart_port *port)
435{
436 unsigned int val;
437 int ret;
438
439 /* mask all irq and flush port */
440 bcm_uart_disable(port);
441 bcm_uart_writel(port, 0, UART_IR_REG);
442 bcm_uart_flush(port);
443
444 /* clear any pending external input interrupt */
445 (void)bcm_uart_readl(port, UART_EXTINP_REG);
446
447 /* set rx/tx fifo thresh to fifo half size */
448 val = bcm_uart_readl(port, UART_MCTL_REG);
449 val &= ~(UART_MCTL_RXFIFOTHRESH_MASK | UART_MCTL_TXFIFOTHRESH_MASK);
450 val |= (port->fifosize / 2) << UART_MCTL_RXFIFOTHRESH_SHIFT;
451 val |= (port->fifosize / 2) << UART_MCTL_TXFIFOTHRESH_SHIFT;
452 bcm_uart_writel(port, val, UART_MCTL_REG);
453
454 /* set rx fifo timeout to 1 char time */
455 val = bcm_uart_readl(port, UART_CTL_REG);
456 val &= ~UART_CTL_RXTMOUTCNT_MASK;
457 val |= 1 << UART_CTL_RXTMOUTCNT_SHIFT;
458 bcm_uart_writel(port, val, UART_CTL_REG);
459
460 /* report any edge on dcd and cts */
461 val = UART_EXTINP_INT_MASK;
462 val |= UART_EXTINP_DCD_NOSENSE_MASK;
463 val |= UART_EXTINP_CTS_NOSENSE_MASK;
464 bcm_uart_writel(port, val, UART_EXTINP_REG);
465
466 /* register irq and enable rx interrupts */
467 ret = request_irq(port->irq, bcm_uart_interrupt, 0,
468 bcm_uart_type(port), port);
469 if (ret)
470 return ret;
471 bcm_uart_writel(port, UART_RX_INT_MASK, UART_IR_REG);
472 bcm_uart_enable(port);
473 return 0;
474}
475
476/*
477 * serial core request to flush & disable uart
478 */
479static void bcm_uart_shutdown(struct uart_port *port)
480{
481 unsigned long flags;
482
483 spin_lock_irqsave(&port->lock, flags);
484 bcm_uart_writel(port, 0, UART_IR_REG);
485 spin_unlock_irqrestore(&port->lock, flags);
486
487 bcm_uart_disable(port);
488 bcm_uart_flush(port);
489 free_irq(port->irq, port);
490}
491
492/*
493 * serial core request to change current uart setting
494 */
495static void bcm_uart_set_termios(struct uart_port *port,
496 struct ktermios *new,
497 struct ktermios *old)
498{
499 unsigned int ctl, baud, quot, ier;
500 unsigned long flags;
501
502 spin_lock_irqsave(&port->lock, flags);
503
504 /* disable uart while changing speed */
505 bcm_uart_disable(port);
506 bcm_uart_flush(port);
507
508 /* update Control register */
509 ctl = bcm_uart_readl(port, UART_CTL_REG);
510 ctl &= ~UART_CTL_BITSPERSYM_MASK;
511
512 switch (new->c_cflag & CSIZE) {
513 case CS5:
514 ctl |= (0 << UART_CTL_BITSPERSYM_SHIFT);
515 break;
516 case CS6:
517 ctl |= (1 << UART_CTL_BITSPERSYM_SHIFT);
518 break;
519 case CS7:
520 ctl |= (2 << UART_CTL_BITSPERSYM_SHIFT);
521 break;
522 default:
523 ctl |= (3 << UART_CTL_BITSPERSYM_SHIFT);
524 break;
525 }
526
527 ctl &= ~UART_CTL_STOPBITS_MASK;
528 if (new->c_cflag & CSTOPB)
529 ctl |= UART_CTL_STOPBITS_2;
530 else
531 ctl |= UART_CTL_STOPBITS_1;
532
533 ctl &= ~(UART_CTL_RXPAREN_MASK | UART_CTL_TXPAREN_MASK);
534 if (new->c_cflag & PARENB)
535 ctl |= (UART_CTL_RXPAREN_MASK | UART_CTL_TXPAREN_MASK);
536 ctl &= ~(UART_CTL_RXPAREVEN_MASK | UART_CTL_TXPAREVEN_MASK);
537 if (new->c_cflag & PARODD)
538 ctl |= (UART_CTL_RXPAREVEN_MASK | UART_CTL_TXPAREVEN_MASK);
539 bcm_uart_writel(port, ctl, UART_CTL_REG);
540
541 /* update Baudword register */
542 baud = uart_get_baud_rate(port, new, old, 0, port->uartclk / 16);
543 quot = uart_get_divisor(port, baud) - 1;
544 bcm_uart_writel(port, quot, UART_BAUD_REG);
545
546 /* update Interrupt register */
547 ier = bcm_uart_readl(port, UART_IR_REG);
548
549 ier &= ~UART_IR_MASK(UART_IR_EXTIP);
550 if (UART_ENABLE_MS(port, new->c_cflag))
551 ier |= UART_IR_MASK(UART_IR_EXTIP);
552
553 bcm_uart_writel(port, ier, UART_IR_REG);
554
555 /* update read/ignore mask */
556 port->read_status_mask = UART_FIFO_VALID_MASK;
557 if (new->c_iflag & INPCK) {
558 port->read_status_mask |= UART_FIFO_FRAMEERR_MASK;
559 port->read_status_mask |= UART_FIFO_PARERR_MASK;
560 }
561 if (new->c_iflag & (BRKINT))
562 port->read_status_mask |= UART_FIFO_BRKDET_MASK;
563
564 port->ignore_status_mask = 0;
565 if (new->c_iflag & IGNPAR)
566 port->ignore_status_mask |= UART_FIFO_PARERR_MASK;
567 if (new->c_iflag & IGNBRK)
568 port->ignore_status_mask |= UART_FIFO_BRKDET_MASK;
569 if (!(new->c_cflag & CREAD))
570 port->ignore_status_mask |= UART_FIFO_VALID_MASK;
571
572 uart_update_timeout(port, new->c_cflag, baud);
573 bcm_uart_enable(port);
574 spin_unlock_irqrestore(&port->lock, flags);
575}
576
577/*
578 * serial core request to claim uart iomem
579 */
580static int bcm_uart_request_port(struct uart_port *port)
581{
582 unsigned int size;
583
584 size = RSET_UART_SIZE;
585 if (!request_mem_region(port->mapbase, size, "bcm63xx")) {
586 dev_err(port->dev, "Memory region busy\n");
587 return -EBUSY;
588 }
589
590 port->membase = ioremap(port->mapbase, size);
591 if (!port->membase) {
592 dev_err(port->dev, "Unable to map registers\n");
593 release_mem_region(port->mapbase, size);
594 return -EBUSY;
595 }
596 return 0;
597}
598
599/*
600 * serial core request to release uart iomem
601 */
602static void bcm_uart_release_port(struct uart_port *port)
603{
604 release_mem_region(port->mapbase, RSET_UART_SIZE);
605 iounmap(port->membase);
606}
607
608/*
609 * serial core request to do any port required autoconfiguration
610 */
611static void bcm_uart_config_port(struct uart_port *port, int flags)
612{
613 if (flags & UART_CONFIG_TYPE) {
614 if (bcm_uart_request_port(port))
615 return;
616 port->type = PORT_BCM63XX;
617 }
618}
619
620/*
621 * serial core request to check that port information in serinfo are
622 * suitable
623 */
624static int bcm_uart_verify_port(struct uart_port *port,
625 struct serial_struct *serinfo)
626{
627 if (port->type != PORT_BCM63XX)
628 return -EINVAL;
629 if (port->irq != serinfo->irq)
630 return -EINVAL;
631 if (port->iotype != serinfo->io_type)
632 return -EINVAL;
633 if (port->mapbase != (unsigned long)serinfo->iomem_base)
634 return -EINVAL;
635 return 0;
636}
637
638/* serial core callbacks */
639static struct uart_ops bcm_uart_ops = {
640 .tx_empty = bcm_uart_tx_empty,
641 .get_mctrl = bcm_uart_get_mctrl,
642 .set_mctrl = bcm_uart_set_mctrl,
643 .start_tx = bcm_uart_start_tx,
644 .stop_tx = bcm_uart_stop_tx,
645 .stop_rx = bcm_uart_stop_rx,
646 .enable_ms = bcm_uart_enable_ms,
647 .break_ctl = bcm_uart_break_ctl,
648 .startup = bcm_uart_startup,
649 .shutdown = bcm_uart_shutdown,
650 .set_termios = bcm_uart_set_termios,
651 .type = bcm_uart_type,
652 .release_port = bcm_uart_release_port,
653 .request_port = bcm_uart_request_port,
654 .config_port = bcm_uart_config_port,
655 .verify_port = bcm_uart_verify_port,
656};
657
658
659
660#ifdef CONFIG_SERIAL_BCM63XX_CONSOLE
661static inline void wait_for_xmitr(struct uart_port *port)
662{
663 unsigned int tmout;
664
665 /* Wait up to 10ms for the character(s) to be sent. */
666 tmout = 10000;
667 while (--tmout) {
668 unsigned int val;
669
670 val = bcm_uart_readl(port, UART_IR_REG);
671 if (val & UART_IR_STAT(UART_IR_TXEMPTY))
672 break;
673 udelay(1);
674 }
675
676 /* Wait up to 1s for flow control if necessary */
677 if (port->flags & UPF_CONS_FLOW) {
678 tmout = 1000000;
679 while (--tmout) {
680 unsigned int val;
681
682 val = bcm_uart_readl(port, UART_EXTINP_REG);
683 if (val & UART_EXTINP_CTS_MASK)
684 break;
685 udelay(1);
686 }
687 }
688}
689
690/*
691 * output given char
692 */
693static void bcm_console_putchar(struct uart_port *port, int ch)
694{
695 wait_for_xmitr(port);
696 bcm_uart_writel(port, ch, UART_FIFO_REG);
697}
698
699/*
700 * console core request to output given string
701 */
702static void bcm_console_write(struct console *co, const char *s,
703 unsigned int count)
704{
705 struct uart_port *port;
706 unsigned long flags;
707 int locked;
708
709 port = &ports[co->index];
710
711 local_irq_save(flags);
712 if (port->sysrq) {
713 /* bcm_uart_interrupt() already took the lock */
714 locked = 0;
715 } else if (oops_in_progress) {
716 locked = spin_trylock(&port->lock);
717 } else {
718 spin_lock(&port->lock);
719 locked = 1;
720 }
721
722 /* call helper to deal with \r\n */
723 uart_console_write(port, s, count, bcm_console_putchar);
724
725 /* and wait for char to be transmitted */
726 wait_for_xmitr(port);
727
728 if (locked)
729 spin_unlock(&port->lock);
730 local_irq_restore(flags);
731}
732
733/*
734 * console core request to setup given console, find matching uart
735 * port and setup it.
736 */
737static int bcm_console_setup(struct console *co, char *options)
738{
739 struct uart_port *port;
740 int baud = 9600;
741 int bits = 8;
742 int parity = 'n';
743 int flow = 'n';
744
745 if (co->index < 0 || co->index >= BCM63XX_NR_UARTS)
746 return -EINVAL;
747 port = &ports[co->index];
748 if (!port->membase)
749 return -ENODEV;
750 if (options)
751 uart_parse_options(options, &baud, &parity, &bits, &flow);
752
753 return uart_set_options(port, co, baud, parity, bits, flow);
754}
755
756static struct uart_driver bcm_uart_driver;
757
758static struct console bcm63xx_console = {
759 .name = "ttyS",
760 .write = bcm_console_write,
761 .device = uart_console_device,
762 .setup = bcm_console_setup,
763 .flags = CON_PRINTBUFFER,
764 .index = -1,
765 .data = &bcm_uart_driver,
766};
767
768static int __init bcm63xx_console_init(void)
769{
770 register_console(&bcm63xx_console);
771 return 0;
772}
773
774console_initcall(bcm63xx_console_init);
775
776#define BCM63XX_CONSOLE (&bcm63xx_console)
777#else
778#define BCM63XX_CONSOLE NULL
779#endif /* CONFIG_SERIAL_BCM63XX_CONSOLE */
780
781static struct uart_driver bcm_uart_driver = {
782 .owner = THIS_MODULE,
783 .driver_name = "bcm63xx_uart",
784 .dev_name = "ttyS",
785 .major = TTY_MAJOR,
786 .minor = 64,
787 .nr = 1,
788 .cons = BCM63XX_CONSOLE,
789};
790
791/*
792 * platform driver probe/remove callback
793 */
794static int __devinit bcm_uart_probe(struct platform_device *pdev)
795{
796 struct resource *res_mem, *res_irq;
797 struct uart_port *port;
798 struct clk *clk;
799 int ret;
800
801 if (pdev->id < 0 || pdev->id >= BCM63XX_NR_UARTS)
802 return -EINVAL;
803
804 if (ports[pdev->id].membase)
805 return -EBUSY;
806
807 res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
808 if (!res_mem)
809 return -ENODEV;
810
811 res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
812 if (!res_irq)
813 return -ENODEV;
814
815 clk = clk_get(&pdev->dev, "periph");
816 if (IS_ERR(clk))
817 return -ENODEV;
818
819 port = &ports[pdev->id];
820 memset(port, 0, sizeof(*port));
821 port->iotype = UPIO_MEM;
822 port->mapbase = res_mem->start;
823 port->irq = res_irq->start;
824 port->ops = &bcm_uart_ops;
825 port->flags = UPF_BOOT_AUTOCONF;
826 port->dev = &pdev->dev;
827 port->fifosize = 16;
828 port->uartclk = clk_get_rate(clk) / 2;
829 clk_put(clk);
830
831 ret = uart_add_one_port(&bcm_uart_driver, port);
832 if (ret) {
833 kfree(port);
834 return ret;
835 }
836 platform_set_drvdata(pdev, port);
837 return 0;
838}
839
840static int __devexit bcm_uart_remove(struct platform_device *pdev)
841{
842 struct uart_port *port;
843
844 port = platform_get_drvdata(pdev);
845 uart_remove_one_port(&bcm_uart_driver, port);
846 platform_set_drvdata(pdev, NULL);
847 /* mark port as free */
848 ports[pdev->id].membase = 0;
849 return 0;
850}
851
852/*
853 * platform driver stuff
854 */
855static struct platform_driver bcm_uart_platform_driver = {
856 .probe = bcm_uart_probe,
857 .remove = __devexit_p(bcm_uart_remove),
858 .driver = {
859 .owner = THIS_MODULE,
860 .name = "bcm63xx_uart",
861 },
862};
863
864static int __init bcm_uart_init(void)
865{
866 int ret;
867
868 ret = uart_register_driver(&bcm_uart_driver);
869 if (ret)
870 return ret;
871
872 ret = platform_driver_register(&bcm_uart_platform_driver);
873 if (ret)
874 uart_unregister_driver(&bcm_uart_driver);
875
876 return ret;
877}
878
879static void __exit bcm_uart_exit(void)
880{
881 platform_driver_unregister(&bcm_uart_platform_driver);
882 uart_unregister_driver(&bcm_uart_driver);
883}
884
885module_init(bcm_uart_init);
886module_exit(bcm_uart_exit);
887
888MODULE_AUTHOR("Maxime Bizon <mbizon@freebox.fr>");
889MODULE_DESCRIPTION("Broadcom 63<xx integrated uart driver");
890MODULE_LICENSE("GPL");
diff --git a/drivers/serial/icom.c b/drivers/serial/icom.c
index 2d7feecaf492..0028b6f89ce6 100644
--- a/drivers/serial/icom.c
+++ b/drivers/serial/icom.c
@@ -307,7 +307,7 @@ static void stop_processor(struct icom_port *icom_port)
307 if (port < 4) { 307 if (port < 4) {
308 temp = readl(stop_proc[port].global_control_reg); 308 temp = readl(stop_proc[port].global_control_reg);
309 temp = 309 temp =
310 (temp & ~start_proc[port].processor_id) | stop_proc[port].processor_id; 310 (temp & ~start_proc[port].processor_id) | stop_proc[port].processor_id;
311 writel(temp, stop_proc[port].global_control_reg); 311 writel(temp, stop_proc[port].global_control_reg);
312 312
313 /* write flush */ 313 /* write flush */
@@ -336,7 +336,7 @@ static void start_processor(struct icom_port *icom_port)
336 if (port < 4) { 336 if (port < 4) {
337 temp = readl(start_proc[port].global_control_reg); 337 temp = readl(start_proc[port].global_control_reg);
338 temp = 338 temp =
339 (temp & ~stop_proc[port].processor_id) | start_proc[port].processor_id; 339 (temp & ~stop_proc[port].processor_id) | start_proc[port].processor_id;
340 writel(temp, start_proc[port].global_control_reg); 340 writel(temp, start_proc[port].global_control_reg);
341 341
342 /* write flush */ 342 /* write flush */
@@ -509,8 +509,8 @@ static void load_code(struct icom_port *icom_port)
509 dev_err(&icom_port->adapter->pci_dev->dev,"Port not opertional\n"); 509 dev_err(&icom_port->adapter->pci_dev->dev,"Port not opertional\n");
510 } 510 }
511 511
512 if (new_page != NULL) 512 if (new_page != NULL)
513 pci_free_consistent(dev, 4096, new_page, temp_pci); 513 pci_free_consistent(dev, 4096, new_page, temp_pci);
514} 514}
515 515
516static int startup(struct icom_port *icom_port) 516static int startup(struct icom_port *icom_port)
@@ -1493,15 +1493,15 @@ static int __devinit icom_probe(struct pci_dev *dev,
1493 const struct pci_device_id *ent) 1493 const struct pci_device_id *ent)
1494{ 1494{
1495 int index; 1495 int index;
1496 unsigned int command_reg; 1496 unsigned int command_reg;
1497 int retval; 1497 int retval;
1498 struct icom_adapter *icom_adapter; 1498 struct icom_adapter *icom_adapter;
1499 struct icom_port *icom_port; 1499 struct icom_port *icom_port;
1500 1500
1501 retval = pci_enable_device(dev); 1501 retval = pci_enable_device(dev);
1502 if (retval) { 1502 if (retval) {
1503 dev_err(&dev->dev, "Device enable FAILED\n"); 1503 dev_err(&dev->dev, "Device enable FAILED\n");
1504 return retval; 1504 return retval;
1505 } 1505 }
1506 1506
1507 if ( (retval = pci_request_regions(dev, "icom"))) { 1507 if ( (retval = pci_request_regions(dev, "icom"))) {
@@ -1510,23 +1510,23 @@ static int __devinit icom_probe(struct pci_dev *dev,
1510 return retval; 1510 return retval;
1511 } 1511 }
1512 1512
1513 pci_set_master(dev); 1513 pci_set_master(dev);
1514 1514
1515 if ( (retval = pci_read_config_dword(dev, PCI_COMMAND, &command_reg))) { 1515 if ( (retval = pci_read_config_dword(dev, PCI_COMMAND, &command_reg))) {
1516 dev_err(&dev->dev, "PCI Config read FAILED\n"); 1516 dev_err(&dev->dev, "PCI Config read FAILED\n");
1517 return retval; 1517 return retval;
1518 } 1518 }
1519 1519
1520 pci_write_config_dword(dev, PCI_COMMAND, 1520 pci_write_config_dword(dev, PCI_COMMAND,
1521 command_reg | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER 1521 command_reg | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER
1522 | PCI_COMMAND_PARITY | PCI_COMMAND_SERR); 1522 | PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
1523 1523
1524 if (ent->driver_data == ADAPTER_V1) { 1524 if (ent->driver_data == ADAPTER_V1) {
1525 pci_write_config_dword(dev, 0x44, 0x8300830A); 1525 pci_write_config_dword(dev, 0x44, 0x8300830A);
1526 } else { 1526 } else {
1527 pci_write_config_dword(dev, 0x44, 0x42004200); 1527 pci_write_config_dword(dev, 0x44, 0x42004200);
1528 pci_write_config_dword(dev, 0x48, 0x42004200); 1528 pci_write_config_dword(dev, 0x48, 0x42004200);
1529 } 1529 }
1530 1530
1531 1531
1532 retval = icom_alloc_adapter(&icom_adapter); 1532 retval = icom_alloc_adapter(&icom_adapter);
@@ -1536,10 +1536,10 @@ static int __devinit icom_probe(struct pci_dev *dev,
1536 goto probe_exit0; 1536 goto probe_exit0;
1537 } 1537 }
1538 1538
1539 icom_adapter->base_addr_pci = pci_resource_start(dev, 0); 1539 icom_adapter->base_addr_pci = pci_resource_start(dev, 0);
1540 icom_adapter->pci_dev = dev; 1540 icom_adapter->pci_dev = dev;
1541 icom_adapter->version = ent->driver_data; 1541 icom_adapter->version = ent->driver_data;
1542 icom_adapter->subsystem_id = ent->subdevice; 1542 icom_adapter->subsystem_id = ent->subdevice;
1543 1543
1544 1544
1545 retval = icom_init_ports(icom_adapter); 1545 retval = icom_init_ports(icom_adapter);
@@ -1548,7 +1548,7 @@ static int __devinit icom_probe(struct pci_dev *dev,
1548 goto probe_exit1; 1548 goto probe_exit1;
1549 } 1549 }
1550 1550
1551 icom_adapter->base_addr = pci_ioremap_bar(dev, 0); 1551 icom_adapter->base_addr = pci_ioremap_bar(dev, 0);
1552 1552
1553 if (!icom_adapter->base_addr) 1553 if (!icom_adapter->base_addr)
1554 goto probe_exit1; 1554 goto probe_exit1;
@@ -1562,7 +1562,7 @@ static int __devinit icom_probe(struct pci_dev *dev,
1562 1562
1563 retval = icom_load_ports(icom_adapter); 1563 retval = icom_load_ports(icom_adapter);
1564 1564
1565 for (index = 0; index < icom_adapter->numb_ports; index++) { 1565 for (index = 0; index < icom_adapter->numb_ports; index++) {
1566 icom_port = &icom_adapter->port_info[index]; 1566 icom_port = &icom_adapter->port_info[index];
1567 1567
1568 if (icom_port->status == ICOM_PORT_ACTIVE) { 1568 if (icom_port->status == ICOM_PORT_ACTIVE) {
@@ -1579,7 +1579,7 @@ static int __devinit icom_probe(struct pci_dev *dev,
1579 icom_port->status = ICOM_PORT_OFF; 1579 icom_port->status = ICOM_PORT_OFF;
1580 dev_err(&dev->dev, "Device add failed\n"); 1580 dev_err(&dev->dev, "Device add failed\n");
1581 } else 1581 } else
1582 dev_info(&dev->dev, "Device added\n"); 1582 dev_info(&dev->dev, "Device added\n");
1583 } 1583 }
1584 } 1584 }
1585 1585
@@ -1595,9 +1595,7 @@ probe_exit0:
1595 pci_release_regions(dev); 1595 pci_release_regions(dev);
1596 pci_disable_device(dev); 1596 pci_disable_device(dev);
1597 1597
1598 return retval; 1598 return retval;
1599
1600
1601} 1599}
1602 1600
1603static void __devexit icom_remove(struct pci_dev *dev) 1601static void __devexit icom_remove(struct pci_dev *dev)
diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c
index 7f5e26873220..2199d819a987 100644
--- a/drivers/serial/sa1100.c
+++ b/drivers/serial/sa1100.c
@@ -638,7 +638,7 @@ static void __init sa1100_init_ports(void)
638 PPSR |= PPC_TXD1 | PPC_TXD3; 638 PPSR |= PPC_TXD1 | PPC_TXD3;
639} 639}
640 640
641void __init sa1100_register_uart_fns(struct sa1100_port_fns *fns) 641void __devinit sa1100_register_uart_fns(struct sa1100_port_fns *fns)
642{ 642{
643 if (fns->get_mctrl) 643 if (fns->get_mctrl)
644 sa1100_pops.get_mctrl = fns->get_mctrl; 644 sa1100_pops.get_mctrl = fns->get_mctrl;
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index 1689bda1d13b..dcc72444e8e7 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -1270,6 +1270,9 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
1270 1270
1271 BUG_ON(!kernel_locked()); 1271 BUG_ON(!kernel_locked());
1272 1272
1273 if (!state)
1274 return;
1275
1273 uport = state->uart_port; 1276 uport = state->uart_port;
1274 port = &state->port; 1277 port = &state->port;
1275 1278
@@ -1316,9 +1319,9 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
1316 */ 1319 */
1317 if (port->flags & ASYNC_INITIALIZED) { 1320 if (port->flags & ASYNC_INITIALIZED) {
1318 unsigned long flags; 1321 unsigned long flags;
1319 spin_lock_irqsave(&port->lock, flags); 1322 spin_lock_irqsave(&uport->lock, flags);
1320 uport->ops->stop_rx(uport); 1323 uport->ops->stop_rx(uport);
1321 spin_unlock_irqrestore(&port->lock, flags); 1324 spin_unlock_irqrestore(&uport->lock, flags);
1322 /* 1325 /*
1323 * Before we drop DTR, make sure the UART transmitter 1326 * Before we drop DTR, make sure the UART transmitter
1324 * has completely drained; this is especially 1327 * has completely drained; this is especially
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index a3bb49031a7f..ff4617e21426 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -873,10 +873,10 @@ static struct pcmcia_device_id serial_ids[] = {
873 PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "cis/PCMLM28.cis"), 873 PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "cis/PCMLM28.cis"),
874 PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet GSM", 0xf5f025c2, 0x4ae85d35, "cis/PCMLM28.cis"), 874 PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet GSM", 0xf5f025c2, 0x4ae85d35, "cis/PCMLM28.cis"),
875 PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "LINKSYS", "PCMLM28", 0xf7cb0b07, 0x66881874, "cis/PCMLM28.cis"), 875 PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "LINKSYS", "PCMLM28", 0xf7cb0b07, 0x66881874, "cis/PCMLM28.cis"),
876 PCMCIA_MFC_DEVICE_CIS_PROD_ID12(1, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "DP83903.cis"), 876 PCMCIA_MFC_DEVICE_CIS_PROD_ID12(1, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "cis/DP83903.cis"),
877 PCMCIA_MFC_DEVICE_CIS_PROD_ID4(1, "NSC MF LAN/Modem", 0x58fc6056, "DP83903.cis"), 877 PCMCIA_MFC_DEVICE_CIS_PROD_ID4(1, "NSC MF LAN/Modem", 0x58fc6056, "cis/DP83903.cis"),
878 PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0556, "cis/3CCFEM556.cis"), 878 PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0556, "cis/3CCFEM556.cis"),
879 PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0175, 0x0000, "DP83903.cis"), 879 PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0175, 0x0000, "cis/DP83903.cis"),
880 PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0035, "cis/3CXEM556.cis"), 880 PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0035, "cis/3CXEM556.cis"),
881 PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x003d, "cis/3CXEM556.cis"), 881 PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x003d, "cis/3CXEM556.cis"),
882 PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC850", 0xd85f6206, 0x42a2c018, "SW_8xx_SER.cis"), /* Sierra Wireless AC850 3G Network Adapter R1 */ 882 PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC850", 0xd85f6206, 0x42a2c018, "SW_8xx_SER.cis"), /* Sierra Wireless AC850 3G Network Adapter R1 */
@@ -884,9 +884,9 @@ static struct pcmcia_device_id serial_ids[] = {
884 PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0xa555, "SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- pre update */ 884 PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0xa555, "SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- pre update */
885 PCMCIA_DEVICE_CIS_MANF_CARD(0x013f, 0xa555, "SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- post update */ 885 PCMCIA_DEVICE_CIS_MANF_CARD(0x013f, 0xa555, "SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- post update */
886 PCMCIA_DEVICE_CIS_PROD_ID12("MultiTech", "PCMCIA 56K DataFax", 0x842047ee, 0xc2efcf03, "cis/MT5634ZLX.cis"), 886 PCMCIA_DEVICE_CIS_PROD_ID12("MultiTech", "PCMCIA 56K DataFax", 0x842047ee, 0xc2efcf03, "cis/MT5634ZLX.cis"),
887 PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-2", 0x96913a85, 0x27ab5437, "COMpad2.cis"), 887 PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-2", 0x96913a85, 0x27ab5437, "cis/COMpad2.cis"),
888 PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-4", 0x96913a85, 0xcec8f102, "COMpad4.cis"), 888 PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-4", 0x96913a85, 0xcec8f102, "cis/COMpad4.cis"),
889 PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH", "COMpad-32/85", "1.0", 0x96913a85, 0x8fbe92ae, 0x0877b627, "COMpad2.cis"), 889 PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH", "COMpad-32/85", "1.0", 0x96913a85, 0x8fbe92ae, 0x0877b627, "cis/COMpad2.cis"),
890 PCMCIA_DEVICE_CIS_PROD_ID2("RS-COM 2P", 0xad20b156, "cis/RS-COM-2P.cis"), 890 PCMCIA_DEVICE_CIS_PROD_ID2("RS-COM 2P", 0xad20b156, "cis/RS-COM-2P.cis"),
891 PCMCIA_DEVICE_CIS_MANF_CARD(0x0013, 0x0000, "GLOBETROTTER.cis"), 891 PCMCIA_DEVICE_CIS_MANF_CARD(0x0013, 0x0000, "GLOBETROTTER.cis"),
892 PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL100 1.00.",0x19ca78af,0xf964f42b), 892 PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL100 1.00.",0x19ca78af,0xf964f42b),
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c
index 0f7cf4c453e6..c50e9fbbf743 100644
--- a/drivers/serial/serial_txx9.c
+++ b/drivers/serial/serial_txx9.c
@@ -221,21 +221,26 @@ sio_quot_set(struct uart_txx9_port *up, int quot)
221 sio_out(up, TXX9_SIBGR, 0xff | TXX9_SIBGR_BCLK_T6); 221 sio_out(up, TXX9_SIBGR, 0xff | TXX9_SIBGR_BCLK_T6);
222} 222}
223 223
224static struct uart_txx9_port *to_uart_txx9_port(struct uart_port *port)
225{
226 return container_of(port, struct uart_txx9_port, port);
227}
228
224static void serial_txx9_stop_tx(struct uart_port *port) 229static void serial_txx9_stop_tx(struct uart_port *port)
225{ 230{
226 struct uart_txx9_port *up = (struct uart_txx9_port *)port; 231 struct uart_txx9_port *up = to_uart_txx9_port(port);
227 sio_mask(up, TXX9_SIDICR, TXX9_SIDICR_TIE); 232 sio_mask(up, TXX9_SIDICR, TXX9_SIDICR_TIE);
228} 233}
229 234
230static void serial_txx9_start_tx(struct uart_port *port) 235static void serial_txx9_start_tx(struct uart_port *port)
231{ 236{
232 struct uart_txx9_port *up = (struct uart_txx9_port *)port; 237 struct uart_txx9_port *up = to_uart_txx9_port(port);
233 sio_set(up, TXX9_SIDICR, TXX9_SIDICR_TIE); 238 sio_set(up, TXX9_SIDICR, TXX9_SIDICR_TIE);
234} 239}
235 240
236static void serial_txx9_stop_rx(struct uart_port *port) 241static void serial_txx9_stop_rx(struct uart_port *port)
237{ 242{
238 struct uart_txx9_port *up = (struct uart_txx9_port *)port; 243 struct uart_txx9_port *up = to_uart_txx9_port(port);
239 up->port.read_status_mask &= ~TXX9_SIDISR_RDIS; 244 up->port.read_status_mask &= ~TXX9_SIDISR_RDIS;
240} 245}
241 246
@@ -246,7 +251,7 @@ static void serial_txx9_enable_ms(struct uart_port *port)
246 251
247static void serial_txx9_initialize(struct uart_port *port) 252static void serial_txx9_initialize(struct uart_port *port)
248{ 253{
249 struct uart_txx9_port *up = (struct uart_txx9_port *)port; 254 struct uart_txx9_port *up = to_uart_txx9_port(port);
250 unsigned int tmout = 10000; 255 unsigned int tmout = 10000;
251 256
252 sio_out(up, TXX9_SIFCR, TXX9_SIFCR_SWRST); 257 sio_out(up, TXX9_SIFCR, TXX9_SIFCR_SWRST);
@@ -414,7 +419,7 @@ static irqreturn_t serial_txx9_interrupt(int irq, void *dev_id)
414 419
415static unsigned int serial_txx9_tx_empty(struct uart_port *port) 420static unsigned int serial_txx9_tx_empty(struct uart_port *port)
416{ 421{
417 struct uart_txx9_port *up = (struct uart_txx9_port *)port; 422 struct uart_txx9_port *up = to_uart_txx9_port(port);
418 unsigned long flags; 423 unsigned long flags;
419 unsigned int ret; 424 unsigned int ret;
420 425
@@ -427,7 +432,7 @@ static unsigned int serial_txx9_tx_empty(struct uart_port *port)
427 432
428static unsigned int serial_txx9_get_mctrl(struct uart_port *port) 433static unsigned int serial_txx9_get_mctrl(struct uart_port *port)
429{ 434{
430 struct uart_txx9_port *up = (struct uart_txx9_port *)port; 435 struct uart_txx9_port *up = to_uart_txx9_port(port);
431 unsigned int ret; 436 unsigned int ret;
432 437
433 /* no modem control lines */ 438 /* no modem control lines */
@@ -440,7 +445,7 @@ static unsigned int serial_txx9_get_mctrl(struct uart_port *port)
440 445
441static void serial_txx9_set_mctrl(struct uart_port *port, unsigned int mctrl) 446static void serial_txx9_set_mctrl(struct uart_port *port, unsigned int mctrl)
442{ 447{
443 struct uart_txx9_port *up = (struct uart_txx9_port *)port; 448 struct uart_txx9_port *up = to_uart_txx9_port(port);
444 449
445 if (mctrl & TIOCM_RTS) 450 if (mctrl & TIOCM_RTS)
446 sio_mask(up, TXX9_SIFLCR, TXX9_SIFLCR_RTSSC); 451 sio_mask(up, TXX9_SIFLCR, TXX9_SIFLCR_RTSSC);
@@ -450,7 +455,7 @@ static void serial_txx9_set_mctrl(struct uart_port *port, unsigned int mctrl)
450 455
451static void serial_txx9_break_ctl(struct uart_port *port, int break_state) 456static void serial_txx9_break_ctl(struct uart_port *port, int break_state)
452{ 457{
453 struct uart_txx9_port *up = (struct uart_txx9_port *)port; 458 struct uart_txx9_port *up = to_uart_txx9_port(port);
454 unsigned long flags; 459 unsigned long flags;
455 460
456 spin_lock_irqsave(&up->port.lock, flags); 461 spin_lock_irqsave(&up->port.lock, flags);
@@ -494,7 +499,7 @@ static int serial_txx9_get_poll_char(struct uart_port *port)
494{ 499{
495 unsigned int ier; 500 unsigned int ier;
496 unsigned char c; 501 unsigned char c;
497 struct uart_txx9_port *up = (struct uart_txx9_port *)port; 502 struct uart_txx9_port *up = to_uart_txx9_port(port);
498 503
499 /* 504 /*
500 * First save the IER then disable the interrupts 505 * First save the IER then disable the interrupts
@@ -520,7 +525,7 @@ static int serial_txx9_get_poll_char(struct uart_port *port)
520static void serial_txx9_put_poll_char(struct uart_port *port, unsigned char c) 525static void serial_txx9_put_poll_char(struct uart_port *port, unsigned char c)
521{ 526{
522 unsigned int ier; 527 unsigned int ier;
523 struct uart_txx9_port *up = (struct uart_txx9_port *)port; 528 struct uart_txx9_port *up = to_uart_txx9_port(port);
524 529
525 /* 530 /*
526 * First save the IER then disable the interrupts 531 * First save the IER then disable the interrupts
@@ -551,7 +556,7 @@ static void serial_txx9_put_poll_char(struct uart_port *port, unsigned char c)
551 556
552static int serial_txx9_startup(struct uart_port *port) 557static int serial_txx9_startup(struct uart_port *port)
553{ 558{
554 struct uart_txx9_port *up = (struct uart_txx9_port *)port; 559 struct uart_txx9_port *up = to_uart_txx9_port(port);
555 unsigned long flags; 560 unsigned long flags;
556 int retval; 561 int retval;
557 562
@@ -596,7 +601,7 @@ static int serial_txx9_startup(struct uart_port *port)
596 601
597static void serial_txx9_shutdown(struct uart_port *port) 602static void serial_txx9_shutdown(struct uart_port *port)
598{ 603{
599 struct uart_txx9_port *up = (struct uart_txx9_port *)port; 604 struct uart_txx9_port *up = to_uart_txx9_port(port);
600 unsigned long flags; 605 unsigned long flags;
601 606
602 /* 607 /*
@@ -636,7 +641,7 @@ static void
636serial_txx9_set_termios(struct uart_port *port, struct ktermios *termios, 641serial_txx9_set_termios(struct uart_port *port, struct ktermios *termios,
637 struct ktermios *old) 642 struct ktermios *old)
638{ 643{
639 struct uart_txx9_port *up = (struct uart_txx9_port *)port; 644 struct uart_txx9_port *up = to_uart_txx9_port(port);
640 unsigned int cval, fcr = 0; 645 unsigned int cval, fcr = 0;
641 unsigned long flags; 646 unsigned long flags;
642 unsigned int baud, quot; 647 unsigned int baud, quot;
@@ -814,19 +819,19 @@ static void serial_txx9_release_resource(struct uart_txx9_port *up)
814 819
815static void serial_txx9_release_port(struct uart_port *port) 820static void serial_txx9_release_port(struct uart_port *port)
816{ 821{
817 struct uart_txx9_port *up = (struct uart_txx9_port *)port; 822 struct uart_txx9_port *up = to_uart_txx9_port(port);
818 serial_txx9_release_resource(up); 823 serial_txx9_release_resource(up);
819} 824}
820 825
821static int serial_txx9_request_port(struct uart_port *port) 826static int serial_txx9_request_port(struct uart_port *port)
822{ 827{
823 struct uart_txx9_port *up = (struct uart_txx9_port *)port; 828 struct uart_txx9_port *up = to_uart_txx9_port(port);
824 return serial_txx9_request_resource(up); 829 return serial_txx9_request_resource(up);
825} 830}
826 831
827static void serial_txx9_config_port(struct uart_port *port, int uflags) 832static void serial_txx9_config_port(struct uart_port *port, int uflags)
828{ 833{
829 struct uart_txx9_port *up = (struct uart_txx9_port *)port; 834 struct uart_txx9_port *up = to_uart_txx9_port(port);
830 int ret; 835 int ret;
831 836
832 /* 837 /*
@@ -897,7 +902,7 @@ static void __init serial_txx9_register_ports(struct uart_driver *drv,
897 902
898static void serial_txx9_console_putchar(struct uart_port *port, int ch) 903static void serial_txx9_console_putchar(struct uart_port *port, int ch)
899{ 904{
900 struct uart_txx9_port *up = (struct uart_txx9_port *)port; 905 struct uart_txx9_port *up = to_uart_txx9_port(port);
901 906
902 wait_for_xmitr(up); 907 wait_for_xmitr(up);
903 sio_out(up, TXX9_SITFIFO, ch); 908 sio_out(up, TXX9_SITFIFO, ch);
diff --git a/drivers/sfi/sfi_core.c b/drivers/sfi/sfi_core.c
index d3b496800477..b204a0929139 100644
--- a/drivers/sfi/sfi_core.c
+++ b/drivers/sfi/sfi_core.c
@@ -90,7 +90,11 @@ static struct sfi_table_simple *syst_va __read_mostly;
90 */ 90 */
91static u32 sfi_use_ioremap __read_mostly; 91static u32 sfi_use_ioremap __read_mostly;
92 92
93static void __iomem *sfi_map_memory(u64 phys, u32 size) 93/*
94 * sfi_un/map_memory calls early_ioremap/iounmap which is a __init function
95 * and introduces section mismatch. So use __ref to make it calm.
96 */
97static void __iomem * __ref sfi_map_memory(u64 phys, u32 size)
94{ 98{
95 if (!phys || !size) 99 if (!phys || !size)
96 return NULL; 100 return NULL;
@@ -101,7 +105,7 @@ static void __iomem *sfi_map_memory(u64 phys, u32 size)
101 return early_ioremap(phys, size); 105 return early_ioremap(phys, size);
102} 106}
103 107
104static void sfi_unmap_memory(void __iomem *virt, u32 size) 108static void __ref sfi_unmap_memory(void __iomem *virt, u32 size)
105{ 109{
106 if (!virt || !size) 110 if (!virt || !size)
107 return; 111 return;
@@ -125,7 +129,7 @@ static void sfi_print_table_header(unsigned long long pa,
125 * sfi_verify_table() 129 * sfi_verify_table()
126 * Sanity check table lengh, calculate checksum 130 * Sanity check table lengh, calculate checksum
127 */ 131 */
128static __init int sfi_verify_table(struct sfi_table_header *table) 132static int sfi_verify_table(struct sfi_table_header *table)
129{ 133{
130 134
131 u8 checksum = 0; 135 u8 checksum = 0;
@@ -213,12 +217,17 @@ static int sfi_table_check_key(struct sfi_table_header *th,
213 * the mapped virt address will be returned, and the virt space 217 * the mapped virt address will be returned, and the virt space
214 * will be released by call sfi_put_table() later 218 * will be released by call sfi_put_table() later
215 * 219 *
220 * This two cases are from two different functions with two different
221 * sections and causes section mismatch warning. So use __ref to tell
222 * modpost not to make any noise.
223 *
216 * Return value: 224 * Return value:
217 * NULL: when can't find a table matching the key 225 * NULL: when can't find a table matching the key
218 * ERR_PTR(error): error value 226 * ERR_PTR(error): error value
219 * virt table address: when a matched table is found 227 * virt table address: when a matched table is found
220 */ 228 */
221struct sfi_table_header *sfi_check_table(u64 pa, struct sfi_table_key *key) 229struct sfi_table_header *
230 __ref sfi_check_table(u64 pa, struct sfi_table_key *key)
222{ 231{
223 struct sfi_table_header *th; 232 struct sfi_table_header *th;
224 void *ret = NULL; 233 void *ret = NULL;
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 6d7a3f82c54b..21a118269cac 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -17,7 +17,7 @@ obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o
17obj-$(CONFIG_SPI_AU1550) += au1550_spi.o 17obj-$(CONFIG_SPI_AU1550) += au1550_spi.o
18obj-$(CONFIG_SPI_BUTTERFLY) += spi_butterfly.o 18obj-$(CONFIG_SPI_BUTTERFLY) += spi_butterfly.o
19obj-$(CONFIG_SPI_GPIO) += spi_gpio.o 19obj-$(CONFIG_SPI_GPIO) += spi_gpio.o
20obj-$(CONFIG_SPI_IMX) += mxc_spi.o 20obj-$(CONFIG_SPI_IMX) += spi_imx.o
21obj-$(CONFIG_SPI_LM70_LLP) += spi_lm70llp.o 21obj-$(CONFIG_SPI_LM70_LLP) += spi_lm70llp.o
22obj-$(CONFIG_SPI_PXA2XX) += pxa2xx_spi.o 22obj-$(CONFIG_SPI_PXA2XX) += pxa2xx_spi.o
23obj-$(CONFIG_SPI_OMAP_UWIRE) += omap_uwire.o 23obj-$(CONFIG_SPI_OMAP_UWIRE) += omap_uwire.o
diff --git a/drivers/spi/amba-pl022.c b/drivers/spi/amba-pl022.c
index 958a3ffc8987..ff5bbb9c43c9 100644
--- a/drivers/spi/amba-pl022.c
+++ b/drivers/spi/amba-pl022.c
@@ -1826,7 +1826,7 @@ static struct amba_id pl022_ids[] = {
1826 * ST Micro derivative, this has 32bit wide 1826 * ST Micro derivative, this has 32bit wide
1827 * and 32 locations deep TX/RX FIFO 1827 * and 32 locations deep TX/RX FIFO
1828 */ 1828 */
1829 .id = 0x00108022, 1829 .id = 0x01080022,
1830 .mask = 0xffffffff, 1830 .mask = 0xffffffff,
1831 .data = &vendor_st, 1831 .data = &vendor_st,
1832 }, 1832 },
diff --git a/drivers/spi/mxc_spi.c b/drivers/spi/spi_imx.c
index b1447236ae81..89c22efedfb0 100644
--- a/drivers/spi/mxc_spi.c
+++ b/drivers/spi/spi_imx.c
@@ -48,14 +48,14 @@
48#define MXC_INT_RR (1 << 0) /* Receive data ready interrupt */ 48#define MXC_INT_RR (1 << 0) /* Receive data ready interrupt */
49#define MXC_INT_TE (1 << 1) /* Transmit FIFO empty interrupt */ 49#define MXC_INT_TE (1 << 1) /* Transmit FIFO empty interrupt */
50 50
51struct mxc_spi_config { 51struct spi_imx_config {
52 unsigned int speed_hz; 52 unsigned int speed_hz;
53 unsigned int bpw; 53 unsigned int bpw;
54 unsigned int mode; 54 unsigned int mode;
55 int cs; 55 int cs;
56}; 56};
57 57
58struct mxc_spi_data { 58struct spi_imx_data {
59 struct spi_bitbang bitbang; 59 struct spi_bitbang bitbang;
60 60
61 struct completion xfer_done; 61 struct completion xfer_done;
@@ -66,43 +66,43 @@ struct mxc_spi_data {
66 int *chipselect; 66 int *chipselect;
67 67
68 unsigned int count; 68 unsigned int count;
69 void (*tx)(struct mxc_spi_data *); 69 void (*tx)(struct spi_imx_data *);
70 void (*rx)(struct mxc_spi_data *); 70 void (*rx)(struct spi_imx_data *);
71 void *rx_buf; 71 void *rx_buf;
72 const void *tx_buf; 72 const void *tx_buf;
73 unsigned int txfifo; /* number of words pushed in tx FIFO */ 73 unsigned int txfifo; /* number of words pushed in tx FIFO */
74 74
75 /* SoC specific functions */ 75 /* SoC specific functions */
76 void (*intctrl)(struct mxc_spi_data *, int); 76 void (*intctrl)(struct spi_imx_data *, int);
77 int (*config)(struct mxc_spi_data *, struct mxc_spi_config *); 77 int (*config)(struct spi_imx_data *, struct spi_imx_config *);
78 void (*trigger)(struct mxc_spi_data *); 78 void (*trigger)(struct spi_imx_data *);
79 int (*rx_available)(struct mxc_spi_data *); 79 int (*rx_available)(struct spi_imx_data *);
80}; 80};
81 81
82#define MXC_SPI_BUF_RX(type) \ 82#define MXC_SPI_BUF_RX(type) \
83static void mxc_spi_buf_rx_##type(struct mxc_spi_data *mxc_spi) \ 83static void spi_imx_buf_rx_##type(struct spi_imx_data *spi_imx) \
84{ \ 84{ \
85 unsigned int val = readl(mxc_spi->base + MXC_CSPIRXDATA); \ 85 unsigned int val = readl(spi_imx->base + MXC_CSPIRXDATA); \
86 \ 86 \
87 if (mxc_spi->rx_buf) { \ 87 if (spi_imx->rx_buf) { \
88 *(type *)mxc_spi->rx_buf = val; \ 88 *(type *)spi_imx->rx_buf = val; \
89 mxc_spi->rx_buf += sizeof(type); \ 89 spi_imx->rx_buf += sizeof(type); \
90 } \ 90 } \
91} 91}
92 92
93#define MXC_SPI_BUF_TX(type) \ 93#define MXC_SPI_BUF_TX(type) \
94static void mxc_spi_buf_tx_##type(struct mxc_spi_data *mxc_spi) \ 94static void spi_imx_buf_tx_##type(struct spi_imx_data *spi_imx) \
95{ \ 95{ \
96 type val = 0; \ 96 type val = 0; \
97 \ 97 \
98 if (mxc_spi->tx_buf) { \ 98 if (spi_imx->tx_buf) { \
99 val = *(type *)mxc_spi->tx_buf; \ 99 val = *(type *)spi_imx->tx_buf; \
100 mxc_spi->tx_buf += sizeof(type); \ 100 spi_imx->tx_buf += sizeof(type); \
101 } \ 101 } \
102 \ 102 \
103 mxc_spi->count -= sizeof(type); \ 103 spi_imx->count -= sizeof(type); \
104 \ 104 \
105 writel(val, mxc_spi->base + MXC_CSPITXDATA); \ 105 writel(val, spi_imx->base + MXC_CSPITXDATA); \
106} 106}
107 107
108MXC_SPI_BUF_RX(u8) 108MXC_SPI_BUF_RX(u8)
@@ -119,7 +119,7 @@ static int mxc_clkdivs[] = {0, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192,
119 256, 384, 512, 768, 1024}; 119 256, 384, 512, 768, 1024};
120 120
121/* MX21, MX27 */ 121/* MX21, MX27 */
122static unsigned int mxc_spi_clkdiv_1(unsigned int fin, 122static unsigned int spi_imx_clkdiv_1(unsigned int fin,
123 unsigned int fspi) 123 unsigned int fspi)
124{ 124{
125 int i, max; 125 int i, max;
@@ -137,7 +137,7 @@ static unsigned int mxc_spi_clkdiv_1(unsigned int fin,
137} 137}
138 138
139/* MX1, MX31, MX35 */ 139/* MX1, MX31, MX35 */
140static unsigned int mxc_spi_clkdiv_2(unsigned int fin, 140static unsigned int spi_imx_clkdiv_2(unsigned int fin,
141 unsigned int fspi) 141 unsigned int fspi)
142{ 142{
143 int i, div = 4; 143 int i, div = 4;
@@ -174,7 +174,7 @@ static unsigned int mxc_spi_clkdiv_2(unsigned int fin,
174 * the i.MX35 has a slightly different register layout for bits 174 * the i.MX35 has a slightly different register layout for bits
175 * we do not use here. 175 * we do not use here.
176 */ 176 */
177static void mx31_intctrl(struct mxc_spi_data *mxc_spi, int enable) 177static void mx31_intctrl(struct spi_imx_data *spi_imx, int enable)
178{ 178{
179 unsigned int val = 0; 179 unsigned int val = 0;
180 180
@@ -183,24 +183,24 @@ static void mx31_intctrl(struct mxc_spi_data *mxc_spi, int enable)
183 if (enable & MXC_INT_RR) 183 if (enable & MXC_INT_RR)
184 val |= MX31_INTREG_RREN; 184 val |= MX31_INTREG_RREN;
185 185
186 writel(val, mxc_spi->base + MXC_CSPIINT); 186 writel(val, spi_imx->base + MXC_CSPIINT);
187} 187}
188 188
189static void mx31_trigger(struct mxc_spi_data *mxc_spi) 189static void mx31_trigger(struct spi_imx_data *spi_imx)
190{ 190{
191 unsigned int reg; 191 unsigned int reg;
192 192
193 reg = readl(mxc_spi->base + MXC_CSPICTRL); 193 reg = readl(spi_imx->base + MXC_CSPICTRL);
194 reg |= MX31_CSPICTRL_XCH; 194 reg |= MX31_CSPICTRL_XCH;
195 writel(reg, mxc_spi->base + MXC_CSPICTRL); 195 writel(reg, spi_imx->base + MXC_CSPICTRL);
196} 196}
197 197
198static int mx31_config(struct mxc_spi_data *mxc_spi, 198static int mx31_config(struct spi_imx_data *spi_imx,
199 struct mxc_spi_config *config) 199 struct spi_imx_config *config)
200{ 200{
201 unsigned int reg = MX31_CSPICTRL_ENABLE | MX31_CSPICTRL_MASTER; 201 unsigned int reg = MX31_CSPICTRL_ENABLE | MX31_CSPICTRL_MASTER;
202 202
203 reg |= mxc_spi_clkdiv_2(mxc_spi->spi_clk, config->speed_hz) << 203 reg |= spi_imx_clkdiv_2(spi_imx->spi_clk, config->speed_hz) <<
204 MX31_CSPICTRL_DR_SHIFT; 204 MX31_CSPICTRL_DR_SHIFT;
205 205
206 if (cpu_is_mx31()) 206 if (cpu_is_mx31())
@@ -223,14 +223,14 @@ static int mx31_config(struct mxc_spi_data *mxc_spi,
223 reg |= (config->cs + 32) << MX35_CSPICTRL_CS_SHIFT; 223 reg |= (config->cs + 32) << MX35_CSPICTRL_CS_SHIFT;
224 } 224 }
225 225
226 writel(reg, mxc_spi->base + MXC_CSPICTRL); 226 writel(reg, spi_imx->base + MXC_CSPICTRL);
227 227
228 return 0; 228 return 0;
229} 229}
230 230
231static int mx31_rx_available(struct mxc_spi_data *mxc_spi) 231static int mx31_rx_available(struct spi_imx_data *spi_imx)
232{ 232{
233 return readl(mxc_spi->base + MX31_CSPISTATUS) & MX31_STATUS_RR; 233 return readl(spi_imx->base + MX31_CSPISTATUS) & MX31_STATUS_RR;
234} 234}
235 235
236#define MX27_INTREG_RR (1 << 4) 236#define MX27_INTREG_RR (1 << 4)
@@ -246,7 +246,7 @@ static int mx31_rx_available(struct mxc_spi_data *mxc_spi)
246#define MX27_CSPICTRL_DR_SHIFT 14 246#define MX27_CSPICTRL_DR_SHIFT 14
247#define MX27_CSPICTRL_CS_SHIFT 19 247#define MX27_CSPICTRL_CS_SHIFT 19
248 248
249static void mx27_intctrl(struct mxc_spi_data *mxc_spi, int enable) 249static void mx27_intctrl(struct spi_imx_data *spi_imx, int enable)
250{ 250{
251 unsigned int val = 0; 251 unsigned int val = 0;
252 252
@@ -255,24 +255,24 @@ static void mx27_intctrl(struct mxc_spi_data *mxc_spi, int enable)
255 if (enable & MXC_INT_RR) 255 if (enable & MXC_INT_RR)
256 val |= MX27_INTREG_RREN; 256 val |= MX27_INTREG_RREN;
257 257
258 writel(val, mxc_spi->base + MXC_CSPIINT); 258 writel(val, spi_imx->base + MXC_CSPIINT);
259} 259}
260 260
261static void mx27_trigger(struct mxc_spi_data *mxc_spi) 261static void mx27_trigger(struct spi_imx_data *spi_imx)
262{ 262{
263 unsigned int reg; 263 unsigned int reg;
264 264
265 reg = readl(mxc_spi->base + MXC_CSPICTRL); 265 reg = readl(spi_imx->base + MXC_CSPICTRL);
266 reg |= MX27_CSPICTRL_XCH; 266 reg |= MX27_CSPICTRL_XCH;
267 writel(reg, mxc_spi->base + MXC_CSPICTRL); 267 writel(reg, spi_imx->base + MXC_CSPICTRL);
268} 268}
269 269
270static int mx27_config(struct mxc_spi_data *mxc_spi, 270static int mx27_config(struct spi_imx_data *spi_imx,
271 struct mxc_spi_config *config) 271 struct spi_imx_config *config)
272{ 272{
273 unsigned int reg = MX27_CSPICTRL_ENABLE | MX27_CSPICTRL_MASTER; 273 unsigned int reg = MX27_CSPICTRL_ENABLE | MX27_CSPICTRL_MASTER;
274 274
275 reg |= mxc_spi_clkdiv_1(mxc_spi->spi_clk, config->speed_hz) << 275 reg |= spi_imx_clkdiv_1(spi_imx->spi_clk, config->speed_hz) <<
276 MX27_CSPICTRL_DR_SHIFT; 276 MX27_CSPICTRL_DR_SHIFT;
277 reg |= config->bpw - 1; 277 reg |= config->bpw - 1;
278 278
@@ -285,14 +285,14 @@ static int mx27_config(struct mxc_spi_data *mxc_spi,
285 if (config->cs < 0) 285 if (config->cs < 0)
286 reg |= (config->cs + 32) << MX27_CSPICTRL_CS_SHIFT; 286 reg |= (config->cs + 32) << MX27_CSPICTRL_CS_SHIFT;
287 287
288 writel(reg, mxc_spi->base + MXC_CSPICTRL); 288 writel(reg, spi_imx->base + MXC_CSPICTRL);
289 289
290 return 0; 290 return 0;
291} 291}
292 292
293static int mx27_rx_available(struct mxc_spi_data *mxc_spi) 293static int mx27_rx_available(struct spi_imx_data *spi_imx)
294{ 294{
295 return readl(mxc_spi->base + MXC_CSPIINT) & MX27_INTREG_RR; 295 return readl(spi_imx->base + MXC_CSPIINT) & MX27_INTREG_RR;
296} 296}
297 297
298#define MX1_INTREG_RR (1 << 3) 298#define MX1_INTREG_RR (1 << 3)
@@ -306,7 +306,7 @@ static int mx27_rx_available(struct mxc_spi_data *mxc_spi)
306#define MX1_CSPICTRL_MASTER (1 << 10) 306#define MX1_CSPICTRL_MASTER (1 << 10)
307#define MX1_CSPICTRL_DR_SHIFT 13 307#define MX1_CSPICTRL_DR_SHIFT 13
308 308
309static void mx1_intctrl(struct mxc_spi_data *mxc_spi, int enable) 309static void mx1_intctrl(struct spi_imx_data *spi_imx, int enable)
310{ 310{
311 unsigned int val = 0; 311 unsigned int val = 0;
312 312
@@ -315,24 +315,24 @@ static void mx1_intctrl(struct mxc_spi_data *mxc_spi, int enable)
315 if (enable & MXC_INT_RR) 315 if (enable & MXC_INT_RR)
316 val |= MX1_INTREG_RREN; 316 val |= MX1_INTREG_RREN;
317 317
318 writel(val, mxc_spi->base + MXC_CSPIINT); 318 writel(val, spi_imx->base + MXC_CSPIINT);
319} 319}
320 320
321static void mx1_trigger(struct mxc_spi_data *mxc_spi) 321static void mx1_trigger(struct spi_imx_data *spi_imx)
322{ 322{
323 unsigned int reg; 323 unsigned int reg;
324 324
325 reg = readl(mxc_spi->base + MXC_CSPICTRL); 325 reg = readl(spi_imx->base + MXC_CSPICTRL);
326 reg |= MX1_CSPICTRL_XCH; 326 reg |= MX1_CSPICTRL_XCH;
327 writel(reg, mxc_spi->base + MXC_CSPICTRL); 327 writel(reg, spi_imx->base + MXC_CSPICTRL);
328} 328}
329 329
330static int mx1_config(struct mxc_spi_data *mxc_spi, 330static int mx1_config(struct spi_imx_data *spi_imx,
331 struct mxc_spi_config *config) 331 struct spi_imx_config *config)
332{ 332{
333 unsigned int reg = MX1_CSPICTRL_ENABLE | MX1_CSPICTRL_MASTER; 333 unsigned int reg = MX1_CSPICTRL_ENABLE | MX1_CSPICTRL_MASTER;
334 334
335 reg |= mxc_spi_clkdiv_2(mxc_spi->spi_clk, config->speed_hz) << 335 reg |= spi_imx_clkdiv_2(spi_imx->spi_clk, config->speed_hz) <<
336 MX1_CSPICTRL_DR_SHIFT; 336 MX1_CSPICTRL_DR_SHIFT;
337 reg |= config->bpw - 1; 337 reg |= config->bpw - 1;
338 338
@@ -341,156 +341,151 @@ static int mx1_config(struct mxc_spi_data *mxc_spi,
341 if (config->mode & SPI_CPOL) 341 if (config->mode & SPI_CPOL)
342 reg |= MX1_CSPICTRL_POL; 342 reg |= MX1_CSPICTRL_POL;
343 343
344 writel(reg, mxc_spi->base + MXC_CSPICTRL); 344 writel(reg, spi_imx->base + MXC_CSPICTRL);
345 345
346 return 0; 346 return 0;
347} 347}
348 348
349static int mx1_rx_available(struct mxc_spi_data *mxc_spi) 349static int mx1_rx_available(struct spi_imx_data *spi_imx)
350{ 350{
351 return readl(mxc_spi->base + MXC_CSPIINT) & MX1_INTREG_RR; 351 return readl(spi_imx->base + MXC_CSPIINT) & MX1_INTREG_RR;
352} 352}
353 353
354static void mxc_spi_chipselect(struct spi_device *spi, int is_active) 354static void spi_imx_chipselect(struct spi_device *spi, int is_active)
355{ 355{
356 struct mxc_spi_data *mxc_spi = spi_master_get_devdata(spi->master); 356 struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master);
357 unsigned int cs = 0; 357 int gpio = spi_imx->chipselect[spi->chip_select];
358 int gpio = mxc_spi->chipselect[spi->chip_select]; 358 int active = is_active != BITBANG_CS_INACTIVE;
359 struct mxc_spi_config config; 359 int dev_is_lowactive = !(spi->mode & SPI_CS_HIGH);
360 360
361 if (spi->mode & SPI_CS_HIGH) 361 if (gpio < 0)
362 cs = 1;
363
364 if (is_active == BITBANG_CS_INACTIVE) {
365 if (gpio >= 0)
366 gpio_set_value(gpio, !cs);
367 return; 362 return;
368 }
369
370 config.bpw = spi->bits_per_word;
371 config.speed_hz = spi->max_speed_hz;
372 config.mode = spi->mode;
373 config.cs = mxc_spi->chipselect[spi->chip_select];
374
375 mxc_spi->config(mxc_spi, &config);
376
377 /* Initialize the functions for transfer */
378 if (config.bpw <= 8) {
379 mxc_spi->rx = mxc_spi_buf_rx_u8;
380 mxc_spi->tx = mxc_spi_buf_tx_u8;
381 } else if (config.bpw <= 16) {
382 mxc_spi->rx = mxc_spi_buf_rx_u16;
383 mxc_spi->tx = mxc_spi_buf_tx_u16;
384 } else if (config.bpw <= 32) {
385 mxc_spi->rx = mxc_spi_buf_rx_u32;
386 mxc_spi->tx = mxc_spi_buf_tx_u32;
387 } else
388 BUG();
389 363
390 if (gpio >= 0) 364 gpio_set_value(gpio, dev_is_lowactive ^ active);
391 gpio_set_value(gpio, cs);
392
393 return;
394} 365}
395 366
396static void mxc_spi_push(struct mxc_spi_data *mxc_spi) 367static void spi_imx_push(struct spi_imx_data *spi_imx)
397{ 368{
398 while (mxc_spi->txfifo < 8) { 369 while (spi_imx->txfifo < 8) {
399 if (!mxc_spi->count) 370 if (!spi_imx->count)
400 break; 371 break;
401 mxc_spi->tx(mxc_spi); 372 spi_imx->tx(spi_imx);
402 mxc_spi->txfifo++; 373 spi_imx->txfifo++;
403 } 374 }
404 375
405 mxc_spi->trigger(mxc_spi); 376 spi_imx->trigger(spi_imx);
406} 377}
407 378
408static irqreturn_t mxc_spi_isr(int irq, void *dev_id) 379static irqreturn_t spi_imx_isr(int irq, void *dev_id)
409{ 380{
410 struct mxc_spi_data *mxc_spi = dev_id; 381 struct spi_imx_data *spi_imx = dev_id;
411 382
412 while (mxc_spi->rx_available(mxc_spi)) { 383 while (spi_imx->rx_available(spi_imx)) {
413 mxc_spi->rx(mxc_spi); 384 spi_imx->rx(spi_imx);
414 mxc_spi->txfifo--; 385 spi_imx->txfifo--;
415 } 386 }
416 387
417 if (mxc_spi->count) { 388 if (spi_imx->count) {
418 mxc_spi_push(mxc_spi); 389 spi_imx_push(spi_imx);
419 return IRQ_HANDLED; 390 return IRQ_HANDLED;
420 } 391 }
421 392
422 if (mxc_spi->txfifo) { 393 if (spi_imx->txfifo) {
423 /* No data left to push, but still waiting for rx data, 394 /* No data left to push, but still waiting for rx data,
424 * enable receive data available interrupt. 395 * enable receive data available interrupt.
425 */ 396 */
426 mxc_spi->intctrl(mxc_spi, MXC_INT_RR); 397 spi_imx->intctrl(spi_imx, MXC_INT_RR);
427 return IRQ_HANDLED; 398 return IRQ_HANDLED;
428 } 399 }
429 400
430 mxc_spi->intctrl(mxc_spi, 0); 401 spi_imx->intctrl(spi_imx, 0);
431 complete(&mxc_spi->xfer_done); 402 complete(&spi_imx->xfer_done);
432 403
433 return IRQ_HANDLED; 404 return IRQ_HANDLED;
434} 405}
435 406
436static int mxc_spi_setupxfer(struct spi_device *spi, 407static int spi_imx_setupxfer(struct spi_device *spi,
437 struct spi_transfer *t) 408 struct spi_transfer *t)
438{ 409{
439 struct mxc_spi_data *mxc_spi = spi_master_get_devdata(spi->master); 410 struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master);
440 struct mxc_spi_config config; 411 struct spi_imx_config config;
441 412
442 config.bpw = t ? t->bits_per_word : spi->bits_per_word; 413 config.bpw = t ? t->bits_per_word : spi->bits_per_word;
443 config.speed_hz = t ? t->speed_hz : spi->max_speed_hz; 414 config.speed_hz = t ? t->speed_hz : spi->max_speed_hz;
444 config.mode = spi->mode; 415 config.mode = spi->mode;
416 config.cs = spi_imx->chipselect[spi->chip_select];
417
418 if (!config.speed_hz)
419 config.speed_hz = spi->max_speed_hz;
420 if (!config.bpw)
421 config.bpw = spi->bits_per_word;
422 if (!config.speed_hz)
423 config.speed_hz = spi->max_speed_hz;
424
425 /* Initialize the functions for transfer */
426 if (config.bpw <= 8) {
427 spi_imx->rx = spi_imx_buf_rx_u8;
428 spi_imx->tx = spi_imx_buf_tx_u8;
429 } else if (config.bpw <= 16) {
430 spi_imx->rx = spi_imx_buf_rx_u16;
431 spi_imx->tx = spi_imx_buf_tx_u16;
432 } else if (config.bpw <= 32) {
433 spi_imx->rx = spi_imx_buf_rx_u32;
434 spi_imx->tx = spi_imx_buf_tx_u32;
435 } else
436 BUG();
445 437
446 mxc_spi->config(mxc_spi, &config); 438 spi_imx->config(spi_imx, &config);
447 439
448 return 0; 440 return 0;
449} 441}
450 442
451static int mxc_spi_transfer(struct spi_device *spi, 443static int spi_imx_transfer(struct spi_device *spi,
452 struct spi_transfer *transfer) 444 struct spi_transfer *transfer)
453{ 445{
454 struct mxc_spi_data *mxc_spi = spi_master_get_devdata(spi->master); 446 struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master);
455 447
456 mxc_spi->tx_buf = transfer->tx_buf; 448 spi_imx->tx_buf = transfer->tx_buf;
457 mxc_spi->rx_buf = transfer->rx_buf; 449 spi_imx->rx_buf = transfer->rx_buf;
458 mxc_spi->count = transfer->len; 450 spi_imx->count = transfer->len;
459 mxc_spi->txfifo = 0; 451 spi_imx->txfifo = 0;
460 452
461 init_completion(&mxc_spi->xfer_done); 453 init_completion(&spi_imx->xfer_done);
462 454
463 mxc_spi_push(mxc_spi); 455 spi_imx_push(spi_imx);
464 456
465 mxc_spi->intctrl(mxc_spi, MXC_INT_TE); 457 spi_imx->intctrl(spi_imx, MXC_INT_TE);
466 458
467 wait_for_completion(&mxc_spi->xfer_done); 459 wait_for_completion(&spi_imx->xfer_done);
468 460
469 return transfer->len; 461 return transfer->len;
470} 462}
471 463
472static int mxc_spi_setup(struct spi_device *spi) 464static int spi_imx_setup(struct spi_device *spi)
473{ 465{
474 if (!spi->bits_per_word) 466 struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master);
475 spi->bits_per_word = 8; 467 int gpio = spi_imx->chipselect[spi->chip_select];
476 468
477 pr_debug("%s: mode %d, %u bpw, %d hz\n", __func__, 469 pr_debug("%s: mode %d, %u bpw, %d hz\n", __func__,
478 spi->mode, spi->bits_per_word, spi->max_speed_hz); 470 spi->mode, spi->bits_per_word, spi->max_speed_hz);
479 471
480 mxc_spi_chipselect(spi, BITBANG_CS_INACTIVE); 472 if (gpio >= 0)
473 gpio_direction_output(gpio, spi->mode & SPI_CS_HIGH ? 0 : 1);
474
475 spi_imx_chipselect(spi, BITBANG_CS_INACTIVE);
481 476
482 return 0; 477 return 0;
483} 478}
484 479
485static void mxc_spi_cleanup(struct spi_device *spi) 480static void spi_imx_cleanup(struct spi_device *spi)
486{ 481{
487} 482}
488 483
489static int __init mxc_spi_probe(struct platform_device *pdev) 484static int __init spi_imx_probe(struct platform_device *pdev)
490{ 485{
491 struct spi_imx_master *mxc_platform_info; 486 struct spi_imx_master *mxc_platform_info;
492 struct spi_master *master; 487 struct spi_master *master;
493 struct mxc_spi_data *mxc_spi; 488 struct spi_imx_data *spi_imx;
494 struct resource *res; 489 struct resource *res;
495 int i, ret; 490 int i, ret;
496 491
@@ -500,7 +495,7 @@ static int __init mxc_spi_probe(struct platform_device *pdev)
500 return -EINVAL; 495 return -EINVAL;
501 } 496 }
502 497
503 master = spi_alloc_master(&pdev->dev, sizeof(struct mxc_spi_data)); 498 master = spi_alloc_master(&pdev->dev, sizeof(struct spi_imx_data));
504 if (!master) 499 if (!master)
505 return -ENOMEM; 500 return -ENOMEM;
506 501
@@ -509,32 +504,32 @@ static int __init mxc_spi_probe(struct platform_device *pdev)
509 master->bus_num = pdev->id; 504 master->bus_num = pdev->id;
510 master->num_chipselect = mxc_platform_info->num_chipselect; 505 master->num_chipselect = mxc_platform_info->num_chipselect;
511 506
512 mxc_spi = spi_master_get_devdata(master); 507 spi_imx = spi_master_get_devdata(master);
513 mxc_spi->bitbang.master = spi_master_get(master); 508 spi_imx->bitbang.master = spi_master_get(master);
514 mxc_spi->chipselect = mxc_platform_info->chipselect; 509 spi_imx->chipselect = mxc_platform_info->chipselect;
515 510
516 for (i = 0; i < master->num_chipselect; i++) { 511 for (i = 0; i < master->num_chipselect; i++) {
517 if (mxc_spi->chipselect[i] < 0) 512 if (spi_imx->chipselect[i] < 0)
518 continue; 513 continue;
519 ret = gpio_request(mxc_spi->chipselect[i], DRIVER_NAME); 514 ret = gpio_request(spi_imx->chipselect[i], DRIVER_NAME);
520 if (ret) { 515 if (ret) {
521 i--; 516 i--;
522 while (i > 0) 517 while (i > 0)
523 if (mxc_spi->chipselect[i] >= 0) 518 if (spi_imx->chipselect[i] >= 0)
524 gpio_free(mxc_spi->chipselect[i--]); 519 gpio_free(spi_imx->chipselect[i--]);
525 dev_err(&pdev->dev, "can't get cs gpios"); 520 dev_err(&pdev->dev, "can't get cs gpios");
526 goto out_master_put; 521 goto out_master_put;
527 } 522 }
528 gpio_direction_output(mxc_spi->chipselect[i], 1);
529 } 523 }
530 524
531 mxc_spi->bitbang.chipselect = mxc_spi_chipselect; 525 spi_imx->bitbang.chipselect = spi_imx_chipselect;
532 mxc_spi->bitbang.setup_transfer = mxc_spi_setupxfer; 526 spi_imx->bitbang.setup_transfer = spi_imx_setupxfer;
533 mxc_spi->bitbang.txrx_bufs = mxc_spi_transfer; 527 spi_imx->bitbang.txrx_bufs = spi_imx_transfer;
534 mxc_spi->bitbang.master->setup = mxc_spi_setup; 528 spi_imx->bitbang.master->setup = spi_imx_setup;
535 mxc_spi->bitbang.master->cleanup = mxc_spi_cleanup; 529 spi_imx->bitbang.master->cleanup = spi_imx_cleanup;
530 spi_imx->bitbang.master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
536 531
537 init_completion(&mxc_spi->xfer_done); 532 init_completion(&spi_imx->xfer_done);
538 533
539 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 534 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
540 if (!res) { 535 if (!res) {
@@ -549,58 +544,58 @@ static int __init mxc_spi_probe(struct platform_device *pdev)
549 goto out_gpio_free; 544 goto out_gpio_free;
550 } 545 }
551 546
552 mxc_spi->base = ioremap(res->start, resource_size(res)); 547 spi_imx->base = ioremap(res->start, resource_size(res));
553 if (!mxc_spi->base) { 548 if (!spi_imx->base) {
554 ret = -EINVAL; 549 ret = -EINVAL;
555 goto out_release_mem; 550 goto out_release_mem;
556 } 551 }
557 552
558 mxc_spi->irq = platform_get_irq(pdev, 0); 553 spi_imx->irq = platform_get_irq(pdev, 0);
559 if (!mxc_spi->irq) { 554 if (!spi_imx->irq) {
560 ret = -EINVAL; 555 ret = -EINVAL;
561 goto out_iounmap; 556 goto out_iounmap;
562 } 557 }
563 558
564 ret = request_irq(mxc_spi->irq, mxc_spi_isr, 0, DRIVER_NAME, mxc_spi); 559 ret = request_irq(spi_imx->irq, spi_imx_isr, 0, DRIVER_NAME, spi_imx);
565 if (ret) { 560 if (ret) {
566 dev_err(&pdev->dev, "can't get irq%d: %d\n", mxc_spi->irq, ret); 561 dev_err(&pdev->dev, "can't get irq%d: %d\n", spi_imx->irq, ret);
567 goto out_iounmap; 562 goto out_iounmap;
568 } 563 }
569 564
570 if (cpu_is_mx31() || cpu_is_mx35()) { 565 if (cpu_is_mx31() || cpu_is_mx35()) {
571 mxc_spi->intctrl = mx31_intctrl; 566 spi_imx->intctrl = mx31_intctrl;
572 mxc_spi->config = mx31_config; 567 spi_imx->config = mx31_config;
573 mxc_spi->trigger = mx31_trigger; 568 spi_imx->trigger = mx31_trigger;
574 mxc_spi->rx_available = mx31_rx_available; 569 spi_imx->rx_available = mx31_rx_available;
575 } else if (cpu_is_mx27() || cpu_is_mx21()) { 570 } else if (cpu_is_mx27() || cpu_is_mx21()) {
576 mxc_spi->intctrl = mx27_intctrl; 571 spi_imx->intctrl = mx27_intctrl;
577 mxc_spi->config = mx27_config; 572 spi_imx->config = mx27_config;
578 mxc_spi->trigger = mx27_trigger; 573 spi_imx->trigger = mx27_trigger;
579 mxc_spi->rx_available = mx27_rx_available; 574 spi_imx->rx_available = mx27_rx_available;
580 } else if (cpu_is_mx1()) { 575 } else if (cpu_is_mx1()) {
581 mxc_spi->intctrl = mx1_intctrl; 576 spi_imx->intctrl = mx1_intctrl;
582 mxc_spi->config = mx1_config; 577 spi_imx->config = mx1_config;
583 mxc_spi->trigger = mx1_trigger; 578 spi_imx->trigger = mx1_trigger;
584 mxc_spi->rx_available = mx1_rx_available; 579 spi_imx->rx_available = mx1_rx_available;
585 } else 580 } else
586 BUG(); 581 BUG();
587 582
588 mxc_spi->clk = clk_get(&pdev->dev, NULL); 583 spi_imx->clk = clk_get(&pdev->dev, NULL);
589 if (IS_ERR(mxc_spi->clk)) { 584 if (IS_ERR(spi_imx->clk)) {
590 dev_err(&pdev->dev, "unable to get clock\n"); 585 dev_err(&pdev->dev, "unable to get clock\n");
591 ret = PTR_ERR(mxc_spi->clk); 586 ret = PTR_ERR(spi_imx->clk);
592 goto out_free_irq; 587 goto out_free_irq;
593 } 588 }
594 589
595 clk_enable(mxc_spi->clk); 590 clk_enable(spi_imx->clk);
596 mxc_spi->spi_clk = clk_get_rate(mxc_spi->clk); 591 spi_imx->spi_clk = clk_get_rate(spi_imx->clk);
597 592
598 if (!cpu_is_mx31() || !cpu_is_mx35()) 593 if (!cpu_is_mx31() || !cpu_is_mx35())
599 writel(1, mxc_spi->base + MXC_RESET); 594 writel(1, spi_imx->base + MXC_RESET);
600 595
601 mxc_spi->intctrl(mxc_spi, 0); 596 spi_imx->intctrl(spi_imx, 0);
602 597
603 ret = spi_bitbang_start(&mxc_spi->bitbang); 598 ret = spi_bitbang_start(&spi_imx->bitbang);
604 if (ret) { 599 if (ret) {
605 dev_err(&pdev->dev, "bitbang start failed with %d\n", ret); 600 dev_err(&pdev->dev, "bitbang start failed with %d\n", ret);
606 goto out_clk_put; 601 goto out_clk_put;
@@ -611,18 +606,18 @@ static int __init mxc_spi_probe(struct platform_device *pdev)
611 return ret; 606 return ret;
612 607
613out_clk_put: 608out_clk_put:
614 clk_disable(mxc_spi->clk); 609 clk_disable(spi_imx->clk);
615 clk_put(mxc_spi->clk); 610 clk_put(spi_imx->clk);
616out_free_irq: 611out_free_irq:
617 free_irq(mxc_spi->irq, mxc_spi); 612 free_irq(spi_imx->irq, spi_imx);
618out_iounmap: 613out_iounmap:
619 iounmap(mxc_spi->base); 614 iounmap(spi_imx->base);
620out_release_mem: 615out_release_mem:
621 release_mem_region(res->start, resource_size(res)); 616 release_mem_region(res->start, resource_size(res));
622out_gpio_free: 617out_gpio_free:
623 for (i = 0; i < master->num_chipselect; i++) 618 for (i = 0; i < master->num_chipselect; i++)
624 if (mxc_spi->chipselect[i] >= 0) 619 if (spi_imx->chipselect[i] >= 0)
625 gpio_free(mxc_spi->chipselect[i]); 620 gpio_free(spi_imx->chipselect[i]);
626out_master_put: 621out_master_put:
627 spi_master_put(master); 622 spi_master_put(master);
628 kfree(master); 623 kfree(master);
@@ -630,24 +625,24 @@ out_master_put:
630 return ret; 625 return ret;
631} 626}
632 627
633static int __exit mxc_spi_remove(struct platform_device *pdev) 628static int __exit spi_imx_remove(struct platform_device *pdev)
634{ 629{
635 struct spi_master *master = platform_get_drvdata(pdev); 630 struct spi_master *master = platform_get_drvdata(pdev);
636 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 631 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
637 struct mxc_spi_data *mxc_spi = spi_master_get_devdata(master); 632 struct spi_imx_data *spi_imx = spi_master_get_devdata(master);
638 int i; 633 int i;
639 634
640 spi_bitbang_stop(&mxc_spi->bitbang); 635 spi_bitbang_stop(&spi_imx->bitbang);
641 636
642 writel(0, mxc_spi->base + MXC_CSPICTRL); 637 writel(0, spi_imx->base + MXC_CSPICTRL);
643 clk_disable(mxc_spi->clk); 638 clk_disable(spi_imx->clk);
644 clk_put(mxc_spi->clk); 639 clk_put(spi_imx->clk);
645 free_irq(mxc_spi->irq, mxc_spi); 640 free_irq(spi_imx->irq, spi_imx);
646 iounmap(mxc_spi->base); 641 iounmap(spi_imx->base);
647 642
648 for (i = 0; i < master->num_chipselect; i++) 643 for (i = 0; i < master->num_chipselect; i++)
649 if (mxc_spi->chipselect[i] >= 0) 644 if (spi_imx->chipselect[i] >= 0)
650 gpio_free(mxc_spi->chipselect[i]); 645 gpio_free(spi_imx->chipselect[i]);
651 646
652 spi_master_put(master); 647 spi_master_put(master);
653 648
@@ -658,27 +653,27 @@ static int __exit mxc_spi_remove(struct platform_device *pdev)
658 return 0; 653 return 0;
659} 654}
660 655
661static struct platform_driver mxc_spi_driver = { 656static struct platform_driver spi_imx_driver = {
662 .driver = { 657 .driver = {
663 .name = DRIVER_NAME, 658 .name = DRIVER_NAME,
664 .owner = THIS_MODULE, 659 .owner = THIS_MODULE,
665 }, 660 },
666 .probe = mxc_spi_probe, 661 .probe = spi_imx_probe,
667 .remove = __exit_p(mxc_spi_remove), 662 .remove = __exit_p(spi_imx_remove),
668}; 663};
669 664
670static int __init mxc_spi_init(void) 665static int __init spi_imx_init(void)
671{ 666{
672 return platform_driver_register(&mxc_spi_driver); 667 return platform_driver_register(&spi_imx_driver);
673} 668}
674 669
675static void __exit mxc_spi_exit(void) 670static void __exit spi_imx_exit(void)
676{ 671{
677 platform_driver_unregister(&mxc_spi_driver); 672 platform_driver_unregister(&spi_imx_driver);
678} 673}
679 674
680module_init(mxc_spi_init); 675module_init(spi_imx_init);
681module_exit(mxc_spi_exit); 676module_exit(spi_imx_exit);
682 677
683MODULE_DESCRIPTION("SPI Master Controller driver"); 678MODULE_DESCRIPTION("SPI Master Controller driver");
684MODULE_AUTHOR("Sascha Hauer, Pengutronix"); 679MODULE_AUTHOR("Sascha Hauer, Pengutronix");
diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c
index f921bd1109e1..5d23983f02fc 100644
--- a/drivers/spi/spidev.c
+++ b/drivers/spi/spidev.c
@@ -537,7 +537,7 @@ static int spidev_release(struct inode *inode, struct file *filp)
537 return status; 537 return status;
538} 538}
539 539
540static struct file_operations spidev_fops = { 540static const struct file_operations spidev_fops = {
541 .owner = THIS_MODULE, 541 .owner = THIS_MODULE,
542 /* REVISIT switch to aio primitives, so that userspace 542 /* REVISIT switch to aio primitives, so that userspace
543 * gets more complete API coverage. It'll simplify things 543 * gets more complete API coverage. It'll simplify things
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 9a4dd5992f65..7df3ba4f1f4d 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -59,8 +59,6 @@ source "drivers/staging/echo/Kconfig"
59 59
60source "drivers/staging/poch/Kconfig" 60source "drivers/staging/poch/Kconfig"
61 61
62source "drivers/staging/agnx/Kconfig"
63
64source "drivers/staging/otus/Kconfig" 62source "drivers/staging/otus/Kconfig"
65 63
66source "drivers/staging/rt2860/Kconfig" 64source "drivers/staging/rt2860/Kconfig"
@@ -129,7 +127,5 @@ source "drivers/staging/sep/Kconfig"
129 127
130source "drivers/staging/iio/Kconfig" 128source "drivers/staging/iio/Kconfig"
131 129
132source "drivers/staging/cowloop/Kconfig"
133
134endif # !STAGING_EXCLUDE_BUILD 130endif # !STAGING_EXCLUDE_BUILD
135endif # STAGING 131endif # STAGING
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 104f2f8897ec..747571172269 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -12,7 +12,6 @@ obj-$(CONFIG_W35UND) += winbond/
12obj-$(CONFIG_PRISM2_USB) += wlan-ng/ 12obj-$(CONFIG_PRISM2_USB) += wlan-ng/
13obj-$(CONFIG_ECHO) += echo/ 13obj-$(CONFIG_ECHO) += echo/
14obj-$(CONFIG_POCH) += poch/ 14obj-$(CONFIG_POCH) += poch/
15obj-$(CONFIG_AGNX) += agnx/
16obj-$(CONFIG_OTUS) += otus/ 15obj-$(CONFIG_OTUS) += otus/
17obj-$(CONFIG_RT2860) += rt2860/ 16obj-$(CONFIG_RT2860) += rt2860/
18obj-$(CONFIG_RT2870) += rt2870/ 17obj-$(CONFIG_RT2870) += rt2870/
@@ -46,4 +45,3 @@ obj-$(CONFIG_VME_BUS) += vme/
46obj-$(CONFIG_RAR_REGISTER) += rar/ 45obj-$(CONFIG_RAR_REGISTER) += rar/
47obj-$(CONFIG_DX_SEP) += sep/ 46obj-$(CONFIG_DX_SEP) += sep/
48obj-$(CONFIG_IIO) += iio/ 47obj-$(CONFIG_IIO) += iio/
49obj-$(CONFIG_COWLOOP) += cowloop/
diff --git a/drivers/staging/agnx/Kconfig b/drivers/staging/agnx/Kconfig
deleted file mode 100644
index 7f43549e36dd..000000000000
--- a/drivers/staging/agnx/Kconfig
+++ /dev/null
@@ -1,5 +0,0 @@
1config AGNX
2 tristate "Wireless Airgo AGNX support"
3 depends on WLAN_80211 && MAC80211
4 ---help---
5 This is an experimental driver for Airgo AGNX00 wireless chip.
diff --git a/drivers/staging/agnx/Makefile b/drivers/staging/agnx/Makefile
deleted file mode 100644
index 1216564a312d..000000000000
--- a/drivers/staging/agnx/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
1obj-$(CONFIG_AGNX) += agnx.o
2
3agnx-objs := rf.o \
4 pci.o \
5 xmit.o \
6 table.o \
7 sta.o \
8 phy.o
diff --git a/drivers/staging/agnx/TODO b/drivers/staging/agnx/TODO
deleted file mode 100644
index 89bec74318aa..000000000000
--- a/drivers/staging/agnx/TODO
+++ /dev/null
@@ -1,22 +0,0 @@
12008 7/18
2
3The RX has can't receive OFDM packet correctly,
4Guess it need be do RX calibrate.
5
6
7before 2008 3/1
8
91: The RX get too much "CRC failed" pakets, it make the card work very unstable,
102: After running a while, the card will get infinity "RX Frame" and "Error"
11interrupt, not know the root reason so far, try to fix it
123: Using two tx queue txd and txm but not only txm.
134: Set the hdr correctly.
145: Try to do recalibrate correvtly
156: To support G mode in future
167: Fix the mac address can't be readed and set correctly in BE machine.
178: Fix include and exclude FCS in promisous mode and manage mode
189: Using sta_notify to notice sta change
1910: Turn on frame reception at the end of start
2011: Guess the card support HW_MULTICAST_FILTER
2112: The tx process should be implment atomic?
2213: Using mac80211 function to control the TX&RX LED.
diff --git a/drivers/staging/agnx/agnx.h b/drivers/staging/agnx/agnx.h
deleted file mode 100644
index 3963d2597a11..000000000000
--- a/drivers/staging/agnx/agnx.h
+++ /dev/null
@@ -1,156 +0,0 @@
1#ifndef AGNX_H_
2#define AGNX_H_
3
4#include <linux/io.h>
5
6#include "xmit.h"
7
8#define PFX KBUILD_MODNAME ": "
9
10static inline u32 agnx_read32(void __iomem *mem_region, u32 offset)
11{
12 return ioread32(mem_region + offset);
13}
14
15static inline void agnx_write32(void __iomem *mem_region, u32 offset, u32 val)
16{
17 iowrite32(val, mem_region + offset);
18}
19
20/* static const struct ieee80211_rate agnx_rates_80211b[] = { */
21/* { .rate = 10, */
22/* .val = 0xa, */
23/* .flags = IEEE80211_RATE_CCK }, */
24/* { .rate = 20, */
25/* .val = 0x14, */
26/* .hw_value = -0x14, */
27/* .flags = IEEE80211_RATE_CCK_2 }, */
28/* { .rate = 55, */
29/* .val = 0x37, */
30/* .val2 = -0x37, */
31/* .flags = IEEE80211_RATE_CCK_2 }, */
32/* { .rate = 110, */
33/* .val = 0x6e, */
34/* .val2 = -0x6e, */
35/* .flags = IEEE80211_RATE_CCK_2 } */
36/* }; */
37
38
39static const struct ieee80211_rate agnx_rates_80211g[] = {
40/* { .bitrate = 10, .hw_value = 1, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, */
41/* { .bitrate = 20, .hw_value = 2, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, */
42/* { .bitrate = 55, .hw_value = 3, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, */
43/* { .bitrate = 110, .hw_value = 4, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, */
44 { .bitrate = 10, .hw_value = 1, },
45 { .bitrate = 20, .hw_value = 2, },
46 { .bitrate = 55, .hw_value = 3, },
47 { .bitrate = 110, .hw_value = 4,},
48
49 { .bitrate = 60, .hw_value = 0xB, },
50 { .bitrate = 90, .hw_value = 0xF, },
51 { .bitrate = 120, .hw_value = 0xA },
52 { .bitrate = 180, .hw_value = 0xE, },
53/* { .bitrate = 240, .hw_value = 0xd, }, */
54 { .bitrate = 360, .hw_value = 0xD, },
55 { .bitrate = 480, .hw_value = 0x8, },
56 { .bitrate = 540, .hw_value = 0xC, },
57};
58
59static const struct ieee80211_channel agnx_channels[] = {
60 { .center_freq = 2412, .hw_value = 1, },
61 { .center_freq = 2417, .hw_value = 2, },
62 { .center_freq = 2422, .hw_value = 3, },
63 { .center_freq = 2427, .hw_value = 4, },
64 { .center_freq = 2432, .hw_value = 5, },
65 { .center_freq = 2437, .hw_value = 6, },
66 { .center_freq = 2442, .hw_value = 7, },
67 { .center_freq = 2447, .hw_value = 8, },
68 { .center_freq = 2452, .hw_value = 9, },
69 { .center_freq = 2457, .hw_value = 10, },
70 { .center_freq = 2462, .hw_value = 11, },
71 { .center_freq = 2467, .hw_value = 12, },
72 { .center_freq = 2472, .hw_value = 13, },
73 { .center_freq = 2484, .hw_value = 14, },
74};
75
76#define NUM_DRIVE_MODES 2
77/* Agnx operate mode */
78enum {
79 AGNX_MODE_80211A,
80 AGNX_MODE_80211A_OOB,
81 AGNX_MODE_80211A_MIMO,
82 AGNX_MODE_80211B_SHORT,
83 AGNX_MODE_80211B_LONG,
84 AGNX_MODE_80211G,
85 AGNX_MODE_80211G_OOB,
86 AGNX_MODE_80211G_MIMO,
87};
88
89enum {
90 AGNX_UNINIT,
91 AGNX_START,
92 AGNX_STOP,
93};
94
95struct agnx_priv {
96 struct pci_dev *pdev;
97 struct ieee80211_hw *hw;
98
99 spinlock_t lock;
100 struct mutex mutex;
101 unsigned int init_status;
102
103 void __iomem *ctl; /* pointer to base ram address */
104 void __iomem *data; /* pointer to mem region #2 */
105
106 struct agnx_ring rx;
107 struct agnx_ring txm;
108 struct agnx_ring txd;
109
110 /* Need volatile? */
111 u32 irq_status;
112
113 struct delayed_work periodic_work; /* Periodic tasks like recalibrate */
114 struct ieee80211_low_level_stats stats;
115
116 /* unsigned int phymode; */
117 int mode;
118 int channel;
119 u8 bssid[ETH_ALEN];
120
121 u8 mac_addr[ETH_ALEN];
122 u8 revid;
123
124 struct ieee80211_supported_band band;
125};
126
127
128#define AGNX_CHAINS_MAX 6
129#define AGNX_PERIODIC_DELAY 60000 /* unit: ms */
130#define LOCAL_STAID 0 /* the station entry for the card itself */
131#define BSSID_STAID 1 /* the station entry for the bsssid AP */
132#define spi_delay() udelay(40)
133#define eeprom_delay() udelay(40)
134#define routing_table_delay() udelay(50)
135
136/* PDU pool MEM region #2 */
137#define AGNX_PDUPOOL 0x40000 /* PDU pool */
138#define AGNX_PDUPOOL_SIZE 0x8000 /* PDU pool size*/
139#define AGNX_PDU_TX_WQ 0x41000 /* PDU list TX workqueue */
140#define AGNX_PDU_FREE 0x41800 /* Free Pool */
141#define PDU_SIZE 0x80 /* Free Pool node size */
142#define PDU_FREE_CNT 0xd0 /* Free pool node count */
143
144
145/* RF stuffs */
146extern void rf_chips_init(struct agnx_priv *priv);
147extern void spi_rc_write(void __iomem *mem_region, u32 chip_ids, u32 sw);
148extern void calibrate_oscillator(struct agnx_priv *priv);
149extern void do_calibration(struct agnx_priv *priv);
150extern void antenna_calibrate(struct agnx_priv *priv);
151extern void __antenna_calibrate(struct agnx_priv *priv);
152extern void print_offsets(struct agnx_priv *priv);
153extern int agnx_set_channel(struct agnx_priv *priv, unsigned int channel);
154
155
156#endif /* AGNX_H_ */
diff --git a/drivers/staging/agnx/debug.h b/drivers/staging/agnx/debug.h
deleted file mode 100644
index 7947f327a214..000000000000
--- a/drivers/staging/agnx/debug.h
+++ /dev/null
@@ -1,416 +0,0 @@
1#ifndef AGNX_DEBUG_H_
2#define AGNX_DEBUG_H_
3
4#include "agnx.h"
5#include "phy.h"
6#include "sta.h"
7#include "xmit.h"
8
9#define AGNX_TRACE printk(KERN_ERR PFX "function:%s line:%d\n", __func__, __LINE__)
10
11#define PRINTK_LE16(prefix, var) printk(KERN_DEBUG PFX #prefix ": " #var " 0x%.4x\n", le16_to_cpu(var))
12#define PRINTK_LE32(prefix, var) printk(KERN_DEBUG PFX #prefix ": " #var " 0x%.8x\n", le32_to_cpu(var))
13#define PRINTK_U8(prefix, var) printk(KERN_DEBUG PFX #prefix ": " #var " 0x%.2x\n", var)
14#define PRINTK_BE16(prefix, var) printk(KERN_DEBUG PFX #prefix ": " #var " 0x%.4x\n", be16_to_cpu(var))
15#define PRINTK_BE32(prefix, var) printk(KERN_DEBUG PFX #prefix ": " #var " 0x%.8x\n", be32_to_cpu(var))
16#define PRINTK_BITS(prefix, field) printk(KERN_DEBUG PFX #prefix ": " #field ": 0x%x\n", (reg & field) >> field##_SHIFT)
17
18static inline void agnx_bug(char *reason)
19{
20 printk(KERN_ERR PFX "%s\n", reason);
21 BUG();
22}
23
24static inline void agnx_print_desc(struct agnx_desc *desc)
25{
26 u32 reg = be32_to_cpu(desc->frag);
27
28 PRINTK_BITS(DESC, PACKET_LEN);
29
30 if (reg & FIRST_FRAG) {
31 PRINTK_BITS(DESC, FIRST_PACKET_MASK);
32 PRINTK_BITS(DESC, FIRST_RESERV2);
33 PRINTK_BITS(DESC, FIRST_TKIP_ERROR);
34 PRINTK_BITS(DESC, FIRST_TKIP_PACKET);
35 PRINTK_BITS(DESC, FIRST_RESERV1);
36 PRINTK_BITS(DESC, FIRST_FRAG_LEN);
37 } else {
38 PRINTK_BITS(DESC, SUB_RESERV2);
39 PRINTK_BITS(DESC, SUB_TKIP_ERROR);
40 PRINTK_BITS(DESC, SUB_TKIP_PACKET);
41 PRINTK_BITS(DESC, SUB_RESERV1);
42 PRINTK_BITS(DESC, SUB_FRAG_LEN);
43 }
44
45 PRINTK_BITS(DESC, FIRST_FRAG);
46 PRINTK_BITS(DESC, LAST_FRAG);
47 PRINTK_BITS(DESC, OWNER);
48}
49
50
51static inline void dump_ieee80211b_phy_hdr(__be32 _11b0, __be32 _11b1)
52{
53
54}
55
56static inline void agnx_print_hdr(struct agnx_hdr *hdr)
57{
58 u32 reg;
59 int i;
60
61 reg = be32_to_cpu(hdr->reg0);
62 PRINTK_BITS(HDR, RTS);
63 PRINTK_BITS(HDR, MULTICAST);
64 PRINTK_BITS(HDR, ACK);
65 PRINTK_BITS(HDR, TM);
66 PRINTK_BITS(HDR, RELAY);
67 PRINTK_BITS(HDR, REVISED_FCS);
68 PRINTK_BITS(HDR, NEXT_BUFFER_ADDR);
69
70 reg = be32_to_cpu(hdr->reg1);
71 PRINTK_BITS(HDR, MAC_HDR_LEN);
72 PRINTK_BITS(HDR, DURATION_OVERIDE);
73 PRINTK_BITS(HDR, PHY_HDR_OVERIDE);
74 PRINTK_BITS(HDR, CRC_FAIL);
75 PRINTK_BITS(HDR, SEQUENCE_NUMBER);
76 PRINTK_BITS(HDR, BUFF_HEAD_ADDR);
77
78 reg = be32_to_cpu(hdr->reg2);
79 PRINTK_BITS(HDR, PDU_COUNT);
80 PRINTK_BITS(HDR, WEP_KEY);
81 PRINTK_BITS(HDR, USES_WEP_KEY);
82 PRINTK_BITS(HDR, KEEP_ALIVE);
83 PRINTK_BITS(HDR, BUFF_TAIL_ADDR);
84
85 reg = be32_to_cpu(hdr->reg3);
86 PRINTK_BITS(HDR, CTS_11G);
87 PRINTK_BITS(HDR, RTS_11G);
88 PRINTK_BITS(HDR, FRAG_SIZE);
89 PRINTK_BITS(HDR, PAYLOAD_LEN);
90 PRINTK_BITS(HDR, FRAG_NUM);
91
92 reg = be32_to_cpu(hdr->reg4);
93 PRINTK_BITS(HDR, RELAY_STAID);
94 PRINTK_BITS(HDR, STATION_ID);
95 PRINTK_BITS(HDR, WORKQUEUE_ID);
96
97 reg = be32_to_cpu(hdr->reg5);
98 /* printf the route flag */
99 PRINTK_BITS(HDR, ROUTE_HOST);
100 PRINTK_BITS(HDR, ROUTE_CARD_CPU);
101 PRINTK_BITS(HDR, ROUTE_ENCRYPTION);
102 PRINTK_BITS(HDR, ROUTE_TX);
103 PRINTK_BITS(HDR, ROUTE_RX1);
104 PRINTK_BITS(HDR, ROUTE_RX2);
105 PRINTK_BITS(HDR, ROUTE_COMPRESSION);
106
107 PRINTK_BE32(HDR, hdr->_11g0);
108 PRINTK_BE32(HDR, hdr->_11g1);
109 PRINTK_BE32(HDR, hdr->_11b0);
110 PRINTK_BE32(HDR, hdr->_11b1);
111
112 dump_ieee80211b_phy_hdr(hdr->_11b0, hdr->_11b1);
113
114 /* Fixme */
115 for (i = 0; i < ARRAY_SIZE(hdr->mac_hdr); i++) {
116 if (i == 0)
117 printk(KERN_DEBUG PFX "IEEE80211 HDR: ");
118 printk("%.2x ", hdr->mac_hdr[i]);
119 if (i + 1 == ARRAY_SIZE(hdr->mac_hdr))
120 printk("\n");
121 }
122
123 PRINTK_BE16(HDR, hdr->rts_duration);
124 PRINTK_BE16(HDR, hdr->last_duration);
125 PRINTK_BE16(HDR, hdr->sec_last_duration);
126 PRINTK_BE16(HDR, hdr->other_duration);
127 PRINTK_BE16(HDR, hdr->tx_other_duration);
128 PRINTK_BE16(HDR, hdr->last_11g_len);
129 PRINTK_BE16(HDR, hdr->other_11g_len);
130 PRINTK_BE16(HDR, hdr->last_11b_len);
131 PRINTK_BE16(HDR, hdr->other_11b_len);
132
133 /* FIXME */
134 reg = be16_to_cpu(hdr->reg6);
135 PRINTK_BITS(HDR, MBF);
136 PRINTK_BITS(HDR, RSVD4);
137
138 PRINTK_BE16(HDR, hdr->rx_frag_stat);
139
140 PRINTK_BE32(HDR, hdr->time_stamp);
141 PRINTK_BE32(HDR, hdr->phy_stats_hi);
142 PRINTK_BE32(HDR, hdr->phy_stats_lo);
143 PRINTK_BE32(HDR, hdr->mic_key0);
144 PRINTK_BE32(HDR, hdr->mic_key1);
145} /* agnx_print_hdr */
146
147
148static inline void agnx_print_rx_hdr(struct agnx_hdr *hdr)
149{
150 agnx_print_hdr(hdr);
151
152 PRINTK_BE16(HDR, hdr->rx.rx_packet_duration);
153 PRINTK_BE16(HDR, hdr->rx.replay_cnt);
154
155 PRINTK_U8(HDR, hdr->rx_channel);
156}
157
158static inline void agnx_print_tx_hdr(struct agnx_hdr *hdr)
159{
160 agnx_print_hdr(hdr);
161
162 PRINTK_U8(HDR, hdr->tx.long_retry_limit);
163 PRINTK_U8(HDR, hdr->tx.short_retry_limit);
164 PRINTK_U8(HDR, hdr->tx.long_retry_cnt);
165 PRINTK_U8(HDR, hdr->tx.short_retry_cnt);
166
167 PRINTK_U8(HDR, hdr->rx_channel);
168}
169
170static inline void
171agnx_print_sta_power(struct agnx_priv *priv, unsigned int sta_idx)
172{
173 struct agnx_sta_power power;
174 u32 reg;
175
176 get_sta_power(priv, &power, sta_idx);
177
178 reg = le32_to_cpu(power.reg);
179 PRINTK_BITS(STA_POWER, SIGNAL);
180 PRINTK_BITS(STA_POWER, RATE);
181 PRINTK_BITS(STA_POWER, TIFS);
182 PRINTK_BITS(STA_POWER, EDCF);
183 PRINTK_BITS(STA_POWER, CHANNEL_BOND);
184 PRINTK_BITS(STA_POWER, PHY_MODE);
185 PRINTK_BITS(STA_POWER, POWER_LEVEL);
186 PRINTK_BITS(STA_POWER, NUM_TRANSMITTERS);
187}
188
189static inline void
190agnx_print_sta_tx_wq(struct agnx_priv *priv, unsigned int sta_idx, unsigned int wq_idx)
191{
192 struct agnx_sta_tx_wq tx_wq;
193 u32 reg;
194
195 get_sta_tx_wq(priv, &tx_wq, sta_idx, wq_idx);
196
197 reg = le32_to_cpu(tx_wq.reg0);
198 PRINTK_BITS(STA_TX_WQ, TAIL_POINTER);
199 PRINTK_BITS(STA_TX_WQ, HEAD_POINTER_LOW);
200
201 reg = le32_to_cpu(tx_wq.reg3);
202 PRINTK_BITS(STA_TX_WQ, HEAD_POINTER_HIGH);
203 PRINTK_BITS(STA_TX_WQ, ACK_POINTER_LOW);
204
205 reg = le32_to_cpu(tx_wq.reg1);
206 PRINTK_BITS(STA_TX_WQ, ACK_POINTER_HIGH);
207 PRINTK_BITS(STA_TX_WQ, HEAD_TIMOUT_TAIL_PACK_CNT);
208 PRINTK_BITS(STA_TX_WQ, ACK_TIMOUT_TAIL_PACK_CNT);
209
210 reg = le32_to_cpu(tx_wq.reg2);
211 PRINTK_BITS(STA_TX_WQ, HEAD_TIMOUT_WIN_LIM_BYTE_CNT);
212 PRINTK_BITS(STA_TX_WQ, HEAD_TIMOUT_WIN_LIM_FRAG_CNT);
213 PRINTK_BITS(STA_TX_WQ, WORK_QUEUE_ACK_TYPE);
214 PRINTK_BITS(STA_TX_WQ, WORK_QUEUE_VALID);
215}
216
217static inline void agnx_print_sta_traffic(struct agnx_sta_traffic *traffic)
218{
219 u32 reg;
220
221 reg = le32_to_cpu(traffic->reg0);
222 PRINTK_BITS(STA_TRAFFIC, ACK_TIMOUT_CNT);
223 PRINTK_BITS(STA_TRAFFIC, TRAFFIC_ACK_TYPE);
224 PRINTK_BITS(STA_TRAFFIC, NEW_PACKET);
225 PRINTK_BITS(STA_TRAFFIC, TRAFFIC_VALID);
226 PRINTK_BITS(STA_TRAFFIC, RX_HDR_DESC_POINTER);
227
228 reg = le32_to_cpu(traffic->reg1);
229 PRINTK_BITS(STA_TRAFFIC, RX_PACKET_TIMESTAMP);
230 PRINTK_BITS(STA_TRAFFIC, TRAFFIC_RESERVED);
231 PRINTK_BITS(STA_TRAFFIC, SV);
232 PRINTK_BITS(STA_TRAFFIC, RX_SEQUENCE_NUM);
233
234 PRINTK_LE32(STA_TRAFFIC, traffic->tx_replay_cnt_low);
235
236 PRINTK_LE16(STA_TRAFFIC, traffic->tx_replay_cnt_high);
237 PRINTK_LE16(STA_TRAFFIC, traffic->rx_replay_cnt_high);
238
239 PRINTK_LE32(STA_TRAFFIC, traffic->rx_replay_cnt_low);
240}
241
242static inline void agnx_print_sta(struct agnx_priv *priv, unsigned int sta_idx)
243{
244 struct agnx_sta station;
245 struct agnx_sta *sta = &station;
246 u32 reg;
247 unsigned int i;
248
249 get_sta(priv, sta, sta_idx);
250
251 for (i = 0; i < 4; i++)
252 PRINTK_LE32(STA, sta->tx_session_keys[i]);
253 for (i = 0; i < 4; i++)
254 PRINTK_LE32(STA, sta->rx_session_keys[i]);
255
256 reg = le32_to_cpu(sta->reg);
257 PRINTK_BITS(STA, ID_1);
258 PRINTK_BITS(STA, ID_0);
259 PRINTK_BITS(STA, ENABLE_CONCATENATION);
260 PRINTK_BITS(STA, ENABLE_DECOMPRESSION);
261 PRINTK_BITS(STA, STA_RESERVED);
262 PRINTK_BITS(STA, EAP);
263 PRINTK_BITS(STA, ED_NULL);
264 PRINTK_BITS(STA, ENCRYPTION_POLICY);
265 PRINTK_BITS(STA, DEFINED_KEY_ID);
266 PRINTK_BITS(STA, FIXED_KEY);
267 PRINTK_BITS(STA, KEY_VALID);
268 PRINTK_BITS(STA, STATION_VALID);
269
270 PRINTK_LE32(STA, sta->tx_aes_blks_unicast);
271 PRINTK_LE32(STA, sta->rx_aes_blks_unicast);
272
273 PRINTK_LE16(STA, sta->aes_format_err_unicast_cnt);
274 PRINTK_LE16(STA, sta->aes_replay_unicast);
275
276 PRINTK_LE16(STA, sta->aes_decrypt_err_unicast);
277 PRINTK_LE16(STA, sta->aes_decrypt_err_default);
278
279 PRINTK_LE16(STA, sta->single_retry_packets);
280 PRINTK_LE16(STA, sta->failed_tx_packets);
281
282 PRINTK_LE16(STA, sta->muti_retry_packets);
283 PRINTK_LE16(STA, sta->ack_timeouts);
284
285 PRINTK_LE16(STA, sta->frag_tx_cnt);
286 PRINTK_LE16(STA, sta->rts_brq_sent);
287
288 PRINTK_LE16(STA, sta->tx_packets);
289 PRINTK_LE16(STA, sta->cts_back_timeout);
290
291 PRINTK_LE32(STA, sta->phy_stats_high);
292 PRINTK_LE32(STA, sta->phy_stats_low);
293
294 /* for (i = 0; i < 8; i++) */
295 agnx_print_sta_traffic(sta->traffic + 0);
296
297 PRINTK_LE16(STA, sta->traffic_class0_frag_success);
298 PRINTK_LE16(STA, sta->traffic_class1_frag_success);
299 PRINTK_LE16(STA, sta->traffic_class2_frag_success);
300 PRINTK_LE16(STA, sta->traffic_class3_frag_success);
301 PRINTK_LE16(STA, sta->traffic_class4_frag_success);
302 PRINTK_LE16(STA, sta->traffic_class5_frag_success);
303 PRINTK_LE16(STA, sta->traffic_class6_frag_success);
304 PRINTK_LE16(STA, sta->traffic_class7_frag_success);
305
306 PRINTK_LE16(STA, sta->num_frag_non_prime_rates);
307 PRINTK_LE16(STA, sta->ack_timeout_non_prime_rates);
308}
309
310
311static inline void dump_ieee80211_hdr(struct ieee80211_hdr *hdr, char *tag)
312{
313 u16 fctl;
314 int hdrlen;
315
316 fctl = le16_to_cpu(hdr->frame_control);
317 switch (fctl & IEEE80211_FCTL_FTYPE) {
318 case IEEE80211_FTYPE_DATA:
319 printk(PFX "%s DATA ", tag);
320 break;
321 case IEEE80211_FTYPE_CTL:
322 printk(PFX "%s CTL ", tag);
323 break;
324 case IEEE80211_FTYPE_MGMT:
325 printk(PFX "%s MGMT ", tag);
326 switch (fctl & IEEE80211_FCTL_STYPE) {
327 case IEEE80211_STYPE_ASSOC_REQ:
328 printk("SubType: ASSOC_REQ ");
329 break;
330 case IEEE80211_STYPE_ASSOC_RESP:
331 printk("SubType: ASSOC_RESP ");
332 break;
333 case IEEE80211_STYPE_REASSOC_REQ:
334 printk("SubType: REASSOC_REQ ");
335 break;
336 case IEEE80211_STYPE_REASSOC_RESP:
337 printk("SubType: REASSOC_RESP ");
338 break;
339 case IEEE80211_STYPE_PROBE_REQ:
340 printk("SubType: PROBE_REQ ");
341 break;
342 case IEEE80211_STYPE_PROBE_RESP:
343 printk("SubType: PROBE_RESP ");
344 break;
345 case IEEE80211_STYPE_BEACON:
346 printk("SubType: BEACON ");
347 break;
348 case IEEE80211_STYPE_ATIM:
349 printk("SubType: ATIM ");
350 break;
351 case IEEE80211_STYPE_DISASSOC:
352 printk("SubType: DISASSOC ");
353 break;
354 case IEEE80211_STYPE_AUTH:
355 printk("SubType: AUTH ");
356 break;
357 case IEEE80211_STYPE_DEAUTH:
358 printk("SubType: DEAUTH ");
359 break;
360 case IEEE80211_STYPE_ACTION:
361 printk("SubType: ACTION ");
362 break;
363 default:
364 printk("SubType: Unknow\n");
365 }
366 break;
367 default:
368 printk(PFX "%s Packet type: Unknow\n", tag);
369 }
370
371 hdrlen = ieee80211_hdrlen(fctl);
372
373 if (hdrlen >= 4)
374 printk("FC=0x%04x DUR=0x%04x",
375 fctl, le16_to_cpu(hdr->duration_id));
376 if (hdrlen >= 10)
377 printk(" A1=%pM", hdr->addr1);
378 if (hdrlen >= 16)
379 printk(" A2=%pM", hdr->addr2);
380 if (hdrlen >= 24)
381 printk(" A3=%pM", hdr->addr3);
382 if (hdrlen >= 30)
383 printk(" A4=%pM", hdr->addr4);
384 printk("\n");
385}
386
387static inline void dump_txm_registers(struct agnx_priv *priv)
388{
389 void __iomem *ctl = priv->ctl;
390 int i;
391 for (i = 0; i <= 0x1e8; i += 4)
392 printk(KERN_DEBUG PFX "TXM: %x---> 0x%.8x\n", i, ioread32(ctl + i));
393}
394static inline void dump_rxm_registers(struct agnx_priv *priv)
395{
396 void __iomem *ctl = priv->ctl;
397 int i;
398 for (i = 0; i <= 0x108; i += 4)
399 printk(KERN_DEBUG PFX "RXM: %x---> 0x%.8x\n", i, ioread32(ctl + 0x2000 + i));
400}
401static inline void dump_bm_registers(struct agnx_priv *priv)
402{
403 void __iomem *ctl = priv->ctl;
404 int i;
405 for (i = 0; i <= 0x90; i += 4)
406 printk(KERN_DEBUG PFX "BM: %x---> 0x%.8x\n", i, ioread32(ctl + 0x2c00 + i));
407}
408static inline void dump_cir_registers(struct agnx_priv *priv)
409{
410 void __iomem *ctl = priv->ctl;
411 int i;
412 for (i = 0; i <= 0xb8; i += 4)
413 printk(KERN_DEBUG PFX "CIR: %x---> 0x%.8x\n", i, ioread32(ctl + 0x3000 + i));
414}
415
416#endif /* AGNX_DEBUG_H_ */
diff --git a/drivers/staging/agnx/pci.c b/drivers/staging/agnx/pci.c
deleted file mode 100644
index 32b5489456a8..000000000000
--- a/drivers/staging/agnx/pci.c
+++ /dev/null
@@ -1,635 +0,0 @@
1/**
2 * Airgo MIMO wireless driver
3 *
4 * Copyright (c) 2007 Li YanBo <dreamfly281@gmail.com>
5
6 * Thanks for Jeff Williams <angelbane@gmail.com> do reverse engineer
7 * works and published the SPECS at http://airgo.wdwconsulting.net/mymoin
8
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/init.h>
15#include <linux/etherdevice.h>
16#include <linux/pci.h>
17#include <linux/delay.h>
18
19#include "agnx.h"
20#include "debug.h"
21#include "xmit.h"
22#include "phy.h"
23
24MODULE_AUTHOR("Li YanBo <dreamfly281@gmail.com>");
25MODULE_DESCRIPTION("Airgo MIMO PCI wireless driver");
26MODULE_LICENSE("GPL");
27
28static struct pci_device_id agnx_pci_id_tbl[] __devinitdata = {
29 { PCI_DEVICE(0x17cb, 0x0001) }, /* Beklin F5d8010, Netgear WGM511 etc */
30 { PCI_DEVICE(0x17cb, 0x0002) }, /* Netgear Wpnt511 */
31 { 0 }
32};
33
34MODULE_DEVICE_TABLE(pci, agnx_pci_id_tbl);
35
36
37static inline void agnx_interrupt_ack(struct agnx_priv *priv, u32 *reason)
38{
39 void __iomem *ctl = priv->ctl;
40 u32 reg;
41
42 if (*reason & AGNX_STAT_RX) {
43 /* Mark complete RX */
44 reg = ioread32(ctl + AGNX_CIR_RXCTL);
45 reg |= 0x4;
46 iowrite32(reg, ctl + AGNX_CIR_RXCTL);
47 /* disable Rx interrupt */
48 }
49 if (*reason & AGNX_STAT_TX) {
50 reg = ioread32(ctl + AGNX_CIR_TXDCTL);
51 if (reg & 0x4) {
52 iowrite32(reg, ctl + AGNX_CIR_TXDCTL);
53 *reason |= AGNX_STAT_TXD;
54 }
55 reg = ioread32(ctl + AGNX_CIR_TXMCTL);
56 if (reg & 0x4) {
57 iowrite32(reg, ctl + AGNX_CIR_TXMCTL);
58 *reason |= AGNX_STAT_TXM;
59 }
60 }
61#if 0
62 if (*reason & AGNX_STAT_X) {
63 reg = ioread32(ctl + AGNX_INT_STAT);
64 iowrite32(reg, ctl + AGNX_INT_STAT);
65 /* FIXME reinit interrupt mask */
66 reg = 0xc390bf9 & ~IRQ_TX_BEACON;
67 reg &= ~IRQ_TX_DISABLE;
68 iowrite32(reg, ctl + AGNX_INT_MASK);
69 iowrite32(0x800, ctl + AGNX_CIR_BLKCTL);
70 }
71#endif
72} /* agnx_interrupt_ack */
73
74static irqreturn_t agnx_interrupt_handler(int irq, void *dev_id)
75{
76 struct ieee80211_hw *dev = dev_id;
77 struct agnx_priv *priv = dev->priv;
78 void __iomem *ctl = priv->ctl;
79 irqreturn_t ret = IRQ_NONE;
80 u32 irq_reason;
81
82 spin_lock(&priv->lock);
83
84/* printk(KERN_ERR PFX "Get a interrupt %s\n", __func__); */
85
86 if (priv->init_status != AGNX_START)
87 goto out;
88
89 /* FiXME Here has no lock, Is this will lead to race? */
90 irq_reason = ioread32(ctl + AGNX_CIR_BLKCTL);
91 if (!(irq_reason & 0x7))
92 goto out;
93
94 ret = IRQ_HANDLED;
95 priv->irq_status = ioread32(ctl + AGNX_INT_STAT);
96
97/* printk(PFX "Interrupt reason is 0x%x\n", irq_reason); */
98 /* Make sure the txm and txd flags don't conflict with other unknown
99 interrupt flag, maybe is not necessary */
100 irq_reason &= 0xF;
101
102 disable_rx_interrupt(priv);
103 /* TODO Make sure the card finished initialized */
104 agnx_interrupt_ack(priv, &irq_reason);
105
106 if (irq_reason & AGNX_STAT_RX)
107 handle_rx_irq(priv);
108 if (irq_reason & AGNX_STAT_TXD)
109 handle_txd_irq(priv);
110 if (irq_reason & AGNX_STAT_TXM)
111 handle_txm_irq(priv);
112 if (irq_reason & AGNX_STAT_X)
113 handle_other_irq(priv);
114
115 enable_rx_interrupt(priv);
116out:
117 spin_unlock(&priv->lock);
118 return ret;
119} /* agnx_interrupt_handler */
120
121
122/* FIXME */
123static int agnx_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
124{
125 AGNX_TRACE;
126 return _agnx_tx(dev->priv, skb);
127} /* agnx_tx */
128
129
130static int agnx_get_mac_address(struct agnx_priv *priv)
131{
132 void __iomem *ctl = priv->ctl;
133 u32 reg;
134 AGNX_TRACE;
135
136 /* Attention! directly read the MAC or other date from EEPROM will
137 lead to cardbus(WGM511) lock up when write to PM PLL register */
138 reg = agnx_read32(ctl, 0x3544);
139 udelay(40);
140 reg = agnx_read32(ctl, 0x354c);
141 udelay(50);
142 /* Get the mac address */
143 reg = agnx_read32(ctl, 0x3544);
144 udelay(40);
145
146 /* HACK */
147 reg = cpu_to_le32(reg);
148 priv->mac_addr[0] = ((u8 *)&reg)[2];
149 priv->mac_addr[1] = ((u8 *)&reg)[3];
150 reg = agnx_read32(ctl, 0x3548);
151 udelay(50);
152 *((u32 *)(priv->mac_addr + 2)) = cpu_to_le32(reg);
153
154 if (!is_valid_ether_addr(priv->mac_addr)) {
155 printk(KERN_WARNING PFX "read mac %pM\n", priv->mac_addr);
156 printk(KERN_WARNING PFX "Invalid hwaddr! Using random hwaddr\n");
157 random_ether_addr(priv->mac_addr);
158 }
159
160 return 0;
161} /* agnx_get_mac_address */
162
163static int agnx_alloc_rings(struct agnx_priv *priv)
164{
165 unsigned int len;
166 AGNX_TRACE;
167
168 /* Allocate RX/TXM/TXD rings info */
169 priv->rx.size = AGNX_RX_RING_SIZE;
170 priv->txm.size = AGNX_TXM_RING_SIZE;
171 priv->txd.size = AGNX_TXD_RING_SIZE;
172
173 len = priv->rx.size + priv->txm.size + priv->txd.size;
174
175/* priv->rx.info = kzalloc(sizeof(struct agnx_info) * len, GFP_KERNEL); */
176 priv->rx.info = kzalloc(sizeof(struct agnx_info) * len, GFP_ATOMIC);
177 if (!priv->rx.info)
178 return -ENOMEM;
179 priv->txm.info = priv->rx.info + priv->rx.size;
180 priv->txd.info = priv->txm.info + priv->txm.size;
181
182 /* Allocate RX/TXM/TXD descriptors */
183 priv->rx.desc = pci_alloc_consistent(priv->pdev, sizeof(struct agnx_desc) * len,
184 &priv->rx.dma);
185 if (!priv->rx.desc) {
186 kfree(priv->rx.info);
187 return -ENOMEM;
188 }
189
190 priv->txm.desc = priv->rx.desc + priv->rx.size;
191 priv->txm.dma = priv->rx.dma + sizeof(struct agnx_desc) * priv->rx.size;
192 priv->txd.desc = priv->txm.desc + priv->txm.size;
193 priv->txd.dma = priv->txm.dma + sizeof(struct agnx_desc) * priv->txm.size;
194
195 return 0;
196} /* agnx_alloc_rings */
197
198static void rings_free(struct agnx_priv *priv)
199{
200 unsigned int len = priv->rx.size + priv->txm.size + priv->txd.size;
201 unsigned long flags;
202 AGNX_TRACE;
203
204 spin_lock_irqsave(&priv->lock, flags);
205 kfree(priv->rx.info);
206 pci_free_consistent(priv->pdev, sizeof(struct agnx_desc) * len,
207 priv->rx.desc, priv->rx.dma);
208 spin_unlock_irqrestore(&priv->lock, flags);
209}
210
211#if 0
212static void agnx_periodic_work_handler(struct work_struct *work)
213{
214 struct agnx_priv *priv = container_of(work, struct agnx_priv, periodic_work.work);
215/* unsigned long flags; */
216 unsigned long delay;
217
218 /* fixme: using mutex?? */
219/* spin_lock_irqsave(&priv->lock, flags); */
220
221 /* TODO Recalibrate*/
222/* calibrate_oscillator(priv); */
223/* antenna_calibrate(priv); */
224/* agnx_send_packet(priv, 997); */
225 /* FIXME */
226/* if (debug == 3) */
227/* delay = msecs_to_jiffies(AGNX_PERIODIC_DELAY); */
228/* else */
229 delay = msecs_to_jiffies(AGNX_PERIODIC_DELAY);
230/* delay = round_jiffies(HZ * 15); */
231
232 queue_delayed_work(priv->hw->workqueue, &priv->periodic_work, delay);
233
234/* spin_unlock_irqrestore(&priv->lock, flags); */
235}
236#endif
237
238static int agnx_start(struct ieee80211_hw *dev)
239{
240 struct agnx_priv *priv = dev->priv;
241 /* unsigned long delay; */
242 int err = 0;
243 AGNX_TRACE;
244
245 err = agnx_alloc_rings(priv);
246 if (err) {
247 printk(KERN_ERR PFX "Can't alloc RX/TXM/TXD rings\n");
248 goto out;
249 }
250 err = request_irq(priv->pdev->irq, &agnx_interrupt_handler,
251 IRQF_SHARED, "agnx_pci", dev);
252 if (err) {
253 printk(KERN_ERR PFX "Failed to register IRQ handler\n");
254 rings_free(priv);
255 goto out;
256 }
257
258/* mdelay(500); */
259
260 might_sleep();
261 agnx_hw_init(priv);
262
263/* mdelay(500); */
264 might_sleep();
265
266 priv->init_status = AGNX_START;
267/* INIT_DELAYED_WORK(&priv->periodic_work, agnx_periodic_work_handler); */
268/* delay = msecs_to_jiffies(AGNX_PERIODIC_DELAY); */
269/* queue_delayed_work(priv->hw->workqueue, &priv->periodic_work, delay); */
270out:
271 return err;
272} /* agnx_start */
273
274static void agnx_stop(struct ieee80211_hw *dev)
275{
276 struct agnx_priv *priv = dev->priv;
277 AGNX_TRACE;
278
279 priv->init_status = AGNX_STOP;
280 /* make sure hardware will not generate irq */
281 agnx_hw_reset(priv);
282 free_irq(priv->pdev->irq, dev);
283/* flush_workqueue(priv->hw->workqueue); */
284/* cancel_delayed_work_sync(&priv->periodic_work); */
285 unfill_rings(priv);
286 rings_free(priv);
287}
288
289static int agnx_config(struct ieee80211_hw *dev, u32 changed)
290{
291 struct agnx_priv *priv = dev->priv;
292 struct ieee80211_conf *conf = &dev->conf;
293 int channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
294 AGNX_TRACE;
295
296 spin_lock(&priv->lock);
297 /* FIXME need priv lock? */
298 if (channel != priv->channel) {
299 priv->channel = channel;
300 agnx_set_channel(priv, priv->channel);
301 }
302
303 spin_unlock(&priv->lock);
304 return 0;
305}
306
307static void agnx_bss_info_changed(struct ieee80211_hw *dev,
308 struct ieee80211_vif *vif,
309 struct ieee80211_bss_conf *conf,
310 u32 changed)
311{
312 struct agnx_priv *priv = dev->priv;
313 void __iomem *ctl = priv->ctl;
314 AGNX_TRACE;
315
316 if (!(changed & BSS_CHANGED_BSSID))
317 return;
318
319 spin_lock(&priv->lock);
320
321 if (memcmp(conf->bssid, priv->bssid, ETH_ALEN)) {
322 agnx_set_bssid(priv, conf->bssid);
323 memcpy(priv->bssid, conf->bssid, ETH_ALEN);
324 hash_write(priv, conf->bssid, BSSID_STAID);
325 sta_init(priv, BSSID_STAID);
326 /* FIXME needed? */
327 sta_power_init(priv, BSSID_STAID);
328 agnx_write32(ctl, AGNX_BM_MTSM, 0xff & ~0x1);
329 }
330 spin_unlock(&priv->lock);
331} /* agnx_bss_info_changed */
332
333
334static void agnx_configure_filter(struct ieee80211_hw *dev,
335 unsigned int changed_flags,
336 unsigned int *total_flags,
337 int mc_count, struct dev_mc_list *mclist)
338{
339 unsigned int new_flags = 0;
340
341 *total_flags = new_flags;
342 /* TODO */
343}
344
345static int agnx_add_interface(struct ieee80211_hw *dev,
346 struct ieee80211_if_init_conf *conf)
347{
348 struct agnx_priv *priv = dev->priv;
349 AGNX_TRACE;
350
351 spin_lock(&priv->lock);
352 /* FIXME */
353 if (priv->mode != NL80211_IFTYPE_MONITOR)
354 return -EOPNOTSUPP;
355
356 switch (conf->type) {
357 case NL80211_IFTYPE_STATION:
358 priv->mode = conf->type;
359 break;
360 default:
361 return -EOPNOTSUPP;
362 }
363
364 spin_unlock(&priv->lock);
365
366 return 0;
367}
368
369static void agnx_remove_interface(struct ieee80211_hw *dev,
370 struct ieee80211_if_init_conf *conf)
371{
372 struct agnx_priv *priv = dev->priv;
373 AGNX_TRACE;
374
375 /* TODO */
376 priv->mode = NL80211_IFTYPE_MONITOR;
377}
378
379static int agnx_get_stats(struct ieee80211_hw *dev,
380 struct ieee80211_low_level_stats *stats)
381{
382 struct agnx_priv *priv = dev->priv;
383 AGNX_TRACE;
384 spin_lock(&priv->lock);
385 /* TODO !! */
386 memcpy(stats, &priv->stats, sizeof(*stats));
387 spin_unlock(&priv->lock);
388
389 return 0;
390}
391
392static u64 agnx_get_tsft(struct ieee80211_hw *dev)
393{
394 void __iomem *ctl = ((struct agnx_priv *)dev->priv)->ctl;
395 u32 tsftl;
396 u64 tsft;
397 AGNX_TRACE;
398
399 /* FIXME */
400 tsftl = ioread32(ctl + AGNX_TXM_TIMESTAMPLO);
401 tsft = ioread32(ctl + AGNX_TXM_TIMESTAMPHI);
402 tsft <<= 32;
403 tsft |= tsftl;
404
405 return tsft;
406}
407
408static int agnx_get_tx_stats(struct ieee80211_hw *dev,
409 struct ieee80211_tx_queue_stats *stats)
410{
411 struct agnx_priv *priv = dev->priv;
412 AGNX_TRACE;
413
414 /* FIXME now we just using txd queue, but should using txm queue too */
415 stats[0].len = (priv->txd.idx - priv->txd.idx_sent) / 2;
416 stats[0].limit = priv->txd.size - 2;
417 stats[0].count = priv->txd.idx / 2;
418
419 return 0;
420}
421
422static struct ieee80211_ops agnx_ops = {
423 .tx = agnx_tx,
424 .start = agnx_start,
425 .stop = agnx_stop,
426 .add_interface = agnx_add_interface,
427 .remove_interface = agnx_remove_interface,
428 .config = agnx_config,
429 .bss_info_changed = agnx_bss_info_changed,
430 .configure_filter = agnx_configure_filter,
431 .get_stats = agnx_get_stats,
432 .get_tx_stats = agnx_get_tx_stats,
433 .get_tsf = agnx_get_tsft
434};
435
436static void __devexit agnx_pci_remove(struct pci_dev *pdev)
437{
438 struct ieee80211_hw *dev = pci_get_drvdata(pdev);
439 struct agnx_priv *priv;
440 AGNX_TRACE;
441
442 if (!dev)
443 return;
444 priv = dev->priv;
445 ieee80211_unregister_hw(dev);
446 pci_iounmap(pdev, priv->ctl);
447 pci_iounmap(pdev, priv->data);
448 pci_release_regions(pdev);
449 pci_disable_device(pdev);
450
451 ieee80211_free_hw(dev);
452}
453
454static int __devinit agnx_pci_probe(struct pci_dev *pdev,
455 const struct pci_device_id *id)
456{
457 struct ieee80211_hw *dev;
458 struct agnx_priv *priv;
459 int err;
460
461 err = pci_enable_device(pdev);
462 if (err) {
463 dev_err(&pdev->dev, "can't enable pci device\n");
464 return err;
465 }
466
467 err = pci_request_regions(pdev, "agnx-pci");
468 if (err) {
469 dev_err(&pdev->dev, "can't reserve PCI resources\n");
470 return err;
471 }
472
473 if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) ||
474 pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
475 dev_err(&pdev->dev, "no suitable DMA available\n");
476 err = -EIO;
477 goto err_free_reg;
478 }
479
480 pci_set_master(pdev);
481
482 dev = ieee80211_alloc_hw(sizeof(*priv), &agnx_ops);
483 if (!dev) {
484 dev_err(&pdev->dev, "ieee80211 alloc failed\n");
485 err = -ENOMEM;
486 goto err_free_reg;
487 }
488 priv = dev->priv;
489 memset(priv, 0, sizeof(*priv));
490 priv->mode = NL80211_IFTYPE_MONITOR;
491 priv->pdev = pdev;
492 priv->hw = dev;
493 spin_lock_init(&priv->lock);
494 priv->init_status = AGNX_UNINIT;
495
496 priv->ctl = pci_iomap(pdev, 0, 0);
497/* dev_dbg(&pdev->dev, "MEM1 mapped address is 0x%p\n", priv->ctl); */
498 if (!priv->ctl) {
499 dev_err(&pdev->dev, "can't map device memory\n");
500 err = -ENOMEM;
501 goto err_free_dev;
502 }
503 priv->data = pci_iomap(pdev, 1, 0);
504 if (!priv->data) {
505 dev_err(&pdev->dev, "can't map device memory\n");
506 err = -ENOMEM;
507 goto err_iounmap2;
508 }
509
510 pci_read_config_byte(pdev, PCI_REVISION_ID, &priv->revid);
511
512 priv->band.channels = (struct ieee80211_channel *)agnx_channels;
513 priv->band.n_channels = ARRAY_SIZE(agnx_channels);
514 priv->band.bitrates = (struct ieee80211_rate *)agnx_rates_80211g;
515 priv->band.n_bitrates = ARRAY_SIZE(agnx_rates_80211g);
516
517 /* Init ieee802.11 dev */
518 SET_IEEE80211_DEV(dev, &pdev->dev);
519 pci_set_drvdata(pdev, dev);
520 dev->extra_tx_headroom = sizeof(struct agnx_hdr);
521
522 /* FIXME It only include FCS in promious mode but not manage mode */
523/* dev->flags = IEEE80211_HW_RX_INCLUDES_FCS; */
524 dev->channel_change_time = 5000;
525 dev->max_signal = 100;
526 /* FIXME */
527 dev->queues = 1;
528
529 agnx_get_mac_address(priv);
530
531 SET_IEEE80211_PERM_ADDR(dev, priv->mac_addr);
532
533/* /\* FIXME *\/ */
534/* for (i = 1; i < NUM_DRIVE_MODES; i++) { */
535/* err = ieee80211_register_hwmode(dev, &priv->modes[i]); */
536/* if (err) { */
537/* printk(KERN_ERR PFX "Can't register hwmode\n"); */
538/* goto err_iounmap; */
539/* } */
540/* } */
541
542 priv->channel = 1;
543 dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band;
544
545 err = ieee80211_register_hw(dev);
546 if (err) {
547 dev_err(&pdev->dev, "can't register hardware\n");
548 goto err_iounmap;
549 }
550
551 agnx_hw_reset(priv);
552
553 dev_info(&pdev->dev, "%s: hwaddr %pM, Rev 0x%02x\n",
554 wiphy_name(dev->wiphy),
555 dev->wiphy->perm_addr, priv->revid);
556 return 0;
557
558 err_iounmap:
559 pci_iounmap(pdev, priv->data);
560
561 err_iounmap2:
562 pci_iounmap(pdev, priv->ctl);
563
564 err_free_dev:
565 pci_set_drvdata(pdev, NULL);
566 ieee80211_free_hw(dev);
567
568 err_free_reg:
569 pci_release_regions(pdev);
570
571 pci_disable_device(pdev);
572 return err;
573} /* agnx_pci_probe*/
574
575#ifdef CONFIG_PM
576
577static int agnx_pci_suspend(struct pci_dev *pdev, pm_message_t state)
578{
579 struct ieee80211_hw *dev = pci_get_drvdata(pdev);
580 AGNX_TRACE;
581
582 ieee80211_stop_queues(dev);
583 agnx_stop(dev);
584
585 pci_save_state(pdev);
586 pci_set_power_state(pdev, pci_choose_state(pdev, state));
587 return 0;
588}
589
590static int agnx_pci_resume(struct pci_dev *pdev)
591{
592 struct ieee80211_hw *dev = pci_get_drvdata(pdev);
593 AGNX_TRACE;
594
595 pci_set_power_state(pdev, PCI_D0);
596 pci_restore_state(pdev);
597
598 agnx_start(dev);
599 ieee80211_wake_queues(dev);
600
601 return 0;
602}
603
604#else
605
606#define agnx_pci_suspend NULL
607#define agnx_pci_resume NULL
608
609#endif /* CONFIG_PM */
610
611
612static struct pci_driver agnx_pci_driver = {
613 .name = "agnx-pci",
614 .id_table = agnx_pci_id_tbl,
615 .probe = agnx_pci_probe,
616 .remove = __devexit_p(agnx_pci_remove),
617 .suspend = agnx_pci_suspend,
618 .resume = agnx_pci_resume,
619};
620
621static int __init agnx_pci_init(void)
622{
623 AGNX_TRACE;
624 return pci_register_driver(&agnx_pci_driver);
625}
626
627static void __exit agnx_pci_exit(void)
628{
629 AGNX_TRACE;
630 pci_unregister_driver(&agnx_pci_driver);
631}
632
633
634module_init(agnx_pci_init);
635module_exit(agnx_pci_exit);
diff --git a/drivers/staging/agnx/phy.c b/drivers/staging/agnx/phy.c
deleted file mode 100644
index ec1ca86fa0c4..000000000000
--- a/drivers/staging/agnx/phy.c
+++ /dev/null
@@ -1,960 +0,0 @@
1/**
2 * Airgo MIMO wireless driver
3 *
4 * Copyright (c) 2007 Li YanBo <dreamfly281@gmail.com>
5
6 * Thanks for Jeff Williams <angelbane@gmail.com> do reverse engineer
7 * works and published the SPECS at http://airgo.wdwconsulting.net/mymoin
8
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/init.h>
15#include <linux/etherdevice.h>
16#include <linux/pci.h>
17#include <linux/delay.h>
18#include "agnx.h"
19#include "debug.h"
20#include "phy.h"
21#include "table.h"
22#include "sta.h"
23#include "xmit.h"
24
25u8 read_from_eeprom(struct agnx_priv *priv, u16 address)
26{
27 void __iomem *ctl = priv->ctl;
28 struct agnx_eeprom cmd;
29 u32 reg;
30
31 memset(&cmd, 0, sizeof(cmd));
32 cmd.cmd = EEPROM_CMD_READ << AGNX_EEPROM_COMMAND_SHIFT;
33 cmd.address = address;
34 /* Verify that the Status bit is clear */
35 /* Read Command and Address are written to the Serial Interface */
36 iowrite32(*(__le32 *)&cmd, ctl + AGNX_CIR_SERIALITF);
37 /* Wait for the Status bit to clear again */
38 eeprom_delay();
39 /* Read from Data */
40 reg = ioread32(ctl + AGNX_CIR_SERIALITF);
41
42 cmd = *(struct agnx_eeprom *)&reg;
43
44 return cmd.data;
45}
46
47static int card_full_reset(struct agnx_priv *priv)
48{
49 void __iomem *ctl = priv->ctl;
50 u32 reg;
51 AGNX_TRACE;
52
53 reg = agnx_read32(ctl, AGNX_CIR_BLKCTL);
54 agnx_write32(ctl, AGNX_CIR_BLKCTL, 0x80);
55 reg = agnx_read32(ctl, AGNX_CIR_BLKCTL);
56 return 0;
57}
58
59inline void enable_power_saving(struct agnx_priv *priv)
60{
61 void __iomem *ctl = priv->ctl;
62 u32 reg;
63
64 reg = agnx_read32(ctl, AGNX_PM_PMCTL);
65 reg &= ~0x8;
66 agnx_write32(ctl, AGNX_PM_PMCTL, reg);
67}
68
69inline void disable_power_saving(struct agnx_priv *priv)
70{
71 void __iomem *ctl = priv->ctl;
72 u32 reg;
73
74 reg = agnx_read32(ctl, AGNX_PM_PMCTL);
75 reg |= 0x8;
76 agnx_write32(ctl, AGNX_PM_PMCTL, reg);
77}
78
79
80void disable_receiver(struct agnx_priv *priv)
81{
82 void __iomem *ctl = priv->ctl;
83 AGNX_TRACE;
84
85 /* FIXME Disable the receiver */
86 agnx_write32(ctl, AGNX_GCR_DISCOVMOD, 0x0);
87 /* Set gain control reset */
88 agnx_write32(ctl, AGNX_GCR_RSTGCTL, 0x1);
89 /* Reset gain control reset */
90 agnx_write32(ctl, AGNX_GCR_RSTGCTL, 0x0);
91}
92
93
94/* Fixme this shoule be disable RX, above is enable RX */
95void enable_receiver(struct agnx_priv *priv)
96{
97 void __iomem *ctl = priv->ctl;
98 AGNX_TRACE;
99
100 /* Set adaptive gain control discovery mode */
101 agnx_write32(ctl, AGNX_GCR_DISCOVMOD, 0x3);
102 /* Set gain control reset */
103 agnx_write32(ctl, AGNX_GCR_RSTGCTL, 0x1);
104 /* Clear gain control reset */
105 agnx_write32(ctl, AGNX_GCR_RSTGCTL, 0x0);
106}
107
108static void mac_address_set(struct agnx_priv *priv)
109{
110 void __iomem *ctl = priv->ctl;
111 u8 *mac_addr = priv->mac_addr;
112 u32 reg;
113
114 /* FIXME */
115 reg = (mac_addr[0] << 24) | (mac_addr[1] << 16) | mac_addr[2] << 8 | mac_addr[3];
116 iowrite32(reg, ctl + AGNX_RXM_MACHI);
117 reg = (mac_addr[4] << 8) | mac_addr[5];
118 iowrite32(reg, ctl + AGNX_RXM_MACLO);
119}
120
121static void receiver_bssid_set(struct agnx_priv *priv, const u8 *bssid)
122{
123 void __iomem *ctl = priv->ctl;
124 u32 reg;
125
126 disable_receiver(priv);
127 /* FIXME */
128 reg = bssid[0] << 24 | (bssid[1] << 16) | (bssid[2] << 8) | bssid[3];
129 iowrite32(reg, ctl + AGNX_RXM_BSSIDHI);
130 reg = (bssid[4] << 8) | bssid[5];
131 iowrite32(reg, ctl + AGNX_RXM_BSSIDLO);
132
133 /* Enable the receiver */
134 enable_receiver(priv);
135
136 /* Clear the TSF */
137/* agnx_write32(ctl, AGNX_TXM_TSFLO, 0x0); */
138/* agnx_write32(ctl, AGNX_TXM_TSFHI, 0x0); */
139 /* Clear the TBTT */
140 agnx_write32(ctl, AGNX_TXM_TBTTLO, 0x0);
141 agnx_write32(ctl, AGNX_TXM_TBTTHI, 0x0);
142 disable_receiver(priv);
143} /* receiver_bssid_set */
144
145static void band_management_init(struct agnx_priv *priv)
146{
147 void __iomem *ctl = priv->ctl;
148 void __iomem *data = priv->data;
149 u32 reg;
150 int i;
151 AGNX_TRACE;
152
153 agnx_write32(ctl, AGNX_BM_TXWADDR, AGNX_PDU_TX_WQ);
154 agnx_write32(ctl, AGNX_CIR_ADDRWIN, 0x0);
155 memset_io(data + AGNX_PDUPOOL, 0x0, AGNX_PDUPOOL_SIZE);
156 agnx_write32(ctl, AGNX_BM_BMCTL, 0x200);
157
158 agnx_write32(ctl, AGNX_BM_CIPDUWCNT, 0x40);
159 agnx_write32(ctl, AGNX_BM_SPPDUWCNT, 0x2);
160 agnx_write32(ctl, AGNX_BM_RFPPDUWCNT, 0x0);
161 agnx_write32(ctl, AGNX_BM_RHPPDUWCNT, 0x22);
162
163 /* FIXME Initialize the Free Pool Linked List */
164 /* 1. Write the Address of the Next Node ((0x41800 + node*size)/size)
165 to the first word of each node. */
166 for (i = 0; i < PDU_FREE_CNT; i++) {
167 iowrite32((AGNX_PDU_FREE + (i+1)*PDU_SIZE)/PDU_SIZE,
168 data + AGNX_PDU_FREE + (PDU_SIZE * i));
169 /* The last node should be set to 0x0 */
170 if ((i + 1) == PDU_FREE_CNT)
171 memset_io(data + AGNX_PDU_FREE + (PDU_SIZE * i),
172 0x0, PDU_SIZE);
173 }
174
175 /* Head is First Pool address (0x41800) / size (0x80) */
176 agnx_write32(ctl, AGNX_BM_FPLHP, AGNX_PDU_FREE/PDU_SIZE);
177 /* Tail is Last Pool Address (0x47f80) / size (0x80) */
178 agnx_write32(ctl, AGNX_BM_FPLTP, 0x47f80/PDU_SIZE);
179 /* Count is Number of Nodes in the Pool (0xd0) */
180 agnx_write32(ctl, AGNX_BM_FPCNT, PDU_FREE_CNT);
181
182 /* Start all workqueue */
183 agnx_write32(ctl, AGNX_BM_CIWQCTL, 0x80000);
184 agnx_write32(ctl, AGNX_BM_CPULWCTL, 0x80000);
185 agnx_write32(ctl, AGNX_BM_CPUHWCTL, 0x80000);
186 agnx_write32(ctl, AGNX_BM_CPUTXWCTL, 0x80000);
187 agnx_write32(ctl, AGNX_BM_CPURXWCTL, 0x80000);
188 agnx_write32(ctl, AGNX_BM_SPRXWCTL, 0x80000);
189 agnx_write32(ctl, AGNX_BM_SPTXWCTL, 0x80000);
190 agnx_write32(ctl, AGNX_BM_RFPWCTL, 0x80000);
191
192 /* Enable the Band Management */
193 reg = agnx_read32(ctl, AGNX_BM_BMCTL);
194 reg |= 0x1;
195 agnx_write32(ctl, AGNX_BM_BMCTL, reg);
196} /* band_managment_init */
197
198
199static void system_itf_init(struct agnx_priv *priv)
200{
201 void __iomem *ctl = priv->ctl;
202 u32 reg;
203 AGNX_TRACE;
204
205 agnx_write32(ctl, AGNX_SYSITF_GPIOUT, 0x0);
206 agnx_write32(ctl, AGNX_PM_TESTPHY, 0x11e143a);
207
208 if (priv->revid == 0) {
209 reg = agnx_read32(ctl, AGNX_SYSITF_SYSMODE);
210 reg |= 0x11;
211 agnx_write32(ctl, AGNX_SYSITF_SYSMODE, reg);
212 }
213 /* ??? What is that means? it should difference for differice type
214 of cards */
215 agnx_write32(ctl, AGNX_CIR_SERIALITF, 0xfff81006);
216
217 agnx_write32(ctl, AGNX_SYSITF_GPIOIN, 0x1f0000);
218 agnx_write32(ctl, AGNX_SYSITF_GPIOUT, 0x5);
219 reg = agnx_read32(ctl, AGNX_SYSITF_GPIOIN);
220}
221
222static void encryption_init(struct agnx_priv *priv)
223{
224 void __iomem *ctl = priv->ctl;
225 AGNX_TRACE;
226
227 agnx_write32(ctl, AGNX_ENCRY_WEPKEY0, 0x0);
228 agnx_write32(ctl, AGNX_ENCRY_WEPKEY1, 0x0);
229 agnx_write32(ctl, AGNX_ENCRY_WEPKEY2, 0x0);
230 agnx_write32(ctl, AGNX_ENCRY_WEPKEY3, 0x0);
231 agnx_write32(ctl, AGNX_ENCRY_CCMRECTL, 0x8);
232}
233
234static void tx_management_init(struct agnx_priv *priv)
235{
236 void __iomem *ctl = priv->ctl;
237 void __iomem *data = priv->data;
238 u32 reg;
239 AGNX_TRACE;
240
241 /* Fill out the ComputationalEngineLookupTable
242 * starting at memory #2 offset 0x800
243 */
244 tx_engine_lookup_tbl_init(priv);
245 memset_io(data + 0x1000, 0, 0xfe0);
246 /* Enable Transmission Management Functions */
247 agnx_write32(ctl, AGNX_TXM_ETMF, 0x3ff);
248 /* Write 0x3f to Transmission Template */
249 agnx_write32(ctl, AGNX_TXM_TXTEMP, 0x3f);
250
251 if (priv->revid >= 2)
252 agnx_write32(ctl, AGNX_TXM_SIFSPIFS, 0x1e140a0b);
253 else
254 agnx_write32(ctl, AGNX_TXM_SIFSPIFS, 0x1e190a0b);
255
256 reg = agnx_read32(ctl, AGNX_TXM_TIFSEIFS);
257 reg &= 0xff00;
258 reg |= 0xb;
259 agnx_write32(ctl, AGNX_TXM_TIFSEIFS, reg);
260 reg = agnx_read32(ctl, AGNX_TXM_TIFSEIFS);
261 reg &= 0xffff00ff;
262 reg |= 0xa00;
263 agnx_write32(ctl, AGNX_TXM_TIFSEIFS, reg);
264 /* Enable TIFS */
265 agnx_write32(ctl, AGNX_TXM_CTL, 0x40000);
266
267 reg = agnx_read32(ctl, AGNX_TXM_TIFSEIFS);
268 reg &= 0xff00ffff;
269 reg |= 0x510000;
270 agnx_write32(ctl, AGNX_TXM_TIFSEIFS, reg);
271 reg = agnx_read32(ctl, AGNX_TXM_PROBDELAY);
272 reg &= 0xff00ffff;
273 agnx_write32(ctl, AGNX_TXM_PROBDELAY, reg);
274 reg = agnx_read32(ctl, AGNX_TXM_TIFSEIFS);
275 reg &= 0x00ffffff;
276 reg |= 0x1c000000;
277 agnx_write32(ctl, AGNX_TXM_TIFSEIFS, reg);
278 reg = agnx_read32(ctl, AGNX_TXM_PROBDELAY);
279 reg &= 0x00ffffff;
280 reg |= 0x01000000;
281 agnx_write32(ctl, AGNX_TXM_PROBDELAY, reg);
282
283 /* # Set DIF 0-1,2-3,4-5,6-7 to defaults */
284 agnx_write32(ctl, AGNX_TXM_DIF01, 0x321d321d);
285 agnx_write32(ctl, AGNX_TXM_DIF23, 0x321d321d);
286 agnx_write32(ctl, AGNX_TXM_DIF45, 0x321d321d);
287 agnx_write32(ctl, AGNX_TXM_DIF67, 0x321d321d);
288
289 /* Max Ack timeout limit */
290 agnx_write32(ctl, AGNX_TXM_MAXACKTIM, 0x1e19);
291 /* Max RX Data Timeout count, */
292 reg = agnx_read32(ctl, AGNX_TXM_MAXRXTIME);
293 reg &= 0xffff0000;
294 reg |= 0xff;
295 agnx_write32(ctl, AGNX_TXM_MAXRXTIME, reg);
296
297 /* CF poll RX Timeout count */
298 reg = agnx_read32(ctl, AGNX_TXM_CFPOLLRXTIM);
299 reg &= 0xffff;
300 reg |= 0xff0000;
301 agnx_write32(ctl, AGNX_TXM_CFPOLLRXTIM, reg);
302
303 /* Max Timeout Exceeded count, */
304 reg = agnx_read32(ctl, AGNX_TXM_MAXTIMOUT);
305 reg &= 0xff00ffff;
306 reg |= 0x190000;
307 agnx_write32(ctl, AGNX_TXM_MAXTIMOUT, reg);
308
309 /* CF ack timeout limit for 11b */
310 reg = agnx_read32(ctl, AGNX_TXM_CFACKT11B);
311 reg &= 0xff00;
312 reg |= 0x1e;
313 agnx_write32(ctl, AGNX_TXM_CFACKT11B, reg);
314
315 /* Max CF Poll Timeout Count */
316 reg = agnx_read32(ctl, AGNX_TXM_CFPOLLRXTIM);
317 reg &= 0xffff0000;
318 reg |= 0x19;
319 agnx_write32(ctl, AGNX_TXM_CFPOLLRXTIM, reg);
320 /* CF Poll RX Timeout Count */
321 reg = agnx_read32(ctl, AGNX_TXM_CFPOLLRXTIM);
322 reg &= 0xffff0000;
323 reg |= 0x1e;
324 agnx_write32(ctl, AGNX_TXM_CFPOLLRXTIM, reg);
325
326 /* # write default to */
327 /* 1. Schedule Empty Count */
328 agnx_write32(ctl, AGNX_TXM_SCHEMPCNT, 0x5);
329 /* 2. CFP Period Count */
330 agnx_write32(ctl, AGNX_TXM_CFPERCNT, 0x1);
331 /* 3. CFP MDV */
332 agnx_write32(ctl, AGNX_TXM_CFPMDV, 0x10000);
333
334 /* Probe Delay */
335 reg = agnx_read32(ctl, AGNX_TXM_PROBDELAY);
336 reg &= 0xffff0000;
337 reg |= 0x400;
338 agnx_write32(ctl, AGNX_TXM_PROBDELAY, reg);
339
340 /* Max CCA count Slot */
341 reg = agnx_read32(ctl, AGNX_TXM_MAXCCACNTSLOT);
342 reg &= 0xffff00ff;
343 reg |= 0x900;
344 agnx_write32(ctl, AGNX_TXM_MAXCCACNTSLOT, reg);
345
346 /* Slot limit/1 msec Limit */
347 reg = agnx_read32(ctl, AGNX_TXM_SLOTLIMIT);
348 reg &= 0xff00ffff;
349 reg |= 0x140077;
350 agnx_write32(ctl, AGNX_TXM_SLOTLIMIT, reg);
351
352 /* # Set CW #(0-7) to default */
353 agnx_write32(ctl, AGNX_TXM_CW0, 0xff0007);
354 agnx_write32(ctl, AGNX_TXM_CW1, 0xff0007);
355 agnx_write32(ctl, AGNX_TXM_CW2, 0xff0007);
356 agnx_write32(ctl, AGNX_TXM_CW3, 0xff0007);
357 agnx_write32(ctl, AGNX_TXM_CW4, 0xff0007);
358 agnx_write32(ctl, AGNX_TXM_CW5, 0xff0007);
359 agnx_write32(ctl, AGNX_TXM_CW6, 0xff0007);
360 agnx_write32(ctl, AGNX_TXM_CW7, 0xff0007);
361
362 /* # Set Short/Long limit #(0-7) to default */
363 agnx_write32(ctl, AGNX_TXM_SLBEALIM0, 0xa000a);
364 agnx_write32(ctl, AGNX_TXM_SLBEALIM1, 0xa000a);
365 agnx_write32(ctl, AGNX_TXM_SLBEALIM2, 0xa000a);
366 agnx_write32(ctl, AGNX_TXM_SLBEALIM3, 0xa000a);
367 agnx_write32(ctl, AGNX_TXM_SLBEALIM4, 0xa000a);
368 agnx_write32(ctl, AGNX_TXM_SLBEALIM5, 0xa000a);
369 agnx_write32(ctl, AGNX_TXM_SLBEALIM6, 0xa000a);
370 agnx_write32(ctl, AGNX_TXM_SLBEALIM7, 0xa000a);
371
372 reg = agnx_read32(ctl, AGNX_TXM_CTL);
373 reg |= 0x1400;
374 agnx_write32(ctl, AGNX_TXM_CTL, reg);
375 /* Wait for bit 0 in Control Reg to clear */
376 udelay(80);
377 reg = agnx_read32(ctl, AGNX_TXM_CTL);
378 /* Or 0x18000 to Control reg */
379 reg = agnx_read32(ctl, AGNX_TXM_CTL);
380 reg |= 0x18000;
381 agnx_write32(ctl, AGNX_TXM_CTL, reg);
382 /* Wait for bit 0 in Control Reg to clear */
383 udelay(80);
384 reg = agnx_read32(ctl, AGNX_TXM_CTL);
385
386 /* Set Listen Interval Count to default */
387 agnx_write32(ctl, AGNX_TXM_LISINTERCNT, 0x1);
388 /* Set DTIM period count to default */
389 agnx_write32(ctl, AGNX_TXM_DTIMPERICNT, 0x2000);
390} /* tx_management_init */
391
392static void rx_management_init(struct agnx_priv *priv)
393{
394 void __iomem *ctl = priv->ctl;
395 AGNX_TRACE;
396
397 /* Initialize the Routing Table */
398 routing_table_init(priv);
399
400 if (priv->revid >= 3) {
401 agnx_write32(ctl, 0x2074, 0x1f171710);
402 agnx_write32(ctl, 0x2078, 0x10100d0d);
403 agnx_write32(ctl, 0x207c, 0x11111010);
404 } else {
405 agnx_write32(ctl, AGNX_RXM_DELAY11, 0x0);
406 }
407 agnx_write32(ctl, AGNX_RXM_REQRATE, 0x8195e00);
408}
409
410
411static void agnx_timer_init(struct agnx_priv *priv)
412{
413 void __iomem *ctl = priv->ctl;
414 AGNX_TRACE;
415
416/* /\* Write 0x249f00 (tick duration?) to Timer 1 *\/ */
417/* agnx_write32(ctl, AGNX_TIMCTL_TIMER1, 0x249f00); */
418/* /\* Write 0xe2 to Timer 1 Control *\/ */
419/* agnx_write32(ctl, AGNX_TIMCTL_TIM1CTL, 0xe2); */
420
421 /* Write 0x249f00 (tick duration?) to Timer 1 */
422 agnx_write32(ctl, AGNX_TIMCTL_TIMER1, 0x0);
423 /* Write 0xe2 to Timer 1 Control */
424 agnx_write32(ctl, AGNX_TIMCTL_TIM1CTL, 0x0);
425
426 iowrite32(0xFFFFFFFF, priv->ctl + AGNX_TXM_BEACON_CTL);
427}
428
429static void power_manage_init(struct agnx_priv *priv)
430{
431 void __iomem *ctl = priv->ctl;
432 u32 reg;
433 AGNX_TRACE;
434
435 agnx_write32(ctl, AGNX_PM_MACMSW, 0x1f);
436 agnx_write32(ctl, AGNX_PM_RFCTL, 0x1f);
437
438 reg = agnx_read32(ctl, AGNX_PM_PMCTL);
439 reg &= 0xf00f;
440 reg |= 0xa0;
441 agnx_write32(ctl, AGNX_PM_PMCTL, reg);
442
443 if (priv->revid >= 3) {
444 reg = agnx_read32(ctl, AGNX_PM_SOFTRST);
445 reg |= 0x18;
446 agnx_write32(ctl, AGNX_PM_SOFTRST, reg);
447 }
448} /* power_manage_init */
449
450
451static void gain_ctlcnt_init(struct agnx_priv *priv)
452{
453 void __iomem *ctl = priv->ctl;
454 u32 reg;
455 AGNX_TRACE;
456
457 agnx_write32(ctl, AGNX_GCR_TRACNT5, 0x119);
458 agnx_write32(ctl, AGNX_GCR_TRACNT6, 0x118);
459 agnx_write32(ctl, AGNX_GCR_TRACNT7, 0x117);
460
461 reg = agnx_read32(ctl, AGNX_PM_PMCTL);
462 reg |= 0x8;
463 agnx_write32(ctl, AGNX_PM_PMCTL, reg);
464
465 reg = agnx_read32(ctl, AGNX_PM_PMCTL);
466 reg &= ~0x8;
467 agnx_write32(ctl, AGNX_PM_PMCTL, reg);
468
469 agnx_write32(ctl, AGNX_CIR_ADDRWIN, 0x0);
470
471 /* FIXME Write the initial Station Descriptor for the card */
472 sta_init(priv, LOCAL_STAID);
473 sta_init(priv, BSSID_STAID);
474
475 /* Enable staion 0 and 1 can do TX */
476 /* It seemed if we set other bit to 1 the bit 0 will
477 be auto change to 0 */
478 agnx_write32(ctl, AGNX_BM_TXTOPEER, 0x2 | 0x1);
479/* agnx_write32(ctl, AGNX_BM_TXTOPEER, 0x1); */
480} /* gain_ctlcnt_init */
481
482
483static void phy_init(struct agnx_priv *priv)
484{
485 void __iomem *ctl = priv->ctl;
486 void __iomem *data = priv->data;
487 u32 reg;
488 AGNX_TRACE;
489
490 /* Load InitialGainTable */
491 gain_table_init(priv);
492
493 agnx_write32(ctl, AGNX_CIR_ADDRWIN, 0x2000000);
494
495 /* Clear the following offsets in Memory Range #2: */
496 memset_io(data + 0x5040, 0, 0xa * 4);
497 memset_io(data + 0x5080, 0, 0xa * 4);
498 memset_io(data + 0x50c0, 0, 0xa * 4);
499 memset_io(data + 0x5400, 0, 0x80 * 4);
500 memset_io(data + 0x6000, 0, 0x280 * 4);
501 memset_io(data + 0x7000, 0, 0x280 * 4);
502 memset_io(data + 0x8000, 0, 0x280 * 4);
503
504 /* Initialize the Following Registers According to PCI Revision ID */
505 if (priv->revid == 0) {
506 /* fixme the part hasn't been update but below has been update
507 based on WGM511 */
508 agnx_write32(ctl, AGNX_ACI_LEN, 0xf);
509 agnx_write32(ctl, AGNX_ACI_TIMER1, 0x1d);
510 agnx_write32(ctl, AGNX_ACI_TIMER2, 0x3);
511 agnx_write32(ctl, AGNX_ACI_AICCHA0OVE, 0x11);
512 agnx_write32(ctl, AGNX_ACI_AICCHA1OVE, 0x0);
513 agnx_write32(ctl, AGNX_GCR_THD0A, 0x64);
514 agnx_write32(ctl, AGNX_GCR_THD0AL, 0x4b);
515 agnx_write32(ctl, AGNX_GCR_THD0B, 0x4b);
516 agnx_write32(ctl, AGNX_GCR_DUNSAT, 0x14);
517 agnx_write32(ctl, AGNX_GCR_DSAT, 0x24);
518 agnx_write32(ctl, AGNX_GCR_DFIRCAL, 0x8);
519 agnx_write32(ctl, AGNX_GCR_DGCTL11A, 0x1a);
520 agnx_write32(ctl, AGNX_GCR_DGCTL11B, 0x3);
521 agnx_write32(ctl, AGNX_GCR_GAININIT, 0xd);
522 agnx_write32(ctl, AGNX_GCR_THNOSIG, 0x1);
523 agnx_write32(ctl, AGNX_GCR_COARSTEP, 0x7);
524 agnx_write32(ctl, AGNX_GCR_SIFST11A, 0x28);
525 agnx_write32(ctl, AGNX_GCR_SIFST11B, 0x28);
526 reg = agnx_read32(ctl, AGNX_GCR_CWDETEC);
527 reg |= 0x1;
528 agnx_write32(ctl, AGNX_GCR_CWDETEC, reg);
529 agnx_write32(ctl, AGNX_GCR_0X38, 0x1e);
530 agnx_write32(ctl, AGNX_GCR_BOACT, 0x26);
531 agnx_write32(ctl, AGNX_GCR_DISCOVMOD, 0x3);
532 agnx_write32(ctl, AGNX_GCR_NLISTANT, 0x3);
533 agnx_write32(ctl, AGNX_GCR_NACTIANT, 0x3);
534 agnx_write32(ctl, AGNX_GCR_NMEASANT, 0x3);
535 agnx_write32(ctl, AGNX_GCR_NCAPTANT, 0x3);
536 agnx_write32(ctl, AGNX_GCR_THCAP11A, 0x0);
537 agnx_write32(ctl, AGNX_GCR_THCAP11B, 0x0);
538 agnx_write32(ctl, AGNX_GCR_THCAPRX11A, 0x0);
539 agnx_write32(ctl, AGNX_GCR_THCAPRX11B, 0x0);
540 agnx_write32(ctl, AGNX_GCR_THLEVDRO, 0x10);
541 agnx_write32(ctl, AGNX_GCR_MAXRXTIME11A, 0x1);
542 agnx_write32(ctl, AGNX_GCR_MAXRXTIME11B, 0x1);
543 agnx_write32(ctl, AGNX_GCR_CORRTIME, 0x190);
544 agnx_write32(ctl, AGNX_GCR_SIGHTH, 0x78);
545 agnx_write32(ctl, AGNX_GCR_SIGLTH, 0x1c);
546 agnx_write32(ctl, AGNX_GCR_CORRDROP, 0x0);
547 agnx_write32(ctl, AGNX_GCR_THCD, 0x0);
548 agnx_write32(ctl, AGNX_GCR_MAXPOWDIFF, 0x1);
549 agnx_write32(ctl, AGNX_GCR_TESTBUS, 0x0);
550 agnx_write32(ctl, AGNX_GCR_ANTCFG, 0x1f);
551 agnx_write32(ctl, AGNX_GCR_THJUMP, 0x14);
552 agnx_write32(ctl, AGNX_GCR_THPOWER, 0x0);
553 agnx_write32(ctl, AGNX_GCR_THPOWCLIP, 0x30);
554 agnx_write32(ctl, AGNX_GCR_THD0BTFEST, 0x32);
555 agnx_write32(ctl, AGNX_GCR_THRX11BPOWMIN, 0x19);
556 agnx_write32(ctl, AGNX_GCR_0X14c, 0x0);
557 agnx_write32(ctl, AGNX_GCR_0X150, 0x0);
558 agnx_write32(ctl, 0x9400, 0x0);
559 agnx_write32(ctl, 0x940c, 0x6ff);
560 agnx_write32(ctl, 0x9428, 0xa0);
561 agnx_write32(ctl, 0x9434, 0x0);
562 agnx_write32(ctl, 0x9c04, 0x15);
563 agnx_write32(ctl, 0x9c0c, 0x7f);
564 agnx_write32(ctl, 0x9c34, 0x0);
565 agnx_write32(ctl, 0xc000, 0x38d);
566 agnx_write32(ctl, 0x14018, 0x0);
567 agnx_write32(ctl, 0x16000, 0x1);
568 agnx_write32(ctl, 0x11004, 0x0);
569 agnx_write32(ctl, 0xec54, 0xa);
570 agnx_write32(ctl, 0xec1c, 0x5);
571 } else if (priv->revid > 0) {
572 agnx_write32(ctl, AGNX_ACI_LEN, 0xf);
573 agnx_write32(ctl, AGNX_ACI_TIMER1, 0x21);
574 agnx_write32(ctl, AGNX_ACI_TIMER2, 0x27);
575 agnx_write32(ctl, AGNX_ACI_AICCHA0OVE, 0x11);
576 agnx_write32(ctl, AGNX_ACI_AICCHA1OVE, 0x0);
577 agnx_write32(ctl, AGNX_GCR_DUNSAT, 0x14);
578 agnx_write32(ctl, AGNX_GCR_DSAT, 0x24);
579 agnx_write32(ctl, AGNX_GCR_DFIRCAL, 0x8);
580 agnx_write32(ctl, AGNX_GCR_DGCTL11A, 0x1a);
581 agnx_write32(ctl, AGNX_GCR_DGCTL11B, 0x3);
582 agnx_write32(ctl, AGNX_GCR_GAININIT, 0xd);
583 agnx_write32(ctl, AGNX_GCR_THNOSIG, 0x1);
584 agnx_write32(ctl, AGNX_GCR_COARSTEP, 0x7);
585 agnx_write32(ctl, AGNX_GCR_SIFST11A, 0x28);
586 agnx_write32(ctl, AGNX_GCR_SIFST11B, 0x28);
587 agnx_write32(ctl, AGNX_GCR_CWDETEC, 0x0);
588 agnx_write32(ctl, AGNX_GCR_0X38, 0x1e);
589/* agnx_write32(ctl, AGNX_GCR_BOACT, 0x26);*/
590 agnx_write32(ctl, AGNX_GCR_DISCOVMOD, 0x3);
591
592 agnx_write32(ctl, AGNX_GCR_THCAP11A, 0x32);
593 agnx_write32(ctl, AGNX_GCR_THCAP11B, 0x32);
594 agnx_write32(ctl, AGNX_GCR_THCAPRX11A, 0x32);
595 agnx_write32(ctl, AGNX_GCR_THCAPRX11B, 0x32);
596 agnx_write32(ctl, AGNX_GCR_THLEVDRO, 0x10);
597 agnx_write32(ctl, AGNX_GCR_MAXRXTIME11A, 0x1ad);
598 agnx_write32(ctl, AGNX_GCR_MAXRXTIME11B, 0xa10);
599 agnx_write32(ctl, AGNX_GCR_CORRTIME, 0x190);
600 agnx_write32(ctl, AGNX_GCR_CORRDROP, 0x0);
601 agnx_write32(ctl, AGNX_GCR_THCD, 0x0);
602 agnx_write32(ctl, AGNX_GCR_THCS, 0x0);
603 agnx_write32(ctl, AGNX_GCR_MAXPOWDIFF, 0x4);
604 agnx_write32(ctl, AGNX_GCR_TESTBUS, 0x0);
605 agnx_write32(ctl, AGNX_GCR_THJUMP, 0x1e);
606 agnx_write32(ctl, AGNX_GCR_THPOWER, 0x0);
607 agnx_write32(ctl, AGNX_GCR_THPOWCLIP, 0x2a);
608 agnx_write32(ctl, AGNX_GCR_THD0BTFEST, 0x3c);
609 agnx_write32(ctl, AGNX_GCR_THRX11BPOWMIN, 0x19);
610 agnx_write32(ctl, AGNX_GCR_0X14c, 0x0);
611 agnx_write32(ctl, AGNX_GCR_0X150, 0x0);
612 agnx_write32(ctl, AGNX_GCR_RXOVERIDE, 0x0);
613 agnx_write32(ctl, AGNX_GCR_WATCHDOG, 0x37);
614 agnx_write32(ctl, 0x9400, 0x0);
615 agnx_write32(ctl, 0x940c, 0x6ff);
616 agnx_write32(ctl, 0x9428, 0xa0);
617 agnx_write32(ctl, 0x9434, 0x0);
618 agnx_write32(ctl, 0x9c04, 0x15);
619 agnx_write32(ctl, 0x9c0c, 0x7f);
620 agnx_write32(ctl, 0x9c34, 0x0);
621 agnx_write32(ctl, 0xc000, 0x38d);
622 agnx_write32(ctl, 0x14014, 0x1000);
623 agnx_write32(ctl, 0x14018, 0x0);
624 agnx_write32(ctl, 0x16000, 0x1);
625 agnx_write32(ctl, 0x11004, 0x0);
626 agnx_write32(ctl, 0xec54, 0xa);
627 agnx_write32(ctl, 0xec1c, 0x50);
628 } else if (priv->revid > 1) {
629 reg = agnx_read32(ctl, 0xec18);
630 reg |= 0x8;
631 agnx_write32(ctl, 0xec18, reg);
632 }
633
634 /* Write the TX Fir Coefficient Table */
635 tx_fir_table_init(priv);
636
637 reg = agnx_read32(ctl, AGNX_PM_PMCTL);
638 reg &= ~0x8;
639 agnx_write32(ctl, AGNX_PM_PMCTL, reg);
640 reg = agnx_read32(ctl, AGNX_PM_PLLCTL);
641 reg |= 0x1;
642 agnx_write32(ctl, AGNX_PM_PLLCTL, reg);
643
644/* reg = agnx_read32(ctl, 0x1a030); */
645/* reg &= ~0x4; */
646/* agnx_write32(ctl, 0x1a030, reg); */
647
648 agnx_write32(ctl, AGNX_GCR_TRACNT4, 0x113);
649} /* phy_init */
650
651static void chip_init(struct agnx_priv *priv)
652{
653 void __iomem *ctl = priv->ctl;
654 u32 reg;
655 AGNX_TRACE;
656
657 band_management_init(priv);
658
659 rf_chips_init(priv);
660
661 reg = agnx_read32(ctl, AGNX_PM_PMCTL);
662 reg |= 0x8;
663 agnx_write32(ctl, AGNX_PM_PMCTL, reg);
664
665 /* Initialize the PHY */
666 phy_init(priv);
667
668 encryption_init(priv);
669
670 tx_management_init(priv);
671
672 rx_management_init(priv);
673
674 power_manage_init(priv);
675
676 /* Initialize the Timers */
677 agnx_timer_init(priv);
678
679 /* Write 0xc390bf9 to Interrupt Mask (Disable TX) */
680 reg = 0xc390bf9 & ~IRQ_TX_BEACON;
681 reg &= ~IRQ_TX_DISABLE;
682 agnx_write32(ctl, AGNX_INT_MASK, reg);
683
684 reg = agnx_read32(ctl, AGNX_CIR_BLKCTL);
685 reg |= 0x800;
686 agnx_write32(ctl, AGNX_CIR_BLKCTL, reg);
687
688 /* set it when need get multicast enable? */
689 agnx_write32(ctl, AGNX_BM_MTSM, 0xff);
690} /* chip_init */
691
692
693static inline void set_promis_and_managed(struct agnx_priv *priv)
694{
695 void __iomem *ctl = priv->ctl;
696 agnx_write32(ctl, AGNX_SYSITF_SYSMODE, 0x10 | 0x2);
697 agnx_write32(ctl, AGNX_SYSITF_SYSMODE, 0x10 | 0x2);
698}
699static inline void set_learn_mode(struct agnx_priv *priv)
700{
701 void __iomem *ctl = priv->ctl;
702 agnx_write32(ctl, AGNX_SYSITF_SYSMODE, 0x8);
703}
704static inline void set_scan_mode(struct agnx_priv *priv)
705{
706 void __iomem *ctl = priv->ctl;
707 agnx_write32(ctl, AGNX_SYSITF_SYSMODE, 0x20);
708}
709static inline void set_promiscuous_mode(struct agnx_priv *priv)
710{
711 void __iomem *ctl = priv->ctl;
712 /* agnx_write32(ctl, AGNX_SYSITF_SYSMODE, 0x210);*/
713 agnx_write32(ctl, AGNX_SYSITF_SYSMODE, 0x10);
714}
715static inline void set_managed_mode(struct agnx_priv *priv)
716{
717 void __iomem *ctl = priv->ctl;
718 agnx_write32(ctl, AGNX_SYSITF_SYSMODE, 0x2);
719}
720static inline void set_adhoc_mode(struct agnx_priv *priv)
721{
722 void __iomem *ctl = priv->ctl;
723 agnx_write32(ctl, AGNX_SYSITF_SYSMODE, 0x0);
724}
725
726#if 0
727static void unknow_register_write(struct agnx_priv *priv)
728{
729 void __iomem *ctl = priv->ctl;
730
731 agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x0, 0x3e);
732 agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x4, 0xb2);
733 agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x8, 0x140);
734 agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0xc, 0x1C0);
735 agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x10, 0x1FF);
736 agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x14, 0x1DD);
737 agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x18, 0x15F);
738 agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x1c, 0xA1);
739 agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x20, 0x3E7);
740 agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x24, 0x36B);
741 agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x28, 0x348);
742 agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x2c, 0x37D);
743 agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x30, 0x3DE);
744 agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x34, 0x36);
745 agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x38, 0x64);
746 agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x3c, 0x57);
747 agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x40, 0x23);
748 agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x44, 0x3ED);
749 agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x48, 0x3C9);
750 agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x4c, 0x3CA);
751 agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x50, 0x3E7);
752 agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x54, 0x8);
753 agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x58, 0x1F);
754 agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x5c, 0x1a);
755}
756#endif
757
758static void card_interface_init(struct agnx_priv *priv)
759{
760 void __iomem *ctl = priv->ctl;
761 u8 bssid[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
762 u32 reg;
763 unsigned int i;
764 AGNX_TRACE;
765
766 might_sleep();
767 /* Clear RX Control and Enable RX queues */
768 agnx_write32(ctl, AGNX_CIR_RXCTL, 0x8);
769
770 might_sleep();
771 /* Do a full reset of the card */
772 card_full_reset(priv);
773 might_sleep();
774
775 /* Check and set Card Endianness */
776 reg = ioread32(priv->ctl + AGNX_CIR_ENDIAN);
777 /* TODO If not 0xB3B2B1B0 set to 0xB3B2B1B0 */
778 printk(KERN_INFO PFX "CIR_ENDIAN is %x\n", reg);
779
780
781 /* Config the eeprom */
782 agnx_write32(ctl, AGNX_CIR_SERIALITF, 0x7000086);
783 udelay(10);
784 reg = agnx_read32(ctl, AGNX_CIR_SERIALITF);
785
786
787 agnx_write32(ctl, AGNX_PM_SOFTRST, 0x80000033);
788 reg = agnx_read32(ctl, 0xec50);
789 reg |= 0xf;
790 agnx_write32(ctl, 0xec50, reg);
791 agnx_write32(ctl, AGNX_PM_SOFTRST, 0x0);
792
793
794 reg = agnx_read32(ctl, AGNX_SYSITF_GPIOIN);
795 udelay(10);
796 reg = agnx_read32(ctl, AGNX_CIR_SERIALITF);
797
798 /* Dump the eeprom */
799 do {
800 char eeprom[0x100000/0x100];
801
802 for (i = 0; i < 0x100000; i += 0x100) {
803 agnx_write32(ctl, AGNX_CIR_SERIALITF, 0x3000000 + i);
804 udelay(13);
805 reg = agnx_read32(ctl, AGNX_CIR_SERIALITF);
806 udelay(70);
807 reg = agnx_read32(ctl, AGNX_CIR_SERIALITF);
808 eeprom[i/0x100] = reg & 0xFF;
809 udelay(10);
810 }
811 print_hex_dump_bytes(PFX "EEPROM: ", DUMP_PREFIX_NONE, eeprom,
812 ARRAY_SIZE(eeprom));
813 } while (0);
814
815 spi_rc_write(ctl, RF_CHIP0, 0x26);
816 reg = agnx_read32(ctl, AGNX_SPI_RLSW);
817
818 /* Initialize the system interface */
819 system_itf_init(priv);
820
821 might_sleep();
822 /* Chip Initialization (Polaris) */
823 chip_init(priv);
824 might_sleep();
825
826 /* Calibrate the antennae */
827 antenna_calibrate(priv);
828
829 reg = agnx_read32(ctl, 0xec50);
830 reg &= ~0x40;
831 agnx_write32(ctl, 0xec50, reg);
832 agnx_write32(ctl, AGNX_PM_SOFTRST, 0x0);
833 agnx_write32(ctl, AGNX_PM_PLLCTL, 0x1);
834
835 reg = agnx_read32(ctl, AGNX_BM_BMCTL);
836 reg |= 0x8000;
837 agnx_write32(ctl, AGNX_BM_BMCTL, reg);
838 enable_receiver(priv);
839 reg = agnx_read32(ctl, AGNX_SYSITF_SYSMODE);
840 reg |= 0x200;
841 agnx_write32(ctl, AGNX_SYSITF_SYSMODE, reg);
842 enable_receiver(priv);
843
844 might_sleep();
845 /* Initialize Gain Control Counts */
846 gain_ctlcnt_init(priv);
847
848 /* Write Initial Station Power Template for this station(#0) */
849 sta_power_init(priv, LOCAL_STAID);
850
851 might_sleep();
852 /* Initialize the rx,td,tm rings, for each node in the ring */
853 fill_rings(priv);
854
855 might_sleep();
856
857
858 agnx_write32(ctl, AGNX_PM_SOFTRST, 0x80000033);
859 agnx_write32(ctl, 0xec50, 0xc);
860 agnx_write32(ctl, AGNX_PM_SOFTRST, 0x0);
861
862 /* FIXME Initialize the transmit control register */
863 agnx_write32(ctl, AGNX_TXM_CTL, 0x194c1);
864
865 enable_receiver(priv);
866
867 might_sleep();
868 /* FIXME Set the Receive Control Mac Address to card address */
869 mac_address_set(priv);
870 enable_receiver(priv);
871 might_sleep();
872
873 /* Set the recieve request rate */
874 /* FIXME Enable the request */
875 /* Check packet length */
876 /* Set maximum packet length */
877/* agnx_write32(ctl, AGNX_RXM_REQRATE, 0x88195e00); */
878/* enable_receiver(priv); */
879
880 /* Set the Receiver BSSID */
881 receiver_bssid_set(priv, bssid);
882
883 /* FIXME Set to managed mode */
884 set_managed_mode(priv);
885/* set_promiscuous_mode(priv); */
886/* set_scan_mode(priv); */
887/* set_learn_mode(priv); */
888/* set_promis_and_managed(priv); */
889/* set_adhoc_mode(priv); */
890
891 /* Set the recieve request rate */
892 /* Check packet length */
893 agnx_write32(ctl, AGNX_RXM_REQRATE, 0x08000000);
894 reg = agnx_read32(ctl, AGNX_RXM_REQRATE);
895 /* Set maximum packet length */
896 reg |= 0x00195e00;
897 agnx_write32(ctl, AGNX_RXM_REQRATE, reg);
898
899 /* Configure the RX and TX interrupt */
900 reg = ENABLE_RX_INTERRUPT | RX_CACHE_LINE | FRAG_LEN_2048 | FRAG_BE;
901 agnx_write32(ctl, AGNX_CIR_RXCFG, reg);
902 /* FIXME */
903 reg = ENABLE_TX_INTERRUPT | TX_CACHE_LINE | FRAG_LEN_2048 | FRAG_BE;
904 agnx_write32(ctl, AGNX_CIR_TXCFG, reg);
905
906 /* Enable RX TX Interrupts */
907 agnx_write32(ctl, AGNX_CIR_RXCTL, 0x80);
908 agnx_write32(ctl, AGNX_CIR_TXMCTL, 0x80);
909 agnx_write32(ctl, AGNX_CIR_TXDCTL, 0x80);
910
911 /* FIXME Set the master control interrupt in block control */
912 agnx_write32(ctl, AGNX_CIR_BLKCTL, 0x800);
913
914 /* Enable RX and TX queues */
915 reg = agnx_read32(ctl, AGNX_CIR_RXCTL);
916 reg |= 0x8;
917 agnx_write32(ctl, AGNX_CIR_RXCTL, reg);
918 reg = agnx_read32(ctl, AGNX_CIR_TXMCTL);
919 reg |= 0x8;
920 agnx_write32(ctl, AGNX_CIR_TXMCTL, reg);
921 reg = agnx_read32(ctl, AGNX_CIR_TXDCTL);
922 reg |= 0x8;
923 agnx_write32(ctl, AGNX_CIR_TXDCTL, reg);
924
925 agnx_write32(ctl, AGNX_SYSITF_GPIOUT, 0x5);
926 /* FIXME */
927 /* unknow_register_write(priv); */
928 /* Update local card hash entry */
929 hash_write(priv, priv->mac_addr, LOCAL_STAID);
930
931 might_sleep();
932
933 /* FIXME */
934 agnx_set_channel(priv, 1);
935 might_sleep();
936} /* agnx_card_interface_init */
937
938
939void agnx_hw_init(struct agnx_priv *priv)
940{
941 AGNX_TRACE;
942 might_sleep();
943 card_interface_init(priv);
944}
945
946int agnx_hw_reset(struct agnx_priv *priv)
947{
948 return card_full_reset(priv);
949}
950
951int agnx_set_ssid(struct agnx_priv *priv, u8 *ssid, size_t ssid_len)
952{
953 AGNX_TRACE;
954 return 0;
955}
956
957void agnx_set_bssid(struct agnx_priv *priv, const u8 *bssid)
958{
959 receiver_bssid_set(priv, bssid);
960}
diff --git a/drivers/staging/agnx/phy.h b/drivers/staging/agnx/phy.h
deleted file mode 100644
index a955f05361e7..000000000000
--- a/drivers/staging/agnx/phy.h
+++ /dev/null
@@ -1,409 +0,0 @@
1#ifndef AGNX_PHY_H_
2#define AGNX_PHY_H_
3
4#include "agnx.h"
5
6/* Transmission Managment Registers */
7#define AGNX_TXM_BASE 0x0000
8#define AGNX_TXM_CTL 0x0000 /* control register */
9#define AGNX_TXM_ETMF 0x0004 /* enable transmission management functions */
10#define AGNX_TXM_TXTEMP 0x0008 /* transmission template */
11#define AGNX_TXM_RETRYSTAID 0x000c /* Retry Station ID */
12#define AGNX_TXM_TIMESTAMPLO 0x0010 /* Timestamp Lo */
13#define AGNX_TXM_TIMESTAMPHI 0x0014 /* Timestamp Hi */
14#define AGNX_TXM_TXDELAY 0x0018 /* tx delay */
15#define AGNX_TXM_TBTTLO 0x0020 /* tbtt Lo */
16#define AGNX_TXM_TBTTHI 0x0024 /* tbtt Hi */
17#define AGNX_TXM_BEAINTER 0x0028 /* Beacon Interval */
18#define AGNX_TXM_NAV 0x0030 /* NAV */
19#define AGNX_TXM_CFPMDV 0x0034 /* CFP MDV */
20#define AGNX_TXM_CFPERCNT 0x0038 /* CFP period count */
21#define AGNX_TXM_PROBDELAY 0x003c /* probe delay */
22#define AGNX_TXM_LISINTERCNT 0x0040 /* listen interval count */
23#define AGNX_TXM_DTIMPERICNT 0x004c /* DTIM period count */
24
25#define AGNX_TXM_BEACON_CTL 0x005c /* beacon control */
26
27#define AGNX_TXM_SCHEMPCNT 0x007c /* schedule empty count */
28#define AGNX_TXM_MAXTIMOUT 0x0084 /* max timeout exceed count */
29#define AGNX_TXM_MAXCFPTIM 0x0088 /* max CF poll timeout count */
30#define AGNX_TXM_MAXRXTIME 0x008c /* max RX timeout count */
31#define AGNX_TXM_MAXACKTIM 0x0090 /* max ACK timeout count */
32#define AGNX_TXM_DIF01 0x00a0 /* DIF 0-1 */
33#define AGNX_TXM_DIF23 0x00a4 /* DIF 2-3 */
34#define AGNX_TXM_DIF45 0x00a8 /* DIF 4-5 */
35#define AGNX_TXM_DIF67 0x00ac /* DIF 6-7 */
36#define AGNX_TXM_SIFSPIFS 0x00b0 /* SIFS/PIFS */
37#define AGNX_TXM_TIFSEIFS 0x00b4 /* TIFS/EIFS */
38#define AGNX_TXM_MAXCCACNTSLOT 0x00b8 /* max CCA count slot */
39#define AGNX_TXM_SLOTLIMIT 0x00bc /* slot limit/1 msec limit */
40#define AGNX_TXM_CFPOLLRXTIM 0x00f0 /* CF poll RX timeout count */
41#define AGNX_TXM_CFACKT11B 0x00f4 /* CF ack timeout limit for 11b */
42#define AGNX_TXM_CW0 0x0100 /* CW 0 */
43#define AGNX_TXM_SLBEALIM0 0x0108 /* short/long beacon limit 0 */
44#define AGNX_TXM_CW1 0x0120 /* CW 1 */
45#define AGNX_TXM_SLBEALIM1 0x0128 /* short/long beacon limit 1 */
46#define AGNX_TXM_CW2 0x0140 /* CW 2 */
47#define AGNX_TXM_SLBEALIM2 0x0148 /* short/long beacon limit 2 */
48#define AGNX_TXM_CW3 0x0160 /* CW 3 */
49#define AGNX_TXM_SLBEALIM3 0x0168 /* short/long beacon limit 3 */
50#define AGNX_TXM_CW4 0x0180 /* CW 4 */
51#define AGNX_TXM_SLBEALIM4 0x0188 /* short/long beacon limit 4 */
52#define AGNX_TXM_CW5 0x01a0 /* CW 5 */
53#define AGNX_TXM_SLBEALIM5 0x01a8 /* short/long beacon limit 5 */
54#define AGNX_TXM_CW6 0x01c0 /* CW 6 */
55#define AGNX_TXM_SLBEALIM6 0x01c8 /* short/long beacon limit 6 */
56#define AGNX_TXM_CW7 0x01e0 /* CW 7 */
57#define AGNX_TXM_SLBEALIM7 0x01e8 /* short/long beacon limit 7 */
58#define AGNX_TXM_BEACONTEMP 0x1000 /* beacon template */
59#define AGNX_TXM_STAPOWTEMP 0x1a00 /* Station Power Template */
60
61/* Receive Management Control Registers */
62#define AGNX_RXM_BASE 0x2000
63#define AGNX_RXM_REQRATE 0x2000 /* requested rate */
64#define AGNX_RXM_MACHI 0x2004 /* first 4 bytes of mac address */
65#define AGNX_RXM_MACLO 0x2008 /* last 2 bytes of mac address */
66#define AGNX_RXM_BSSIDHI 0x200c /* bssid hi */
67#define AGNX_RXM_BSSIDLO 0x2010 /* bssid lo */
68#define AGNX_RXM_HASH_CMD_FLAG 0x2014 /* Flags for the RX Hash Command Default:0 */
69#define AGNX_RXM_HASH_CMD_HIGH 0x2018 /* The High half of the Hash Command */
70#define AGNX_RXM_HASH_CMD_LOW 0x201c /* The Low half of the Hash Command */
71#define AGNX_RXM_ROUTAB 0x2020 /* routing table */
72#define ROUTAB_SUBTYPE_SHIFT 24
73#define ROUTAB_TYPE_SHIFT 28
74#define ROUTAB_STATUS_SHIFT 30
75#define ROUTAB_RW_SHIFT 31
76#define ROUTAB_ROUTE_DROP 0xf00000 /* Drop */
77#define ROUTAB_ROUTE_CPU 0x400000 /* CPU */
78#define ROUTAB_ROUTE_ENCRY 0x500800 /* Encryption */
79#define ROUTAB_ROUTE_RFP 0x800000 /* RFP */
80
81#define ROUTAB_TYPE_MANAG 0x0 /* Management */
82#define ROUTAB_TYPE_CTL 0x1 /* Control */
83#define ROUTAB_TYPE_DATA 0x2 /* Data */
84
85#define ROUTAB_SUBTYPE_DATA 0x0
86#define ROUTAB_SUBTYPE_DATAACK 0x1
87#define ROUTAB_SUBTYPE_DATAPOLL 0x2
88#define ROUTAB_SUBTYPE_DATAPOLLACK 0x3
89#define ROUTAB_SUBTYPE_NULL 0x4 /* NULL */
90#define ROUTAB_SUBTYPE_NULLACK 0x5
91#define ROUTAB_SUBTYPE_NULLPOLL 0x6
92#define ROUTAB_SUBTYPE_NULLPOLLACK 0x7
93#define ROUTAB_SUBTYPE_QOSDATA 0x8 /* QOS DATA */
94#define ROUTAB_SUBTYPE_QOSDATAACK 0x9
95#define ROUTAB_SUBTYPE_QOSDATAPOLL 0xa
96#define ROUTAB_SUBTYPE_QOSDATAACKPOLL 0xb
97#define ROUTAB_SUBTYPE_QOSNULL 0xc
98#define ROUTAB_SUBTYPE_QOSNULLACK 0xd
99#define ROUTAB_SUBTYPE_QOSNULLPOLL 0xe
100#define ROUTAB_SUBTYPE_QOSNULLPOLLACK 0xf
101#define AGNX_RXM_DELAY11 0x2024 /* delay 11(AB) */
102#define AGNX_RXM_SOF_CNT 0x2028 /* SOF Count */
103#define AGNX_RXM_FRAG_CNT 0x202c /* Fragment Count*/
104#define AGNX_RXM_FCS_CNT 0x2030 /* FCS Count */
105#define AGNX_RXM_BSSID_MISS_CNT 0x2034 /* BSSID Miss Count */
106#define AGNX_RXM_PDU_ERR_CNT 0x2038 /* PDU Error Count */
107#define AGNX_RXM_DEST_MISS_CNT 0x203C /* Destination Miss Count */
108#define AGNX_RXM_DROP_CNT 0x2040 /* Drop Count */
109#define AGNX_RXM_ABORT_CNT 0x2044 /* Abort Count */
110#define AGNX_RXM_RELAY_CNT 0x2048 /* Relay Count */
111#define AGNX_RXM_HASH_MISS_CNT 0x204c /* Hash Miss Count */
112#define AGNX_RXM_SA_HI 0x2050 /* Address of received packet Hi */
113#define AGNX_RXM_SA_LO 0x2054 /* Address of received packet Lo */
114#define AGNX_RXM_HASH_DUMP_LST 0x2100 /* Contains Hash Data */
115#define AGNX_RXM_HASH_DUMP_MST 0x2104 /* Contains Hash Data */
116#define AGNX_RXM_HASH_DUMP_DATA 0x2108 /* The Station ID to dump */
117
118
119/* Encryption Managment */
120#define AGNX_ENCRY_BASE 0x2400
121#define AGNX_ENCRY_WEPKEY0 0x2440 /* wep key #0 */
122#define AGNX_ENCRY_WEPKEY1 0x2444 /* wep key #1 */
123#define AGNX_ENCRY_WEPKEY2 0x2448 /* wep key #2 */
124#define AGNX_ENCRY_WEPKEY3 0x244c /* wep key #3 */
125#define AGNX_ENCRY_CCMRECTL 0x2460 /* ccm replay control */
126
127
128/* Band Management Registers */
129#define AGNX_BM_BASE 0x2c00
130#define AGNX_BM_BMCTL 0x2c00 /* band management control */
131#define AGNX_BM_TXWADDR 0x2c18 /* tx workqueue address start */
132#define AGNX_BM_TXTOPEER 0x2c24 /* transmit to peers */
133#define AGNX_BM_FPLHP 0x2c2c /* free pool list head pointer */
134#define AGNX_BM_FPLTP 0x2c30 /* free pool list tail pointer */
135#define AGNX_BM_FPCNT 0x2c34 /* free pool count */
136#define AGNX_BM_CIPDUWCNT 0x2c38 /* card interface pdu workqueue count */
137#define AGNX_BM_SPPDUWCNT 0x2c3c /* sp pdu workqueue count */
138#define AGNX_BM_RFPPDUWCNT 0x2c40 /* rfp pdu workqueue count */
139#define AGNX_BM_RHPPDUWCNT 0x2c44 /* rhp pdu workqueue count */
140#define AGNX_BM_CIWQCTL 0x2c48 /* Card Interface WorkQueue Control */
141#define AGNX_BM_CPUTXWCTL 0x2c50 /* cpu tx workqueue control */
142#define AGNX_BM_CPURXWCTL 0x2c58 /* cpu rx workqueue control */
143#define AGNX_BM_CPULWCTL 0x2c60 /* cpu low workqueue control */
144#define AGNX_BM_CPUHWCTL 0x2c68 /* cpu high workqueue control */
145#define AGNX_BM_SPTXWCTL 0x2c70 /* sp tx workqueue control */
146#define AGNX_BM_SPRXWCTL 0x2c78 /* sp rx workqueue control */
147#define AGNX_BM_RFPWCTL 0x2c80 /* RFP workqueue control */
148#define AGNX_BM_MTSM 0x2c90 /* Multicast Transmit Station Mask */
149
150/* Card Interface Registers (32bits) */
151#define AGNX_CIR_BASE 0x3000
152#define AGNX_CIR_BLKCTL 0x3000 /* block control*/
153#define AGNX_STAT_TX 0x1
154#define AGNX_STAT_RX 0x2
155#define AGNX_STAT_X 0x4
156/* Below two interrupt flags will be set by our but not CPU or the card */
157#define AGNX_STAT_TXD 0x10
158#define AGNX_STAT_TXM 0x20
159
160#define AGNX_CIR_ADDRWIN 0x3004 /* Addressable Windows*/
161#define AGNX_CIR_ENDIAN 0x3008 /* card endianness */
162#define AGNX_CIR_SERIALITF 0x3020 /* serial interface */
163#define AGNX_CIR_RXCFG 0x3040 /* receive config */
164#define ENABLE_RX_INTERRUPT 0x20
165#define RX_CACHE_LINE 0x8
166/* the RX fragment length */
167#define FRAG_LEN_256 0x0 /* 256B */
168#define FRAG_LEN_512 0x1
169#define FRAG_LEN_1024 0x2
170#define FRAG_LEN_2048 0x3
171#define FRAG_BE 0x10
172#define AGNX_CIR_RXCTL 0x3050 /* receive control */
173/* memory address, chipside */
174#define AGNX_CIR_RXCMSTART 0x3054 /* receive client memory start */
175#define AGNX_CIR_RXCMEND 0x3058 /* receive client memory end */
176/* memory address, pci */
177#define AGNX_CIR_RXHOSTADDR 0x3060 /* receive hostside address */
178/* memory address, chipside */
179#define AGNX_CIR_RXCLIADDR 0x3064 /* receive clientside address */
180#define AGNX_CIR_RXDMACTL 0x3068 /* receive dma control */
181#define AGNX_CIR_TXCFG 0x3080 /* transmit config */
182#define AGNX_CIR_TXMCTL 0x3090 /* Transmit Management Control */
183#define ENABLE_TX_INTERRUPT 0x20
184#define TX_CACHE_LINE 0x8
185#define AGNX_CIR_TXMSTART 0x3094 /* Transmit Management Start */
186#define AGNX_CIR_TXMEND 0x3098 /* Transmit Management End */
187#define AGNX_CIR_TXDCTL 0x30a0 /* transmit data control */
188/* memeory address, chipset */
189#define AGNX_CIR_TXDSTART 0x30a4 /* transmit data start */
190#define AGNX_CIR_TXDEND 0x30a8 /* transmit data end */
191#define AGNX_CIR_TXMHADDR 0x30b0 /* Transmit Management Hostside Address */
192#define AGNX_CIR_TXMCADDR 0x30b4 /* Transmit Management Clientside Address */
193#define AGNX_CIR_TXDMACTL 0x30b8 /* transmit dma control */
194
195
196/* Power Managment Unit */
197#define AGNX_PM_BASE 0x3c00
198#define AGNX_PM_PMCTL 0x3c00 /* PM Control*/
199#define AGNX_PM_MACMSW 0x3c08 /* MAC Manual Slow Work Enable */
200#define AGNX_PM_RFCTL 0x3c0c /* RF Control */
201#define AGNX_PM_PHYMW 0x3c14 /* Phy Mannal Work */
202#define AGNX_PM_SOFTRST 0x3c18 /* PMU Soft Reset */
203#define AGNX_PM_PLLCTL 0x3c1c /* PMU PLL control*/
204#define AGNX_PM_TESTPHY 0x3c24 /* PMU Test Phy */
205
206
207/* Interrupt Control interface */
208#define AGNX_INT_BASE 0x4000
209#define AGNX_INT_STAT 0x4000 /* interrupt status */
210#define AGNX_INT_MASK 0x400c /* interrupt mask */
211/* FIXME */
212#define IRQ_TX_BEACON 0x1 /* TX Beacon */
213#define IRQ_TX_RETRY 0x8 /* TX Retry Interrupt */
214#define IRQ_TX_ACTIVITY 0x10 /* TX Activity */
215#define IRQ_RX_ACTIVITY 0x20 /* RX Activity */
216/* FIXME I guess that instead RX a none exist staion's packet or
217 the station hasn't been init */
218#define IRQ_RX_X 0x40
219#define IRQ_RX_Y 0x80 /* RX ? */
220#define IRQ_RX_HASHHIT 0x100 /* RX Hash Hit */
221#define IRQ_RX_FRAME 0x200 /* RX Frame */
222#define IRQ_ERR_INT 0x400 /* Error Interrupt */
223#define IRQ_TX_QUE_FULL 0x800 /* TX Workqueue Full */
224#define IRQ_BANDMAN_ERR 0x10000 /* Bandwidth Management Error */
225#define IRQ_TX_DISABLE 0x20000 /* TX Disable */
226#define IRQ_RX_IVASESKEY 0x80000 /* RX Invalid Session Key */
227#define IRQ_RX_KEYIDMIS 0x100000 /* RX key ID Mismatch */
228#define IRQ_REP_THHIT 0x200000 /* Replay Threshold Hit */
229#define IRQ_TIMER1 0x4000000 /* Timer1 */
230#define IRQ_TIMER_CNT 0x10000000 /* Timer Count */
231#define IRQ_PHY_FASTINT 0x20000000 /* Phy Fast Interrupt */
232#define IRQ_PHY_SLOWINT 0x40000000 /* Phy Slow Interrupt */
233#define IRQ_OTHER 0x80000000 /* Unknow interrupt */
234#define AGNX_IRQ_ALL 0xffffffff
235
236/* System Interface */
237#define AGNX_SYSITF_BASE 0x4400
238#define AGNX_SYSITF_SYSMODE 0x4400 /* system mode */
239#define AGNX_SYSITF_GPIOIN 0x4410 /* GPIO In */
240/* PIN lines for leds? */
241#define AGNX_SYSITF_GPIOUT 0x4414 /* GPIO Out */
242
243/* Timer Control */
244#define AGNX_TIMCTL_TIMER1 0x4800 /* Timer 1 */
245#define AGNX_TIMCTL_TIM1CTL 0x4808 /* Timer 1 Control */
246
247
248/* Antenna Calibration Interface */
249#define AGNX_ACI_BASE 0x5000
250#define AGNX_ACI_MODE 0x5000 /* Mode */
251#define AGNX_ACI_MEASURE 0x5004 /* Measure */
252#define AGNX_ACI_SELCHAIN 0x5008 /* Select Chain */
253#define AGNX_ACI_LEN 0x500c /* Length */
254#define AGNX_ACI_TIMER1 0x5018 /* Timer 1 */
255#define AGNX_ACI_TIMER2 0x501c /* Timer 2 */
256#define AGNX_ACI_OFFSET 0x5020 /* Offset */
257#define AGNX_ACI_STATUS 0x5030 /* Status */
258#define CALI_IDLE 0x0
259#define CALI_DONE 0x1
260#define CALI_BUSY 0x2
261#define CALI_ERR 0x3
262#define AGNX_ACI_AICCHA0OVE 0x5034 /* AIC Channel 0 Override */
263#define AGNX_ACI_AICCHA1OVE 0x5038 /* AIC Channel 1 Override */
264
265/* Gain Control Registers */
266#define AGNX_GCR_BASE 0x9000
267/* threshold of primary antenna */
268#define AGNX_GCR_THD0A 0x9000 /* threshold? D0 A */
269/* low threshold of primary antenna */
270#define AGNX_GCR_THD0AL 0x9004 /* threshold? D0 A low */
271/* threshold of secondary antenna */
272#define AGNX_GCR_THD0B 0x9008 /* threshold? D0_B */
273#define AGNX_GCR_DUNSAT 0x900c /* d unsaturated */
274#define AGNX_GCR_DSAT 0x9010 /* d saturated */
275#define AGNX_GCR_DFIRCAL 0x9014 /* D Fir/Cal */
276#define AGNX_GCR_DGCTL11A 0x9018 /* d gain control 11a */
277#define AGNX_GCR_DGCTL11B 0x901c /* d gain control 11b */
278/* strength of gain */
279#define AGNX_GCR_GAININIT 0x9020 /* gain initialization */
280#define AGNX_GCR_THNOSIG 0x9024 /* threhold no signal */
281#define AGNX_GCR_COARSTEP 0x9028 /* coarse stepping */
282#define AGNX_GCR_SIFST11A 0x902c /* sifx time 11a */
283#define AGNX_GCR_SIFST11B 0x9030 /* sifx time 11b */
284#define AGNX_GCR_CWDETEC 0x9034 /* cw detection */
285#define AGNX_GCR_0X38 0x9038 /* ???? */
286#define AGNX_GCR_BOACT 0x903c /* BO Active */
287#define AGNX_GCR_BOINACT 0x9040 /* BO Inactive */
288#define AGNX_GCR_BODYNA 0x9044 /* BO dynamic */
289/* 802.11 mode(a,b,g) */
290#define AGNX_GCR_DISCOVMOD 0x9048 /* discovery mode */
291#define AGNX_GCR_NLISTANT 0x904c /* number of listening antenna */
292#define AGNX_GCR_NACTIANT 0x9050 /* number of active antenna */
293#define AGNX_GCR_NMEASANT 0x9054 /* number of measuring antenna */
294#define AGNX_GCR_NCAPTANT 0x9058 /* number of capture antenna */
295#define AGNX_GCR_THCAP11A 0x905c /* threshold capture 11a */
296#define AGNX_GCR_THCAP11B 0x9060 /* threshold capture 11b */
297#define AGNX_GCR_THCAPRX11A 0x9064 /* threshold capture rx 11a */
298#define AGNX_GCR_THCAPRX11B 0x9068 /* threshold capture rx 11b */
299#define AGNX_GCR_THLEVDRO 0x906c /* threshold level drop */
300#define AGNX_GCR_GAINSET0 0x9070 /* Gainset 0 */
301#define AGNX_GCR_GAINSET1 0x9074 /* Gainset 1 */
302#define AGNX_GCR_GAINSET2 0x9078 /* Gainset 2 */
303#define AGNX_GCR_MAXRXTIME11A 0x907c /* maximum rx time 11a */
304#define AGNX_GCR_MAXRXTIME11B 0x9080 /* maximum rx time 11b */
305#define AGNX_GCR_CORRTIME 0x9084 /* correction time */
306/* reset the subsystem, 0 = disable, 1 = enable */
307#define AGNX_GCR_RSTGCTL 0x9088 /* reset gain control */
308/* channel receiving */
309#define AGNX_GCR_RXCHANEL 0x908c /* receive channel */
310#define AGNX_GCR_NOISE0 0x9090 /* Noise 0 */
311#define AGNX_GCR_NOISE1 0x9094 /* Noise 1 */
312#define AGNX_GCR_NOISE2 0x9098 /* Noise 2 */
313#define AGNX_GCR_SIGHTH 0x909c /* Signal High Threshold */
314#define AGNX_GCR_SIGLTH 0x90a0 /* Signal Low Threshold */
315#define AGNX_GCR_CORRDROP 0x90a4 /* correction drop */
316/* threshold of tertiay antenna */
317#define AGNX_GCR_THCD 0x90a8 /* threshold? CD */
318#define AGNX_GCR_THCS 0x90ac /* threshold? CS */
319#define AGNX_GCR_MAXPOWDIFF 0x90b8 /* maximum power difference */
320#define AGNX_GCR_TRACNT4 0x90ec /* Transition Count 4 */
321#define AGNX_GCR_TRACNT5 0x90f0 /* transition count 5 */
322#define AGNX_GCR_TRACNT6 0x90f4 /* transition count 6 */
323#define AGNX_GCR_TRACNT7 0x90f8 /* transition coutn 7 */
324#define AGNX_GCR_TESTBUS 0x911c /* test bus */
325#define AGNX_GCR_CHAINNUM 0x9120 /* Number of Chains */
326#define AGNX_GCR_ANTCFG 0x9124 /* Antenna Config */
327#define AGNX_GCR_THJUMP 0x912c /* threhold jump */
328#define AGNX_GCR_THPOWER 0x9130 /* threshold power */
329#define AGNX_GCR_THPOWCLIP 0x9134 /* threshold power clip*/
330#define AGNX_GCR_FORCECTLCLK 0x9138 /* Force Gain Control Clock */
331#define AGNX_GCR_GAINSETWRITE 0x913c /* Gainset Write */
332#define AGNX_GCR_THD0BTFEST 0x9140 /* threshold d0 b tf estimate */
333#define AGNX_GCR_THRX11BPOWMIN 0x9144 /* threshold rx 11b power minimum */
334#define AGNX_GCR_0X14c 0x914c /* ?? */
335#define AGNX_GCR_0X150 0x9150 /* ?? */
336#define AGNX_GCR_RXOVERIDE 0x9194 /* recieve override */
337#define AGNX_GCR_WATCHDOG 0x91b0 /* watchdog timeout */
338
339
340/* Spi Interface */
341#define AGNX_SPI_BASE 0xdc00
342#define AGNX_SPI_CFG 0xdc00 /* spi configuration */
343/* Only accept 16 bits */
344#define AGNX_SPI_WMSW 0xdc04 /* write most significant word */
345/* Only accept 16 bits */
346#define AGNX_SPI_WLSW 0xdc08 /* write least significant word */
347#define AGNX_SPI_CTL 0xdc0c /* spi control */
348#define AGNX_SPI_RMSW 0xdc10 /* read most significant word */
349#define AGNX_SPI_RLSW 0xdc14 /* read least significant word */
350/* SPI Control Mask */
351#define SPI_READ_CTL 0x4000 /* read control */
352#define SPI_BUSY_CTL 0x8000 /* busy control */
353/* RF and synth chips in spi */
354#define RF_CHIP0 0x400
355#define RF_CHIP1 0x800
356#define RF_CHIP2 0x1000
357#define SYNTH_CHIP 0x2000
358
359/* Unknown register */
360#define AGNX_UNKNOWN_BASE 0x7800
361
362/* FIXME MonitorGain */
363#define AGNX_MONGCR_BASE 0x12000
364
365/* Gain Table */
366#define AGNX_GAIN_TABLE 0x12400
367
368/* The initial FIR coefficient table */
369#define AGNX_FIR_BASE 0x19804
370
371#define AGNX_ENGINE_LOOKUP_TBL 0x800
372
373/* eeprom commands */
374#define EEPROM_CMD_NULL 0x0 /* NULL */
375#define EEPROM_CMD_WRITE 0x2 /* write */
376#define EEPROM_CMD_READ 0x3 /* read */
377#define EEPROM_CMD_STATUSREAD 0x5 /* status register read */
378#define EEPROM_CMD_WRITEENABLE 0x6 /* write enable */
379#define EEPROM_CMD_CONFIGURE 0x7 /* configure */
380
381#define EEPROM_DATAFORCOFIGURE 0x6 /* ??? */
382
383/* eeprom address */
384#define EEPROM_ADDR_SUBVID 0x0 /* Sub Vendor ID */
385#define EEPROM_ADDR_SUBSID 0x2 /* Sub System ID */
386#define EEPROM_ADDR_MACADDR 0x146 /* MAC Address */
387#define EEPROM_ADDR_LOTYPE 0x14f /* LO type */
388
389struct agnx_eeprom {
390 u8 data; /* date */
391 u16 address; /* address in EEPROM */
392 u8 cmd; /* command, unknown, status */
393} __attribute__((__packed__));
394
395#define AGNX_EEPROM_COMMAND_SHIFT 5
396#define AGNX_EEPROM_COMMAND_STAT 0x01
397
398void disable_receiver(struct agnx_priv *priv);
399void enable_receiver(struct agnx_priv *priv);
400u8 read_from_eeprom(struct agnx_priv *priv, u16 address);
401void agnx_hw_init(struct agnx_priv *priv);
402int agnx_hw_reset(struct agnx_priv *priv);
403int agnx_set_ssid(struct agnx_priv *priv, u8 *ssid, size_t ssid_len);
404void agnx_set_bssid(struct agnx_priv *priv, const u8 *bssid);
405void enable_power_saving(struct agnx_priv *priv);
406void disable_power_saving(struct agnx_priv *priv);
407void calibrate_antenna_period(unsigned long data);
408
409#endif /* AGNX_PHY_H_ */
diff --git a/drivers/staging/agnx/rf.c b/drivers/staging/agnx/rf.c
deleted file mode 100644
index 42e457a1844f..000000000000
--- a/drivers/staging/agnx/rf.c
+++ /dev/null
@@ -1,893 +0,0 @@
1/**
2 * Airgo MIMO wireless driver
3 *
4 * Copyright (c) 2007 Li YanBo <dreamfly281@gmail.com>
5
6 * Thanks for Jeff Williams <angelbane@gmail.com> do reverse engineer
7 * works and published the SPECS at http://airgo.wdwconsulting.net/mymoin
8
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation;
12 */
13
14#include <linux/pci.h>
15#include <linux/delay.h>
16#include "agnx.h"
17#include "debug.h"
18#include "phy.h"
19#include "table.h"
20
21/* FIXME! */
22static inline void spi_write(void __iomem *region, u32 chip_ids, u32 sw,
23 u16 size, u32 control)
24{
25 u32 reg;
26 u32 lsw = sw & 0xffff; /* lower 16 bits of sw*/
27 u32 msw = sw >> 16; /* high 16 bits of sw */
28
29 /* FIXME Write Most Significant Word of the 32bit data to MSW */
30 /* FIXME And Least Significant Word to LSW */
31 iowrite32((lsw), region + AGNX_SPI_WLSW);
32 iowrite32((msw), region + AGNX_SPI_WMSW);
33 reg = chip_ids | size | control;
34 /* Write chip id(s), write size and busy control to Control Register */
35 iowrite32((reg), region + AGNX_SPI_CTL);
36 /* Wait for Busy control to clear */
37 spi_delay();
38}
39
40/*
41 * Write to SPI Synth register
42 */
43static inline void spi_sy_write(void __iomem *region, u32 chip_ids, u32 sw)
44{
45 /* FIXME the size 0x15 is a magic value*/
46 spi_write(region, chip_ids, sw, 0x15, SPI_BUSY_CTL);
47}
48
49/*
50 * Write to SPI RF register
51 */
52static inline void spi_rf_write(void __iomem *region, u32 chip_ids, u32 sw)
53{
54 /* FIXME the size 0xd is a magic value*/
55 spi_write(region, chip_ids, sw, 0xd, SPI_BUSY_CTL);
56} /* spi_rf_write */
57
58/*
59 * Write to SPI with Read Control bit set
60 */
61inline void spi_rc_write(void __iomem *region, u32 chip_ids, u32 sw)
62{
63 /* FIXME the size 0xe5 is a magic value */
64 spi_write(region, chip_ids, sw, 0xe5, SPI_BUSY_CTL|SPI_READ_CTL);
65}
66
67/* Get the active chains's count */
68static int get_active_chains(struct agnx_priv *priv)
69{
70 void __iomem *ctl = priv->ctl;
71 int num = 0;
72 u32 reg;
73 AGNX_TRACE;
74
75 spi_rc_write(ctl, RF_CHIP0, 0x21);
76 reg = agnx_read32(ctl, AGNX_SPI_RLSW);
77 if (reg == 1)
78 num++;
79
80 spi_rc_write(ctl, RF_CHIP1, 0x21);
81 reg = agnx_read32(ctl, AGNX_SPI_RLSW);
82 if (reg == 1)
83 num++;
84
85 spi_rc_write(ctl, RF_CHIP2, 0x21);
86 reg = agnx_read32(ctl, AGNX_SPI_RLSW);
87 if (reg == 1)
88 num++;
89
90 spi_rc_write(ctl, RF_CHIP0, 0x26);
91 reg = agnx_read32(ctl, AGNX_SPI_RLSW);
92 if (0x33 != reg)
93 printk(KERN_WARNING PFX "Unmatched rf chips result\n");
94
95 return num;
96} /* get_active_chains */
97
98void rf_chips_init(struct agnx_priv *priv)
99{
100 void __iomem *ctl = priv->ctl;
101 u32 reg;
102 int num;
103 AGNX_TRACE;
104
105 if (priv->revid == 1) {
106 reg = agnx_read32(ctl, AGNX_SYSITF_GPIOUT);
107 reg |= 0x8;
108 agnx_write32(ctl, AGNX_SYSITF_GPIOUT, reg);
109 }
110
111 /* Set SPI clock speed to 200NS */
112 reg = agnx_read32(ctl, AGNX_SPI_CFG);
113 reg &= ~0xF;
114 reg |= 0x3;
115 agnx_write32(ctl, AGNX_SPI_CFG, reg);
116
117 /* Set SPI clock speed to 50NS */
118 reg = agnx_read32(ctl, AGNX_SPI_CFG);
119 reg &= ~0xF;
120 reg |= 0x1;
121 agnx_write32(ctl, AGNX_SPI_CFG, reg);
122
123 spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, 0x1101);
124
125 num = get_active_chains(priv);
126 printk(KERN_INFO PFX "Active chains are %d\n", num);
127
128 reg = agnx_read32(ctl, AGNX_SPI_CFG);
129 reg &= ~0xF;
130 agnx_write32(ctl, AGNX_SPI_CFG, reg);
131
132 spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, 0x1908);
133} /* rf_chips_init */
134
135
136static u32 channel_tbl[15][9] = {
137 {0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
138 {1, 0x00, 0x00, 0x624, 0x00, 0x1a4, 0x28, 0x00, 0x1e},
139 {2, 0x00, 0x00, 0x615, 0x00, 0x1ae, 0x28, 0x00, 0x1e},
140 {3, 0x00, 0x00, 0x61a, 0x00, 0x1ae, 0x28, 0x00, 0x1e},
141 {4, 0x00, 0x00, 0x61f, 0x00, 0x1ae, 0x28, 0x00, 0x1e},
142 {5, 0x00, 0x00, 0x624, 0x00, 0x1ae, 0x28, 0x00, 0x1e},
143 {6, 0x00, 0x00, 0x61f, 0x00, 0x1b3, 0x28, 0x00, 0x1e},
144 {7, 0x00, 0x00, 0x624, 0x00, 0x1b3, 0x28, 0x00, 0x1e},
145 {8, 0x00, 0x00, 0x629, 0x00, 0x1b3, 0x28, 0x00, 0x1e},
146 {9, 0x00, 0x00, 0x624, 0x00, 0x1b8, 0x28, 0x00, 0x1e},
147 {10, 0x00, 0x00, 0x629, 0x00, 0x1b8, 0x28, 0x00, 0x1e},
148 {11, 0x00, 0x00, 0x62e, 0x00, 0x1b8, 0x28, 0x00, 0x1e},
149 {12, 0x00, 0x00, 0x633, 0x00, 0x1b8, 0x28, 0x00, 0x1e},
150 {13, 0x00, 0x00, 0x628, 0x00, 0x1b8, 0x28, 0x00, 0x1e},
151 {14, 0x00, 0x00, 0x644, 0x00, 0x1b8, 0x28, 0x00, 0x1e},
152};
153
154
155static inline void
156channel_tbl_write(struct agnx_priv *priv, unsigned int channel, unsigned int reg_num)
157{
158 void __iomem *ctl = priv->ctl;
159 u32 reg;
160
161 reg = channel_tbl[channel][reg_num];
162 reg <<= 4;
163 reg |= reg_num;
164 spi_sy_write(ctl, SYNTH_CHIP, reg);
165}
166
167static void synth_freq_set(struct agnx_priv *priv, unsigned int channel)
168{
169 void __iomem *ctl = priv->ctl;
170 u32 reg;
171 AGNX_TRACE;
172
173 spi_rf_write(ctl, RF_CHIP0|RF_CHIP1, 0x1201);
174
175 /* Set the Clock bits to 50NS */
176 reg = agnx_read32(ctl, AGNX_SPI_CFG);
177 reg &= ~0xF;
178 reg |= 0x1;
179 agnx_write32(ctl, AGNX_SPI_CFG, reg);
180
181 /* Write 0x00c0 to LSW and 0x3 to MSW of Synth Chip */
182 spi_sy_write(ctl, SYNTH_CHIP, 0x300c0);
183
184 spi_sy_write(ctl, SYNTH_CHIP, 0x32);
185
186 /* # Write to Register 1 on the Synth Chip */
187 channel_tbl_write(priv, channel, 1);
188 /* # Write to Register 3 on the Synth Chip */
189 channel_tbl_write(priv, channel, 3);
190 /* # Write to Register 6 on the Synth Chip */
191 channel_tbl_write(priv, channel, 6);
192 /* # Write to Register 5 on the Synth Chip */
193 channel_tbl_write(priv, channel, 5);
194 /* # Write to register 8 on the Synth Chip */
195 channel_tbl_write(priv, channel, 8);
196
197 /* FIXME Clear the clock bits */
198 reg = agnx_read32(ctl, AGNX_SPI_CFG);
199 reg &= ~0xf;
200 agnx_write32(ctl, AGNX_SPI_CFG, reg);
201} /* synth_chip_init */
202
203
204static void antenna_init(struct agnx_priv *priv, int num_antenna)
205{
206 void __iomem *ctl = priv->ctl;
207
208 switch (num_antenna) {
209 case 1:
210 agnx_write32(ctl, AGNX_GCR_NLISTANT, 1);
211 agnx_write32(ctl, AGNX_GCR_NMEASANT, 1);
212 agnx_write32(ctl, AGNX_GCR_NACTIANT, 1);
213 agnx_write32(ctl, AGNX_GCR_NCAPTANT, 1);
214
215 agnx_write32(ctl, AGNX_GCR_ANTCFG, 7);
216 agnx_write32(ctl, AGNX_GCR_BOACT, 34);
217 agnx_write32(ctl, AGNX_GCR_BOINACT, 34);
218 agnx_write32(ctl, AGNX_GCR_BODYNA, 30);
219
220 agnx_write32(ctl, AGNX_GCR_THD0A, 125);
221 agnx_write32(ctl, AGNX_GCR_THD0AL, 100);
222 agnx_write32(ctl, AGNX_GCR_THD0B, 90);
223
224 agnx_write32(ctl, AGNX_GCR_THD0BTFEST, 80);
225 agnx_write32(ctl, AGNX_GCR_SIGHTH, 100);
226 agnx_write32(ctl, AGNX_GCR_SIGLTH, 16);
227 break;
228 case 2:
229 agnx_write32(ctl, AGNX_GCR_NLISTANT, 2);
230 agnx_write32(ctl, AGNX_GCR_NMEASANT, 2);
231 agnx_write32(ctl, AGNX_GCR_NACTIANT, 2);
232 agnx_write32(ctl, AGNX_GCR_NCAPTANT, 2);
233 agnx_write32(ctl, AGNX_GCR_ANTCFG, 15);
234 agnx_write32(ctl, AGNX_GCR_BOACT, 36);
235 agnx_write32(ctl, AGNX_GCR_BOINACT, 36);
236 agnx_write32(ctl, AGNX_GCR_BODYNA, 32);
237 agnx_write32(ctl, AGNX_GCR_THD0A, 120);
238 agnx_write32(ctl, AGNX_GCR_THD0AL, 100);
239 agnx_write32(ctl, AGNX_GCR_THD0B, 80);
240 agnx_write32(ctl, AGNX_GCR_THD0BTFEST, 70);
241 agnx_write32(ctl, AGNX_GCR_SIGHTH, 100);
242 agnx_write32(ctl, AGNX_GCR_SIGLTH, 32);
243 break;
244 case 3:
245 agnx_write32(ctl, AGNX_GCR_NLISTANT, 3);
246 agnx_write32(ctl, AGNX_GCR_NMEASANT, 3);
247 agnx_write32(ctl, AGNX_GCR_NACTIANT, 3);
248 agnx_write32(ctl, AGNX_GCR_NCAPTANT, 3);
249 agnx_write32(ctl, AGNX_GCR_ANTCFG, 31);
250 agnx_write32(ctl, AGNX_GCR_BOACT, 36);
251 agnx_write32(ctl, AGNX_GCR_BOINACT, 36);
252 agnx_write32(ctl, AGNX_GCR_BODYNA, 32);
253 agnx_write32(ctl, AGNX_GCR_THD0A, 100);
254 agnx_write32(ctl, AGNX_GCR_THD0AL, 100);
255 agnx_write32(ctl, AGNX_GCR_THD0B, 70);
256 agnx_write32(ctl, AGNX_GCR_THD0BTFEST, 70);
257 agnx_write32(ctl, AGNX_GCR_SIGHTH, 100);
258 agnx_write32(ctl, AGNX_GCR_SIGLTH, 48);
259/* agnx_write32(ctl, AGNX_GCR_SIGLTH, 16); */
260 break;
261 default:
262 printk(KERN_WARNING PFX "Unknow antenna number\n");
263 }
264} /* antenna_init */
265
266static void chain_update(struct agnx_priv *priv, u32 chain)
267{
268 void __iomem *ctl = priv->ctl;
269 u32 reg;
270 AGNX_TRACE;
271
272 spi_rc_write(ctl, RF_CHIP0, 0x20);
273 reg = agnx_read32(ctl, AGNX_SPI_RLSW);
274
275 if (reg == 0x4)
276 spi_rf_write(ctl, RF_CHIP0|RF_CHIP1, reg|0x1000);
277 else if (reg != 0x0)
278 spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, reg|0x1000);
279 else {
280 if (chain == 3 || chain == 6) {
281 spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, reg|0x1000);
282 agnx_write32(ctl, AGNX_GCR_RXOVERIDE, 0x0);
283 } else if (chain == 2 || chain == 4) {
284 spi_rf_write(ctl, RF_CHIP0|RF_CHIP1, reg|0x1000);
285 spi_rf_write(ctl, RF_CHIP2, 0x1005);
286 agnx_write32(ctl, AGNX_GCR_RXOVERIDE, 0x824);
287 } else if (chain == 1) {
288 spi_rf_write(ctl, RF_CHIP0, reg|0x1000);
289 spi_rf_write(ctl, RF_CHIP1|RF_CHIP2, 0x1004);
290 agnx_write32(ctl, AGNX_GCR_RXOVERIDE, 0xc36);
291 }
292 }
293
294 spi_rc_write(ctl, RF_CHIP0, 0x22);
295 reg = agnx_read32(ctl, AGNX_SPI_RLSW);
296
297 switch (reg) {
298 case 0:
299 spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, 0x1005);
300 break;
301 case 1:
302 spi_rf_write(ctl, RF_CHIP0|RF_CHIP1, 0x1201);
303 break;
304 case 2:
305 if (chain == 6 || chain == 4) {
306 spi_rf_write(ctl, RF_CHIP0|RF_CHIP1, 0x1202);
307 spi_rf_write(ctl, RF_CHIP2, 0x1005);
308 } else if (chain < 3) {
309 spi_rf_write(ctl, RF_CHIP0, 0x1202);
310 spi_rf_write(ctl, RF_CHIP1|RF_CHIP2, 0x1005);
311 }
312 break;
313 default:
314 if (chain == 3) {
315 spi_rf_write(ctl, RF_CHIP0|RF_CHIP1, 0x1203);
316 spi_rf_write(ctl, RF_CHIP2, 0x1201);
317 } else if (chain == 2) {
318 spi_rf_write(ctl, RF_CHIP0, 0x1203);
319 spi_rf_write(ctl, RF_CHIP2, 0x1200);
320 spi_rf_write(ctl, RF_CHIP1, 0x1201);
321 } else if (chain == 1) {
322 spi_rf_write(ctl, RF_CHIP0, 0x1203);
323 spi_rf_write(ctl, RF_CHIP1|RF_CHIP2, 0x1200);
324 } else if (chain == 4) {
325 spi_rf_write(ctl, RF_CHIP0|RF_CHIP1, 0x1203);
326 spi_rf_write(ctl, RF_CHIP2, 0x1201);
327 } else {
328 spi_rf_write(ctl, RF_CHIP0, 0x1203);
329 spi_rf_write(ctl, RF_CHIP1|RF_CHIP2, 0x1201);
330 }
331 }
332} /* chain_update */
333
334static void antenna_config(struct agnx_priv *priv)
335{
336 void __iomem *ctl = priv->ctl;
337 u32 reg;
338 AGNX_TRACE;
339
340 /* Write 0x0 to the TX Management Control Register Enable bit */
341 reg = agnx_read32(ctl, AGNX_TXM_CTL);
342 reg &= ~0x1;
343 agnx_write32(ctl, AGNX_TXM_CTL, reg);
344
345 /* FIXME */
346 /* Set initial value based on number of Antennae */
347 antenna_init(priv, 3);
348
349 /* FIXME Update Power Templates for current valid Stations */
350 /* sta_power_init(priv, 0);*/
351
352 /* FIXME the number of chains should get from eeprom*/
353 chain_update(priv, AGNX_CHAINS_MAX);
354} /* antenna_config */
355
356void calibrate_oscillator(struct agnx_priv *priv)
357{
358 void __iomem *ctl = priv->ctl;
359 u32 reg;
360 AGNX_TRACE;
361
362 spi_rc_write(ctl, RF_CHIP0|RF_CHIP1, 0x1201);
363 reg = agnx_read32(ctl, AGNX_GCR_GAINSET1);
364 reg |= 0x10;
365 agnx_write32(ctl, AGNX_GCR_GAINSET1, reg);
366
367 agnx_write32(ctl, AGNX_GCR_GAINSETWRITE, 1);
368 agnx_write32(ctl, AGNX_GCR_RSTGCTL, 1);
369
370 agnx_write32(ctl, AGNX_ACI_LEN, 0x3ff);
371
372 agnx_write32(ctl, AGNX_ACI_TIMER1, 0x27);
373 agnx_write32(ctl, AGNX_ACI_TIMER2, 0x27);
374 /* (Residual DC Calibration) to Calibration Mode */
375 agnx_write32(ctl, AGNX_ACI_MODE, 0x2);
376
377 spi_rc_write(ctl, RF_CHIP0|RF_CHIP1, 0x1004);
378 agnx_write32(ctl, AGNX_ACI_LEN, 0x3ff);
379 /* (TX LO Calibration) to Calibration Mode */
380 agnx_write32(ctl, AGNX_ACI_MODE, 0x4);
381
382 do {
383 u32 reg1, reg2, reg3;
384 /* Enable Power Saving Control */
385 enable_power_saving(priv);
386 /* Save the following registers to restore */
387 reg1 = ioread32(ctl + 0x11000);
388 reg2 = ioread32(ctl + 0xec50);
389 reg3 = ioread32(ctl + 0xec54);
390 wmb();
391
392 agnx_write32(ctl, 0x11000, 0xcfdf);
393 agnx_write32(ctl, 0xec50, 0x70);
394 /* Restore the registers */
395 agnx_write32(ctl, 0x11000, reg1);
396 agnx_write32(ctl, 0xec50, reg2);
397 agnx_write32(ctl, 0xec54, reg3);
398 /* Disable Power Saving Control */
399 disable_power_saving(priv);
400 } while (0);
401
402 agnx_write32(ctl, AGNX_GCR_RSTGCTL, 0);
403} /* calibrate_oscillator */
404
405
406static void radio_channel_set(struct agnx_priv *priv, unsigned int channel)
407{
408 void __iomem *ctl = priv->ctl;
409 unsigned int freq = priv->band.channels[channel - 1].center_freq;
410 u32 reg;
411 AGNX_TRACE;
412
413 spi_rf_write(ctl, RF_CHIP0|RF_CHIP1, 0x1201);
414 /* Set SPI Clock to 50 Ns */
415 reg = agnx_read32(ctl, AGNX_SPI_CFG);
416 reg &= ~0xF;
417 reg |= 0x1;
418 agnx_write32(ctl, AGNX_SPI_CFG, reg);
419
420 /* Clear the Disable Tx interrupt bit in Interrupt Mask */
421/* reg = agnx_read32(ctl, AGNX_INT_MASK); */
422/* reg &= ~IRQ_TX_DISABLE; */
423/* agnx_write32(ctl, AGNX_INT_MASK, reg); */
424
425 /* Band Selection */
426 reg = agnx_read32(ctl, AGNX_SYSITF_GPIOUT);
427 reg |= 0x8;
428 agnx_write32(ctl, AGNX_SYSITF_GPIOUT, reg);
429
430 /* FIXME Set the SiLabs Chip Frequency */
431 synth_freq_set(priv, channel);
432
433 reg = agnx_read32(ctl, AGNX_PM_SOFTRST);
434 reg |= 0x80100030;
435 agnx_write32(ctl, AGNX_PM_SOFTRST, reg);
436 reg = agnx_read32(ctl, AGNX_PM_PLLCTL);
437 reg |= 0x20009;
438 agnx_write32(ctl, AGNX_PM_PLLCTL, reg);
439
440 agnx_write32(ctl, AGNX_SYSITF_GPIOUT, 0x5);
441
442 spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, 0x1100);
443
444 /* Load the MonitorGain Table */
445 monitor_gain_table_init(priv);
446
447 /* Load the TX Fir table */
448 tx_fir_table_init(priv);
449
450 reg = agnx_read32(ctl, AGNX_PM_PMCTL);
451 reg |= 0x8;
452 agnx_write32(ctl, AGNX_PM_PMCTL, reg);
453
454 spi_rc_write(ctl, RF_CHIP0|RF_CHIP1, 0x22);
455 udelay(80);
456 reg = agnx_read32(ctl, AGNX_SPI_RLSW);
457
458
459 agnx_write32(ctl, AGNX_GCR_RXOVERIDE, 0xff);
460 agnx_write32(ctl, AGNX_GCR_DISCOVMOD, 0x3);
461
462 reg = agnx_read32(ctl, 0xec50);
463 reg |= 0x4f;
464 agnx_write32(ctl, 0xec50, reg);
465
466 spi_rf_write(ctl, RF_CHIP0|RF_CHIP1, 0x1201);
467 agnx_write32(ctl, 0x11008, 0x1);
468 agnx_write32(ctl, 0x1100c, 0x0);
469 agnx_write32(ctl, 0x11008, 0x0);
470 agnx_write32(ctl, 0xec50, 0xc);
471
472 agnx_write32(ctl, AGNX_GCR_DISCOVMOD, 0x3);
473 agnx_write32(ctl, AGNX_GCR_RXOVERIDE, 0x0);
474 agnx_write32(ctl, 0x11010, 0x6e);
475 agnx_write32(ctl, 0x11014, 0x6c);
476
477 spi_rf_write(ctl, RF_CHIP0|RF_CHIP1, 0x1201);
478
479 /* Calibrate the Antenna */
480 /* antenna_calibrate(priv); */
481 /* Calibrate the TxLocalOscillator */
482 calibrate_oscillator(priv);
483
484 reg = agnx_read32(ctl, AGNX_PM_PMCTL);
485 reg &= ~0x8;
486 agnx_write32(ctl, AGNX_PM_PMCTL, reg);
487 agnx_write32(ctl, AGNX_GCR_GAININIT, 0xa);
488 agnx_write32(ctl, AGNX_GCR_THCD, 0x0);
489
490 agnx_write32(ctl, 0x11018, 0xb);
491 agnx_write32(ctl, AGNX_GCR_DISCOVMOD, 0x0);
492
493 /* Write Frequency to Gain Control Channel */
494 agnx_write32(ctl, AGNX_GCR_RXCHANEL, freq);
495 /* Write 0x140000/Freq to 0x9c08 */
496 reg = 0x140000/freq;
497 agnx_write32(ctl, 0x9c08, reg);
498
499 reg = agnx_read32(ctl, AGNX_PM_SOFTRST);
500 reg &= ~0x80100030;
501 agnx_write32(ctl, AGNX_PM_SOFTRST, reg);
502
503 reg = agnx_read32(ctl, AGNX_PM_PLLCTL);
504 reg &= ~0x20009;
505 reg |= 0x1;
506 agnx_write32(ctl, AGNX_PM_PLLCTL, reg);
507
508 agnx_write32(ctl, AGNX_ACI_MODE, 0x0);
509
510/* FIXME According to Number of Chains: */
511
512/* 1. 1: */
513/* 1. Write 0x1203 to RF Chip 0 */
514/* 2. Write 0x1200 to RF Chips 1 +2 */
515/* 2. 2: */
516/* 1. Write 0x1203 to RF Chip 0 */
517/* 2. Write 0x1200 to RF Chip 2 */
518/* 3. Write 0x1201 to RF Chip 1 */
519/* 3. 3: */
520/* 1. Write 0x1203 to RF Chip 0 */
521/* 2. Write 0x1201 to RF Chip 1 + 2 */
522/* 4. 4: */
523/* 1. Write 0x1203 to RF Chip 0 + 1 */
524/* 2. Write 0x1200 to RF Chip 2 */
525
526/* 5. 6: */
527 spi_rf_write(ctl, RF_CHIP0|RF_CHIP1, 0x1203);
528 spi_rf_write(ctl, RF_CHIP2, 0x1201);
529
530 spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, 0x1000);
531 agnx_write32(ctl, AGNX_GCR_RXOVERIDE, 0x0);
532
533 /* FIXME Set the Disable Tx interrupt bit in Interrupt Mask
534 (Or 0x20000 to Interrupt Mask) */
535/* reg = agnx_read32(ctl, AGNX_INT_MASK); */
536/* reg |= IRQ_TX_DISABLE; */
537/* agnx_write32(ctl, AGNX_INT_MASK, reg); */
538
539 agnx_write32(ctl, AGNX_GCR_RSTGCTL, 0x1);
540 agnx_write32(ctl, AGNX_GCR_RSTGCTL, 0x0);
541
542 /* Configure the Antenna */
543 antenna_config(priv);
544
545 /* Write 0x0 to Discovery Mode Enable detect G, B, A packet? */
546 agnx_write32(ctl, AGNX_GCR_DISCOVMOD, 0);
547
548 reg = agnx_read32(ctl, AGNX_RXM_REQRATE);
549 reg |= 0x80000000;
550 agnx_write32(ctl, AGNX_RXM_REQRATE, reg);
551 agnx_write32(ctl, AGNX_GCR_RSTGCTL, 0x1);
552 agnx_write32(ctl, AGNX_GCR_RSTGCTL, 0x0);
553
554 /* enable radio on and the power LED */
555 reg = agnx_read32(ctl, AGNX_SYSITF_GPIOUT);
556 reg &= ~0x1;
557 reg |= 0x2;
558 agnx_write32(ctl, AGNX_SYSITF_GPIOUT, reg);
559
560 reg = agnx_read32(ctl, AGNX_TXM_CTL);
561 reg |= 0x1;
562 agnx_write32(ctl, AGNX_TXM_CTL, reg);
563} /* radio_channel_set */
564
565static void base_band_filter_calibrate(struct agnx_priv *priv)
566{
567 void __iomem *ctl = priv->ctl;
568
569 spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, 0x1700);
570 spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, 0x1001);
571 agnx_write32(ctl, AGNX_GCR_FORCECTLCLK, 0x0);
572 spi_rc_write(ctl, RF_CHIP0, 0x27);
573 spi_rc_write(ctl, RF_CHIP1, 0x27);
574 spi_rc_write(ctl, RF_CHIP2, 0x27);
575 agnx_write32(ctl, AGNX_GCR_FORCECTLCLK, 0x1);
576}
577
578static void print_offset(struct agnx_priv *priv, u32 chain)
579{
580 void __iomem *ctl = priv->ctl;
581 u32 offset;
582
583 iowrite32((chain), ctl + AGNX_ACI_SELCHAIN);
584 udelay(10);
585 offset = (ioread32(ctl + AGNX_ACI_OFFSET));
586 printk(PFX "Chain is 0x%x, Offset is 0x%x\n", chain, offset);
587}
588
589void print_offsets(struct agnx_priv *priv)
590{
591 print_offset(priv, 0);
592 print_offset(priv, 4);
593 print_offset(priv, 1);
594 print_offset(priv, 5);
595 print_offset(priv, 2);
596 print_offset(priv, 6);
597}
598
599
600struct chains {
601 u32 cali; /* calibrate value*/
602
603#define NEED_CALIBRATE 0
604#define SUCCESS_CALIBRATE 1
605 int status;
606};
607
608static void chain_calibrate(struct agnx_priv *priv, struct chains *chains,
609 unsigned int num)
610{
611 void __iomem *ctl = priv->ctl;
612 u32 calibra = chains[num].cali;
613
614 if (num < 3)
615 calibra |= 0x1400;
616 else
617 calibra |= 0x1500;
618
619 switch (num) {
620 case 0:
621 case 4:
622 spi_rf_write(ctl, RF_CHIP0, calibra);
623 break;
624 case 1:
625 case 5:
626 spi_rf_write(ctl, RF_CHIP1, calibra);
627 break;
628 case 2:
629 case 6:
630 spi_rf_write(ctl, RF_CHIP2, calibra);
631 break;
632 default:
633 BUG();
634 }
635} /* chain_calibrate */
636
637static inline void get_calibrete_value(struct agnx_priv *priv, struct chains *chains,
638 unsigned int num)
639{
640 void __iomem *ctl = priv->ctl;
641 u32 offset;
642
643 iowrite32((num), ctl + AGNX_ACI_SELCHAIN);
644 /* FIXME */
645 udelay(10);
646 offset = (ioread32(ctl + AGNX_ACI_OFFSET));
647
648 if (offset < 0xf) {
649 chains[num].status = SUCCESS_CALIBRATE;
650 return;
651 }
652
653 if (num == 0 || num == 1 || num == 2) {
654 if (0 == chains[num].cali)
655 chains[num].cali = 0xff;
656 else
657 chains[num].cali--;
658 } else
659 chains[num].cali++;
660
661 chains[num].status = NEED_CALIBRATE;
662}
663
664static inline void calibra_delay(struct agnx_priv *priv)
665{
666 void __iomem *ctl = priv->ctl;
667 u32 reg;
668 unsigned int i = 100;
669
670 wmb();
671 while (--i) {
672 reg = (ioread32(ctl + AGNX_ACI_STATUS));
673 if (reg == 0x4000)
674 break;
675 udelay(10);
676 }
677 if (!i)
678 printk(PFX "calibration failed\n");
679}
680
681void do_calibration(struct agnx_priv *priv)
682{
683 void __iomem *ctl = priv->ctl;
684 struct chains chains[7];
685 unsigned int i, j;
686 AGNX_TRACE;
687
688 for (i = 0; i < 7; i++) {
689 if (i == 3)
690 continue;
691
692 chains[i].cali = 0x7f;
693 chains[i].status = NEED_CALIBRATE;
694 }
695
696 /* FIXME 0x300 is a magic number */
697 for (j = 0; j < 0x300; j++) {
698 if (chains[0].status == SUCCESS_CALIBRATE &&
699 chains[1].status == SUCCESS_CALIBRATE &&
700 chains[2].status == SUCCESS_CALIBRATE &&
701 chains[4].status == SUCCESS_CALIBRATE &&
702 chains[5].status == SUCCESS_CALIBRATE &&
703 chains[6].status == SUCCESS_CALIBRATE)
704 break;
705
706 /* Attention, there is no chain 3 */
707 for (i = 0; i < 7; i++) {
708 if (i == 3)
709 continue;
710 if (chains[i].status == NEED_CALIBRATE)
711 chain_calibrate(priv, chains, i);
712 }
713 /* Write 0x1 to Calibration Measure */
714 iowrite32((0x1), ctl + AGNX_ACI_MEASURE);
715 calibra_delay(priv);
716
717 for (i = 0; i < 7; i++) {
718 if (i == 3)
719 continue;
720
721 get_calibrete_value(priv, chains, i);
722 }
723 }
724 printk(PFX "Clibrate times is %d\n", j);
725 print_offsets(priv);
726} /* do_calibration */
727
728void antenna_calibrate(struct agnx_priv *priv)
729{
730 void __iomem *ctl = priv->ctl;
731 u32 reg;
732 AGNX_TRACE;
733
734 agnx_write32(ctl, AGNX_GCR_NLISTANT, 0x3);
735 agnx_write32(ctl, AGNX_GCR_NMEASANT, 0x3);
736 agnx_write32(ctl, AGNX_GCR_NACTIANT, 0x3);
737 agnx_write32(ctl, AGNX_GCR_NCAPTANT, 0x3);
738
739 agnx_write32(ctl, AGNX_GCR_ANTCFG, 0x1f);
740 agnx_write32(ctl, AGNX_GCR_BOACT, 0x24);
741 agnx_write32(ctl, AGNX_GCR_BOINACT, 0x24);
742 agnx_write32(ctl, AGNX_GCR_BODYNA, 0x20);
743 agnx_write32(ctl, AGNX_GCR_THD0A, 0x64);
744 agnx_write32(ctl, AGNX_GCR_THD0AL, 0x64);
745 agnx_write32(ctl, AGNX_GCR_THD0B, 0x46);
746 agnx_write32(ctl, AGNX_GCR_THD0BTFEST, 0x3c);
747 agnx_write32(ctl, AGNX_GCR_SIGHTH, 0x64);
748 agnx_write32(ctl, AGNX_GCR_SIGLTH, 0x30);
749
750 spi_rc_write(ctl, RF_CHIP0, 0x20);
751 /* Fixme */
752 udelay(80);
753 /* 1. Should read 0x0 */
754 reg = agnx_read32(ctl, AGNX_SPI_RLSW);
755 if (0x0 != reg)
756 printk(KERN_WARNING PFX "Unmatched rf chips result\n");
757 spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, 0x1000);
758
759 agnx_write32(ctl, AGNX_GCR_RXOVERIDE, 0x0);
760
761 spi_rc_write(ctl, RF_CHIP0, 0x22);
762 udelay(80);
763 reg = agnx_read32(ctl, AGNX_SPI_RLSW);
764 if (0x0 != reg)
765 printk(KERN_WARNING PFX "Unmatched rf chips result\n");
766 spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, 0x1005);
767
768 agnx_write32(ctl, AGNX_GCR_RSTGCTL, 0x1);
769 agnx_write32(ctl, AGNX_GCR_RSTGCTL, 0x0);
770
771 reg = agnx_read32(ctl, AGNX_PM_SOFTRST);
772 reg |= 0x1c000032;
773 agnx_write32(ctl, AGNX_PM_SOFTRST, reg);
774 reg = agnx_read32(ctl, AGNX_PM_PLLCTL);
775 reg |= 0x0003f07;
776 agnx_write32(ctl, AGNX_PM_PLLCTL, reg);
777
778 reg = agnx_read32(ctl, 0xec50);
779 reg |= 0x40;
780 agnx_write32(ctl, 0xec50, reg);
781
782 agnx_write32(ctl, AGNX_GCR_RXOVERIDE, 0xff8);
783 agnx_write32(ctl, AGNX_GCR_DISCOVMOD, 0x3);
784
785 agnx_write32(ctl, AGNX_GCR_CHAINNUM, 0x6);
786 agnx_write32(ctl, 0x19874, 0x0);
787 spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, 0x1700);
788
789 /* Calibrate the BaseBandFilter */
790 base_band_filter_calibrate(priv);
791
792 spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, 0x1002);
793
794 agnx_write32(ctl, AGNX_GCR_GAINSET0, 0x1d);
795 agnx_write32(ctl, AGNX_GCR_GAINSET1, 0x1d);
796 agnx_write32(ctl, AGNX_GCR_GAINSET2, 0x1d);
797 agnx_write32(ctl, AGNX_GCR_GAINSETWRITE, 0x1);
798
799 agnx_write32(ctl, AGNX_ACI_MODE, 0x1);
800 agnx_write32(ctl, AGNX_ACI_LEN, 0x3ff);
801
802 agnx_write32(ctl, AGNX_ACI_TIMER1, 0x27);
803 agnx_write32(ctl, AGNX_ACI_TIMER2, 0x27);
804
805 spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, 0x1400);
806 spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, 0x1500);
807
808 /* Measure Calibration */
809 agnx_write32(ctl, AGNX_ACI_MEASURE, 0x1);
810 calibra_delay(priv);
811
812 /* do calibration */
813 do_calibration(priv);
814
815 agnx_write32(ctl, AGNX_GCR_RXOVERIDE, 0x0);
816 agnx_write32(ctl, AGNX_ACI_TIMER1, 0x21);
817 agnx_write32(ctl, AGNX_ACI_TIMER2, 0x27);
818 agnx_write32(ctl, AGNX_ACI_LEN, 0xf);
819
820 reg = agnx_read32(ctl, AGNX_GCR_GAINSET0);
821 reg &= 0xf;
822 agnx_write32(ctl, AGNX_GCR_GAINSET0, reg);
823 reg = agnx_read32(ctl, AGNX_GCR_GAINSET1);
824 reg &= 0xf;
825 agnx_write32(ctl, AGNX_GCR_GAINSET1, reg);
826 reg = agnx_read32(ctl, AGNX_GCR_GAINSET2);
827 reg &= 0xf;
828 agnx_write32(ctl, AGNX_GCR_GAINSET2, reg);
829
830 agnx_write32(ctl, AGNX_GCR_GAINSETWRITE, 0x0);
831 disable_receiver(priv);
832} /* antenna_calibrate */
833
834void __antenna_calibrate(struct agnx_priv *priv)
835{
836 void __iomem *ctl = priv->ctl;
837 u32 reg;
838
839 /* Calibrate the BaseBandFilter */
840 /* base_band_filter_calibrate(priv); */
841 spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, 0x1002);
842
843
844 agnx_write32(ctl, AGNX_GCR_GAINSET0, 0x1d);
845 agnx_write32(ctl, AGNX_GCR_GAINSET1, 0x1d);
846 agnx_write32(ctl, AGNX_GCR_GAINSET2, 0x1d);
847
848 agnx_write32(ctl, AGNX_GCR_GAINSETWRITE, 0x1);
849
850 agnx_write32(ctl, AGNX_ACI_MODE, 0x1);
851 agnx_write32(ctl, AGNX_ACI_LEN, 0x3ff);
852
853
854 agnx_write32(ctl, AGNX_ACI_TIMER1, 0x27);
855 agnx_write32(ctl, AGNX_ACI_TIMER2, 0x27);
856 spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, 0x1400);
857 spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, 0x1500);
858 /* Measure Calibration */
859 agnx_write32(ctl, AGNX_ACI_MEASURE, 0x1);
860 calibra_delay(priv);
861 do_calibration(priv);
862 agnx_write32(ctl, AGNX_GCR_RXOVERIDE, 0x0);
863
864 agnx_write32(ctl, AGNX_ACI_TIMER1, 0x21);
865 agnx_write32(ctl, AGNX_ACI_TIMER2, 0x27);
866
867 agnx_write32(ctl, AGNX_ACI_LEN, 0xf);
868
869 reg = agnx_read32(ctl, AGNX_GCR_GAINSET0);
870 reg &= 0xf;
871 agnx_write32(ctl, AGNX_GCR_GAINSET0, reg);
872 reg = agnx_read32(ctl, AGNX_GCR_GAINSET1);
873 reg &= 0xf;
874 agnx_write32(ctl, AGNX_GCR_GAINSET1, reg);
875 reg = agnx_read32(ctl, AGNX_GCR_GAINSET2);
876 reg &= 0xf;
877 agnx_write32(ctl, AGNX_GCR_GAINSET2, reg);
878
879
880 agnx_write32(ctl, AGNX_GCR_GAINSETWRITE, 0x0);
881
882 /* Write 0x3 Gain Control Discovery Mode */
883 enable_receiver(priv);
884}
885
886int agnx_set_channel(struct agnx_priv *priv, unsigned int channel)
887{
888 AGNX_TRACE;
889
890 printk(KERN_ERR PFX "Channel is %d %s\n", channel, __func__);
891 radio_channel_set(priv, channel);
892 return 0;
893}
diff --git a/drivers/staging/agnx/sta.c b/drivers/staging/agnx/sta.c
deleted file mode 100644
index 3e7db5e2811a..000000000000
--- a/drivers/staging/agnx/sta.c
+++ /dev/null
@@ -1,218 +0,0 @@
1#include <linux/delay.h>
2#include <linux/etherdevice.h>
3#include "phy.h"
4#include "sta.h"
5#include "debug.h"
6
7void hash_read(struct agnx_priv *priv, u32 reghi, u32 reglo, u8 sta_id)
8{
9 void __iomem *ctl = priv->ctl;
10
11 reglo &= 0xFFFF;
12 reglo |= 0x30000000;
13 reglo |= 0x40000000; /* Set status busy */
14 reglo |= sta_id << 16;
15
16 iowrite32(0, ctl + AGNX_RXM_HASH_CMD_FLAG);
17 iowrite32(reghi, ctl + AGNX_RXM_HASH_CMD_HIGH);
18 iowrite32(reglo, ctl + AGNX_RXM_HASH_CMD_LOW);
19
20 reghi = ioread32(ctl + AGNX_RXM_HASH_CMD_HIGH);
21 reglo = ioread32(ctl + AGNX_RXM_HASH_CMD_LOW);
22 printk(PFX "RX hash cmd are : %.8x%.8x\n", reghi, reglo);
23}
24
25void hash_write(struct agnx_priv *priv, const u8 *mac_addr, u8 sta_id)
26{
27 void __iomem *ctl = priv->ctl;
28 u32 reghi, reglo;
29
30 if (!is_valid_ether_addr(mac_addr))
31 printk(KERN_WARNING PFX "Update hash table: Invalid hwaddr!\n");
32
33 reghi = mac_addr[0] << 24 | mac_addr[1] << 16 | mac_addr[2] << 8 | mac_addr[3];
34 reglo = mac_addr[4] << 8 | mac_addr[5];
35 reglo |= 0x10000000; /* Set hash commmand */
36 reglo |= 0x40000000; /* Set status busy */
37 reglo |= sta_id << 16;
38
39 iowrite32(0, ctl + AGNX_RXM_HASH_CMD_FLAG);
40 iowrite32(reghi, ctl + AGNX_RXM_HASH_CMD_HIGH);
41 iowrite32(reglo, ctl + AGNX_RXM_HASH_CMD_LOW);
42
43 reglo = ioread32(ctl + AGNX_RXM_HASH_CMD_LOW);
44 if (!(reglo & 0x80000000))
45 printk(KERN_WARNING PFX "Update hash table failed\n");
46}
47
48void hash_delete(struct agnx_priv *priv, u32 reghi, u32 reglo, u8 sta_id)
49{
50 void __iomem *ctl = priv->ctl;
51
52 reglo &= 0xFFFF;
53 reglo |= 0x20000000;
54 reglo |= 0x40000000; /* Set status busy */
55 reglo |= sta_id << 16;
56
57 iowrite32(0, ctl + AGNX_RXM_HASH_CMD_FLAG);
58 iowrite32(reghi, ctl + AGNX_RXM_HASH_CMD_HIGH);
59 iowrite32(reglo, ctl + AGNX_RXM_HASH_CMD_LOW);
60 reghi = ioread32(ctl + AGNX_RXM_HASH_CMD_HIGH);
61
62 reglo = ioread32(ctl + AGNX_RXM_HASH_CMD_LOW);
63 printk(PFX "RX hash cmd are : %.8x%.8x\n", reghi, reglo);
64
65}
66
67void hash_dump(struct agnx_priv *priv, u8 sta_id)
68{
69 void __iomem *ctl = priv->ctl;
70 u32 reghi, reglo;
71
72 reglo = 0x40000000; /* status bit */
73 iowrite32(reglo, ctl + AGNX_RXM_HASH_CMD_LOW);
74 iowrite32(sta_id << 16, ctl + AGNX_RXM_HASH_DUMP_DATA);
75
76 udelay(80);
77
78 reghi = ioread32(ctl + AGNX_RXM_HASH_CMD_HIGH);
79 reglo = ioread32(ctl + AGNX_RXM_HASH_CMD_LOW);
80 printk(PFX "hash cmd are : %.8x%.8x\n", reghi, reglo);
81 reghi = ioread32(ctl + AGNX_RXM_HASH_CMD_FLAG);
82 printk(PFX "hash flag is : %.8x\n", reghi);
83 reghi = ioread32(ctl + AGNX_RXM_HASH_DUMP_MST);
84 reglo = ioread32(ctl + AGNX_RXM_HASH_DUMP_LST);
85 printk(PFX "hash dump mst lst: %.8x%.8x\n", reghi, reglo);
86 reghi = ioread32(ctl + AGNX_RXM_HASH_DUMP_DATA);
87 printk(PFX "hash dump data: %.8x\n", reghi);
88}
89
90void get_sta_power(struct agnx_priv *priv, struct agnx_sta_power *power, unsigned int sta_idx)
91{
92 void __iomem *ctl = priv->ctl;
93 memcpy_fromio(power, ctl + AGNX_TXM_STAPOWTEMP + sizeof(*power) * sta_idx,
94 sizeof(*power));
95}
96
97inline void
98set_sta_power(struct agnx_priv *priv, struct agnx_sta_power *power, unsigned int sta_idx)
99{
100 void __iomem *ctl = priv->ctl;
101 /* FIXME 2. Write Template to offset + station number */
102 memcpy_toio(ctl + AGNX_TXM_STAPOWTEMP + sizeof(*power) * sta_idx,
103 power, sizeof(*power));
104}
105
106
107void get_sta_tx_wq(struct agnx_priv *priv, struct agnx_sta_tx_wq *tx_wq,
108 unsigned int sta_idx, unsigned int wq_idx)
109{
110 void __iomem *data = priv->data;
111 memcpy_fromio(tx_wq, data + AGNX_PDU_TX_WQ + sizeof(*tx_wq) * STA_TX_WQ_NUM * sta_idx +
112 sizeof(*tx_wq) * wq_idx, sizeof(*tx_wq));
113
114}
115
116inline void set_sta_tx_wq(struct agnx_priv *priv, struct agnx_sta_tx_wq *tx_wq,
117 unsigned int sta_idx, unsigned int wq_idx)
118{
119 void __iomem *data = priv->data;
120 memcpy_toio(data + AGNX_PDU_TX_WQ + sizeof(*tx_wq) * STA_TX_WQ_NUM * sta_idx +
121 sizeof(*tx_wq) * wq_idx, tx_wq, sizeof(*tx_wq));
122}
123
124
125void get_sta(struct agnx_priv *priv, struct agnx_sta *sta, unsigned int sta_idx)
126{
127 void __iomem *data = priv->data;
128
129 memcpy_fromio(sta, data + AGNX_PDUPOOL + sizeof(*sta) * sta_idx,
130 sizeof(*sta));
131}
132
133inline void set_sta(struct agnx_priv *priv, struct agnx_sta *sta, unsigned int sta_idx)
134{
135 void __iomem *data = priv->data;
136
137 memcpy_toio(data + AGNX_PDUPOOL + sizeof(*sta) * sta_idx,
138 sta, sizeof(*sta));
139}
140
141/* FIXME */
142void sta_power_init(struct agnx_priv *priv, unsigned int sta_idx)
143{
144 struct agnx_sta_power power;
145 u32 reg;
146 AGNX_TRACE;
147
148 memset(&power, 0, sizeof(power));
149 reg = agnx_set_bits(EDCF, EDCF_SHIFT, 0x1);
150 power.reg = cpu_to_le32(reg);
151 set_sta_power(priv, &power, sta_idx);
152 udelay(40);
153} /* add_power_template */
154
155
156/* @num: The #number of station that is visible to the card */
157static void sta_tx_workqueue_init(struct agnx_priv *priv, unsigned int sta_idx)
158{
159 struct agnx_sta_tx_wq tx_wq;
160 u32 reg;
161 unsigned int i;
162
163 memset(&tx_wq, 0, sizeof(tx_wq));
164
165 reg = agnx_set_bits(WORK_QUEUE_VALID, WORK_QUEUE_VALID_SHIFT, 1);
166 reg |= agnx_set_bits(WORK_QUEUE_ACK_TYPE, WORK_QUEUE_ACK_TYPE_SHIFT, 1);
167/* reg |= agnx_set_bits(WORK_QUEUE_ACK_TYPE, WORK_QUEUE_ACK_TYPE_SHIFT, 0); */
168 tx_wq.reg2 |= cpu_to_le32(reg);
169
170 /* Suppose all 8 traffic class are used */
171 for (i = 0; i < STA_TX_WQ_NUM; i++)
172 set_sta_tx_wq(priv, &tx_wq, sta_idx, i);
173} /* sta_tx_workqueue_init */
174
175
176static void sta_traffic_init(struct agnx_sta_traffic *traffic)
177{
178 u32 reg;
179 memset(traffic, 0, sizeof(*traffic));
180
181 reg = agnx_set_bits(NEW_PACKET, NEW_PACKET_SHIFT, 1);
182 reg |= agnx_set_bits(TRAFFIC_VALID, TRAFFIC_VALID_SHIFT, 1);
183/* reg |= agnx_set_bits(TRAFFIC_ACK_TYPE, TRAFFIC_ACK_TYPE_SHIFT, 1); */
184 traffic->reg0 = cpu_to_le32(reg);
185
186 /* 3. setting RX Sequence Number to 4095 */
187 reg = agnx_set_bits(RX_SEQUENCE_NUM, RX_SEQUENCE_NUM_SHIFT, 4095);
188 traffic->reg1 = cpu_to_le32(reg);
189}
190
191
192/* @num: The #number of station that is visible to the card */
193void sta_init(struct agnx_priv *priv, unsigned int sta_idx)
194{
195 /* FIXME the length of sta is 256 bytes Is that
196 * dangerous to stack overflow? */
197 struct agnx_sta sta;
198 u32 reg;
199 int i;
200
201 memset(&sta, 0, sizeof(sta));
202 /* Set valid to 1 */
203 reg = agnx_set_bits(STATION_VALID, STATION_VALID_SHIFT, 1);
204 /* Set Enable Concatenation to 0 (?) */
205 reg |= agnx_set_bits(ENABLE_CONCATENATION, ENABLE_CONCATENATION_SHIFT, 0);
206 /* Set Enable Decompression to 0 (?) */
207 reg |= agnx_set_bits(ENABLE_DECOMPRESSION, ENABLE_DECOMPRESSION_SHIFT, 0);
208 sta.reg = cpu_to_le32(reg);
209
210 /* Initialize each of the Traffic Class Structures by: */
211 for (i = 0; i < 8; i++)
212 sta_traffic_init(sta.traffic + i);
213
214 set_sta(priv, &sta, sta_idx);
215 sta_tx_workqueue_init(priv, sta_idx);
216} /* sta_descriptor_init */
217
218
diff --git a/drivers/staging/agnx/sta.h b/drivers/staging/agnx/sta.h
deleted file mode 100644
index fd504e3f3870..000000000000
--- a/drivers/staging/agnx/sta.h
+++ /dev/null
@@ -1,222 +0,0 @@
1#ifndef AGNX_STA_H_
2#define AGNX_STA_H_
3
4#define STA_TX_WQ_NUM 8 /* The number of TX workqueue one STA has */
5
6struct agnx_hash_cmd {
7 __be32 cmdhi;
8#define MACLO 0xFFFF0000
9#define MACLO_SHIFT 16
10#define STA_ID 0x0000FFF0
11#define STA_ID_SHIFT 4
12#define CMD 0x0000000C
13#define CMD_SHIFT 2
14#define STATUS 0x00000002
15#define STATUS_SHIFT 1
16#define PASS 0x00000001
17#define PASS_SHIFT 1
18 __be32 cmdlo;
19} __attribute__((__packed__));
20
21
22/*
23 * Station Power Template
24 * FIXME Just for agn100 yet
25 */
26struct agnx_sta_power {
27 __le32 reg;
28#define SIGNAL 0x000000FF /* signal */
29#define SIGNAL_SHIFT 0
30#define RATE 0x00000F00
31#define RATE_SHIFT 8
32#define TIFS 0x00001000
33#define TIFS_SHIFT 12
34#define EDCF 0x00002000
35#define EDCF_SHIFT 13
36#define CHANNEL_BOND 0x00004000
37#define CHANNEL_BOND_SHIFT 14
38#define PHY_MODE 0x00038000
39#define PHY_MODE_SHIFT 15
40#define POWER_LEVEL 0x007C0000
41#define POWER_LEVEL_SHIFT 18
42#define NUM_TRANSMITTERS 0x00800000
43#define NUM_TRANSMITTERS_SHIFT 23
44} __attribute__((__packed__));
45
46/*
47 * TX Workqueue Descriptor
48 */
49struct agnx_sta_tx_wq {
50 __le32 reg0;
51#define HEAD_POINTER_LOW 0xFF000000 /* Head pointer low */
52#define HEAD_POINTER_LOW_SHIFT 24
53#define TAIL_POINTER 0x00FFFFFF /* Tail pointer */
54#define TAIL_POINTER_SHIFT 0
55
56 __le32 reg3;
57#define ACK_POINTER_LOW 0xFFFF0000 /* ACK pointer low */
58#define ACK_POINTER_LOW_SHIFT 16
59#define HEAD_POINTER_HIGH 0x0000FFFF /* Head pointer high */
60#define HEAD_POINTER_HIGH_SHIFT 0
61
62 __le32 reg1;
63/* ACK timeout tail packet count */
64#define ACK_TIMOUT_TAIL_PACK_CNT 0xFFF00000
65#define ACK_TIMOUT_TAIL_PACK_CNT_SHIFT 20
66/* Head timeout tail packet count */
67#define HEAD_TIMOUT_TAIL_PACK_CNT 0x000FFF00
68#define HEAD_TIMOUT_TAIL_PACK_CNT_SHIFT 8
69#define ACK_POINTER_HIGH 0x000000FF /* ACK pointer high */
70#define ACK_POINTER_HIGH_SHIFT 0
71
72 __le32 reg2;
73#define WORK_QUEUE_VALID 0x80000000 /* valid */
74#define WORK_QUEUE_VALID_SHIFT 31
75#define WORK_QUEUE_ACK_TYPE 0x40000000 /* ACK type */
76#define WORK_QUEUE_ACK_TYPE_SHIFT 30
77/* Head timeout window limit fragmentation count */
78#define HEAD_TIMOUT_WIN_LIM_FRAG_CNT 0x3FFF0000
79#define HEAD_TIMOUT_WIN_LIM_FRAG_CNT_SHIFT 16
80/* Head timeout window limit byte count */
81#define HEAD_TIMOUT_WIN_LIM_BYTE_CNT 0x0000FFFF
82#define HEAD_TIMOUT_WIN_LIM_BYTE_CNT_SHIFT 0
83} __attribute__((__packed__));
84
85
86/*
87 * Traffic Class Structure
88 */
89struct agnx_sta_traffic {
90 __le32 reg0;
91#define ACK_TIMOUT_CNT 0xFF800000 /* ACK Timeout Counts */
92#define ACK_TIMOUT_CNT_SHIFT 23
93#define TRAFFIC_ACK_TYPE 0x00600000 /* ACK Type */
94#define TRAFFIC_ACK_TYPE_SHIFT 21
95#define NEW_PACKET 0x00100000 /* New Packet */
96#define NEW_PACKET_SHIFT 20
97#define TRAFFIC_VALID 0x00080000 /* Valid */
98#define TRAFFIC_VALID_SHIFT 19
99#define RX_HDR_DESC_POINTER 0x0007FFFF /* RX Header Descripter pointer */
100#define RX_HDR_DESC_POINTER_SHIFT 0
101
102 __le32 reg1;
103#define RX_PACKET_TIMESTAMP 0xFFFF0000 /* RX Packet Timestamp */
104#define RX_PACKET_TIMESTAMP_SHIFT 16
105#define TRAFFIC_RESERVED 0x0000E000 /* Reserved */
106#define TRAFFIC_RESERVED_SHIFT 13
107#define SV 0x00001000 /* sv */
108#define SV_SHIFT 12
109#define RX_SEQUENCE_NUM 0x00000FFF /* RX Sequence Number */
110#define RX_SEQUENCE_NUM_SHIFT 0
111
112 __le32 tx_replay_cnt_low; /* TX Replay Counter Low */
113
114 __le16 tx_replay_cnt_high; /* TX Replay Counter High */
115 __le16 rx_replay_cnt_high; /* RX Replay Counter High */
116
117 __be32 rx_replay_cnt_low; /* RX Replay Counter Low */
118} __attribute__((__packed__));
119
120/*
121 * Station Descriptors
122 */
123struct agnx_sta {
124 __le32 tx_session_keys[4]; /* Transmit Session Key (0-3) */
125 __le32 rx_session_keys[4]; /* Receive Session Key (0-3) */
126
127 __le32 reg;
128#define ID_1 0xC0000000 /* id 1 */
129#define ID_1_SHIFT 30
130#define ID_0 0x30000000 /* id 0 */
131#define ID_0_SHIFT 28
132#define ENABLE_CONCATENATION 0x0FF00000 /* Enable concatenation */
133#define ENABLE_CONCATENATION_SHIFT 20
134#define ENABLE_DECOMPRESSION 0x000FF000 /* Enable decompression */
135#define ENABLE_DECOMPRESSION_SHIFT 12
136#define STA_RESERVED 0x00000C00 /* Reserved */
137#define STA_RESERVED_SHIFT 10
138#define EAP 0x00000200 /* EAP */
139#define EAP_SHIFT 9
140#define ED_NULL 0x00000100 /* ED NULL */
141#define ED_NULL_SHIFT 8
142#define ENCRYPTION_POLICY 0x000000E0 /* Encryption Policy */
143#define ENCRYPTION_POLICY_SHIFT 5
144#define DEFINED_KEY_ID 0x00000018 /* Defined Key ID */
145#define DEFINED_KEY_ID_SHIFT 3
146#define FIXED_KEY 0x00000004 /* Fixed Key */
147#define FIXED_KEY_SHIFT 2
148#define KEY_VALID 0x00000002 /* Key Valid */
149#define KEY_VALID_SHIFT 1
150#define STATION_VALID 0x00000001 /* Station Valid */
151#define STATION_VALID_SHIFT 0
152
153 __le32 tx_aes_blks_unicast; /* TX AES Blks Unicast */
154 __le32 rx_aes_blks_unicast; /* RX AES Blks Unicast */
155
156 __le16 aes_format_err_unicast_cnt; /* AES Format Error Unicast Counts */
157 __le16 aes_replay_unicast; /* AES Replay Unicast */
158
159 __le16 aes_decrypt_err_unicast; /* AES Decrypt Error Unicast */
160 __le16 aes_decrypt_err_default; /* AES Decrypt Error default */
161
162 __le16 single_retry_packets; /* Single Retry Packets */
163 __le16 failed_tx_packets; /* Failed Tx Packets */
164
165 __le16 muti_retry_packets; /* Multiple Retry Packets */
166 __le16 ack_timeouts; /* ACK Timeouts */
167
168 __le16 frag_tx_cnt; /* Fragment TX Counts */
169 __le16 rts_brq_sent; /* RTS Brq Sent */
170
171 __le16 tx_packets; /* TX Packets */
172 __le16 cts_back_timeout; /* CTS Back Timeout */
173
174 __le32 phy_stats_high; /* PHY Stats High */
175 __le32 phy_stats_low; /* PHY Stats Low */
176
177 struct agnx_sta_traffic traffic[8]; /* Traffic Class Structure (8) */
178
179 __le16 traffic_class0_frag_success; /* Traffic Class 0 Fragment Success */
180 __le16 traffic_class1_frag_success; /* Traffic Class 1 Fragment Success */
181 __le16 traffic_class2_frag_success; /* Traffic Class 2 Fragment Success */
182 __le16 traffic_class3_frag_success; /* Traffic Class 3 Fragment Success */
183 __le16 traffic_class4_frag_success; /* Traffic Class 4 Fragment Success */
184 __le16 traffic_class5_frag_success; /* Traffic Class 5 Fragment Success */
185 __le16 traffic_class6_frag_success; /* Traffic Class 6 Fragment Success */
186 __le16 traffic_class7_frag_success; /* Traffic Class 7 Fragment Success */
187
188 __le16 num_frag_non_prime_rates; /* number of Fragments for non-prime rates */
189 __le16 ack_timeout_non_prime_rates; /* ACK Timeout for non-prime rates */
190
191} __attribute__((__packed__));
192
193
194struct agnx_beacon_hdr {
195 struct agnx_sta_power power; /* Tx Station Power Template */
196 u8 phy_hdr[6]; /* PHY Hdr */
197 u8 frame_len_lo; /* Frame Length Lo */
198 u8 frame_len_hi; /* Frame Length Hi */
199 u8 mac_hdr[24]; /* MAC Header */
200 /* FIXME */
201 /* 802.11(abg) beacon */
202} __attribute__((__packed__));
203
204void hash_write(struct agnx_priv *priv, const u8 *mac_addr, u8 sta_id);
205void hash_dump(struct agnx_priv *priv, u8 sta_id);
206void hash_read(struct agnx_priv *priv, u32 reghi, u32 reglo, u8 sta_id);
207void hash_delete(struct agnx_priv *priv, u32 reghi, u32 reglo, u8 sta_id);
208
209void get_sta_power(struct agnx_priv *priv, struct agnx_sta_power *power, unsigned int sta_idx);
210void set_sta_power(struct agnx_priv *priv, struct agnx_sta_power *power,
211 unsigned int sta_idx);
212void get_sta_tx_wq(struct agnx_priv *priv, struct agnx_sta_tx_wq *tx_wq,
213 unsigned int sta_idx, unsigned int wq_idx);
214void set_sta_tx_wq(struct agnx_priv *priv, struct agnx_sta_tx_wq *tx_wq,
215 unsigned int sta_idx, unsigned int wq_idx);
216void get_sta(struct agnx_priv *priv, struct agnx_sta *sta, unsigned int sta_idx);
217void set_sta(struct agnx_priv *priv, struct agnx_sta *sta, unsigned int sta_idx);
218
219void sta_power_init(struct agnx_priv *priv, unsigned int num);
220void sta_init(struct agnx_priv *priv, unsigned int num);
221
222#endif /* AGNX_STA_H_ */
diff --git a/drivers/staging/agnx/table.c b/drivers/staging/agnx/table.c
deleted file mode 100644
index b52fef9db0e3..000000000000
--- a/drivers/staging/agnx/table.c
+++ /dev/null
@@ -1,168 +0,0 @@
1#include <linux/pci.h>
2#include <linux/delay.h>
3#include "agnx.h"
4#include "debug.h"
5#include "phy.h"
6
7static const u32
8tx_fir_table[] = { 0x19, 0x5d, 0xce, 0x151, 0x1c3, 0x1ff, 0x1ea, 0x17c, 0xcf,
9 0x19, 0x38e, 0x350, 0x362, 0x3ad, 0x5, 0x44, 0x59, 0x49,
10 0x21, 0x3f7, 0x3e0, 0x3e3, 0x3f3, 0x0 };
11
12void tx_fir_table_init(struct agnx_priv *priv)
13{
14 void __iomem *ctl = priv->ctl;
15 int i;
16
17 for (i = 0; i < ARRAY_SIZE(tx_fir_table); i++)
18 iowrite32(tx_fir_table[i], ctl + AGNX_FIR_BASE + i*4);
19} /* fir_table_setup */
20
21
22static const u32
23gain_table[] = { 0x8, 0x8, 0xf, 0x13, 0x17, 0x1b, 0x1f, 0x23, 0x27, 0x2b,
24 0x2f, 0x33, 0x37, 0x3b, 0x3f, 0x43, 0x47, 0x4b, 0x4f,
25 0x53, 0x57, 0x5b, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
26 0x5f, 0x5f, 0x5f, 0x5f };
27
28void gain_table_init(struct agnx_priv *priv)
29{
30 void __iomem *ctl = priv->ctl;
31 int i;
32
33 for (i = 0; i < ARRAY_SIZE(gain_table); i++) {
34 iowrite32(gain_table[i], ctl + AGNX_GAIN_TABLE + i*4);
35 iowrite32(gain_table[i], ctl + AGNX_GAIN_TABLE + i*4 + 0x80);
36 }
37} /* gain_table_init */
38
39void monitor_gain_table_init(struct agnx_priv *priv)
40{
41 void __iomem *ctl = priv->ctl;
42 unsigned int i;
43
44 for (i = 0; i < 0x44; i += 4) {
45 iowrite32(0x61, ctl + AGNX_MONGCR_BASE + i);
46 iowrite32(0x61, ctl + AGNX_MONGCR_BASE + 0x200 + i);
47 }
48 for (i = 0x44; i < 0x64; i += 4) {
49 iowrite32(0x6e, ctl + AGNX_MONGCR_BASE + i);
50 iowrite32(0x6e, ctl + AGNX_MONGCR_BASE + 0x200 + i);
51 }
52 for (i = 0x64; i < 0x94; i += 4) {
53 iowrite32(0x7a, ctl + AGNX_MONGCR_BASE + i);
54 iowrite32(0x7a, ctl + AGNX_MONGCR_BASE + 0x200 + i);
55 }
56 for (i = 0x94; i < 0xdc; i += 4) {
57 iowrite32(0x87, ctl + AGNX_MONGCR_BASE + i);
58 iowrite32(0x87, ctl + AGNX_MONGCR_BASE + 0x200 + i);
59 }
60 for (i = 0xdc; i < 0x148; i += 4) {
61 iowrite32(0x95, ctl + AGNX_MONGCR_BASE + i);
62 iowrite32(0x95, ctl + AGNX_MONGCR_BASE + 0x200 + i);
63 }
64 for (i = 0x148; i < 0x1e8; i += 4) {
65 iowrite32(0xa2, ctl + AGNX_MONGCR_BASE + i);
66 iowrite32(0xa2, ctl + AGNX_MONGCR_BASE + 0x200 + i);
67 }
68 for (i = 0x1e8; i <= 0x1fc; i += 4) {
69 iowrite32(0xb0, ctl + AGNX_MONGCR_BASE + i);
70 iowrite32(0xb0, ctl + AGNX_MONGCR_BASE + 0x200 + i);
71 }
72} /* monitor_gain_table_init */
73
74
75void routing_table_init(struct agnx_priv *priv)
76{
77 void __iomem *ctl = priv->ctl;
78 unsigned int type, subtype;
79 u32 reg;
80
81 disable_receiver(priv);
82
83 for (type = 0; type < 0x3; type++) {
84 for (subtype = 0; subtype < 0x10; subtype++) {
85 /* 1. Set Routing table to R/W and to Return status on Read */
86 reg = (type << ROUTAB_TYPE_SHIFT) |
87 (subtype << ROUTAB_SUBTYPE_SHIFT);
88 reg |= (1 << ROUTAB_RW_SHIFT) | (1 << ROUTAB_STATUS_SHIFT);
89 if (type == ROUTAB_TYPE_DATA) {
90 /* NULL goes to RFP */
91 if (subtype == ROUTAB_SUBTYPE_NULL)
92/* reg |= ROUTAB_ROUTE_RFP; */
93 reg |= ROUTAB_ROUTE_CPU;
94 /* QOS NULL goes to CPU */
95 else if (subtype == ROUTAB_SUBTYPE_QOSNULL)
96 reg |= ROUTAB_ROUTE_CPU;
97 /* All Data and QOS data subtypes go to Encryption */
98 else if ((subtype == ROUTAB_SUBTYPE_DATA) ||
99 (subtype == ROUTAB_SUBTYPE_DATAACK) ||
100 (subtype == ROUTAB_SUBTYPE_DATAPOLL) ||
101 (subtype == ROUTAB_SUBTYPE_DATAPOLLACK) ||
102 (subtype == ROUTAB_SUBTYPE_QOSDATA) ||
103 (subtype == ROUTAB_SUBTYPE_QOSDATAACK) ||
104 (subtype == ROUTAB_SUBTYPE_QOSDATAPOLL) ||
105 (subtype == ROUTAB_SUBTYPE_QOSDATAACKPOLL))
106 reg |= ROUTAB_ROUTE_ENCRY;
107/* reg |= ROUTAB_ROUTE_CPU; */
108 /*Drop NULL and QOS NULL ack, poll and poll ack*/
109 else if ((subtype == ROUTAB_SUBTYPE_NULLACK) ||
110 (subtype == ROUTAB_SUBTYPE_QOSNULLACK) ||
111 (subtype == ROUTAB_SUBTYPE_NULLPOLL) ||
112 (subtype == ROUTAB_SUBTYPE_QOSNULLPOLL) ||
113 (subtype == ROUTAB_SUBTYPE_NULLPOLLACK) ||
114 (subtype == ROUTAB_SUBTYPE_QOSNULLPOLLACK))
115/* reg |= ROUTAB_ROUTE_DROP; */
116 reg |= ROUTAB_ROUTE_CPU;
117 } else {
118 reg |= (ROUTAB_ROUTE_CPU);
119 }
120 iowrite32(reg, ctl + AGNX_RXM_ROUTAB);
121 /* Check to verify that the status bit cleared */
122 routing_table_delay();
123 }
124 }
125 enable_receiver(priv);
126} /* routing_table_init */
127
128void tx_engine_lookup_tbl_init(struct agnx_priv *priv)
129{
130 void __iomem *data = priv->data;
131 unsigned int i;
132
133 for (i = 0; i <= 28; i += 4)
134 iowrite32(0xb00c, data + AGNX_ENGINE_LOOKUP_TBL + i);
135 for (i = 32; i <= 120; i += 8) {
136 iowrite32(0x1e58, data + AGNX_ENGINE_LOOKUP_TBL + i);
137 iowrite32(0xb00c, data + AGNX_ENGINE_LOOKUP_TBL + i + 4);
138 }
139
140 for (i = 128; i <= 156; i += 4)
141 iowrite32(0x980c, data + AGNX_ENGINE_LOOKUP_TBL + i);
142 for (i = 160; i <= 248; i += 8) {
143 iowrite32(0x1858, data + AGNX_ENGINE_LOOKUP_TBL + i);
144 iowrite32(0x980c, data + AGNX_ENGINE_LOOKUP_TBL + i + 4);
145 }
146
147 for (i = 256; i <= 284; i += 4)
148 iowrite32(0x980c, data + AGNX_ENGINE_LOOKUP_TBL + i);
149 for (i = 288; i <= 376; i += 8) {
150 iowrite32(0x1a58, data + AGNX_ENGINE_LOOKUP_TBL + i);
151 iowrite32(0x1858, data + AGNX_ENGINE_LOOKUP_TBL + i + 4);
152 }
153
154 for (i = 512; i <= 540; i += 4)
155 iowrite32(0xc00c, data + AGNX_ENGINE_LOOKUP_TBL + i);
156 for (i = 544; i <= 632; i += 8) {
157 iowrite32(0x2058, data + AGNX_ENGINE_LOOKUP_TBL + i);
158 iowrite32(0xc00c, data + AGNX_ENGINE_LOOKUP_TBL + i + 4);
159 }
160
161 for (i = 640; i <= 668; i += 4)
162 iowrite32(0xc80c, data + AGNX_ENGINE_LOOKUP_TBL + i);
163 for (i = 672; i <= 764; i += 8) {
164 iowrite32(0x2258, data + AGNX_ENGINE_LOOKUP_TBL + i);
165 iowrite32(0xc80c, data + AGNX_ENGINE_LOOKUP_TBL + i + 4);
166 }
167}
168
diff --git a/drivers/staging/agnx/table.h b/drivers/staging/agnx/table.h
deleted file mode 100644
index f0626b5ee86b..000000000000
--- a/drivers/staging/agnx/table.h
+++ /dev/null
@@ -1,10 +0,0 @@
1#ifndef AGNX_TABLE_H_
2#define AGNX_TABLE_H_
3
4void tx_fir_table_init(struct agnx_priv *priv);
5void gain_table_init(struct agnx_priv *priv);
6void monitor_gain_table_init(struct agnx_priv *priv);
7void routing_table_init(struct agnx_priv *priv);
8void tx_engine_lookup_tbl_init(struct agnx_priv *priv);
9
10#endif /* AGNX_TABLE_H_ */
diff --git a/drivers/staging/agnx/xmit.c b/drivers/staging/agnx/xmit.c
deleted file mode 100644
index 42db41070cf0..000000000000
--- a/drivers/staging/agnx/xmit.c
+++ /dev/null
@@ -1,836 +0,0 @@
1/**
2 * Airgo MIMO wireless driver
3 *
4 * Copyright (c) 2007 Li YanBo <dreamfly281@gmail.com>
5
6 * Thanks for Jeff Williams <angelbane@gmail.com> do reverse engineer
7 * works and published the SPECS at http://airgo.wdwconsulting.net/mymoin
8
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/pci.h>
15#include <linux/delay.h>
16#include "agnx.h"
17#include "debug.h"
18#include "phy.h"
19
20unsigned int rx_frame_cnt;
21/* unsigned int local_tx_sent_cnt = 0; */
22
23static inline void disable_rx_engine(struct agnx_priv *priv)
24{
25 void __iomem *ctl = priv->ctl;
26 iowrite32(0x100, ctl + AGNX_CIR_RXCTL);
27 /* Wait for RX Control to have the Disable Rx Interrupt (0x100) set */
28 ioread32(ctl + AGNX_CIR_RXCTL);
29}
30
31static inline void enable_rx_engine(struct agnx_priv *priv)
32{
33 void __iomem *ctl = priv->ctl;
34 iowrite32(0x80, ctl + AGNX_CIR_RXCTL);
35 ioread32(ctl + AGNX_CIR_RXCTL);
36}
37
38inline void disable_rx_interrupt(struct agnx_priv *priv)
39{
40 void __iomem *ctl = priv->ctl;
41 u32 reg;
42
43 disable_rx_engine(priv);
44 reg = ioread32(ctl + AGNX_CIR_RXCFG);
45 reg &= ~0x20;
46 iowrite32(reg, ctl + AGNX_CIR_RXCFG);
47 ioread32(ctl + AGNX_CIR_RXCFG);
48}
49
50inline void enable_rx_interrupt(struct agnx_priv *priv)
51{
52 void __iomem *ctl = priv->ctl;
53 u32 reg;
54
55 reg = ioread32(ctl + AGNX_CIR_RXCFG);
56 reg |= 0x20;
57 iowrite32(reg, ctl + AGNX_CIR_RXCFG);
58 ioread32(ctl + AGNX_CIR_RXCFG);
59 enable_rx_engine(priv);
60}
61
62static inline void rx_desc_init(struct agnx_priv *priv, unsigned int idx)
63{
64 struct agnx_desc *desc = priv->rx.desc + idx;
65 struct agnx_info *info = priv->rx.info + idx;
66
67 memset(info, 0, sizeof(*info));
68
69 info->dma_len = IEEE80211_MAX_RTS_THRESHOLD + sizeof(struct agnx_hdr);
70 info->skb = dev_alloc_skb(info->dma_len);
71 if (info->skb == NULL)
72 agnx_bug("refill err");
73
74 info->mapping = pci_map_single(priv->pdev, skb_tail_pointer(info->skb),
75 info->dma_len, PCI_DMA_FROMDEVICE);
76 memset(desc, 0, sizeof(*desc));
77 desc->dma_addr = cpu_to_be32(info->mapping);
78 /* Set the owner to the card */
79 desc->frag = cpu_to_be32(be32_to_cpu(desc->frag) | OWNER);
80}
81
82static inline void rx_desc_reinit(struct agnx_priv *priv, unsigned int idx)
83{
84 struct agnx_info *info = priv->rx.info + idx;
85
86 /* Cause ieee80211 will free the skb buffer, so we needn't to free it again?! */
87 pci_unmap_single(priv->pdev, info->mapping, info->dma_len, PCI_DMA_FROMDEVICE);
88 rx_desc_init(priv, idx);
89}
90
91static inline void rx_desc_reusing(struct agnx_priv *priv, unsigned int idx)
92{
93 struct agnx_desc *desc = priv->rx.desc + idx;
94 struct agnx_info *info = priv->rx.info + idx;
95
96 memset(desc, 0, sizeof(*desc));
97 desc->dma_addr = cpu_to_be32(info->mapping);
98 /* Set the owner to the card */
99 desc->frag = cpu_to_be32(be32_to_cpu(desc->frag) | OWNER);
100}
101
102static void rx_desc_free(struct agnx_priv *priv, unsigned int idx)
103{
104 struct agnx_desc *desc = priv->rx.desc + idx;
105 struct agnx_info *info = priv->rx.info + idx;
106
107 BUG_ON(!desc || !info);
108 if (info->mapping)
109 pci_unmap_single(priv->pdev, info->mapping, info->dma_len, PCI_DMA_FROMDEVICE);
110 if (info->skb)
111 dev_kfree_skb(info->skb);
112 memset(info, 0, sizeof(*info));
113 memset(desc, 0, sizeof(*desc));
114}
115
116static inline void __tx_desc_free(struct agnx_priv *priv,
117 struct agnx_desc *desc, struct agnx_info *info)
118{
119 BUG_ON(!desc || !info);
120 /* TODO make sure mapping, skb and len are consistency */
121 if (info->mapping)
122 pci_unmap_single(priv->pdev, info->mapping,
123 info->dma_len, PCI_DMA_TODEVICE);
124 if (info->type == PACKET)
125 dev_kfree_skb(info->skb);
126
127 memset(info, 0, sizeof(*info));
128 memset(desc, 0, sizeof(*desc));
129}
130
131static void txm_desc_free(struct agnx_priv *priv, unsigned int idx)
132{
133 struct agnx_desc *desc = priv->txm.desc + idx;
134 struct agnx_info *info = priv->txm.info + idx;
135
136 __tx_desc_free(priv, desc, info);
137}
138
139static void txd_desc_free(struct agnx_priv *priv, unsigned int idx)
140{
141 struct agnx_desc *desc = priv->txd.desc + idx;
142 struct agnx_info *info = priv->txd.info + idx;
143
144 __tx_desc_free(priv, desc, info);
145}
146
147int fill_rings(struct agnx_priv *priv)
148{
149 void __iomem *ctl = priv->ctl;
150 unsigned int i;
151 u32 reg;
152 AGNX_TRACE;
153
154 priv->txd.idx_sent = priv->txm.idx_sent = 0;
155 priv->rx.idx = priv->txm.idx = priv->txd.idx = 0;
156
157 for (i = 0; i < priv->rx.size; i++)
158 rx_desc_init(priv, i);
159 for (i = 0; i < priv->txm.size; i++) {
160 memset(priv->txm.desc + i, 0, sizeof(struct agnx_desc));
161 memset(priv->txm.info + i, 0, sizeof(struct agnx_info));
162 }
163 for (i = 0; i < priv->txd.size; i++) {
164 memset(priv->txd.desc + i, 0, sizeof(struct agnx_desc));
165 memset(priv->txd.info + i, 0, sizeof(struct agnx_info));
166 }
167
168 /* FIXME Set the card RX TXM and TXD address */
169 agnx_write32(ctl, AGNX_CIR_RXCMSTART, priv->rx.dma);
170 agnx_write32(ctl, AGNX_CIR_RXCMEND, priv->txm.dma);
171
172 agnx_write32(ctl, AGNX_CIR_TXMSTART, priv->txm.dma);
173 agnx_write32(ctl, AGNX_CIR_TXMEND, priv->txd.dma);
174
175 agnx_write32(ctl, AGNX_CIR_TXDSTART, priv->txd.dma);
176 agnx_write32(ctl, AGNX_CIR_TXDEND, priv->txd.dma +
177 sizeof(struct agnx_desc) * priv->txd.size);
178
179 /* FIXME Relinquish control of rings to card */
180 reg = agnx_read32(ctl, AGNX_CIR_BLKCTL);
181 reg &= ~0x800;
182 agnx_write32(ctl, AGNX_CIR_BLKCTL, reg);
183 return 0;
184} /* fill_rings */
185
186void unfill_rings(struct agnx_priv *priv)
187{
188 unsigned long flags;
189 unsigned int i;
190 AGNX_TRACE;
191
192 spin_lock_irqsave(&priv->lock, flags);
193
194 for (i = 0; i < priv->rx.size; i++)
195 rx_desc_free(priv, i);
196 for (i = 0; i < priv->txm.size; i++)
197 txm_desc_free(priv, i);
198 for (i = 0; i < priv->txd.size; i++)
199 txd_desc_free(priv, i);
200
201 spin_unlock_irqrestore(&priv->lock, flags);
202}
203
204/* Extract the bitrate out of a CCK PLCP header.
205 copy from bcm43xx driver */
206static inline u8 agnx_plcp_get_bitrate_cck(__be32 *phyhdr_11b)
207{
208 /* FIXME */
209 switch (*(u8 *)phyhdr_11b) {
210 case 0x0A:
211 return 0;
212 case 0x14:
213 return 1;
214 case 0x37:
215 return 2;
216 case 0x6E:
217 return 3;
218 }
219 agnx_bug("Wrong plcp rate");
220 return 0;
221}
222
223/* FIXME */
224static inline u8 agnx_plcp_get_bitrate_ofdm(__be32 *phyhdr_11g)
225{
226 u8 rate = *(u8 *)phyhdr_11g & 0xF;
227
228 printk(PFX "G mode rate is 0x%x\n", rate);
229 return rate;
230}
231
232/* FIXME */
233static void get_rx_stats(struct agnx_priv *priv, struct agnx_hdr *hdr,
234 struct ieee80211_rx_status *stat)
235{
236 void __iomem *ctl = priv->ctl;
237 u8 *rssi;
238 u32 noise;
239 /* FIXME just for test */
240 int snr = 40; /* signal-to-noise ratio */
241
242 memset(stat, 0, sizeof(*stat));
243 /* RSSI */
244 rssi = (u8 *)&hdr->phy_stats_lo;
245/* stat->ssi = (rssi[0] + rssi[1] + rssi[2]) / 3; */
246 /* Noise */
247 noise = ioread32(ctl + AGNX_GCR_NOISE0);
248 noise += ioread32(ctl + AGNX_GCR_NOISE1);
249 noise += ioread32(ctl + AGNX_GCR_NOISE2);
250 stat->noise = noise / 3;
251 /* Signal quality */
252/* snr = stat->ssi - stat->noise; */
253 if (snr >= 0 && snr < 40)
254 stat->signal = 5 * snr / 2;
255 else if (snr >= 40)
256 stat->signal = 100;
257 else
258 stat->signal = 0;
259
260
261 if (hdr->_11b0 && !hdr->_11g0) {
262 stat->rate_idx = agnx_plcp_get_bitrate_cck(&hdr->_11b0);
263 } else if (!hdr->_11b0 && hdr->_11g0) {
264 printk(PFX "RX: Found G mode packet\n");
265 stat->rate_idx = agnx_plcp_get_bitrate_ofdm(&hdr->_11g0);
266 } else
267 agnx_bug("Unknown packets type");
268
269
270 stat->band = IEEE80211_BAND_2GHZ;
271 stat->freq = agnx_channels[priv->channel - 1].center_freq;
272/* stat->antenna = 3;
273 stat->mactime = be32_to_cpu(hdr->time_stamp);
274 stat->channel = priv->channel; */
275}
276
277static inline void combine_hdr_frag(struct ieee80211_hdr *ieeehdr,
278 struct sk_buff *skb)
279{
280 u16 fctl;
281 unsigned int hdrlen;
282
283 fctl = le16_to_cpu(ieeehdr->frame_control);
284 hdrlen = ieee80211_hdrlen(fctl);
285 /* FIXME */
286 if (hdrlen < (2+2+6)/*minimum hdr*/ ||
287 hdrlen > sizeof(struct ieee80211_mgmt)) {
288 printk(KERN_ERR PFX "hdr len is %d\n", hdrlen);
289 agnx_bug("Wrong ieee80211 hdr detected");
290 }
291 skb_push(skb, hdrlen);
292 memcpy(skb->data, ieeehdr, hdrlen);
293} /* combine_hdr_frag */
294
295static inline int agnx_packet_check(struct agnx_priv *priv, struct agnx_hdr *agnxhdr,
296 unsigned packet_len)
297{
298 if (agnx_get_bits(CRC_FAIL, CRC_FAIL_SHIFT, be32_to_cpu(agnxhdr->reg1)) == 1) {
299 printk(PFX "RX: CRC check fail\n");
300 goto drop;
301 }
302 if (packet_len > 2048) {
303 printk(PFX "RX: Too long packet detected\n");
304 goto drop;
305 }
306
307 /* FIXME Just usable for Promious Mode, for Manage mode exclude FCS */
308/* if (packet_len - sizeof(*agnxhdr) < FCS_LEN) { */
309/* printk(PFX "RX: Too short packet detected\n"); */
310/* goto drop; */
311/* } */
312 return 0;
313drop:
314 priv->stats.dot11FCSErrorCount++;
315 return -1;
316}
317
318void handle_rx_irq(struct agnx_priv *priv)
319{
320 struct ieee80211_rx_status status;
321 unsigned int len;
322/* AGNX_TRACE; */
323
324 do {
325 struct agnx_desc *desc;
326 u32 frag;
327 struct agnx_info *info;
328 struct agnx_hdr *hdr;
329 struct sk_buff *skb;
330 unsigned int i = priv->rx.idx % priv->rx.size;
331
332 desc = priv->rx.desc + i;
333 frag = be32_to_cpu(desc->frag);
334 if (frag & OWNER)
335 break;
336
337 info = priv->rx.info + i;
338 skb = info->skb;
339 hdr = (struct agnx_hdr *)(skb->data);
340
341 len = (frag & PACKET_LEN) >> PACKET_LEN_SHIFT;
342 if (agnx_packet_check(priv, hdr, len) == -1) {
343 rx_desc_reusing(priv, i);
344 continue;
345 }
346 skb_put(skb, len);
347
348 do {
349 u16 fctl;
350 fctl = le16_to_cpu(((struct ieee80211_hdr *)hdr->mac_hdr)->frame_control);
351 if ((fctl & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_BEACON)/* && !(fctl & IEEE80211_STYPE_BEACON)) */
352 dump_ieee80211_hdr((struct ieee80211_hdr *)hdr->mac_hdr, "RX");
353 } while (0);
354
355 if (hdr->_11b0 && !hdr->_11g0) {
356/* int j;
357 u16 fctl = le16_to_cpu(((struct ieee80211_hdr *)hdr->mac_hdr)
358 ->frame_control);
359 if ( (fctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) {
360 agnx_print_rx_hdr(hdr);
361 agnx_print_sta(priv, BSSID_STAID);
362 for (j = 0; j < 8; j++)
363 agnx_print_sta_tx_wq(priv, BSSID_STAID, j);
364 } */
365
366 get_rx_stats(priv, hdr, &status);
367 skb_pull(skb, sizeof(*hdr));
368 combine_hdr_frag((struct ieee80211_hdr *)hdr->mac_hdr, skb);
369 } else if (!hdr->_11b0 && hdr->_11g0) {
370/* int j; */
371 agnx_print_rx_hdr(hdr);
372 agnx_print_sta(priv, BSSID_STAID);
373/* for (j = 0; j < 8; j++) */
374 agnx_print_sta_tx_wq(priv, BSSID_STAID, 0);
375
376 print_hex_dump_bytes("agnx: RX_PACKET: ", DUMP_PREFIX_NONE,
377 skb->data, skb->len + 8);
378
379/* if (agnx_plcp_get_bitrate_ofdm(&hdr->_11g0) == 0) */
380 get_rx_stats(priv, hdr, &status);
381 skb_pull(skb, sizeof(*hdr));
382 combine_hdr_frag((struct ieee80211_hdr *)
383 ((void *)&hdr->mac_hdr), skb);
384/* dump_ieee80211_hdr((struct ieee80211_hdr *)skb->data, "RX G"); */
385 } else
386 agnx_bug("Unknown packets type");
387 memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
388 ieee80211_rx_irqsafe(priv->hw, skb);
389 rx_desc_reinit(priv, i);
390
391 } while (priv->rx.idx++);
392} /* handle_rx_irq */
393
394static inline void handle_tx_irq(struct agnx_priv *priv, struct agnx_ring *ring)
395{
396 struct agnx_desc *desc;
397 struct agnx_info *info;
398 unsigned int idx;
399
400 for (idx = ring->idx_sent; idx < ring->idx; idx++) {
401 unsigned int i = idx % ring->size;
402 u32 frag;
403
404 desc = ring->desc + i;
405 info = ring->info + i;
406
407 frag = be32_to_cpu(desc->frag);
408 if (frag & OWNER) {
409 if (info->type == HEADER)
410 break;
411 else
412 agnx_bug("TX error");
413 }
414
415 pci_unmap_single(priv->pdev, info->mapping, info->dma_len, PCI_DMA_TODEVICE);
416
417 do {
418/* int j; */
419 size_t len;
420 len = info->skb->len - sizeof(struct agnx_hdr) + info->hdr_len;
421/* if (len == 614) { */
422/* agnx_print_desc(desc); */
423 if (info->type == PACKET) {
424/* agnx_print_tx_hdr((struct agnx_hdr *)info->skb->data); */
425/* agnx_print_sta_power(priv, LOCAL_STAID); */
426/* agnx_print_sta(priv, LOCAL_STAID); */
427/* for (j = 0; j < 8; j++) */
428/* agnx_print_sta_tx_wq(priv, LOCAL_STAID, 0); */
429/* agnx_print_sta_power(priv, BSSID_STAID); */
430/* agnx_print_sta(priv, BSSID_STAID); */
431/* for (j = 0; j < 8; j++) */
432/* agnx_print_sta_tx_wq(priv, BSSID_STAID, 0); */
433 }
434/* } */
435 } while (0);
436
437 if (info->type == PACKET) {
438/* dump_txm_registers(priv);
439 dump_rxm_registers(priv);
440 dump_bm_registers(priv);
441 dump_cir_registers(priv); */
442 }
443
444 if (info->type == PACKET) {
445/* struct ieee80211_hdr *hdr; */
446 struct ieee80211_tx_info *txi = IEEE80211_SKB_CB(info->skb);
447
448 skb_pull(info->skb, sizeof(struct agnx_hdr));
449 memcpy(skb_push(info->skb, info->hdr_len), &info->hdr, info->hdr_len);
450
451/* dump_ieee80211_hdr((struct ieee80211_hdr *)info->skb->data, "TX_HANDLE"); */
452/* print_hex_dump_bytes("agnx: TX_HANDLE: ", DUMP_PREFIX_NONE, */
453/* info->skb->data, info->skb->len); */
454
455 if (!(txi->flags & IEEE80211_TX_CTL_NO_ACK))
456 txi->flags |= IEEE80211_TX_STAT_ACK;
457
458 ieee80211_tx_status_irqsafe(priv->hw, info->skb);
459
460
461/* info->tx_status.queue_number = (ring->size - i) / 2; */
462/* ieee80211_tx_status_irqsafe(priv->hw, info->skb, &(info->tx_status)); */
463/* } else */
464/* dev_kfree_skb_irq(info->skb); */
465 }
466 memset(desc, 0, sizeof(*desc));
467 memset(info, 0, sizeof(*info));
468 }
469
470 ring->idx_sent = idx;
471 /* TODO fill the priv->low_level_stats */
472
473 /* ieee80211_wake_queue(priv->hw, 0); */
474}
475
476void handle_txm_irq(struct agnx_priv *priv)
477{
478 handle_tx_irq(priv, &priv->txm);
479}
480
481void handle_txd_irq(struct agnx_priv *priv)
482{
483 handle_tx_irq(priv, &priv->txd);
484}
485
486void handle_other_irq(struct agnx_priv *priv)
487{
488/* void __iomem *ctl = priv->ctl; */
489 u32 status = priv->irq_status;
490 void __iomem *ctl = priv->ctl;
491 u32 reg;
492
493 if (status & IRQ_TX_BEACON) {
494 iowrite32(IRQ_TX_BEACON, ctl + AGNX_INT_STAT);
495 printk(PFX "IRQ: TX Beacon control is 0X%.8X\n", ioread32(ctl + AGNX_TXM_BEACON_CTL));
496 printk(PFX "IRQ: TX Beacon rx frame num: %d\n", rx_frame_cnt);
497 }
498 if (status & IRQ_TX_RETRY) {
499 reg = ioread32(ctl + AGNX_TXM_RETRYSTAID);
500 printk(PFX "IRQ: TX Retry, RETRY STA ID is %x\n", reg);
501 }
502 if (status & IRQ_TX_ACTIVITY)
503 printk(PFX "IRQ: TX Activity\n");
504 if (status & IRQ_RX_ACTIVITY)
505 printk(PFX "IRQ: RX Activity\n");
506 if (status & IRQ_RX_X)
507 printk(PFX "IRQ: RX X\n");
508 if (status & IRQ_RX_Y) {
509 reg = ioread32(ctl + AGNX_INT_MASK);
510 reg &= ~IRQ_RX_Y;
511 iowrite32(reg, ctl + AGNX_INT_MASK);
512 iowrite32(IRQ_RX_Y, ctl + AGNX_INT_STAT);
513 printk(PFX "IRQ: RX Y\n");
514 }
515 if (status & IRQ_RX_HASHHIT) {
516 reg = ioread32(ctl + AGNX_INT_MASK);
517 reg &= ~IRQ_RX_HASHHIT;
518 iowrite32(reg, ctl + AGNX_INT_MASK);
519 iowrite32(IRQ_RX_HASHHIT, ctl + AGNX_INT_STAT);
520 printk(PFX "IRQ: RX Hash Hit\n");
521
522 }
523 if (status & IRQ_RX_FRAME) {
524 reg = ioread32(ctl + AGNX_INT_MASK);
525 reg &= ~IRQ_RX_FRAME;
526 iowrite32(reg, ctl + AGNX_INT_MASK);
527 iowrite32(IRQ_RX_FRAME, ctl + AGNX_INT_STAT);
528 printk(PFX "IRQ: RX Frame\n");
529 rx_frame_cnt++;
530 }
531 if (status & IRQ_ERR_INT) {
532 iowrite32(IRQ_ERR_INT, ctl + AGNX_INT_STAT);
533/* agnx_hw_reset(priv); */
534 printk(PFX "IRQ: Error Interrupt\n");
535 }
536 if (status & IRQ_TX_QUE_FULL)
537 printk(PFX "IRQ: TX Workqueue Full\n");
538 if (status & IRQ_BANDMAN_ERR)
539 printk(PFX "IRQ: Bandwidth Management Error\n");
540 if (status & IRQ_TX_DISABLE)
541 printk(PFX "IRQ: TX Disable\n");
542 if (status & IRQ_RX_IVASESKEY)
543 printk(PFX "IRQ: RX Invalid Session Key\n");
544 if (status & IRQ_REP_THHIT)
545 printk(PFX "IRQ: Replay Threshold Hit\n");
546 if (status & IRQ_TIMER1)
547 printk(PFX "IRQ: Timer1\n");
548 if (status & IRQ_TIMER_CNT)
549 printk(PFX "IRQ: Timer Count\n");
550 if (status & IRQ_PHY_FASTINT)
551 printk(PFX "IRQ: Phy Fast Interrupt\n");
552 if (status & IRQ_PHY_SLOWINT)
553 printk(PFX "IRQ: Phy Slow Interrupt\n");
554 if (status & IRQ_OTHER)
555 printk(PFX "IRQ: 0x80000000\n");
556} /* handle_other_irq */
557
558
559static inline void route_flag_set(struct agnx_hdr *txhdr)
560{
561/* u32 reg = 0; */
562
563 /* FIXME */
564/* reg = (0x7 << ROUTE_COMPRESSION_SHIFT) & ROUTE_COMPRESSION; */
565/* txhdr->reg5 = cpu_to_be32(reg); */
566 txhdr->reg5 = (0xa << 0x0) | (0x7 << 0x18);
567/* txhdr->reg5 = cpu_to_be32((0xa << 0x0) | (0x7 << 0x18)); */
568/* txhdr->reg5 = cpu_to_be32(0x7 << 0x0); */
569}
570
571/* Return 0 if no match */
572static inline unsigned int get_power_level(unsigned int rate, unsigned int antennas_num)
573{
574 unsigned int power_level;
575
576 switch (rate) {
577 case 10:
578 case 20:
579 case 55:
580 case 60:
581 case 90:
582 case 120:
583 power_level = 22;
584 break;
585
586 case 180:
587 power_level = 19;
588 break;
589
590 case 240:
591 power_level = 18;
592 break;
593
594 case 360:
595 power_level = 16;
596 break;
597
598 case 480:
599 power_level = 15;
600 break;
601
602 case 540:
603 power_level = 14;
604 break;
605 default:
606 agnx_bug("Error rate setting\n");
607 }
608
609 if (power_level && (antennas_num == 2))
610 power_level -= 3;
611
612 return power_level;
613}
614
615static inline void fill_agnx_hdr(struct agnx_priv *priv, struct agnx_info *tx_info)
616{
617 struct agnx_hdr *txhdr = (struct agnx_hdr *)tx_info->skb->data;
618 size_t len;
619 u16 fc = le16_to_cpu(*(__le16 *)&tx_info->hdr);
620 u32 reg;
621
622 memset(txhdr, 0, sizeof(*txhdr));
623
624/* reg = agnx_set_bits(STATION_ID, STATION_ID_SHIFT, LOCAL_STAID); */
625 reg = agnx_set_bits(STATION_ID, STATION_ID_SHIFT, BSSID_STAID);
626 reg |= agnx_set_bits(WORKQUEUE_ID, WORKQUEUE_ID_SHIFT, 0);
627 txhdr->reg4 = cpu_to_be32(reg);
628
629 /* Set the Hardware Sequence Number to 1? */
630 reg = agnx_set_bits(SEQUENCE_NUMBER, SEQUENCE_NUMBER_SHIFT, 0);
631/* reg = agnx_set_bits(SEQUENCE_NUMBER, SEQUENCE_NUMBER_SHIFT, 1); */
632 reg |= agnx_set_bits(MAC_HDR_LEN, MAC_HDR_LEN_SHIFT, tx_info->hdr_len);
633 txhdr->reg1 = cpu_to_be32(reg);
634 /* Set the agnx_hdr's MAC header */
635 memcpy(txhdr->mac_hdr, &tx_info->hdr, tx_info->hdr_len);
636
637 reg = agnx_set_bits(ACK, ACK_SHIFT, 1);
638/* reg = agnx_set_bits(ACK, ACK_SHIFT, 0); */
639 reg |= agnx_set_bits(MULTICAST, MULTICAST_SHIFT, 0);
640/* reg |= agnx_set_bits(MULTICAST, MULTICAST_SHIFT, 1); */
641 reg |= agnx_set_bits(RELAY, RELAY_SHIFT, 0);
642 reg |= agnx_set_bits(TM, TM_SHIFT, 0);
643 txhdr->reg0 = cpu_to_be32(reg);
644
645 /* Set the long and short retry limits */
646 txhdr->tx.short_retry_limit = tx_info->txi->control.rates[0].count;
647 txhdr->tx.long_retry_limit = tx_info->txi->control.rates[0].count;
648
649 /* FIXME */
650 len = tx_info->skb->len - sizeof(*txhdr) + tx_info->hdr_len + FCS_LEN;
651 if (fc & IEEE80211_FCTL_PROTECTED)
652 len += 8;
653 len = 2398;
654 reg = agnx_set_bits(FRAG_SIZE, FRAG_SIZE_SHIFT, len);
655 len = tx_info->skb->len - sizeof(*txhdr);
656 reg |= agnx_set_bits(PAYLOAD_LEN, PAYLOAD_LEN_SHIFT, len);
657 txhdr->reg3 = cpu_to_be32(reg);
658
659 route_flag_set(txhdr);
660} /* fill_hdr */
661
662static void txm_power_set(struct agnx_priv *priv,
663 struct ieee80211_tx_info *txi)
664{
665 struct agnx_sta_power power;
666 u32 reg;
667
668 /* FIXME */
669 if (txi->control.rates[0].idx < 0) {
670 /* For B mode Short Preamble */
671 reg = agnx_set_bits(PHY_MODE, PHY_MODE_SHIFT, AGNX_MODE_80211B_SHORT);
672/* control->tx_rate = -control->tx_rate; */
673 } else
674 reg = agnx_set_bits(PHY_MODE, PHY_MODE_SHIFT, AGNX_MODE_80211G);
675/* reg = agnx_set_bits(PHY_MODE, PHY_MODE_SHIFT, AGNX_MODE_80211B_LONG); */
676 reg |= agnx_set_bits(SIGNAL, SIGNAL_SHIFT, 0xB);
677 reg |= agnx_set_bits(RATE, RATE_SHIFT, 0xB);
678/* reg |= agnx_set_bits(POWER_LEVEL, POWER_LEVEL_SHIFT, 15); */
679 reg |= agnx_set_bits(POWER_LEVEL, POWER_LEVEL_SHIFT, 20);
680 /* if rate < 11M set it to 0 */
681 reg |= agnx_set_bits(NUM_TRANSMITTERS, NUM_TRANSMITTERS_SHIFT, 1);
682/* reg |= agnx_set_bits(EDCF, EDCF_SHIFT, 1); */
683/* reg |= agnx_set_bits(TIFS, TIFS_SHIFT, 1); */
684
685 power.reg = reg;
686/* power.reg = cpu_to_le32(reg); */
687
688/* set_sta_power(priv, &power, LOCAL_STAID); */
689 set_sta_power(priv, &power, BSSID_STAID);
690}
691
692static inline int tx_packet_check(struct sk_buff *skb)
693{
694 unsigned int ieee_len = ieee80211_get_hdrlen_from_skb(skb);
695 if (skb->len > 2048) {
696 printk(KERN_ERR PFX "length is %d\n", skb->len);
697 agnx_bug("Too long TX skb");
698 return -1;
699 }
700 /* FIXME */
701 if (skb->len == ieee_len) {
702 printk(PFX "A strange TX packet\n");
703 return -1;
704 /* tx_faile_irqsafe(); */
705 }
706 return 0;
707}
708
709static int __agnx_tx(struct agnx_priv *priv, struct sk_buff *skb,
710 struct agnx_ring *ring)
711{
712 struct agnx_desc *hdr_desc, *frag_desc;
713 struct agnx_info *hdr_info, *frag_info;
714 struct ieee80211_tx_info *txi = IEEE80211_SKB_CB(skb);
715 unsigned long flags;
716 unsigned int i;
717
718 spin_lock_irqsave(&priv->lock, flags);
719
720 /* The RX interrupt need be Disable until this TX packet
721 is handled in the next tx interrupt */
722 disable_rx_interrupt(priv);
723
724 i = ring->idx;
725 ring->idx += 2;
726/* if (priv->txm_idx - priv->txm_idx_sent == AGNX_TXM_RING_SIZE - 2) */
727/* ieee80211_stop_queue(priv->hw, 0); */
728
729 /* Set agnx header's info and desc */
730 i %= ring->size;
731 hdr_desc = ring->desc + i;
732 hdr_info = ring->info + i;
733 hdr_info->hdr_len = ieee80211_get_hdrlen_from_skb(skb);
734 memcpy(&hdr_info->hdr, skb->data, hdr_info->hdr_len);
735
736 /* Add the agnx header to the front of the SKB */
737 skb_push(skb, sizeof(struct agnx_hdr) - hdr_info->hdr_len);
738
739 hdr_info->txi = txi;
740 hdr_info->dma_len = sizeof(struct agnx_hdr);
741 hdr_info->skb = skb;
742 hdr_info->type = HEADER;
743 fill_agnx_hdr(priv, hdr_info);
744 hdr_info->mapping = pci_map_single(priv->pdev, skb->data,
745 hdr_info->dma_len, PCI_DMA_TODEVICE);
746 do {
747 u32 frag = 0;
748 frag |= agnx_set_bits(FIRST_FRAG, FIRST_FRAG_SHIFT, 1);
749 frag |= agnx_set_bits(LAST_FRAG, LAST_FRAG_SHIFT, 0);
750 frag |= agnx_set_bits(PACKET_LEN, PACKET_LEN_SHIFT, skb->len);
751 frag |= agnx_set_bits(FIRST_FRAG_LEN, FIRST_FRAG_LEN_SHIFT, 1);
752 frag |= agnx_set_bits(OWNER, OWNER_SHIFT, 1);
753 hdr_desc->frag = cpu_to_be32(frag);
754 } while (0);
755 hdr_desc->dma_addr = cpu_to_be32(hdr_info->mapping);
756
757
758 /* Set Frag's info and desc */
759 i = (i + 1) % ring->size;
760 frag_desc = ring->desc + i;
761 frag_info = ring->info + i;
762 memcpy(frag_info, hdr_info, sizeof(struct agnx_info));
763 frag_info->type = PACKET;
764 frag_info->dma_len = skb->len - hdr_info->dma_len;
765 frag_info->mapping = pci_map_single(priv->pdev, skb->data + hdr_info->dma_len,
766 frag_info->dma_len, PCI_DMA_TODEVICE);
767 do {
768 u32 frag = 0;
769 frag |= agnx_set_bits(FIRST_FRAG, FIRST_FRAG_SHIFT, 0);
770 frag |= agnx_set_bits(LAST_FRAG, LAST_FRAG_SHIFT, 1);
771 frag |= agnx_set_bits(PACKET_LEN, PACKET_LEN_SHIFT, skb->len);
772 frag |= agnx_set_bits(SUB_FRAG_LEN, SUB_FRAG_LEN_SHIFT, frag_info->dma_len);
773 frag_desc->frag = cpu_to_be32(frag);
774 } while (0);
775 frag_desc->dma_addr = cpu_to_be32(frag_info->mapping);
776
777 txm_power_set(priv, txi);
778
779/* do { */
780/* int j; */
781/* size_t len; */
782/* len = skb->len - hdr_info->dma_len + hdr_info->hdr_len; */
783/* if (len == 614) { */
784/* agnx_print_desc(hdr_desc); */
785/* agnx_print_desc(frag_desc); */
786/* agnx_print_tx_hdr((struct agnx_hdr *)skb->data); */
787/* agnx_print_sta_power(priv, LOCAL_STAID); */
788/* agnx_print_sta(priv, LOCAL_STAID); */
789/* for (j = 0; j < 8; j++) */
790/* agnx_print_sta_tx_wq(priv, LOCAL_STAID, j); */
791/* agnx_print_sta_power(priv, BSSID_STAID); */
792/* agnx_print_sta(priv, BSSID_STAID); */
793/* for (j = 0; j < 8; j++) */
794/* agnx_print_sta_tx_wq(priv, BSSID_STAID, j); */
795/* } */
796/* } while (0); */
797
798 spin_unlock_irqrestore(&priv->lock, flags);
799
800 /* FIXME ugly code */
801 /* Trigger TXM */
802 do {
803 u32 reg;
804 reg = (ioread32(priv->ctl + AGNX_CIR_TXMCTL));
805 reg |= 0x8;
806 iowrite32((reg), priv->ctl + AGNX_CIR_TXMCTL);
807 } while (0);
808
809 /* Trigger TXD */
810 do {
811 u32 reg;
812 reg = (ioread32(priv->ctl + AGNX_CIR_TXDCTL));
813 reg |= 0x8;
814 iowrite32((reg), priv->ctl + AGNX_CIR_TXDCTL);
815 } while (0);
816
817 return 0;
818}
819
820int _agnx_tx(struct agnx_priv *priv, struct sk_buff *skb)
821{
822 u16 fctl;
823
824 if (tx_packet_check(skb))
825 return 0;
826
827/* print_hex_dump_bytes("agnx: TX_PACKET: ", DUMP_PREFIX_NONE, */
828/* skb->data, skb->len); */
829
830 fctl = le16_to_cpu(*((__le16 *)skb->data));
831
832 if ((fctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)
833 return __agnx_tx(priv, skb, &priv->txd);
834 else
835 return __agnx_tx(priv, skb, &priv->txm);
836}
diff --git a/drivers/staging/agnx/xmit.h b/drivers/staging/agnx/xmit.h
deleted file mode 100644
index 93ac4157e697..000000000000
--- a/drivers/staging/agnx/xmit.h
+++ /dev/null
@@ -1,250 +0,0 @@
1#ifndef AGNX_XMIT_H_
2#define AGNX_XMIT_H_
3
4#include <net/mac80211.h>
5
6struct agnx_priv;
7
8static inline u32 agnx_set_bits(u32 mask, u8 shift, u32 value)
9{
10 return (value << shift) & mask;
11}
12
13static inline u32 agnx_get_bits(u32 mask, u8 shift, u32 value)
14{
15 return (value & mask) >> shift;
16}
17
18
19struct agnx_rx {
20 __be16 rx_packet_duration; /* RX Packet Duration */
21 __be16 replay_cnt; /* Replay Count */
22} __attribute__((__packed__));
23
24
25struct agnx_tx {
26 u8 long_retry_limit; /* Long Retry Limit */
27 u8 short_retry_limit; /* Short Retry Limit */
28 u8 long_retry_cnt; /* Long Retry Count */
29 u8 short_retry_cnt; /* Short Retry Count */
30} __attribute__((__packed__));
31
32
33/* Copy from bcm43xx */
34#define P4D_BYT3S(magic, nr_bytes) u8 __p4dding##magic[nr_bytes]
35#define P4D_BYTES(line, nr_bytes) P4D_BYT3S(line, nr_bytes)
36#define PAD_BYTES(nr_bytes) P4D_BYTES(__LINE__, nr_bytes)
37
38#define P4D_BIT3S(magic, nr_bits) __be32 __padding##magic:nr_bits
39#define P4D_BITS(line, nr_bits) P4D_BIT3S(line, nr_bits)
40#define PAD_BITS(nr_bits) P4D_BITS(__LINE__, nr_bits)
41
42
43struct agnx_hdr {
44 __be32 reg0;
45#define RTS 0x80000000 /* RTS */
46#define RTS_SHIFT 31
47#define MULTICAST 0x40000000 /* multicast */
48#define MULTICAST_SHIFT 30
49#define ACK 0x30000000 /* ACK */
50#define ACK_SHIFT 28
51#define TM 0x08000000 /* TM */
52#define TM_SHIFT 27
53#define RELAY 0x04000000 /* Relay */
54#define RELAY_SHIFT 26
55/* PAD_BITS(4); */
56#define REVISED_FCS 0x00380000 /* revised FCS */
57#define REVISED_FCS_SHIFT 19
58#define NEXT_BUFFER_ADDR 0x0007FFFF /* Next Buffer Address */
59#define NEXT_BUFFER_ADDR_SHIFT 0
60
61 __be32 reg1;
62#define MAC_HDR_LEN 0xFC000000 /* MAC Header Length */
63#define MAC_HDR_LEN_SHIFT 26
64#define DURATION_OVERIDE 0x02000000 /* Duration Override */
65#define DURATION_OVERIDE_SHIFT 25
66#define PHY_HDR_OVERIDE 0x01000000 /* PHY Header Override */
67#define PHY_HDR_OVERIDE_SHIFT 24
68#define CRC_FAIL 0x00800000 /* CRC fail */
69#define CRC_FAIL_SHIFT 23
70/* PAD_BITS(1); */
71#define SEQUENCE_NUMBER 0x00200000 /* Sequence Number */
72#define SEQUENCE_NUMBER_SHIFT 21
73/* PAD_BITS(2); */
74#define BUFF_HEAD_ADDR 0x0007FFFF /* Buffer Head Address */
75#define BUFF_HEAD_ADDR_SHIFT 0
76
77 __be32 reg2;
78#define PDU_COUNT 0xFC000000 /* PDU Count */
79#define PDU_COUNT_SHIFT 26
80/* PAD_BITS(3); */
81#define WEP_KEY 0x00600000 /* WEP Key # */
82#define WEP_KEY_SHIFT 21
83#define USES_WEP_KEY 0x00100000 /* Uses WEP Key */
84#define USES_WEP_KEY_SHIFT 20
85#define KEEP_ALIVE 0x00080000 /* Keep alive */
86#define KEEP_ALIVE_SHIFT 19
87#define BUFF_TAIL_ADDR 0x0007FFFF /* Buffer Tail Address */
88#define BUFF_TAIL_ADDR_SHIFT 0
89
90 __be32 reg3;
91#define CTS_11G 0x80000000 /* CTS in 11g */
92#define CTS_11G_SHIFT 31
93#define RTS_11G 0x40000000 /* RTS in 11g */
94#define RTS_11G_SHIFT 30
95/* PAD_BITS(2); */
96#define FRAG_SIZE 0x0FFF0000 /* fragment size */
97#define FRAG_SIZE_SHIFT 16
98#define PAYLOAD_LEN 0x0000FFF0 /* payload length */
99#define PAYLOAD_LEN_SHIFT 4
100#define FRAG_NUM 0x0000000F /* number of frags */
101#define FRAG_NUM_SHIFT 0
102
103 __be32 reg4;
104/* PAD_BITS(4); */
105#define RELAY_STAID 0x0FFF0000 /* relayStald */
106#define RELAY_STAID_SHIFT 16
107#define STATION_ID 0x0000FFF0 /* Station ID */
108#define STATION_ID_SHIFT 4
109#define WORKQUEUE_ID 0x0000000F /* Workqueue ID */
110#define WORKQUEUE_ID_SHIFT 0
111
112 /* FIXME this register maybe is LE? */
113 __be32 reg5;
114/* PAD_BITS(4); */
115#define ROUTE_HOST 0x0F000000
116#define ROUTE_HOST_SHIFT 24
117#define ROUTE_CARD_CPU 0x00F00000
118#define ROUTE_CARD_CPU_SHIFT 20
119#define ROUTE_ENCRYPTION 0x000F0000
120#define ROUTE_ENCRYPTION_SHIFT 16
121#define ROUTE_TX 0x0000F000
122#define ROUTE_TX_SHIFT 12
123#define ROUTE_RX1 0x00000F00
124#define ROUTE_RX1_SHIFT 8
125#define ROUTE_RX2 0x000000F0
126#define ROUTE_RX2_SHIFT 4
127#define ROUTE_COMPRESSION 0x0000000F
128#define ROUTE_COMPRESSION_SHIFT 0
129
130 __be32 _11g0; /* 11g */
131 __be32 _11g1; /* 11g */
132 __be32 _11b0; /* 11b */
133 __be32 _11b1; /* 11b */
134 u8 mac_hdr[32]; /* MAC header */
135
136 __be16 rts_duration; /* RTS duration */
137 __be16 last_duration; /* Last duration */
138 __be16 sec_last_duration; /* Second to Last duration */
139 __be16 other_duration; /* Other duration */
140 __be16 tx_last_duration; /* TX Last duration */
141 __be16 tx_other_duration; /* TX Other Duration */
142 __be16 last_11g_len; /* Length of last 11g */
143 __be16 other_11g_len; /* Lenght of other 11g */
144
145 __be16 last_11b_len; /* Length of last 11b */
146 __be16 other_11b_len; /* Lenght of other 11b */
147
148
149 __be16 reg6;
150#define MBF 0xF000 /* mbf */
151#define MBF_SHIFT 12
152#define RSVD4 0x0FFF /* rsvd4 */
153#define RSVD4_SHIFT 0
154
155 __be16 rx_frag_stat; /* RX fragmentation status */
156
157 __be32 time_stamp; /* TimeStamp */
158 __be32 phy_stats_hi; /* PHY stats hi */
159 __be32 phy_stats_lo; /* PHY stats lo */
160 __be32 mic_key0; /* MIC key 0 */
161 __be32 mic_key1; /* MIC key 1 */
162
163 union { /* RX/TX Union */
164 struct agnx_rx rx;
165 struct agnx_tx tx;
166 };
167
168 u8 rx_channel; /* Recieve Channel */
169 PAD_BYTES(3);
170
171 u8 reserved[4];
172} __attribute__((__packed__));
173
174
175struct agnx_desc {
176#define PACKET_LEN 0xFFF00000
177#define PACKET_LEN_SHIFT 20
178/* ------------------------------------------------ */
179#define FIRST_PACKET_MASK 0x00080000
180#define FIRST_PACKET_MASK_SHIFT 19
181#define FIRST_RESERV2 0x00040000
182#define FIRST_RESERV2_SHIFT 18
183#define FIRST_TKIP_ERROR 0x00020000
184#define FIRST_TKIP_ERROR_SHIFT 17
185#define FIRST_TKIP_PACKET 0x00010000
186#define FIRST_TKIP_PACKET_SHIFT 16
187#define FIRST_RESERV1 0x0000F000
188#define FIRST_RESERV1_SHIFT 12
189#define FIRST_FRAG_LEN 0x00000FF8
190#define FIRST_FRAG_LEN_SHIFT 3
191/* ------------------------------------------------ */
192#define SUB_RESERV2 0x000c0000
193#define SUB_RESERV2_SHIFT 18
194#define SUB_TKIP_ERROR 0x00020000
195#define SUB_TKIP_ERROR_SHIFT 17
196#define SUB_TKIP_PACKET 0x00010000
197#define SUB_TKIP_PACKET_SHIFT 16
198#define SUB_RESERV1 0x00008000
199#define SUB_RESERV1_SHIFT 15
200#define SUB_FRAG_LEN 0x00007FF8
201#define SUB_FRAG_LEN_SHIFT 3
202/* ------------------------------------------------ */
203#define FIRST_FRAG 0x00000004
204#define FIRST_FRAG_SHIFT 2
205#define LAST_FRAG 0x00000002
206#define LAST_FRAG_SHIFT 1
207#define OWNER 0x00000001
208#define OWNER_SHIFT 0
209 __be32 frag;
210 __be32 dma_addr;
211} __attribute__((__packed__));
212
213enum {HEADER, PACKET};
214
215struct agnx_info {
216 struct sk_buff *skb;
217 dma_addr_t mapping;
218 u32 dma_len; /* dma buffer len */
219 /* Below fields only usful for tx */
220 u32 hdr_len; /* ieee80211 header length */
221 unsigned int type;
222 struct ieee80211_tx_info *txi;
223 struct ieee80211_hdr hdr;
224};
225
226
227struct agnx_ring {
228 struct agnx_desc *desc;
229 dma_addr_t dma;
230 struct agnx_info *info;
231 /* Will lead to overflow when sent packet number enough? */
232 unsigned int idx;
233 unsigned int idx_sent; /* only usful for txd and txm */
234 unsigned int size;
235};
236
237#define AGNX_RX_RING_SIZE 128
238#define AGNX_TXD_RING_SIZE 256
239#define AGNX_TXM_RING_SIZE 128
240
241void disable_rx_interrupt(struct agnx_priv *priv);
242void enable_rx_interrupt(struct agnx_priv *priv);
243int fill_rings(struct agnx_priv *priv);
244void unfill_rings(struct agnx_priv *priv);
245void handle_rx_irq(struct agnx_priv *priv);
246void handle_txd_irq(struct agnx_priv *priv);
247void handle_txm_irq(struct agnx_priv *priv);
248void handle_other_irq(struct agnx_priv *priv);
249int _agnx_tx(struct agnx_priv *priv, struct sk_buff *skb);
250#endif /* AGNX_XMIT_H_ */
diff --git a/drivers/staging/b3dfg/b3dfg.c b/drivers/staging/b3dfg/b3dfg.c
index 94c5d27d24d7..cda26bb493b3 100644
--- a/drivers/staging/b3dfg/b3dfg.c
+++ b/drivers/staging/b3dfg/b3dfg.c
@@ -36,6 +36,7 @@
36#include <linux/wait.h> 36#include <linux/wait.h>
37#include <linux/mm.h> 37#include <linux/mm.h>
38#include <linux/uaccess.h> 38#include <linux/uaccess.h>
39#include <linux/sched.h>
39 40
40static unsigned int b3dfg_nbuf = 2; 41static unsigned int b3dfg_nbuf = 2;
41 42
diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig
index af723cb9d08f..d63c889ce557 100644
--- a/drivers/staging/comedi/Kconfig
+++ b/drivers/staging/comedi/Kconfig
@@ -1,7 +1,7 @@
1config COMEDI 1config COMEDI
2 tristate "Data acquisition support (comedi)" 2 tristate "Data acquisition support (comedi)"
3 default N 3 default N
4 depends on m 4 depends on m && (PCI || PCMCIA || PCCARD || USB)
5 ---help--- 5 ---help---
6 Enable support a wide range of data acquisition devices 6 Enable support a wide range of data acquisition devices
7 for Linux. 7 for Linux.
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c
index f54bb9b3ee37..aaad76e0a76a 100644
--- a/drivers/staging/comedi/comedi_fops.c
+++ b/drivers/staging/comedi/comedi_fops.c
@@ -2337,7 +2337,7 @@ static int resize_async_buffer(struct comedi_device *dev,
2337 } 2337 }
2338 2338
2339 DPRINTK("comedi%i subd %d buffer resized to %i bytes\n", 2339 DPRINTK("comedi%i subd %d buffer resized to %i bytes\n",
2340 dev->minor, s - dev->subdevices, async->prealloc_bufsz); 2340 dev->minor, (int)(s - dev->subdevices), async->prealloc_bufsz);
2341 return 0; 2341 return 0;
2342} 2342}
2343 2343
diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c
index 12d12b43a6f1..80c0df8656f3 100644
--- a/drivers/staging/comedi/drivers/cb_das16_cs.c
+++ b/drivers/staging/comedi/drivers/cb_das16_cs.c
@@ -744,7 +744,7 @@ static int das16cs_pcmcia_attach(struct pcmcia_device *link)
744 744
745 /* Initialize the pcmcia_device structure */ 745 /* Initialize the pcmcia_device structure */
746 /* Interrupt setup */ 746 /* Interrupt setup */
747 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; 747 link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
748 link->irq.IRQInfo1 = IRQ_LEVEL_ID; 748 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
749 link->irq.Handler = NULL; 749 link->irq.Handler = NULL;
750 750
diff --git a/drivers/staging/comedi/drivers/cb_pcidio.c b/drivers/staging/comedi/drivers/cb_pcidio.c
index 4d10bc31d461..09e6e3bdfb3e 100644
--- a/drivers/staging/comedi/drivers/cb_pcidio.c
+++ b/drivers/staging/comedi/drivers/cb_pcidio.c
@@ -53,7 +53,8 @@ Passing a zero for an option is the same as leaving it unspecified.
53 * Some drivers use arrays such as this, other do not. 53 * Some drivers use arrays such as this, other do not.
54 */ 54 */
55struct pcidio_board { 55struct pcidio_board {
56 const char *name; /* anme of the board */ 56 const char *name; /* name of the board */
57 int dev_id;
57 int n_8255; /* number of 8255 chips on board */ 58 int n_8255; /* number of 8255 chips on board */
58 59
59 /* indices of base address regions */ 60 /* indices of base address regions */
@@ -64,18 +65,21 @@ struct pcidio_board {
64static const struct pcidio_board pcidio_boards[] = { 65static const struct pcidio_board pcidio_boards[] = {
65 { 66 {
66 .name = "pci-dio24", 67 .name = "pci-dio24",
68 .dev_id = 0x0028,
67 .n_8255 = 1, 69 .n_8255 = 1,
68 .pcicontroler_badrindex = 1, 70 .pcicontroler_badrindex = 1,
69 .dioregs_badrindex = 2, 71 .dioregs_badrindex = 2,
70 }, 72 },
71 { 73 {
72 .name = "pci-dio24h", 74 .name = "pci-dio24h",
75 .dev_id = 0x0014,
73 .n_8255 = 1, 76 .n_8255 = 1,
74 .pcicontroler_badrindex = 1, 77 .pcicontroler_badrindex = 1,
75 .dioregs_badrindex = 2, 78 .dioregs_badrindex = 2,
76 }, 79 },
77 { 80 {
78 .name = "pci-dio48h", 81 .name = "pci-dio48h",
82 .dev_id = 0x000b,
79 .n_8255 = 2, 83 .n_8255 = 2,
80 .pcicontroler_badrindex = 0, 84 .pcicontroler_badrindex = 0,
81 .dioregs_badrindex = 1, 85 .dioregs_badrindex = 1,
@@ -206,7 +210,7 @@ static int pcidio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
206 continue; 210 continue;
207 /* loop through cards supported by this driver */ 211 /* loop through cards supported by this driver */
208 for (index = 0; index < ARRAY_SIZE(pcidio_boards); index++) { 212 for (index = 0; index < ARRAY_SIZE(pcidio_boards); index++) {
209 if (pcidio_pci_table[index].device != pcidev->device) 213 if (pcidio_boards[index].dev_id != pcidev->device)
210 continue; 214 continue;
211 215
212 /* was a particular bus/slot requested? */ 216 /* was a particular bus/slot requested? */
diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c
index 14bf29bf5781..0d2c2eb23b23 100644
--- a/drivers/staging/comedi/drivers/jr3_pci.c
+++ b/drivers/staging/comedi/drivers/jr3_pci.c
@@ -515,6 +515,7 @@ static struct poll_delay_t jr3_pci_poll_subdevice(struct comedi_subdevice *s)
515{ 515{
516 struct poll_delay_t result = poll_delay_min_max(1000, 2000); 516 struct poll_delay_t result = poll_delay_min_max(1000, 2000);
517 struct jr3_pci_subdev_private *p = s->private; 517 struct jr3_pci_subdev_private *p = s->private;
518 int i;
518 519
519 if (p) { 520 if (p) {
520 volatile struct jr3_channel *channel = p->channel; 521 volatile struct jr3_channel *channel = p->channel;
@@ -570,18 +571,11 @@ static struct poll_delay_t jr3_pci_poll_subdevice(struct comedi_subdevice *s)
570 p->serial_no); 571 p->serial_no);
571 572
572 /* Transformation all zeros */ 573 /* Transformation all zeros */
573 transf.link[0].link_type = 574 for (i = 0; i < ARRAY_SIZE(transf.link); i++) {
574 (enum link_types)0; 575 transf.link[i].link_type =
575 transf.link[0].link_amount = 0; 576 (enum link_types)0;
576 transf.link[1].link_type = 577 transf.link[i].link_amount = 0;
577 (enum link_types)0; 578 }
578 transf.link[1].link_amount = 0;
579 transf.link[2].link_type =
580 (enum link_types)0;
581 transf.link[2].link_amount = 0;
582 transf.link[3].link_type =
583 (enum link_types)0;
584 transf.link[3].link_amount = 0;
585 579
586 set_transforms(channel, transf, 0); 580 set_transforms(channel, transf, 0);
587 use_transform(channel, 0); 581 use_transform(channel, 0);
diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c
index 2cda7ad1d32f..80e192d2e77e 100644
--- a/drivers/staging/comedi/drivers/me_daq.c
+++ b/drivers/staging/comedi/drivers/me_daq.c
@@ -51,6 +51,7 @@ from http://www.comedi.org
51*/ 51*/
52 52
53#include <linux/interrupt.h> 53#include <linux/interrupt.h>
54#include <linux/sched.h>
54#include "../comedidev.h" 55#include "../comedidev.h"
55 56
56#include "comedi_pci.h" 57#include "comedi_pci.h"
diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c
index 6b118c15b49e..bbf75eb6d7f2 100644
--- a/drivers/staging/comedi/drivers/ni_65xx.c
+++ b/drivers/staging/comedi/drivers/ni_65xx.c
@@ -418,15 +418,15 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev,
418 return -EINVAL; 418 return -EINVAL;
419 base_bitfield_channel = CR_CHAN(insn->chanspec); 419 base_bitfield_channel = CR_CHAN(insn->chanspec);
420 for (j = 0; j < max_ports_per_bitfield; ++j) { 420 for (j = 0; j < max_ports_per_bitfield; ++j) {
421 const unsigned port_offset = ni_65xx_port_by_channel(base_bitfield_channel) + j;
421 const unsigned port = 422 const unsigned port =
422 sprivate(s)->base_port + 423 sprivate(s)->base_port + port_offset;
423 ni_65xx_port_by_channel(base_bitfield_channel) + j;
424 unsigned base_port_channel; 424 unsigned base_port_channel;
425 unsigned port_mask, port_data, port_read_bits; 425 unsigned port_mask, port_data, port_read_bits;
426 int bitshift; 426 int bitshift;
427 if (port >= ni_65xx_total_num_ports(board(dev))) 427 if (port >= ni_65xx_total_num_ports(board(dev)))
428 break; 428 break;
429 base_port_channel = port * ni_65xx_channels_per_port; 429 base_port_channel = port_offset * ni_65xx_channels_per_port;
430 port_mask = data[0]; 430 port_mask = data[0];
431 port_data = data[1]; 431 port_data = data[1];
432 bitshift = base_port_channel - base_bitfield_channel; 432 bitshift = base_port_channel - base_bitfield_channel;
@@ -457,6 +457,12 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev,
457 port_read_bits = 457 port_read_bits =
458 readb(private(dev)->mite->daq_io_addr + Port_Data(port)); 458 readb(private(dev)->mite->daq_io_addr + Port_Data(port));
459/* printk("read 0x%x from port %i\n", port_read_bits, port); */ 459/* printk("read 0x%x from port %i\n", port_read_bits, port); */
460 if (s->type == COMEDI_SUBD_DO && board(dev)->invert_outputs) {
461 /* Outputs inverted, so invert value read back from
462 * DO subdevice. (Does not apply to boards with DIO
463 * subdevice.) */
464 port_read_bits ^= 0xFF;
465 }
460 if (bitshift > 0) { 466 if (bitshift > 0) {
461 port_read_bits <<= bitshift; 467 port_read_bits <<= bitshift;
462 } else { 468 } else {
diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c
index 6a7797604c97..ec31a3970664 100644
--- a/drivers/staging/comedi/drivers/ni_daq_700.c
+++ b/drivers/staging/comedi/drivers/ni_daq_700.c
@@ -520,7 +520,7 @@ static int dio700_cs_attach(struct pcmcia_device *link)
520 link->priv = local; 520 link->priv = local;
521 521
522 /* Interrupt setup */ 522 /* Interrupt setup */
523 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; 523 link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
524 link->irq.IRQInfo1 = IRQ_LEVEL_ID; 524 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
525 link->irq.Handler = NULL; 525 link->irq.Handler = NULL;
526 526
diff --git a/drivers/staging/comedi/drivers/ni_daq_dio24.c b/drivers/staging/comedi/drivers/ni_daq_dio24.c
index b06e81c526e8..0700a8bddd1e 100644
--- a/drivers/staging/comedi/drivers/ni_daq_dio24.c
+++ b/drivers/staging/comedi/drivers/ni_daq_dio24.c
@@ -271,7 +271,7 @@ static int dio24_cs_attach(struct pcmcia_device *link)
271 link->priv = local; 271 link->priv = local;
272 272
273 /* Interrupt setup */ 273 /* Interrupt setup */
274 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; 274 link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
275 link->irq.IRQInfo1 = IRQ_LEVEL_ID; 275 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
276 link->irq.Handler = NULL; 276 link->irq.Handler = NULL;
277 277
diff --git a/drivers/staging/comedi/drivers/ni_labpc_cs.c b/drivers/staging/comedi/drivers/ni_labpc_cs.c
index 57aecfa883c7..a3053b8da1c6 100644
--- a/drivers/staging/comedi/drivers/ni_labpc_cs.c
+++ b/drivers/staging/comedi/drivers/ni_labpc_cs.c
@@ -246,7 +246,7 @@ static int labpc_cs_attach(struct pcmcia_device *link)
246 link->priv = local; 246 link->priv = local;
247 247
248 /* Interrupt setup */ 248 /* Interrupt setup */
249 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_FORCED_PULSE; 249 link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_FORCED_PULSE;
250 link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_PULSE_ID; 250 link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_PULSE_ID;
251 link->irq.Handler = NULL; 251 link->irq.Handler = NULL;
252 252
diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c
index e3ffb067ead1..753ee0512342 100644
--- a/drivers/staging/comedi/drivers/ni_mio_common.c
+++ b/drivers/staging/comedi/drivers/ni_mio_common.c
@@ -62,6 +62,7 @@
62/* #define DEBUG_STATUS_B */ 62/* #define DEBUG_STATUS_B */
63 63
64#include <linux/interrupt.h> 64#include <linux/interrupt.h>
65#include <linux/sched.h>
65#include "8255.h" 66#include "8255.h"
66#include "mite.h" 67#include "mite.h"
67#include "comedi_fc.h" 68#include "comedi_fc.h"
diff --git a/drivers/staging/comedi/drivers/ni_mio_cs.c b/drivers/staging/comedi/drivers/ni_mio_cs.c
index b7322963cf78..9aef87fc81dc 100644
--- a/drivers/staging/comedi/drivers/ni_mio_cs.c
+++ b/drivers/staging/comedi/drivers/ni_mio_cs.c
@@ -273,7 +273,7 @@ static int cs_attach(struct pcmcia_device *link)
273{ 273{
274 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; 274 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
275 link->io.NumPorts1 = 16; 275 link->io.NumPorts1 = 16;
276 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; 276 link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
277 link->irq.IRQInfo1 = IRQ_LEVEL_ID; 277 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
278 link->conf.Attributes = CONF_ENABLE_IRQ; 278 link->conf.Attributes = CONF_ENABLE_IRQ;
279 link->conf.IntType = INT_MEMORY_AND_IO; 279 link->conf.IntType = INT_MEMORY_AND_IO;
diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c
index 52b2eca9e73d..d544698f2414 100644
--- a/drivers/staging/comedi/drivers/ni_pcidio.c
+++ b/drivers/staging/comedi/drivers/ni_pcidio.c
@@ -70,6 +70,7 @@ comedi_nonfree_firmware tarball available from http://www.comedi.org
70/* #define DEBUG_FLAGS */ 70/* #define DEBUG_FLAGS */
71 71
72#include <linux/interrupt.h> 72#include <linux/interrupt.h>
73#include <linux/sched.h>
73#include "../comedidev.h" 74#include "../comedidev.h"
74 75
75#include "mite.h" 76#include "mite.h"
diff --git a/drivers/staging/comedi/drivers/ni_pcimio.c b/drivers/staging/comedi/drivers/ni_pcimio.c
index 19d87553d906..24c8b8ed5b4c 100644
--- a/drivers/staging/comedi/drivers/ni_pcimio.c
+++ b/drivers/staging/comedi/drivers/ni_pcimio.c
@@ -29,7 +29,7 @@ Devices: [National Instruments] PCI-MIO-16XE-50 (ni_pcimio),
29 PCI-MIO-16XE-10, PXI-6030E, PCI-MIO-16E-1, PCI-MIO-16E-4, PCI-6014, PCI-6040E, 29 PCI-MIO-16XE-10, PXI-6030E, PCI-MIO-16E-1, PCI-MIO-16E-4, PCI-6014, PCI-6040E,
30 PXI-6040E, PCI-6030E, PCI-6031E, PCI-6032E, PCI-6033E, PCI-6071E, PCI-6023E, 30 PXI-6040E, PCI-6030E, PCI-6031E, PCI-6032E, PCI-6033E, PCI-6071E, PCI-6023E,
31 PCI-6024E, PCI-6025E, PXI-6025E, PCI-6034E, PCI-6035E, PCI-6052E, 31 PCI-6024E, PCI-6025E, PXI-6025E, PCI-6034E, PCI-6035E, PCI-6052E,
32 PCI-6110, PCI-6111, PCI-6220, PCI-6221, PCI-6224, PXI-6224, PCI-6225, 32 PCI-6110, PCI-6111, PCI-6220, PCI-6221, PCI-6224, PXI-6224, PCI-6225, PXI-6225,
33 PCI-6229, PCI-6250, PCI-6251, PCIe-6251, PCI-6254, PCI-6259, PCIe-6259, 33 PCI-6229, PCI-6250, PCI-6251, PCIe-6251, PCI-6254, PCI-6259, PCIe-6259,
34 PCI-6280, PCI-6281, PXI-6281, PCI-6284, PCI-6289, 34 PCI-6280, PCI-6281, PXI-6281, PCI-6284, PCI-6289,
35 PCI-6711, PXI-6711, PCI-6713, PXI-6713, 35 PCI-6711, PXI-6711, PCI-6713, PXI-6713,
@@ -179,6 +179,7 @@ static DEFINE_PCI_DEVICE_TABLE(ni_pci_table) = {
179 PCI_VENDOR_ID_NATINST, 0x70f2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { 179 PCI_VENDOR_ID_NATINST, 0x70f2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
180 PCI_VENDOR_ID_NATINST, 0x710d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { 180 PCI_VENDOR_ID_NATINST, 0x710d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
181 PCI_VENDOR_ID_NATINST, 0x716c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { 181 PCI_VENDOR_ID_NATINST, 0x716c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
182 PCI_VENDOR_ID_NATINST, 0x716d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
182 PCI_VENDOR_ID_NATINST, 0x717f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { 183 PCI_VENDOR_ID_NATINST, 0x717f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
183 PCI_VENDOR_ID_NATINST, 0x71bc, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { 184 PCI_VENDOR_ID_NATINST, 0x71bc, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
184 PCI_VENDOR_ID_NATINST, 0x717d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { 185 PCI_VENDOR_ID_NATINST, 0x717d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
@@ -953,6 +954,25 @@ static const struct ni_board_struct ni_boards[] = {
953 .has_8255 = 0, 954 .has_8255 = 0,
954 }, 955 },
955 { 956 {
957 .device_id = 0x716d,
958 .name = "pxi-6225",
959 .n_adchan = 80,
960 .adbits = 16,
961 .ai_fifo_depth = 4095,
962 .gainlkup = ai_gain_622x,
963 .ai_speed = 4000,
964 .n_aochan = 2,
965 .aobits = 16,
966 .ao_fifo_depth = 8191,
967 .ao_range_table = &range_ni_M_622x_ao,
968 .reg_type = ni_reg_622x,
969 .ao_unipolar = 0,
970 .ao_speed = 1200,
971 .num_p0_dio_channels = 32,
972 .caldac = {caldac_none},
973 .has_8255 = 0,
974 },
975 {
956 .device_id = 0x70aa, 976 .device_id = 0x70aa,
957 .name = "pci-6229", 977 .name = "pci-6229",
958 .n_adchan = 32, 978 .n_adchan = 32,
diff --git a/drivers/staging/comedi/drivers/quatech_daqp_cs.c b/drivers/staging/comedi/drivers/quatech_daqp_cs.c
index f63bdc35cffd..344b82353e08 100644
--- a/drivers/staging/comedi/drivers/quatech_daqp_cs.c
+++ b/drivers/staging/comedi/drivers/quatech_daqp_cs.c
@@ -1079,7 +1079,7 @@ static int daqp_cs_attach(struct pcmcia_device *link)
1079 link->priv = local; 1079 link->priv = local;
1080 1080
1081 /* Interrupt setup */ 1081 /* Interrupt setup */
1082 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; 1082 link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
1083 link->irq.IRQInfo1 = IRQ_LEVEL_ID; 1083 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
1084 link->irq.Handler = daqp_interrupt; 1084 link->irq.Handler = daqp_interrupt;
1085 link->irq.Instance = local; 1085 link->irq.Instance = local;
diff --git a/drivers/staging/comedi/drivers/s526.c b/drivers/staging/comedi/drivers/s526.c
index b89e1ec267c5..07c21e686f27 100644
--- a/drivers/staging/comedi/drivers/s526.c
+++ b/drivers/staging/comedi/drivers/s526.c
@@ -43,6 +43,7 @@ comedi_config /dev/comedi0 s526 0x2C0,0x3
43 43
44#include "../comedidev.h" 44#include "../comedidev.h"
45#include <linux/ioport.h> 45#include <linux/ioport.h>
46#include <asm/byteorder.h>
46 47
47#define S526_SIZE 64 48#define S526_SIZE 64
48 49
@@ -113,6 +114,7 @@ static const int s526_ports[] = {
113}; 114};
114 115
115struct counter_mode_register_t { 116struct counter_mode_register_t {
117#if defined (__LITTLE_ENDIAN_BITFIELD)
116 unsigned short coutSource:1; 118 unsigned short coutSource:1;
117 unsigned short coutPolarity:1; 119 unsigned short coutPolarity:1;
118 unsigned short autoLoadResetRcap:3; 120 unsigned short autoLoadResetRcap:3;
@@ -124,12 +126,27 @@ struct counter_mode_register_t {
124 unsigned short outputRegLatchCtrl:1; 126 unsigned short outputRegLatchCtrl:1;
125 unsigned short preloadRegSel:1; 127 unsigned short preloadRegSel:1;
126 unsigned short reserved:1; 128 unsigned short reserved:1;
129 #elif defined(__BIG_ENDIAN_BITFIELD)
130 unsigned short reserved:1;
131 unsigned short preloadRegSel:1;
132 unsigned short outputRegLatchCtrl:1;
133 unsigned short countDirCtrl:1;
134 unsigned short countDir:1;
135 unsigned short clockSource:2;
136 unsigned short ctEnableCtrl:2;
137 unsigned short hwCtEnableSource:2;
138 unsigned short autoLoadResetRcap:3;
139 unsigned short coutPolarity:1;
140 unsigned short coutSource:1;
141#else
142#error Unknown bit field order
143#endif
127}; 144};
128 145
129union { 146union cmReg {
130 struct counter_mode_register_t reg; 147 struct counter_mode_register_t reg;
131 unsigned short value; 148 unsigned short value;
132} cmReg; 149};
133 150
134#define MAX_GPCT_CONFIG_DATA 6 151#define MAX_GPCT_CONFIG_DATA 6
135 152
@@ -285,6 +302,7 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it)
285 int i, n; 302 int i, n;
286/* short value; */ 303/* short value; */
287/* int subdev_channel = 0; */ 304/* int subdev_channel = 0; */
305 union cmReg cmReg;
288 306
289 printk("comedi%d: s526: ", dev->minor); 307 printk("comedi%d: s526: ", dev->minor);
290 308
@@ -375,7 +393,7 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it)
375 if (thisboard->have_dio) { 393 if (thisboard->have_dio) {
376 s->type = COMEDI_SUBD_DIO; 394 s->type = COMEDI_SUBD_DIO;
377 s->subdev_flags = SDF_READABLE | SDF_WRITABLE; 395 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
378 s->n_chan = 2; 396 s->n_chan = 8;
379 s->maxdata = 1; 397 s->maxdata = 1;
380 s->range_table = &range_digital; 398 s->range_table = &range_digital;
381 s->insn_bits = s526_dio_insn_bits; 399 s->insn_bits = s526_dio_insn_bits;
@@ -435,11 +453,11 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it)
435 udelay(1000); 453 udelay(1000);
436 printk("Read back mode reg=0x%04x\n", inw(ADDR_CHAN_REG(REG_C0M, n))); 454 printk("Read back mode reg=0x%04x\n", inw(ADDR_CHAN_REG(REG_C0M, n)));
437 455
438 /* Load the pre-laod register high word */ 456 /* Load the pre-load register high word */
439/* value = (short) (0x55); */ 457/* value = (short) (0x55); */
440/* outw(value, ADDR_CHAN_REG(REG_C0H, n)); */ 458/* outw(value, ADDR_CHAN_REG(REG_C0H, n)); */
441 459
442 /* Load the pre-laod register low word */ 460 /* Load the pre-load register low word */
443/* value = (short)(0xaa55); */ 461/* value = (short)(0xaa55); */
444/* outw(value, ADDR_CHAN_REG(REG_C0L, n)); */ 462/* outw(value, ADDR_CHAN_REG(REG_C0L, n)); */
445 463
@@ -516,6 +534,7 @@ static int s526_gpct_insn_config(struct comedi_device *dev,
516 int subdev_channel = CR_CHAN(insn->chanspec); /* Unpack chanspec */ 534 int subdev_channel = CR_CHAN(insn->chanspec); /* Unpack chanspec */
517 int i; 535 int i;
518 short value; 536 short value;
537 union cmReg cmReg;
519 538
520/* printk("s526: GPCT_INSN_CONFIG: Configuring Channel %d\n", subdev_channel); */ 539/* printk("s526: GPCT_INSN_CONFIG: Configuring Channel %d\n", subdev_channel); */
521 540
@@ -568,19 +587,8 @@ static int s526_gpct_insn_config(struct comedi_device *dev,
568 587
569#if 1 588#if 1
570 /* Set Counter Mode Register */ 589 /* Set Counter Mode Register */
571 cmReg.reg.coutSource = 0; /* out RCAP */ 590 cmReg.value = insn->data[1] & 0xFFFF;
572 cmReg.reg.coutPolarity = 0; /* Polarity inverted */
573 cmReg.reg.autoLoadResetRcap = 0; /* Auto load disabled */
574 cmReg.reg.hwCtEnableSource = 2; /* NOT RCAP */
575 cmReg.reg.ctEnableCtrl = 1; /* 1: Software, >1 : Hardware */
576 cmReg.reg.clockSource = 3; /* x4 */
577 cmReg.reg.countDir = 0; /* up */
578 cmReg.reg.countDirCtrl = 0; /* quadrature */
579 cmReg.reg.outputRegLatchCtrl = 0; /* latch on read */
580 cmReg.reg.preloadRegSel = 0; /* PR0 */
581 cmReg.reg.reserved = 0;
582 591
583 /* Set Counter Mode Register */
584/* printk("s526: Counter Mode register=%x\n", cmReg.value); */ 592/* printk("s526: Counter Mode register=%x\n", cmReg.value); */
585 outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel)); 593 outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel));
586 594
@@ -615,11 +623,11 @@ static int s526_gpct_insn_config(struct comedi_device *dev,
615 cmReg.value = (short)(insn->data[1] & 0xFFFF); 623 cmReg.value = (short)(insn->data[1] & 0xFFFF);
616 outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel)); 624 outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel));
617 625
618 /* Load the pre-laod register high word */ 626 /* Load the pre-load register high word */
619 value = (short)((insn->data[2] >> 16) & 0xFFFF); 627 value = (short)((insn->data[2] >> 16) & 0xFFFF);
620 outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel)); 628 outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel));
621 629
622 /* Load the pre-laod register low word */ 630 /* Load the pre-load register low word */
623 value = (short)(insn->data[2] & 0xFFFF); 631 value = (short)(insn->data[2] & 0xFFFF);
624 outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel)); 632 outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel));
625 633
@@ -653,11 +661,11 @@ static int s526_gpct_insn_config(struct comedi_device *dev,
653 cmReg.reg.preloadRegSel = 0; /* PR0 */ 661 cmReg.reg.preloadRegSel = 0; /* PR0 */
654 outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel)); 662 outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel));
655 663
656 /* Load the pre-laod register 0 high word */ 664 /* Load the pre-load register 0 high word */
657 value = (short)((insn->data[2] >> 16) & 0xFFFF); 665 value = (short)((insn->data[2] >> 16) & 0xFFFF);
658 outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel)); 666 outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel));
659 667
660 /* Load the pre-laod register 0 low word */ 668 /* Load the pre-load register 0 low word */
661 value = (short)(insn->data[2] & 0xFFFF); 669 value = (short)(insn->data[2] & 0xFFFF);
662 outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel)); 670 outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel));
663 671
@@ -666,17 +674,17 @@ static int s526_gpct_insn_config(struct comedi_device *dev,
666 cmReg.reg.preloadRegSel = 1; /* PR1 */ 674 cmReg.reg.preloadRegSel = 1; /* PR1 */
667 outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel)); 675 outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel));
668 676
669 /* Load the pre-laod register 1 high word */ 677 /* Load the pre-load register 1 high word */
670 value = (short)((insn->data[3] >> 16) & 0xFFFF); 678 value = (short)((insn->data[3] >> 16) & 0xFFFF);
671 outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel)); 679 outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel));
672 680
673 /* Load the pre-laod register 1 low word */ 681 /* Load the pre-load register 1 low word */
674 value = (short)(insn->data[3] & 0xFFFF); 682 value = (short)(insn->data[3] & 0xFFFF);
675 outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel)); 683 outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel));
676 684
677 /* Write the Counter Control Register */ 685 /* Write the Counter Control Register */
678 if (insn->data[3] != 0) { 686 if (insn->data[4] != 0) {
679 value = (short)(insn->data[3] & 0xFFFF); 687 value = (short)(insn->data[4] & 0xFFFF);
680 outw(value, ADDR_CHAN_REG(REG_C0C, subdev_channel)); 688 outw(value, ADDR_CHAN_REG(REG_C0C, subdev_channel));
681 } 689 }
682 break; 690 break;
@@ -698,11 +706,11 @@ static int s526_gpct_insn_config(struct comedi_device *dev,
698 cmReg.reg.preloadRegSel = 0; /* PR0 */ 706 cmReg.reg.preloadRegSel = 0; /* PR0 */
699 outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel)); 707 outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel));
700 708
701 /* Load the pre-laod register 0 high word */ 709 /* Load the pre-load register 0 high word */
702 value = (short)((insn->data[2] >> 16) & 0xFFFF); 710 value = (short)((insn->data[2] >> 16) & 0xFFFF);
703 outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel)); 711 outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel));
704 712
705 /* Load the pre-laod register 0 low word */ 713 /* Load the pre-load register 0 low word */
706 value = (short)(insn->data[2] & 0xFFFF); 714 value = (short)(insn->data[2] & 0xFFFF);
707 outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel)); 715 outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel));
708 716
@@ -711,17 +719,17 @@ static int s526_gpct_insn_config(struct comedi_device *dev,
711 cmReg.reg.preloadRegSel = 1; /* PR1 */ 719 cmReg.reg.preloadRegSel = 1; /* PR1 */
712 outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel)); 720 outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel));
713 721
714 /* Load the pre-laod register 1 high word */ 722 /* Load the pre-load register 1 high word */
715 value = (short)((insn->data[3] >> 16) & 0xFFFF); 723 value = (short)((insn->data[3] >> 16) & 0xFFFF);
716 outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel)); 724 outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel));
717 725
718 /* Load the pre-laod register 1 low word */ 726 /* Load the pre-load register 1 low word */
719 value = (short)(insn->data[3] & 0xFFFF); 727 value = (short)(insn->data[3] & 0xFFFF);
720 outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel)); 728 outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel));
721 729
722 /* Write the Counter Control Register */ 730 /* Write the Counter Control Register */
723 if (insn->data[3] != 0) { 731 if (insn->data[4] != 0) {
724 value = (short)(insn->data[3] & 0xFFFF); 732 value = (short)(insn->data[4] & 0xFFFF);
725 outw(value, ADDR_CHAN_REG(REG_C0C, subdev_channel)); 733 outw(value, ADDR_CHAN_REG(REG_C0C, subdev_channel));
726 } 734 }
727 break; 735 break;
@@ -741,6 +749,7 @@ static int s526_gpct_winsn(struct comedi_device *dev,
741{ 749{
742 int subdev_channel = CR_CHAN(insn->chanspec); /* Unpack chanspec */ 750 int subdev_channel = CR_CHAN(insn->chanspec); /* Unpack chanspec */
743 short value; 751 short value;
752 union cmReg cmReg;
744 753
745 printk("s526: GPCT_INSN_WRITE on channel %d\n", subdev_channel); 754 printk("s526: GPCT_INSN_WRITE on channel %d\n", subdev_channel);
746 cmReg.value = inw(ADDR_CHAN_REG(REG_C0M, subdev_channel)); 755 cmReg.value = inw(ADDR_CHAN_REG(REG_C0M, subdev_channel));
@@ -775,9 +784,8 @@ static int s526_gpct_winsn(struct comedi_device *dev,
775 (devpriv->s526_gpct_config[subdev_channel]).data[1] = 784 (devpriv->s526_gpct_config[subdev_channel]).data[1] =
776 insn->data[1]; 785 insn->data[1];
777 } else { 786 } else {
778 printk("%d \t %d\n", insn->data[1], insn->data[2]); 787 printk("s526: INSN_WRITE: PTG: Problem with Pulse params -> %d %d\n",
779 printk 788 insn->data[0], insn->data[1]);
780 ("s526: INSN_WRITE: PTG: Problem with Pulse params\n");
781 return -EINVAL; 789 return -EINVAL;
782 } 790 }
783 791
@@ -949,7 +957,7 @@ static int s526_dio_insn_bits(struct comedi_device *dev,
949 data[1] = inw(ADDR_REG(REG_DIO)) & 0xFF; /* low 8 bits are the data */ 957 data[1] = inw(ADDR_REG(REG_DIO)) & 0xFF; /* low 8 bits are the data */
950 /* or we could just return the software copy of the output values if 958 /* or we could just return the software copy of the output values if
951 * it was a purely digital output subdevice */ 959 * it was a purely digital output subdevice */
952 /* data[1]=s->state; */ 960 /* data[1]=s->state & 0xFF; */
953 961
954 return 2; 962 return 2;
955} 963}
@@ -959,28 +967,33 @@ static int s526_dio_insn_config(struct comedi_device *dev,
959 struct comedi_insn *insn, unsigned int *data) 967 struct comedi_insn *insn, unsigned int *data)
960{ 968{
961 int chan = CR_CHAN(insn->chanspec); 969 int chan = CR_CHAN(insn->chanspec);
962 short value; 970 int group, mask;
963 971
964 printk("S526 DIO insn_config\n"); 972 printk("S526 DIO insn_config\n");
965 973
966 if (insn->n != 1)
967 return -EINVAL;
968
969 value = inw(ADDR_REG(REG_DIO));
970
971 /* The input or output configuration of each digital line is 974 /* The input or output configuration of each digital line is
972 * configured by a special insn_config instruction. chanspec 975 * configured by a special insn_config instruction. chanspec
973 * contains the channel to be changed, and data[0] contains the 976 * contains the channel to be changed, and data[0] contains the
974 * value COMEDI_INPUT or COMEDI_OUTPUT. */ 977 * value COMEDI_INPUT or COMEDI_OUTPUT. */
975 978
976 if (data[0] == COMEDI_OUTPUT) { 979 group = chan >> 2;
977 value |= 1 << (chan + 10); /* bit 10/11 set the group 1/2's mode */ 980 mask = 0xF << (group << 2);
978 s->io_bits |= (0xF << chan); 981 switch (data[0]) {
979 } else { 982 case INSN_CONFIG_DIO_OUTPUT:
980 value &= ~(1 << (chan + 10)); /* 1 is output, 0 is input. */ 983 s->state |= 1 << (group + 10); // bit 10/11 set the group 1/2's mode
981 s->io_bits &= ~(0xF << chan); 984 s->io_bits |= mask;
985 break;
986 case INSN_CONFIG_DIO_INPUT:
987 s->state &= ~(1 << (group + 10));// 1 is output, 0 is input.
988 s->io_bits &= ~mask;
989 break;
990 case INSN_CONFIG_DIO_QUERY:
991 data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT;
992 return insn->n;
993 default:
994 return -EINVAL;
982 } 995 }
983 outw(value, ADDR_REG(REG_DIO)); 996 outw(s->state, ADDR_REG(REG_DIO));
984 997
985 return 1; 998 return 1;
986} 999}
diff --git a/drivers/staging/comedi/drivers/serial2002.c b/drivers/staging/comedi/drivers/serial2002.c
index a21967983942..82aa86e718b2 100644
--- a/drivers/staging/comedi/drivers/serial2002.c
+++ b/drivers/staging/comedi/drivers/serial2002.c
@@ -35,6 +35,7 @@ Status: in development
35 35
36#include <linux/delay.h> 36#include <linux/delay.h>
37#include <linux/ioport.h> 37#include <linux/ioport.h>
38#include <linux/sched.h>
38 39
39#include <asm/termios.h> 40#include <asm/termios.h>
40#include <asm/ioctls.h> 41#include <asm/ioctls.h>
diff --git a/drivers/staging/cowloop/Kconfig b/drivers/staging/cowloop/Kconfig
deleted file mode 100644
index 58d2a23bd2c1..000000000000
--- a/drivers/staging/cowloop/Kconfig
+++ /dev/null
@@ -1,16 +0,0 @@
1config COWLOOP
2 tristate "copy-on-write pseudo Block Driver"
3 depends on BLOCK
4 default n
5 ---help---
6 Cowloop is a "copy-on-write" pseudo block driver. It can be
7 stacked on top of a "real" block driver, and catches all write
8 operations on their way from the file systems layer above to
9 the real driver below, effectively shielding the lower driver
10 from those write accesses. The requests are then diverted to
11 an ordinary file, located somewhere else (configurable). Later
12 read requests are checked to see whether they can be serviced
13 by the "real" block driver below, or must be pulled in from
14 the diverted location. More information and userspace tools to
15 use the driver are on the project's website
16 http://www.ATComputing.nl/cowloop/
diff --git a/drivers/staging/cowloop/Makefile b/drivers/staging/cowloop/Makefile
deleted file mode 100644
index 2b6b81a63d21..000000000000
--- a/drivers/staging/cowloop/Makefile
+++ /dev/null
@@ -1 +0,0 @@
1obj-$(CONFIG_COWLOOP) += cowloop.o
diff --git a/drivers/staging/cowloop/TODO b/drivers/staging/cowloop/TODO
deleted file mode 100644
index 9399d1c16e15..000000000000
--- a/drivers/staging/cowloop/TODO
+++ /dev/null
@@ -1,11 +0,0 @@
1TODO:
2 - checkpatch.pl cleanups
3 - run sparse to ensure clean
4 - fix up 32/64bit ioctl issues
5 - move proc file usage to debugfs
6 - audit ioctls
7 - add documentation
8 - get linux-fsdevel to review it
9
10Please send patches to "H.J. Thomassen" <hjt@ATComputing.nl> and
11Greg Kroah-Hartman <gregkh@suse.de>
diff --git a/drivers/staging/cowloop/cowloop.c b/drivers/staging/cowloop/cowloop.c
deleted file mode 100644
index a71c743a1196..000000000000
--- a/drivers/staging/cowloop/cowloop.c
+++ /dev/null
@@ -1,2842 +0,0 @@
1/*
2** COWLOOP block device driver (2.6 kernel compliant)
3** =======================================================================
4** Read-write loop-driver with copy-on-write functionality.
5**
6** Synopsis:
7**
8** modprobe cowloop [maxcows=..] [rdofile=..... cowfile=.... [option=r]]
9**
10** Definition of number of configured cowdevices:
11** maxcows= number of configured cowdevices (default: 16)
12** (do not confuse this with MAXCOWS: absolute maximum as compiled)
13**
14** One pair of filenames can be supplied during insmod/modprobe to open
15** the first cowdevice:
16** rdofile= read-only file (or filesystem)
17** cowfile= storage-space for modified blocks of read-only file(system)
18** option=r repair cowfile automatically if it appears to be dirty
19**
20** Other cowdevices can be activated via the command "cowdev"
21** whenever the cowloop-driver is loaded.
22**
23** The read-only file may be of type 'regular' or 'block-device'.
24**
25** The cowfile must be of type 'regular'.
26** If an existing regular file is used as cowfile, its contents will be
27** used again for the current read-only file. When the cowfile has not been
28** closed properly during a previous session (i.e. rmmod cowloop), the
29** cowloop-driver refuses to open it unless the parameter "option=r" is
30** specified.
31**
32** Layout of cowfile:
33**
34** +-----------------------------+
35** | cow head block | MAPUNIT bytes
36** |-----------------------------|
37** | | MAPUNIT bytes
38** |--- ---|
39** | | MAPUNIT bytes
40** |--- ---|
41** | used-block bitmap | MAPUNIT bytes
42** |-----------------------------|
43** | gap to align start-offset |
44** | to 4K multiple |
45** |-----------------------------| <---- start-offset cow blocks
46** | |
47** | written cow blocks | MAPUNIT bytes
48** | ..... |
49**
50** cowhead block:
51** - contains general info about the rdofile which is related
52** to this cowfile
53**
54** used-block bitmap:
55** - contains one bit per block with a size of MAPUNIT bytes
56** - bit-value '1' = block has been written on cow
57** '0' = block unused on cow
58** - total bitmap rounded to multiples of MAPUNIT
59**
60** ============================================================================
61** Author: Gerlof Langeveld - AT Computing (March 2003)
62** Current maintainer: Hendrik-Jan Thomassen - AT Computing (Summer 2006)
63** Email: hjt@ATComputing.nl
64** ----------------------------------------------------------------------------
65** Copyright (C) 2003-2009 AT Consultancy
66**
67** This program is free software; you can redistribute it and/or modify it
68** under the terms of the GNU General Public License as published by the
69** Free Software Foundation; either version 2, or (at your option) any
70** later version.
71**
72** This program is distributed in the hope that it will be useful, but
73** WITHOUT ANY WARRANTY; without even the implied warranty of
74** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
75** See the GNU General Public License for more details.
76**
77** You should have received a copy of the GNU General Public License
78** along with this program; if not, write to the Free Software
79** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
80** ----------------------------------------------------------------------------
81**
82** Major modifications:
83**
84** 200405 Ported to kernel-version 2.6 Hendrik-Jan Thomassen
85** 200405 Added cowhead to cowfile to garantee
86** consistency with read-only file Gerlof Langeveld
87** 200405 Postponed flushing of bitmaps to improve
88** performance. Gerlof Langeveld
89** 200405 Inline recovery for dirty cowfiles. Gerlof Langeveld
90** 200502 Redesign to support more cowdevices. Gerlof Langeveld
91** 200502 Support devices/file > 2 Gbytes. Gerlof Langeveld
92** 200507 Check for free space to expand cowfile. Gerlof Langeveld
93** 200902 Upgrade for kernel 2.6.28 Hendrik-Jan Thomassen
94**
95** Inspired by
96** loop.c by Theodore Ts'o and
97** cloop.c by Paul `Rusty' Russell & Klaus Knopper.
98**
99** Design-considerations:
100**
101** For the first experiments with the cowloop-driver, the request-queue
102** made use of the do_generic_file_read() which worked fine except
103** in combination with the cloop-driver; that combination
104** resulted in a non-interruptible hangup of the system during
105** heavy load. Other experiments using the `make_request' interface also
106** resulted in unpredictable system hangups (with proper use of spinlocks).
107**
108** To overcome these problems, the cowloop-driver starts a kernel-thread
109** for every active cowdevice.
110** All read- and write-request on the read-only file and copy-on-write file
111** are handled in the context of that thread.
112** A scheme has been designed to wakeup the kernel-thread as
113** soon as I/O-requests are available in the request-queue; this thread
114** handles the requests one-by-one by calling the proper read- or
115** write-function related to the open read-only file or copy-on-write file.
116** When all pending requests have been handled, the kernel-thread goes
117** back to sleep-state.
118** This approach requires some additional context-switches; however the
119** performance loss during heavy I/O is less than 3%.
120**
121** -------------------------------------------------------------------------*/
122/* The following is the cowloop package version number. It must be
123 identical to the content of the include-file "version.h" that is
124 used in all supporting utilities: */
125char revision[] = "$Revision: 3.1 $"; /* cowlo_init_module() has
126 assumptions about this string's format */
127
128/* Note that the following numbers are *not* the cowloop package version
129 numbers, but separate revision history numbers to track the
130 modifications of this particular source file: */
131/* $Log: cowloop.c,v $
132**
133** Revision 1.30 2009/02/08 hjt
134** Integrated earlier fixes
135** Upgraded to kernel 2.6.28 (thanks Jerome Poulin)
136**
137** Revision 1.29 2006/12/03 22:12:00 hjt
138** changed 'cowdevlock' from spinlock to semaphore, to avoid
139** "scheduling while atomic". Contributed by Juergen Christ.
140** Added version.h again
141**
142** Revision 1.28 2006/08/16 16:00:00 hjt
143** malloc each individual cowloopdevice struct separately
144**
145** Revision 1.27 2006/03/14 14:57:03 root
146** Removed include version.h
147**
148** Revision 1.26 2005/08/08 11:22:48 root
149** Implement possibility to close a cow file or reopen a cowfile read-only.
150**
151** Revision 1.25 2005/08/03 14:00:39 root
152** Added modinfo info to driver.
153**
154** Revision 1.24 2005/07/21 06:14:53 root
155** Cosmetic changes source code.
156**
157** Revision 1.23 2005/07/20 13:07:32 root
158** Supply ioctl to write watchdog program to react on lack of cowfile space.
159**
160** Revision 1.22 2005/07/20 07:53:34 root
161** Regular verification of free space in filesystem holding the cowfile
162** (give warnings whenever space is almost exhausted).
163** Terminology change: checksum renamed to fingerprint.
164**
165** Revision 1.21 2005/07/19 09:21:52 root
166** Removing maximum limit of 16 Gb per cowdevice.
167**
168** Revision 1.20 2005/07/19 07:50:33 root
169** Minor bugfixes and cosmetic changes.
170**
171** Revision 1.19 2005/06/10 12:29:55 root
172** Removed lock/unlock operation from cowlo_open().
173**
174** Revision 1.18 2005/05/09 12:56:26 root
175** Allow a cowdevice to be open more than once
176** (needed for support of ReiserFS and XFS).
177**
178** Revision 1.17 2005/03/17 14:36:16 root
179** Fixed some license issues.
180**
181** Revision 1.16 2005/03/07 14:42:05 root
182** Only allow one parallel open per cowdevice.
183**
184** Revision 1.15 2005/02/18 11:52:04 gerlof
185** Redesign to support more than one cowdevice > 2 Gb space.
186**
187** Revision 1.14 2004/08/17 14:19:16 gerlof
188** Modified output of /proc/cowloop.
189**
190** Revision 1.13 2004/08/16 07:21:10 gerlof
191** Separate statistical counter for read on rdofile and cowfile.
192**
193** Revision 1.12 2004/08/11 06:52:11 gerlof
194** Modified messages.
195**
196** Revision 1.11 2004/08/11 06:44:11 gerlof
197** Modified log messages.
198**
199** Revision 1.10 2004/08/10 12:27:27 gerlof
200** Cosmetic changes.
201**
202** Revision 1.9 2004/08/09 11:43:37 gerlof
203** Removed double definition of major number (COWMAJOR).
204**
205** Revision 1.8 2004/08/09 08:03:39 gerlof
206** Cleanup of messages.
207**
208** Revision 1.7 2004/05/27 06:37:33 gerlof
209** Modified /proc message.
210**
211** Revision 1.6 2004/05/26 21:23:28 gerlof
212** Modified /proc output.
213**
214** Revision 1.5 2004/05/26 13:23:34 gerlof
215** Support cowsync to force flushing the bitmaps and cowhead.
216**
217** Revision 1.4 2004/05/26 11:11:10 gerlof
218** Updated the comment to the actual situation.
219**
220** Revision 1.3 2004/05/26 10:50:00 gerlof
221** Implemented recovery-option.
222**
223** Revision 1.2 2004/05/25 15:14:41 gerlof
224** Modified bitmap flushing strategy.
225**
226*/
227
228#define COWMAJOR 241
229
230// #define COWDEBUG
231
232#ifdef COWDEBUG
233#define DEBUGP printk
234#define DCOW KERN_ALERT
235#else
236#define DEBUGP(format, x...)
237#endif
238
239#include <linux/types.h>
240#include <linux/autoconf.h>
241#ifndef AUTOCONF_INCLUDED
242#include <linux/config.h>
243#endif
244#include <linux/module.h>
245#include <linux/version.h>
246#include <linux/moduleparam.h>
247#include <linux/init.h>
248#include <linux/errno.h>
249#include <linux/kernel.h>
250#include <linux/major.h>
251#include <linux/sched.h>
252#include <linux/fs.h>
253#include <linux/file.h>
254#include <linux/stat.h>
255#include <linux/vmalloc.h>
256#include <linux/slab.h>
257#include <linux/semaphore.h>
258#include <asm/uaccess.h>
259#include <linux/proc_fs.h>
260#include <linux/blkdev.h>
261#include <linux/buffer_head.h>
262#include <linux/hdreg.h>
263#include <linux/genhd.h>
264#include <linux/statfs.h>
265
266#include "cowloop.h"
267
268MODULE_LICENSE("GPL");
269/* MODULE_AUTHOR("Gerlof Langeveld <gerlof@ATComputing.nl>"); obsolete address */
270MODULE_AUTHOR("Hendrik-Jan Thomassen <hjt@ATComputing.nl>"); /* current maintainer */
271MODULE_DESCRIPTION("Copy-on-write loop driver");
272MODULE_PARM_DESC(maxcows, " Number of configured cowdevices (default 16)");
273MODULE_PARM_DESC(rdofile, " Read-only file for /dev/cow/0");
274MODULE_PARM_DESC(cowfile, " Cowfile for /dev/cow/0");
275MODULE_PARM_DESC(option, " Repair cowfile if inconsistent: option=r");
276
277#define DEVICE_NAME "cow"
278
279#define DFLCOWS 16 /* default cowloop devices */
280
281static int maxcows = DFLCOWS;
282module_param(maxcows, int, 0);
283static char *rdofile = "";
284module_param(rdofile, charp, 0);
285static char *cowfile = "";
286module_param(cowfile, charp, 0);
287static char *option = "";
288module_param(option, charp, 0);
289
290/*
291** per cowdevice several bitmap chunks are allowed of MAPCHUNKSZ each
292**
293** each bitmap chunk can describe MAPCHUNKSZ * 8 * MAPUNIT bytes of data
294** suppose:
295** MAPCHUNKSZ 4096 and MAPUNIT 1024 --> 4096 * 8 * 1024 = 32 Mb per chunk
296*/
297#define MAPCHUNKSZ 4096 /* #bytes per bitmap chunk (do not change) */
298
299#define SPCMINBLK 100 /* space threshold to give warning messages */
300#define SPCDFLINTVL 16 /* once every SPCDFLINTVL writes to cowfile, */
301 /* available space in filesystem is checked */
302
303#define CALCMAP(x) ((x)/(MAPCHUNKSZ*8))
304#define CALCBYTE(x) (((x)%(MAPCHUNKSZ*8))>>3)
305#define CALCBIT(x) ((x)&7)
306
307#define ALLCOW 1
308#define ALLRDO 2
309#define MIXEDUP 3
310
311static char allzeroes[MAPUNIT];
312
313/*
314** administration per cowdevice (pair of cowfile/rdofile)
315*/
316
317/* bit-values for state */
318#define COWDEVOPEN 0x01 /* cowdevice opened */
319#define COWRWCOWOPEN 0x02 /* cowfile opened read-write */
320#define COWRDCOWOPEN 0x04 /* cowfile opened read-only */
321#define COWWATCHDOG 0x08 /* ioctl for watchdog cowfile space active */
322
323#define COWCOWOPEN (COWRWCOWOPEN|COWRDCOWOPEN)
324
325struct cowloop_device
326{
327 /*
328 ** current status
329 */
330 int state; /* bit-values (see above) */
331 int opencnt; /* # opens for cowdevice */
332
333 /*
334 ** open file pointers
335 */
336 struct file *rdofp, *cowfp; /* open file pointers */
337 char *rdoname, *cowname; /* file names */
338
339 /*
340 ** request queue administration
341 */
342 struct request_queue *rqueue;
343 spinlock_t rqlock;
344 struct gendisk *gd;
345
346 /*
347 ** administration about read-only file
348 */
349 unsigned int numblocks; /* # blocks input file in MAPUNIT */
350 unsigned int blocksz; /* minimum unit to access this dev */
351 unsigned long fingerprint; /* fingerprint of current rdofile */
352 struct block_device *belowdev; /* block device below us */
353 struct gendisk *belowgd; /* gendisk for blk dev below us */
354 struct request_queue *belowq; /* req. queue of blk dev below us */
355
356 /*
357 ** bitmap administration to register which blocks are modified
358 */
359 long int mapsize; /* total size of bitmap (bytes) */
360 long int mapremain; /* remaining bytes in last bitmap */
361 int mapcount; /* number of bitmaps in use */
362 char **mapcache; /* area with pointers to bitmaps */
363
364 char *iobuf; /* databuffer of MAPUNIT bytes */
365 struct cowhead *cowhead; /* buffer containing cowhead */
366
367 /*
368 ** administration for interface with the kernel-thread
369 */
370 int pid; /* pid==0: no thread available */
371 struct request *req; /* request to be handled now */
372 wait_queue_head_t waitq; /* wait-Q: thread waits for work */
373 char closedown; /* boolean: thread exit required */
374 char qfilled; /* boolean: I/O request pending */
375 char iobusy; /* boolean: req under treatment */
376
377 /*
378 ** administration to keep track of free space in cowfile filesystem
379 */
380 unsigned long blksize; /* block size of fs (bytes) */
381 unsigned long blktotal; /* recent total space in fs (blocks) */
382 unsigned long blkavail; /* recent free space in fs (blocks) */
383
384 wait_queue_head_t watchq; /* wait-Q: watcher awaits threshold */
385 unsigned long watchthresh; /* threshold of watcher (blocks) */
386
387 /*
388 ** statistical counters
389 */
390 unsigned long rdoreads; /* number of read-actions rdo */
391 unsigned long cowreads; /* number of read-actions cow */
392 unsigned long cowwrites; /* number of write-actions */
393 unsigned long nrcowblocks; /* number of blocks in use on cow */
394};
395
396static struct cowloop_device **cowdevall; /* ptr to ptrs to all cowdevices */
397static struct semaphore cowdevlock; /* generic lock for cowdevs */
398
399static struct gendisk *cowctlgd; /* gendisk control channel */
400static spinlock_t cowctlrqlock; /* for req.q. of ctrl. channel */
401
402/*
403** private directory /proc/cow
404*/
405struct proc_dir_entry *cowlo_procdir;
406
407/*
408** function prototypes
409*/
410static long int cowlo_do_request (struct request *req);
411static void cowlo_sync (void);
412static int cowlo_checkio (struct cowloop_device *, int, loff_t);
413static int cowlo_readmix (struct cowloop_device *, void *, int, loff_t);
414static int cowlo_writemix (struct cowloop_device *, void *, int, loff_t);
415static long int cowlo_readrdo (struct cowloop_device *, void *, int, loff_t);
416static long int cowlo_readcow (struct cowloop_device *, void *, int, loff_t);
417static long int cowlo_readcowraw (struct cowloop_device *, void *, int, loff_t);
418static long int cowlo_writecow (struct cowloop_device *, void *, int, loff_t);
419static long int cowlo_writecowraw(struct cowloop_device *, void *, int, loff_t);
420static int cowlo_ioctl (struct block_device *, fmode_t,
421 unsigned int, unsigned long);
422static int cowlo_makepair (struct cowpair __user *);
423static int cowlo_removepair (unsigned long __user *);
424static int cowlo_watch (struct cowpair __user *);
425static int cowlo_cowctl (unsigned long __user *, int);
426static int cowlo_openpair (char *, char *, int, int);
427static int cowlo_closepair (struct cowloop_device *);
428static int cowlo_openrdo (struct cowloop_device *, char *);
429static int cowlo_opencow (struct cowloop_device *, char *, int);
430static void cowlo_undo_openrdo(struct cowloop_device *);
431static void cowlo_undo_opencow(struct cowloop_device *);
432
433/*****************************************************************************/
434/* System call handling */
435/*****************************************************************************/
436
437/*
438** handle system call open()/mount()
439**
440** returns:
441** 0 - okay
442** < 0 - error value
443*/
444static int cowlo_open(struct block_device *bdev, fmode_t mode)
445{
446 struct inode *inode = bdev->bd_inode;
447
448 if (!inode)
449 return -EINVAL;
450
451 if (imajor(inode) != COWMAJOR) {
452 printk(KERN_WARNING
453 "cowloop - unexpected major %d\n", imajor(inode));
454 return -ENODEV;
455 }
456
457 switch (iminor(inode)) {
458 case COWCTL:
459 DEBUGP(DCOW"cowloop - open %d control\n", COWCTL);
460 break;
461
462 default:
463 DEBUGP(DCOW"cowloop - open minor %d\n", iminor(inode));
464
465 if ( iminor(inode) >= maxcows )
466 return -ENODEV;
467
468 if ( !((cowdevall[iminor(inode)])->state & COWDEVOPEN) )
469 return -ENODEV;
470
471 (cowdevall[iminor(inode)])->opencnt++;
472 }
473
474 return 0;
475}
476
477/*
478** handle system call close()/umount()
479**
480** returns:
481** 0 - okay
482*/
483static int cowlo_release(struct gendisk *gd, fmode_t mode)
484{
485 struct block_device *bdev;
486 struct inode *inode;
487
488 bdev = bdget_disk(gd, 0);
489 inode = bdev->bd_inode;
490 if (!inode)
491 return 0;
492
493 DEBUGP(DCOW"cowloop - release (close) minor %d\n", iminor(inode));
494
495 if ( iminor(inode) != COWCTL)
496 (cowdevall[iminor(inode)])->opencnt--;
497
498 return 0;
499}
500
501/*
502** handle system call ioctl()
503**
504** returns:
505** 0 - okay
506** < 0 - error value
507*/
508static int cowlo_ioctl(struct block_device *bdev, fmode_t mode,
509 unsigned int cmd, unsigned long arg)
510{
511 struct hd_geometry geo;
512 struct inode *inode = bdev->bd_inode;
513
514 DEBUGP(DCOW "cowloop - ioctl cmd %x\n", cmd);
515
516 switch ( iminor(inode) ) {
517
518 /*
519 ** allowed via control device only
520 */
521 case COWCTL:
522 switch (cmd) {
523 /*
524 ** write all bitmap chunks and cowheaders to cowfiles
525 */
526 case COWSYNC:
527 down(&cowdevlock);
528 cowlo_sync();
529 up(&cowdevlock);
530 return 0;
531
532 /*
533 ** open a new cowdevice (pair of rdofile/cowfile)
534 */
535 case COWMKPAIR:
536 return cowlo_makepair((void __user *)arg);
537
538 /*
539 ** close a cowdevice (pair of rdofile/cowfile)
540 */
541 case COWRMPAIR:
542 return cowlo_removepair((void __user *)arg);
543
544 /*
545 ** watch free space of filesystem containing cowfile
546 */
547 case COWWATCH:
548 return cowlo_watch((void __user *)arg);
549
550 /*
551 ** close cowfile for active device
552 */
553 case COWCLOSE:
554 return cowlo_cowctl((void __user *)arg, COWCLOSE);
555
556 /*
557 ** reopen cowfile read-only for active device
558 */
559 case COWRDOPEN:
560 return cowlo_cowctl((void __user *)arg, COWRDOPEN);
561
562 default:
563 return -EINVAL;
564 } /* end of switch on command */
565
566 /*
567 ** allowed for any other cowdevice
568 */
569 default:
570 switch (cmd) {
571 /*
572 ** HDIO_GETGEO must be supported for fdisk, etc
573 */
574 case HDIO_GETGEO:
575 geo.cylinders = 0;
576 geo.heads = 0;
577 geo.sectors = 0;
578
579 if (copy_to_user((void __user *)arg, &geo, sizeof geo))
580 return -EFAULT;
581 return 0;
582
583 default:
584 return -EINVAL;
585 } /* end of switch on ioctl-cmd code parameter */
586 } /* end of switch on minor number */
587}
588
589static struct block_device_operations cowlo_fops =
590{
591 .owner = THIS_MODULE,
592 .open = cowlo_open, /* called upon open */
593 .release = cowlo_release, /* called upon close */
594 .ioctl = cowlo_ioctl, /* called upon ioctl */
595};
596
597/*
598** handle ioctl-command COWMKPAIR:
599** open a new cowdevice (pair of rdofile/cowfile) on-the-fly
600**
601** returns:
602** 0 - okay
603** < 0 - error value
604*/
605static int
606cowlo_makepair(struct cowpair __user *arg)
607{
608 int i, rv=0;
609 struct cowpair cowpair;
610 unsigned char *cowpath;
611 unsigned char *rdopath;
612
613 /*
614 ** retrieve info about pathnames
615 */
616 if ( copy_from_user(&cowpair, arg, sizeof cowpair) )
617 return -EFAULT;
618
619 if ( (MAJOR(cowpair.device) != COWMAJOR) && (cowpair.device != ANYDEV) )
620 return -EINVAL;
621
622 if ( (MINOR(cowpair.device) >= maxcows) && (cowpair.device != ANYDEV) )
623 return -EINVAL;
624
625 /*
626 ** retrieve pathname strings
627 */
628 if ( (cowpair.cowflen > PATH_MAX) || (cowpair.rdoflen > PATH_MAX) )
629 return -ENAMETOOLONG;
630
631 if ( !(cowpath = kmalloc(cowpair.cowflen+1, GFP_KERNEL)) )
632 return -ENOMEM;
633
634 if ( copy_from_user(cowpath, (void __user *)cowpair.cowfile,
635 cowpair.cowflen) ) {
636 kfree(cowpath);
637 return -EFAULT;
638 }
639 *(cowpath+cowpair.cowflen) = 0;
640
641 if ( !(rdopath = kmalloc(cowpair.rdoflen+1, GFP_KERNEL)) ) {
642 kfree(cowpath);
643 return -ENOMEM;
644 }
645
646 if ( copy_from_user(rdopath, (void __user *)cowpair.rdofile,
647 cowpair.rdoflen) ) {
648 kfree(rdopath);
649 kfree(cowpath);
650 return -EFAULT;
651 }
652 *(rdopath+cowpair.rdoflen) = 0;
653
654 /*
655 ** open new cowdevice
656 */
657 if ( cowpair.device == ANYDEV) {
658 /*
659 ** search first unused minor
660 */
661 for (i=0, rv=-EBUSY; i < maxcows; i++) {
662 if ( !((cowdevall[i])->state & COWDEVOPEN) ) {
663 rv = cowlo_openpair(rdopath, cowpath, 0, i);
664 break;
665 }
666 }
667
668 if (rv) { /* open failed? */
669 kfree(rdopath);
670 kfree(cowpath);
671 return rv;
672 }
673
674 /*
675 ** return newly allocated cowdevice to user space
676 */
677 cowpair.device = MKDEV(COWMAJOR, i);
678
679 if ( copy_to_user(arg, &cowpair, sizeof cowpair)) {
680 kfree(rdopath);
681 kfree(cowpath);
682 return -EFAULT;
683 }
684 } else { /* specific minor requested */
685 if ( (rv = cowlo_openpair(rdopath, cowpath, 0,
686 MINOR(cowpair.device)))) {
687 kfree(rdopath);
688 kfree(cowpath);
689 return rv;
690 }
691 }
692
693 return 0;
694}
695
696/*
697** handle ioctl-command COWRMPAIR:
698** deactivate an existing cowdevice (pair of rdofile/cowfile) on-the-fly
699**
700** returns:
701** 0 - okay
702** < 0 - error value
703*/
704static int
705cowlo_removepair(unsigned long __user *arg)
706{
707 unsigned long cowdevice;
708 struct cowloop_device *cowdev;
709
710 /*
711 ** retrieve info about device to be removed
712 */
713 if ( copy_from_user(&cowdevice, arg, sizeof cowdevice))
714 return -EFAULT;
715
716 /*
717 ** verify major-minor number
718 */
719 if ( MAJOR(cowdevice) != COWMAJOR)
720 return -EINVAL;
721
722 if ( MINOR(cowdevice) >= maxcows)
723 return -EINVAL;
724
725 cowdev = cowdevall[MINOR(cowdevice)];
726
727 if ( !(cowdev->state & COWDEVOPEN) )
728 return -ENODEV;
729
730 /*
731 ** synchronize bitmaps and close cowdevice
732 */
733 if (cowdev->state & COWRWCOWOPEN) {
734 down(&cowdevlock);
735 cowlo_sync();
736 up(&cowdevlock);
737 }
738
739 return cowlo_closepair(cowdev);
740}
741
742/*
743** handle ioctl-command COWWATCH:
744** watch the free space of the filesystem containing a cowfile
745** of an open cowdevice
746**
747** returns:
748** 0 - okay
749** < 0 - error value
750*/
751static int
752cowlo_watch(struct cowpair __user *arg)
753{
754 struct cowloop_device *cowdev;
755 struct cowwatch cowwatch;
756
757 /*
758 ** retrieve structure holding info
759 */
760 if ( copy_from_user(&cowwatch, arg, sizeof cowwatch))
761 return -EFAULT;
762
763 /*
764 ** verify if cowdevice exists and is currently open
765 */
766 if ( MINOR(cowwatch.device) >= maxcows)
767 return -EINVAL;
768
769 cowdev = cowdevall[MINOR(cowwatch.device)];
770
771 if ( !(cowdev->state & COWDEVOPEN) )
772 return -ENODEV;
773
774 /*
775 ** if the WATCHWAIT-option is set, wait until the indicated
776 ** threshold is reached (only one waiter allowed)
777 */
778 if (cowwatch.flags & WATCHWAIT) {
779 /*
780 ** check if already another waiter active
781 ** for this cowdevice
782 */
783 if (cowdev->state & COWWATCHDOG)
784 return -EAGAIN;
785
786 cowdev->state |= COWWATCHDOG;
787
788 cowdev->watchthresh = (unsigned long long)
789 cowwatch.threshold /
790 (cowdev->blksize / 1024);
791
792 if (wait_event_interruptible(cowdev->watchq,
793 cowdev->watchthresh >= cowdev->blkavail)) {
794 cowdev->state &= ~COWWATCHDOG;
795 return EINTR;
796 }
797
798 cowdev->state &= ~COWWATCHDOG;
799 }
800
801 cowwatch.totalkb = (unsigned long long)cowdev->blktotal *
802 cowdev->blksize / 1024;
803 cowwatch.availkb = (unsigned long long)cowdev->blkavail *
804 cowdev->blksize / 1024;
805
806 if ( copy_to_user(arg, &cowwatch, sizeof cowwatch))
807 return -EFAULT;
808
809 return 0;
810}
811
812/*
813** handle ioctl-commands COWCLOSE and COWRDOPEN:
814** COWCLOSE - close the cowfile while the cowdevice remains open;
815** this allows an unmount of the filesystem on which
816** the cowfile resides
817** COWRDOPEN - close the cowfile and reopen it for read-only;
818** this allows a remount read-ony of the filesystem
819** on which the cowfile resides
820**
821** returns:
822** 0 - okay
823** < 0 - error value
824*/
825static int
826cowlo_cowctl(unsigned long __user *arg, int cmd)
827{
828 struct cowloop_device *cowdev;
829 unsigned long cowdevice;
830
831 /*
832 ** retrieve info about device to be removed
833 */
834 if ( copy_from_user(&cowdevice, arg, sizeof cowdevice))
835 return -EFAULT;
836
837 /*
838 ** verify major-minor number
839 */
840 if ( MAJOR(cowdevice) != COWMAJOR)
841 return -EINVAL;
842
843 if ( MINOR(cowdevice) >= maxcows)
844 return -EINVAL;
845
846 cowdev = cowdevall[MINOR(cowdevice)];
847
848 if ( !(cowdev->state & COWDEVOPEN) )
849 return -ENODEV;
850
851 /*
852 ** synchronize bitmaps and close cowfile
853 */
854 if (cowdev->state & COWRWCOWOPEN) {
855 down(&cowdevlock);
856 cowlo_sync();
857 up(&cowdevlock);
858 }
859
860 /*
861 ** handle specific ioctl-command
862 */
863 switch (cmd) {
864 case COWRDOPEN:
865 /*
866 ** if the cowfile is still opened read-write
867 */
868 if (cowdev->state & COWRWCOWOPEN) {
869 /*
870 ** close the cowfile
871 */
872 if (cowdev->cowfp)
873 filp_close(cowdev->cowfp, 0);
874
875 cowdev->state &= ~COWRWCOWOPEN;
876
877 /*
878 ** open again for read-only
879 */
880 cowdev->cowfp = filp_open(cowdev->cowname,
881 O_RDONLY|O_LARGEFILE, 0600);
882
883 if ( (cowdev->cowfp == NULL) || IS_ERR(cowdev->cowfp) ) {
884 printk(KERN_ERR
885 "cowloop - failed to reopen cowfile %s\n",
886 cowdev->cowname);
887 return -EINVAL;
888 }
889
890 /*
891 ** mark cowfile open for read-only
892 */
893 cowdev->state |= COWRDCOWOPEN;
894 } else {
895 return -EINVAL;
896 }
897 break;
898
899 case COWCLOSE:
900 /*
901 ** if the cowfile is still open
902 */
903 if (cowdev->state & COWCOWOPEN) {
904 /*
905 ** close the cowfile
906 */
907 if (cowdev->cowfp)
908 filp_close(cowdev->cowfp, 0);
909
910 cowdev->state &= ~COWCOWOPEN;
911 }
912 }
913
914 return 0;
915}
916
917
918/*****************************************************************************/
919/* Handling of I/O-requests for a cowdevice */
920/*****************************************************************************/
921
922/*
923** function to be called by core-kernel to handle the I/O-requests
924** in the queue
925*/
926static void cowlo_request(struct request_queue *q)
927{
928 struct request *req;
929 struct cowloop_device *cowdev;
930
931 DEBUGP(DCOW "cowloop - request function called....\n");
932
933 while((req = blk_peek_request(q)) != NULL) {
934 DEBUGP(DCOW "cowloop - got next request\n");
935
936 if (! blk_fs_request(req)) {
937 /* this is not a normal file system request */
938 __blk_end_request_cur(req, -EIO);
939 continue;
940 }
941 cowdev = req->rq_disk->private_data;
942
943 if (cowdev->iobusy)
944 return;
945 else
946 cowdev->iobusy = 1;
947
948 /*
949 ** when no kernel-thread is available, the request will
950 ** produce an I/O-error
951 */
952 if (!cowdev->pid) {
953 printk(KERN_ERR"cowloop - no thread available\n");
954 __blk_end_request_cur(req, -EIO); /* request failed */
955 cowdev->iobusy = 0;
956 continue;
957 }
958
959 /*
960 ** handle I/O-request in the context of the kernel-thread
961 */
962 cowdev->req = req;
963 cowdev->qfilled = 1;
964
965 wake_up_interruptible_sync(&cowdev->waitq);
966
967 /*
968 ** get out of this function now while the I/O-request is
969 ** under treatment of the kernel-thread; this function
970 ** will be called again after the current I/O-request has
971 ** been finished by the thread
972 */
973 return;
974 }
975}
976
977/*
978** daemon-process (kernel-thread) executes this function
979*/
980static int
981cowlo_daemon(struct cowloop_device *cowdev)
982{
983 int rv;
984 int minor;
985 char myname[16];
986
987 for (minor = 0; minor < maxcows; minor++) {
988 if (cowdev == cowdevall[minor]) break;
989 }
990 sprintf(myname, "cowloopd%d", minor);
991
992 daemonize(myname);
993
994 while (!cowdev->closedown) {
995 /*
996 ** sleep while waiting for an I/O request;
997 ** note that no non-interruptible wait has been used
998 ** because the non-interruptible version of
999 ** a *synchronous* wake_up does not exist (any more)
1000 */
1001 if (wait_event_interruptible(cowdev->waitq, cowdev->qfilled)){
1002 flush_signals(current); /* ignore signal-based wakeup */
1003 continue;
1004 }
1005
1006 if (cowdev->closedown) /* module will be unloaded ? */{
1007 cowdev->pid = 0;
1008 return 0;
1009 }
1010
1011 /*
1012 ** woken up by the I/O-request handler: treat requested I/O
1013 */
1014 cowdev->qfilled = 0;
1015
1016 rv = cowlo_do_request(cowdev->req);
1017
1018 /*
1019 ** reacquire the queue-spinlock for manipulating
1020 ** the request-queue and dequeue the request
1021 */
1022 spin_lock_irq(&cowdev->rqlock);
1023
1024 __blk_end_request_cur(cowdev->req, rv);
1025 cowdev->iobusy = 0;
1026
1027 /*
1028 ** initiate the next request from the queue
1029 */
1030 cowlo_request(cowdev->rqueue);
1031
1032 spin_unlock_irq(&cowdev->rqlock);
1033 }
1034 return 0;
1035}
1036
1037/*
1038** function to be called in the context of the kernel thread
1039** to handle the queued I/O-requests
1040**
1041** returns:
1042** 0 - fail
1043** 1 - success
1044*/
1045static long int
1046cowlo_do_request(struct request *req)
1047{
1048 unsigned long len;
1049 long int rv;
1050 loff_t offset;
1051 struct cowloop_device *cowdev = req->rq_disk->private_data;
1052
1053 /*
1054 ** calculate some variables which are needed later on
1055 */
1056 len = blk_rq_cur_sectors(req) << 9;
1057 offset = (loff_t) blk_rq_pos(req) << 9;
1058
1059 DEBUGP(DCOW"cowloop - req cmd=%d offset=%lld len=%lu addr=%p\n",
1060 *(req->cmd), offset, len, req->buffer);
1061
1062 /*
1063 ** handle READ- or WRITE-request
1064 */
1065 switch (rq_data_dir(req)) {
1066 /**********************************************************/
1067 case READ:
1068 switch ( cowlo_checkio(cowdev, len, offset) ) {
1069 case ALLCOW:
1070 rv = cowlo_readcow(cowdev, req->buffer, len, offset);
1071 break;
1072
1073 case ALLRDO:
1074 rv = cowlo_readrdo(cowdev, req->buffer, len, offset);
1075 break;
1076
1077 case MIXEDUP:
1078 rv = cowlo_readmix(cowdev, req->buffer, len, offset);
1079 break;
1080
1081 default:
1082 rv = 0; /* never happens */
1083 }
1084 break;
1085
1086 /**********************************************************/
1087 case WRITE:
1088 switch ( cowlo_checkio(cowdev, len, offset) ) {
1089 case ALLCOW:
1090 /*
1091 ** straight-forward write will do...
1092 */
1093 DEBUGP(DCOW"cowloop - write straight ");
1094
1095 rv = cowlo_writecow(cowdev, req->buffer, len, offset);
1096 break; /* from switch */
1097
1098 case ALLRDO:
1099 if ( (len & MUMASK) == 0) {
1100 DEBUGP(DCOW"cowloop - write straight ");
1101
1102 rv = cowlo_writecow(cowdev, req->buffer,
1103 len, offset);
1104 break;
1105 }
1106
1107 case MIXEDUP:
1108 rv = cowlo_writemix(cowdev, req->buffer, len, offset);
1109 break;
1110
1111 default:
1112 rv = 0; /* never happens */
1113 }
1114 break;
1115
1116 default:
1117 printk(KERN_ERR
1118 "cowloop - unrecognized command %d\n", *(req->cmd));
1119 rv = 0;
1120 }
1121
1122 return (rv <= 0 ? 0 : 1);
1123}
1124
1125/*
1126** check for a given I/O-request if all underlying blocks
1127** (with size MAPUNIT) are either in the read-only file or in
1128** the cowfile (or a combination of the two)
1129**
1130** returns:
1131** ALLRDO - all underlying blocks in rdofile
1132** ALLCOW - all underlying blocks in cowfile
1133** MIXEDUP - underlying blocks partly in rdofile and partly in cowfile
1134*/
1135static int
1136cowlo_checkio(struct cowloop_device *cowdev, int len, loff_t offset)
1137{
1138 unsigned long mapnum, bytenum, bitnum, blocknr, partlen;
1139 long int totcnt, cowcnt;
1140 char *mc;
1141
1142 /*
1143 ** notice that the requested block might cross
1144 ** a blocksize boundary while one of the concerned
1145 ** blocks resides in the read-only file and another
1146 ** one in the copy-on-write file; in that case the
1147 ** request will be broken up into pieces
1148 */
1149 if ( (len <= MAPUNIT) &&
1150 (MAPUNIT - (offset & MUMASK) <= len) ) {
1151 /*
1152 ** easy situation:
1153 ** requested data-block entirely fits within
1154 ** the mapunit used for the bitmap
1155 ** check if that block is located in rdofile or
1156 ** cowfile
1157 */
1158 blocknr = offset >> MUSHIFT;
1159
1160 mapnum = CALCMAP (blocknr);
1161 bytenum = CALCBYTE(blocknr);
1162 bitnum = CALCBIT (blocknr);
1163
1164 if (*(*(cowdev->mapcache+mapnum)+bytenum)&(1<<bitnum))
1165 return ALLCOW;
1166 else
1167 return ALLRDO;
1168 }
1169
1170 /*
1171 ** less easy situation:
1172 ** the requested data-block does not fit within the mapunit
1173 ** used for the bitmap
1174 ** check if *all* underlying blocks involved reside on the rdofile
1175 ** or the cowfile (so still no breakup required)
1176 */
1177 for (cowcnt=totcnt=0; len > 0; len-=partlen, offset+=partlen, totcnt++){
1178 /*
1179 ** calculate blocknr of involved block
1180 */
1181 blocknr = offset >> MUSHIFT;
1182
1183 /*
1184 ** calculate partial length for this transfer
1185 */
1186 partlen = MAPUNIT - (offset & MUMASK);
1187 if (partlen > len)
1188 partlen = len;
1189
1190 /*
1191 ** is this block located in the cowfile
1192 */
1193 mapnum = CALCMAP (blocknr);
1194 bytenum = CALCBYTE(blocknr);
1195 bitnum = CALCBIT (blocknr);
1196
1197 mc = *(cowdev->mapcache+mapnum);
1198
1199 if (*(mc+bytenum)&(1<<bitnum))
1200 cowcnt++;;
1201
1202 DEBUGP(DCOW
1203 "cowloop - check %lu - map %lu, byte %lu, bit %lu, "
1204 "cowcnt %ld, totcnt %ld %02x %p\n",
1205 blocknr, mapnum, bytenum, bitnum, cowcnt, totcnt,
1206 *(mc+bytenum), mc);
1207 }
1208
1209 if (cowcnt == 0) /* all involved blocks on rdofile? */
1210 return ALLRDO;
1211
1212 if (cowcnt == totcnt) /* all involved blocks on cowfile? */
1213 return ALLCOW;
1214
1215 /*
1216 ** situation somewhat more complicated:
1217 ** involved underlying blocks spread over both files
1218 */
1219 return MIXEDUP;
1220}
1221
1222/*
1223** read requested chunk partly from rdofile and partly from cowfile
1224**
1225** returns:
1226** 0 - fail
1227** 1 - success
1228*/
1229static int
1230cowlo_readmix(struct cowloop_device *cowdev, void *buf, int len, loff_t offset)
1231{
1232 unsigned long mapnum, bytenum, bitnum, blocknr, partlen;
1233 long int rv;
1234 char *mc;
1235
1236 /*
1237 ** complicated approach: breakup required of read-request
1238 */
1239 for (rv=1; len > 0; len-=partlen, buf+=partlen, offset+=partlen) {
1240 /*
1241 ** calculate blocknr of entire block
1242 */
1243 blocknr = offset >> MUSHIFT;
1244
1245 /*
1246 ** calculate partial length for this transfer
1247 */
1248 partlen = MAPUNIT - (offset & MUMASK);
1249 if (partlen > len)
1250 partlen = len;
1251
1252 /*
1253 ** is this block located in the cowfile
1254 */
1255 mapnum = CALCMAP (blocknr);
1256 bytenum = CALCBYTE(blocknr);
1257 bitnum = CALCBIT (blocknr);
1258 mc = *(cowdev->mapcache+mapnum);
1259
1260 if (*(mc+bytenum)&(1<<bitnum)) {
1261 /*
1262 ** read (partial) block from cowfile
1263 */
1264 DEBUGP(DCOW"cowloop - split read "
1265 "cow partlen=%ld off=%lld\n", partlen, offset);
1266
1267 if (cowlo_readcow(cowdev, buf, partlen, offset) <= 0)
1268 rv = 0;
1269 } else {
1270 /*
1271 ** read (partial) block from rdofile
1272 */
1273 DEBUGP(DCOW"cowloop - split read "
1274 "rdo partlen=%ld off=%lld\n", partlen, offset);
1275
1276 if (cowlo_readrdo(cowdev, buf, partlen, offset) <= 0)
1277 rv = 0;
1278 }
1279 }
1280
1281 return rv;
1282}
1283
1284/*
1285** chunk to be written to the cowfile needs pieces to be
1286** read from the rdofile
1287**
1288** returns:
1289** 0 - fail
1290** 1 - success
1291*/
1292static int
1293cowlo_writemix(struct cowloop_device *cowdev, void *buf, int len, loff_t offset)
1294{
1295 unsigned long mapnum, bytenum, bitnum, blocknr, partlen;
1296 long int rv;
1297 char *mc;
1298
1299 /*
1300 ** somewhat more complicated stuff is required:
1301 ** if the request is larger than one underlying
1302 ** block or is spread over two underlying blocks,
1303 ** split the request into pieces; if a block does not
1304 ** start at a block boundary, take care that
1305 ** surrounding data is read first (if needed),
1306 ** fit the new data in and write it as a full block
1307 */
1308 for (rv=1; len > 0; len-=partlen, buf+=partlen, offset+=partlen) {
1309 /*
1310 ** calculate partial length for this transfer
1311 */
1312 partlen = MAPUNIT - (offset & MUMASK);
1313 if (partlen > len)
1314 partlen = len;
1315
1316 /*
1317 ** calculate blocknr of entire block
1318 */
1319 blocknr = offset >> MUSHIFT;
1320
1321 /*
1322 ** has this block been written before?
1323 */
1324 mapnum = CALCMAP (blocknr);
1325 bytenum = CALCBYTE(blocknr);
1326 bitnum = CALCBIT (blocknr);
1327 mc = *(cowdev->mapcache+mapnum);
1328
1329 if (*(mc+bytenum)&(1<<bitnum)) {
1330 /*
1331 ** block has been written before;
1332 ** write transparantly to cowfile
1333 */
1334 DEBUGP(DCOW
1335 "cowloop - splitwr transp\n");
1336
1337 if (cowlo_writecow(cowdev, buf, partlen, offset) <= 0)
1338 rv = 0;
1339 } else {
1340 /*
1341 ** block has never been written before,
1342 ** so read entire block from
1343 ** read-only file first, unless
1344 ** a full block is requested to
1345 ** be written
1346 */
1347 if (partlen < MAPUNIT) {
1348 if (cowlo_readrdo(cowdev, cowdev->iobuf,
1349 MAPUNIT, (loff_t)blocknr << MUSHIFT) <= 0)
1350 rv = 0;
1351 }
1352
1353 /*
1354 ** transfer modified part into
1355 ** the block just read
1356 */
1357 memcpy(cowdev->iobuf + (offset & MUMASK), buf, partlen);
1358
1359 /*
1360 ** write entire block to cowfile
1361 */
1362 DEBUGP(DCOW"cowloop - split "
1363 "partlen=%ld off=%lld\n",
1364 partlen, (loff_t)blocknr << MUSHIFT);
1365
1366 if (cowlo_writecow(cowdev, cowdev->iobuf, MAPUNIT,
1367 (loff_t)blocknr << MUSHIFT) <= 0)
1368 rv = 0;
1369 }
1370 }
1371
1372 return rv;
1373}
1374
1375/*****************************************************************************/
1376/* I/O-support for read-only file and copy-on-write file */
1377/*****************************************************************************/
1378
1379/*
1380** read data from the read-only file
1381**
1382** return-value: similar to user-mode read
1383*/
1384static long int
1385cowlo_readrdo(struct cowloop_device *cowdev, void *buf, int len, loff_t offset)
1386{
1387 long int rv;
1388 mm_segment_t old_fs;
1389 loff_t saveoffset = offset;
1390
1391 DEBUGP(DCOW"cowloop - readrdo called\n");
1392
1393 old_fs = get_fs();
1394 set_fs( get_ds() );
1395 rv = cowdev->rdofp->f_op->read(cowdev->rdofp, buf, len, &offset);
1396 set_fs(old_fs);
1397
1398 if (rv < len) {
1399 printk(KERN_WARNING "cowloop - read-failure %ld on rdofile"
1400 "- offset=%lld len=%d\n",
1401 rv, saveoffset, len);
1402 }
1403
1404 cowdev->rdoreads++;
1405 return rv;
1406}
1407
1408/*
1409** read cowfile from a modified offset, i.e. skipping the bitmap and cowhead
1410**
1411** return-value: similar to user-mode read
1412*/
1413static long int
1414cowlo_readcow(struct cowloop_device *cowdev, void *buf, int len, loff_t offset)
1415{
1416 DEBUGP(DCOW"cowloop - readcow called\n");
1417
1418 offset += cowdev->cowhead->doffset;
1419
1420 return cowlo_readcowraw(cowdev, buf, len, offset);
1421}
1422
1423/*
1424** read cowfile from an absolute offset
1425**
1426** return-value: similar to user-mode read
1427*/
1428static long int
1429cowlo_readcowraw(struct cowloop_device *cowdev,
1430 void *buf, int len, loff_t offset)
1431{
1432 long int rv;
1433 mm_segment_t old_fs;
1434 loff_t saveoffset = offset;
1435
1436 DEBUGP(DCOW"cowloop - readcowraw called\n");
1437
1438 /*
1439 ** be sure that cowfile is opened for read-write
1440 */
1441 if ( !(cowdev->state & COWCOWOPEN) ) {
1442 printk(KERN_WARNING
1443 "cowloop - read request from cowfile refused\n");
1444
1445 return -EBADF;
1446 }
1447
1448 /*
1449 ** issue low level read
1450 */
1451 old_fs = get_fs();
1452 set_fs( get_ds() );
1453 rv = cowdev->cowfp->f_op->read(cowdev->cowfp, buf, len, &offset);
1454 set_fs(old_fs);
1455
1456 if (rv < len) {
1457 printk(KERN_WARNING
1458 "cowloop - read-failure %ld on cowfile"
1459 "- offset=%lld len=%d\n", rv, saveoffset, len);
1460 }
1461
1462 cowdev->cowreads++;
1463 return rv;
1464}
1465
1466/*
1467** write cowfile from a modified offset, i.e. skipping the bitmap and cowhead
1468**
1469** if a block is written for the first time while its contents consists
1470** of binary zeroes only, the concerning bitmap is flushed to the cowfile
1471**
1472** return-value: similar to user-mode write
1473*/
1474static long int
1475cowlo_writecow(struct cowloop_device *cowdev, void *buf, int len, loff_t offset)
1476{
1477 long int rv;
1478 unsigned long mapnum=0, mapbyte=0, mapbit=0, cowblock=0, partlen;
1479 char *tmpptr, *mapptr = NULL;
1480 loff_t tmpoffset, mapoffset = 0;
1481
1482 DEBUGP(DCOW"cowloop - writecow called\n");
1483
1484 /*
1485 ** be sure that cowfile is opened for read-write
1486 */
1487 if ( !(cowdev->state & COWRWCOWOPEN) ) {
1488 printk(KERN_WARNING
1489 "cowloop - Write request to cowfile refused\n");
1490
1491 return -EBADF;
1492 }
1493
1494 /*
1495 ** write the entire block to the cowfile
1496 */
1497 tmpoffset = offset + cowdev->cowhead->doffset;
1498
1499 rv = cowlo_writecowraw(cowdev, buf, len, tmpoffset);
1500
1501 /*
1502 ** verify if enough space available on filesystem holding
1503 ** the cowfile
1504 ** - when the last write failed (might be caused by lack of space)
1505 ** - when a watcher is active (to react adequatly)
1506 ** - when the previous check indicated fs was almost full
1507 ** - with regular intervals
1508 */
1509 if ( (rv <= 0) ||
1510 (cowdev->state & COWWATCHDOG) ||
1511 (cowdev->blkavail / 2 < SPCDFLINTVL) ||
1512 (cowdev->cowwrites % SPCDFLINTVL == 0) ) {
1513 struct kstatfs ks;
1514
1515 if (vfs_statfs(cowdev->cowfp->f_dentry, &ks)==0){
1516 if (ks.f_bavail <= SPCMINBLK) {
1517 switch (ks.f_bavail) {
1518 case 0:
1519 case 1:
1520 case 2:
1521 case 3:
1522 printk(KERN_ALERT
1523 "cowloop - "
1524 "ALERT: cowfile full!\n");
1525 break;
1526
1527 default:
1528 printk(KERN_WARNING
1529 "cowloop - cowfile almost "
1530 "full (only %llu Kb free)\n",
1531 (unsigned long long)
1532 ks.f_bsize * ks.f_bavail /1024);
1533 }
1534 }
1535
1536 cowdev->blktotal = ks.f_blocks;
1537 cowdev->blkavail = ks.f_bavail;
1538
1539 /*
1540 ** wakeup watcher if threshold has been reached
1541 */
1542 if ( (cowdev->state & COWWATCHDOG) &&
1543 (cowdev->watchthresh >= cowdev->blkavail) ) {
1544 wake_up_interruptible(&cowdev->watchq);
1545 }
1546 }
1547 }
1548
1549 if (rv <= 0)
1550 return rv;
1551
1552 DEBUGP(DCOW"cowloop - block written\n");
1553
1554 /*
1555 ** check if block(s) is/are written to the cowfile
1556 ** for the first time; if so, adapt the bitmap
1557 */
1558 for (; len > 0; len-=partlen, offset+=partlen, buf+=partlen) {
1559 /*
1560 ** calculate partial length for this transfer
1561 */
1562 partlen = MAPUNIT - (offset & MUMASK);
1563 if (partlen > len)
1564 partlen = len;
1565
1566 /*
1567 ** calculate bitnr of written chunk of cowblock
1568 */
1569 cowblock = offset >> MUSHIFT;
1570
1571 mapnum = CALCMAP (cowblock);
1572 mapbyte = CALCBYTE(cowblock);
1573 mapbit = CALCBIT (cowblock);
1574
1575 if (*(*(cowdev->mapcache+mapnum)+mapbyte) & (1<<mapbit))
1576 continue; /* already written before */
1577
1578 /*
1579 ** if the block is written for the first time,
1580 ** the corresponding bit should be set in the bitmap
1581 */
1582 *(*(cowdev->mapcache+mapnum)+mapbyte) |= (1<<mapbit);
1583
1584 cowdev->nrcowblocks++;
1585
1586 DEBUGP(DCOW"cowloop - bitupdate blk=%ld map=%ld "
1587 "byte=%ld bit=%ld\n",
1588 cowblock, mapnum, mapbyte, mapbit);
1589
1590 /*
1591 ** check if the cowhead in the cowfile is currently
1592 ** marked clean; if so, mark it dirty and flush it
1593 */
1594 if ( !(cowdev->cowhead->flags &= COWDIRTY)) {
1595 cowdev->cowhead->flags |= COWDIRTY;
1596
1597 cowlo_writecowraw(cowdev, cowdev->cowhead,
1598 MAPUNIT, (loff_t)0);
1599 }
1600
1601 /*
1602 ** if the written datablock contained binary zeroes,
1603 ** the bitmap block should be marked to be flushed to disk
1604 ** (blocks containing all zeroes cannot be recovered by
1605 ** the cowrepair-program later on if cowloop is not properly
1606 ** removed via rmmod)
1607 */
1608 if ( memcmp(buf, allzeroes, partlen) ) /* not all zeroes? */
1609 continue; /* no flush needed */
1610
1611 /*
1612 ** calculate positions of bitmap block to be flushed
1613 ** - pointer of bitmap block in memory
1614 ** - offset of bitmap block in cowfile
1615 */
1616 tmpptr = *(cowdev->mapcache+mapnum) + (mapbyte & (~MUMASK));
1617 tmpoffset = (loff_t) MAPUNIT + mapnum * MAPCHUNKSZ +
1618 (mapbyte & (~MUMASK));
1619
1620 /*
1621 ** flush a bitmap block at the moment that all bits have
1622 ** been set in that block, i.e. at the moment that we
1623 ** switch to another bitmap block
1624 */
1625 if ( (mapoffset != 0) && (mapoffset != tmpoffset) ) {
1626 if (cowlo_writecowraw(cowdev, mapptr, MAPUNIT,
1627 mapoffset) < 0) {
1628 printk(KERN_WARNING
1629 "cowloop - write-failure on bitmap - "
1630 "blk=%ld map=%ld byte=%ld bit=%ld\n",
1631 cowblock, mapnum, mapbyte, mapbit);
1632 }
1633
1634 DEBUGP(DCOW"cowloop - bitmap blk written %lld\n",
1635 mapoffset);
1636 }
1637
1638 /*
1639 ** remember offset in cowfile and offset in memory
1640 ** for bitmap to be flushed; flushing will be done
1641 ** as soon as all updates in this bitmap block have
1642 ** been done
1643 */
1644 mapoffset = tmpoffset;
1645 mapptr = tmpptr;
1646 }
1647
1648 /*
1649 ** any new block written containing binary zeroes?
1650 */
1651 if (mapoffset) {
1652 if (cowlo_writecowraw(cowdev, mapptr, MAPUNIT, mapoffset) < 0) {
1653 printk(KERN_WARNING
1654 "cowloop - write-failure on bitmap - "
1655 "blk=%ld map=%ld byte=%ld bit=%ld\n",
1656 cowblock, mapnum, mapbyte, mapbit);
1657 }
1658
1659 DEBUGP(DCOW"cowloop - bitmap block written %lld\n", mapoffset);
1660 }
1661
1662 return rv;
1663}
1664
1665/*
1666** write cowfile from an absolute offset
1667**
1668** return-value: similar to user-mode write
1669*/
1670static long int
1671cowlo_writecowraw(struct cowloop_device *cowdev,
1672 void *buf, int len, loff_t offset)
1673{
1674 long int rv;
1675 mm_segment_t old_fs;
1676 loff_t saveoffset = offset;
1677
1678 DEBUGP(DCOW"cowloop - writecowraw called\n");
1679
1680 /*
1681 ** be sure that cowfile is opened for read-write
1682 */
1683 if ( !(cowdev->state & COWRWCOWOPEN) ) {
1684 printk(KERN_WARNING
1685 "cowloop - write request to cowfile refused\n");
1686
1687 return -EBADF;
1688 }
1689
1690 /*
1691 ** issue low level write
1692 */
1693 old_fs = get_fs();
1694 set_fs( get_ds() );
1695 rv = cowdev->cowfp->f_op->write(cowdev->cowfp, buf, len, &offset);
1696 set_fs(old_fs);
1697
1698 if (rv < len) {
1699 printk(KERN_WARNING
1700 "cowloop - write-failure %ld on cowfile"
1701 "- offset=%lld len=%d\n", rv, saveoffset, len);
1702 }
1703
1704 cowdev->cowwrites++;
1705 return rv;
1706}
1707
1708
1709/*
1710** readproc-function: called when the corresponding /proc-file is read
1711*/
1712static int
1713cowlo_readproc(char *buf, char **start, off_t pos, int cnt, int *eof, void *p)
1714{
1715 struct cowloop_device *cowdev = p;
1716
1717 revision[sizeof revision - 3] = '\0';
1718
1719 return sprintf(buf,
1720 " cowloop version: %9s\n\n"
1721 " device state: %s%s%s%s\n"
1722 " number of opens: %9d\n"
1723 " pid of thread: %9d\n\n"
1724 " read-only file: %9s\n"
1725 " rdoreads: %9lu\n\n"
1726 "copy-on-write file: %9s\n"
1727 " state cowfile: %9s\n"
1728 " bitmap-blocks: %9lu (of %d bytes)\n"
1729 " cowblocks in use: %9lu (of %d bytes)\n"
1730 " cowreads: %9lu\n"
1731 " cowwrites: %9lu\n",
1732 &revision[11],
1733
1734 cowdev->state & COWDEVOPEN ? "devopen " : "",
1735 cowdev->state & COWRWCOWOPEN ? "cowopenrw " : "",
1736 cowdev->state & COWRDCOWOPEN ? "cowopenro " : "",
1737 cowdev->state & COWWATCHDOG ? "watchdog " : "",
1738
1739 cowdev->opencnt,
1740 cowdev->pid,
1741 cowdev->rdoname,
1742 cowdev->rdoreads,
1743 cowdev->cowname,
1744 cowdev->cowhead->flags & COWDIRTY ? "dirty":"clean",
1745 cowdev->mapsize >> MUSHIFT, MAPUNIT,
1746 cowdev->nrcowblocks, MAPUNIT,
1747 cowdev->cowreads,
1748 cowdev->cowwrites);
1749}
1750
1751/*****************************************************************************/
1752/* Setup and destroy cowdevices */
1753/*****************************************************************************/
1754
1755/*
1756** open and prepare a cowdevice (rdofile and cowfile) and allocate bitmaps
1757**
1758** returns:
1759** 0 - okay
1760** < 0 - error value
1761*/
1762static int
1763cowlo_openpair(char *rdof, char *cowf, int autorecover, int minor)
1764{
1765 long int rv;
1766 struct cowloop_device *cowdev = cowdevall[minor];
1767 struct kstatfs ks;
1768
1769 down(&cowdevlock);
1770
1771 /*
1772 ** requested device exists?
1773 */
1774 if (minor >= maxcows) {
1775 up(&cowdevlock);
1776 return -ENODEV;
1777 }
1778
1779 /*
1780 ** requested device already assigned to cowdevice?
1781 */
1782 if (cowdev->state & COWDEVOPEN) {
1783 up(&cowdevlock);
1784 return -EBUSY;
1785 }
1786
1787 /*
1788 ** initialize administration
1789 */
1790 memset(cowdev, 0, sizeof *cowdev);
1791
1792 spin_lock_init (&cowdev->rqlock);
1793 init_waitqueue_head(&cowdev->waitq);
1794 init_waitqueue_head(&cowdev->watchq);
1795
1796 /*
1797 ** open the read-only file
1798 */
1799 DEBUGP(DCOW"cowloop - call openrdo....\n");
1800
1801 if ( (rv = cowlo_openrdo(cowdev, rdof)) ) {
1802 cowlo_undo_openrdo(cowdev);
1803 up(&cowdevlock);
1804 return rv;
1805 }
1806
1807 /*
1808 ** open the cowfile
1809 */
1810 DEBUGP(DCOW"cowloop - call opencow....\n");
1811
1812 if ( (rv = cowlo_opencow(cowdev, cowf, autorecover)) ) {
1813 cowlo_undo_openrdo(cowdev);
1814 cowlo_undo_opencow(cowdev);
1815 up(&cowdevlock);
1816 return rv;
1817 }
1818
1819 /*
1820 ** administer total and available size of filesystem holding cowfile
1821 */
1822 if (vfs_statfs(cowdev->cowfp->f_dentry, &ks)==0) {
1823 cowdev->blksize = ks.f_bsize;
1824 cowdev->blktotal = ks.f_blocks;
1825 cowdev->blkavail = ks.f_bavail;
1826 } else {
1827 cowdev->blksize = 1024; /* avoid division by zero */
1828 }
1829
1830 /*
1831 ** flush the (recovered) bitmaps and cowhead to the cowfile
1832 */
1833 DEBUGP(DCOW"cowloop - call cowsync....\n");
1834
1835 cowlo_sync();
1836
1837 /*
1838 ** allocate gendisk for the cow device
1839 */
1840 DEBUGP(DCOW"cowloop - alloc disk....\n");
1841
1842 if ((cowdev->gd = alloc_disk(1)) == NULL) {
1843 printk(KERN_WARNING
1844 "cowloop - unable to alloc_disk for cowloop\n");
1845
1846 cowlo_undo_openrdo(cowdev);
1847 cowlo_undo_opencow(cowdev);
1848 up(&cowdevlock);
1849 return -ENOMEM;
1850 }
1851
1852 cowdev->gd->major = COWMAJOR;
1853 cowdev->gd->first_minor = minor;
1854 cowdev->gd->minors = 1;
1855 cowdev->gd->fops = &cowlo_fops;
1856 cowdev->gd->private_data = cowdev;
1857 sprintf(cowdev->gd->disk_name, "%s%d", DEVICE_NAME, minor);
1858
1859 /* in .5 Kb units */
1860 set_capacity(cowdev->gd, (cowdev->numblocks*(MAPUNIT/512)));
1861
1862 DEBUGP(DCOW"cowloop - init request queue....\n");
1863
1864 if ((cowdev->rqueue = blk_init_queue(cowlo_request, &cowdev->rqlock))
1865 == NULL) {
1866 printk(KERN_WARNING
1867 "cowloop - unable to get request queue for cowloop\n");
1868
1869 del_gendisk(cowdev->gd);
1870 cowlo_undo_openrdo(cowdev);
1871 cowlo_undo_opencow(cowdev);
1872 up(&cowdevlock);
1873 return -EINVAL;
1874 }
1875
1876 blk_queue_logical_block_size(cowdev->rqueue, cowdev->blocksz);
1877 cowdev->gd->queue = cowdev->rqueue;
1878
1879 /*
1880 ** start kernel thread to handle requests
1881 */
1882 DEBUGP(DCOW"cowloop - kickoff daemon....\n");
1883
1884 cowdev->pid = kernel_thread((int (*)(void *))cowlo_daemon, cowdev, 0);
1885
1886 /*
1887 ** create a file below directory /proc/cow for this new cowdevice
1888 */
1889 if (cowlo_procdir) {
1890 char tmpname[64];
1891
1892 sprintf(tmpname, "%d", minor);
1893
1894 create_proc_read_entry(tmpname, 0 , cowlo_procdir,
1895 cowlo_readproc, cowdev);
1896 }
1897
1898 cowdev->state |= COWDEVOPEN;
1899
1900 cowdev->rdoname = rdof;
1901 cowdev->cowname = cowf;
1902
1903 /*
1904 ** enable the new disk; this triggers the first request!
1905 */
1906 DEBUGP(DCOW"cowloop - call add_disk....\n");
1907
1908 add_disk(cowdev->gd);
1909
1910 up(&cowdevlock);
1911 return 0;
1912}
1913
1914/*
1915** close a cowdevice (pair of rdofile/cowfile) and release memory
1916**
1917** returns:
1918** 0 - okay
1919** < 0 - error value
1920*/
1921static int
1922cowlo_closepair(struct cowloop_device *cowdev)
1923{
1924 int minor;
1925
1926 down(&cowdevlock);
1927
1928 /*
1929 ** if cowdevice is not activated at all, refuse
1930 */
1931 if ( !(cowdev->state & COWDEVOPEN) ) {
1932 up(&cowdevlock);
1933 return -ENODEV;
1934 }
1935
1936 /*
1937 ** if this cowdevice is still open, refuse
1938 */
1939 if (cowdev->opencnt > 0) {
1940 up(&cowdevlock);
1941 return -EBUSY;
1942 }
1943
1944 up(&cowdevlock);
1945
1946 /*
1947 ** wakeup watcher (if any)
1948 */
1949 if (cowdev->state & COWWATCHDOG) {
1950 cowdev->watchthresh = cowdev->blkavail;
1951 wake_up_interruptible(&cowdev->watchq);
1952 }
1953
1954 /*
1955 ** wakeup kernel-thread to be able to exit
1956 ** and wait until it has exited
1957 */
1958 cowdev->closedown = 1;
1959 cowdev->qfilled = 1;
1960 wake_up_interruptible(&cowdev->waitq);
1961
1962 while (cowdev->pid)
1963 schedule();
1964
1965 del_gendisk(cowdev->gd); /* revert the alloc_disk() */
1966 put_disk(cowdev->gd); /* revert the add_disk() */
1967
1968 if (cowlo_procdir) {
1969 char tmpname[64];
1970
1971 for (minor = 0; minor < maxcows; minor++) {
1972 if (cowdev == cowdevall[minor]) break;
1973 }
1974 sprintf(tmpname, "%d", minor);
1975
1976 remove_proc_entry(tmpname, cowlo_procdir);
1977 }
1978
1979 blk_cleanup_queue(cowdev->rqueue);
1980
1981 /*
1982 ** release memory for filenames if these names have
1983 ** been allocated dynamically
1984 */
1985 if ( (cowdev->cowname) && (cowdev->cowname != cowfile))
1986 kfree(cowdev->cowname);
1987
1988 if ( (cowdev->rdoname) && (cowdev->rdoname != rdofile))
1989 kfree(cowdev->rdoname);
1990
1991 cowlo_undo_openrdo(cowdev);
1992 cowlo_undo_opencow(cowdev);
1993
1994 cowdev->state &= ~COWDEVOPEN;
1995
1996 return 0;
1997}
1998
1999/*
2000** open the read-only file
2001**
2002** returns:
2003** 0 - okay
2004** < 0 - error value
2005*/
2006static int
2007cowlo_openrdo(struct cowloop_device *cowdev, char *rdof)
2008{
2009 struct file *f;
2010 struct inode *inode;
2011 long int i, nrval;
2012
2013 DEBUGP(DCOW"cowloop - openrdo called\n");
2014
2015 /*
2016 ** open the read-only file
2017 */
2018 if(*rdof == '\0') {
2019 printk(KERN_ERR
2020 "cowloop - specify name for read-only file\n\n");
2021 return -EINVAL;
2022 }
2023
2024 f = filp_open(rdof, O_RDONLY|O_LARGEFILE, 0);
2025
2026 if ( (f == NULL) || IS_ERR(f) ) {
2027 printk(KERN_ERR
2028 "cowloop - open of rdofile %s failed\n", rdof);
2029 return -EINVAL;
2030 }
2031
2032 cowdev->rdofp = f;
2033
2034 inode = f->f_dentry->d_inode;
2035
2036 if ( !S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode) ) {
2037 printk(KERN_ERR
2038 "cowloop - %s not regular file or blockdev\n", rdof);
2039 return -EINVAL;
2040 }
2041
2042 DEBUGP(DCOW"cowloop - determine size rdo....\n");
2043
2044 /*
2045 ** determine block-size and total size of read-only file
2046 */
2047 if (S_ISREG(inode->i_mode)) {
2048 /*
2049 ** read-only file is a regular file
2050 */
2051 cowdev->blocksz = 512; /* other value fails */
2052 cowdev->numblocks = inode->i_size >> MUSHIFT;
2053
2054 if (inode->i_size & MUMASK) {
2055 printk(KERN_WARNING
2056 "cowloop - rdofile %s truncated to multiple "
2057 "of %d bytes\n", rdof, MAPUNIT);
2058 }
2059
2060 DEBUGP(DCOW"cowloop - RO=regular: numblocks=%d, blocksz=%d\n",
2061 cowdev->numblocks, cowdev->blocksz);
2062 } else {
2063 /*
2064 ** read-only file is a block device
2065 */
2066 cowdev->belowdev = inode->i_bdev;
2067 cowdev->belowgd = cowdev->belowdev->bd_disk; /* gendisk */
2068
2069 if (cowdev->belowdev->bd_part) {
2070 cowdev->numblocks = cowdev->belowdev->bd_part->nr_sects
2071 / (MAPUNIT/512);
2072 }
2073
2074 if (cowdev->belowgd) {
2075 cowdev->belowq = cowdev->belowgd->queue;
2076
2077 if (cowdev->numblocks == 0) {
2078 cowdev->numblocks = get_capacity(cowdev->belowgd)
2079 / (MAPUNIT/512);
2080 }
2081 }
2082
2083
2084 if (cowdev->belowq)
2085 cowdev->blocksz = queue_logical_block_size(cowdev->belowq);
2086
2087 if (cowdev->blocksz == 0)
2088 cowdev->blocksz = BLOCK_SIZE; /* default 2^10 */
2089
2090 DEBUGP(DCOW"cowloop - numblocks=%d, "
2091 "blocksz=%d, belowgd=%p, belowq=%p\n",
2092 cowdev->numblocks, cowdev->blocksz,
2093 cowdev->belowgd, cowdev->belowq);
2094
2095 DEBUGP(DCOW"cowloop - belowdev.bd_block_size=%d\n",
2096 cowdev->belowdev->bd_block_size);
2097 }
2098
2099 if (cowdev->numblocks == 0) {
2100 printk(KERN_ERR "cowloop - %s has no contents\n", rdof);
2101 return -EINVAL;
2102 }
2103
2104 /*
2105 ** reserve space in memory as generic I/O buffer
2106 */
2107 cowdev->iobuf = kmalloc(MAPUNIT, GFP_KERNEL);
2108
2109 if (!cowdev->iobuf) {
2110 printk(KERN_ERR
2111 "cowloop - cannot get space for buffer %d\n", MAPUNIT);
2112 return -ENOMEM;
2113 }
2114
2115 DEBUGP(DCOW"cowloop - determine fingerprint rdo....\n");
2116
2117 /*
2118 ** determine fingerprint for read-only file
2119 ** calculate fingerprint from first four datablocks
2120 ** which do not contain binary zeroes
2121 */
2122 for (i=0, cowdev->fingerprint=0, nrval=0;
2123 (nrval < 4)&&(i < cowdev->numblocks); i++) {
2124 int j;
2125 unsigned char cs;
2126
2127 /*
2128 ** read next block
2129 */
2130 if (cowlo_readrdo(cowdev, cowdev->iobuf, MAPUNIT,
2131 (loff_t)i << MUSHIFT) < 1)
2132 break;
2133
2134 /*
2135 ** calculate fingerprint by adding all byte-values
2136 */
2137 for (j=0, cs=0; j < MAPUNIT; j++)
2138 cs += *(cowdev->iobuf+j);
2139
2140 if (cs == 0) /* block probably contained zeroes */
2141 continue;
2142
2143 /*
2144 ** shift byte-value to proper place in final fingerprint
2145 */
2146 cowdev->fingerprint |= cs << (nrval*8);
2147 nrval++;
2148 }
2149
2150 return 0;
2151}
2152
2153/*
2154** undo memory allocs and file opens issued so far
2155** related to the read-only file
2156*/
2157static void
2158cowlo_undo_openrdo(struct cowloop_device *cowdev)
2159{
2160 if(cowdev->iobuf);
2161 kfree(cowdev->iobuf);
2162
2163 if (cowdev->rdofp)
2164 filp_close(cowdev->rdofp, 0);
2165}
2166
2167/*
2168** open the cowfile
2169**
2170** returns:
2171** 0 - okay
2172** < 0 - error value
2173*/
2174static int
2175cowlo_opencow(struct cowloop_device *cowdev, char *cowf, int autorecover)
2176{
2177 long int i, rv;
2178 int minor;
2179 unsigned long nb;
2180 struct file *f;
2181 struct inode *inode;
2182 loff_t offset;
2183 struct cowloop_device *cowtmp;
2184
2185 DEBUGP(DCOW"cowloop - opencow called\n");
2186
2187 /*
2188 ** open copy-on-write file (read-write)
2189 */
2190 if (cowf[0] == '\0') {
2191 printk(KERN_ERR
2192 "cowloop - specify name of copy-on-write file\n\n");
2193 return -EINVAL;
2194 }
2195
2196 f = filp_open(cowf, O_RDWR|O_LARGEFILE, 0600);
2197
2198 if ( (f == NULL) || IS_ERR(f) ) {
2199 /*
2200 ** non-existing cowfile: try to create
2201 */
2202 f = filp_open(cowf, O_RDWR|O_CREAT|O_LARGEFILE, 0600);
2203
2204 if ( (f == NULL) || IS_ERR(f) ) {
2205 printk(KERN_ERR
2206 "cowloop - failed to open file %s for read-write\n\n",
2207 cowf);
2208 return -EINVAL;
2209 }
2210 }
2211
2212 cowdev->cowfp = f;
2213
2214 inode = f->f_dentry->d_inode;
2215
2216 if (!S_ISREG(inode->i_mode)) {
2217 printk(KERN_ERR "cowloop - %s is not regular file\n", cowf);
2218 return -EINVAL;
2219 }
2220
2221 /*
2222 ** check if this cowfile is already in use for another cowdevice
2223 */
2224 for (minor = 0; minor < maxcows; minor++) {
2225
2226 cowtmp = cowdevall[minor];
2227
2228 if ( !(cowtmp->state & COWDEVOPEN) )
2229 continue;
2230
2231 if (cowtmp == cowdev)
2232 continue;
2233
2234 if (cowtmp->cowfp->f_dentry->d_inode == f->f_dentry->d_inode) {
2235 printk(KERN_ERR
2236 "cowloop - %s: already in use as cow\n", cowf);
2237 return -EBUSY;
2238 }
2239 }
2240
2241 /*
2242 ** mark cowfile open for read-write
2243 */
2244 cowdev->state |= COWRWCOWOPEN;
2245
2246 /*
2247 ** calculate size (in bytes) for total bitmap in cowfile;
2248 ** when the size of the cowhead block is added, the start-offset
2249 ** for the modified data blocks can be found
2250 */
2251 nb = cowdev->numblocks;
2252
2253 if (nb%8) /* transform #bits to #bytes */
2254 nb+=8; /* rounded if necessary */
2255 nb /= 8;
2256
2257 if (nb & MUMASK) /* round up #bytes to MAPUNIT chunks */
2258 cowdev->mapsize = ( (nb>>MUSHIFT) +1) << MUSHIFT;
2259 else
2260 cowdev->mapsize = nb;
2261
2262 /*
2263 ** reserve space in memory for the cowhead
2264 */
2265 cowdev->cowhead = kmalloc(MAPUNIT, GFP_KERNEL);
2266
2267 if (!cowdev->cowhead) {
2268 printk(KERN_ERR "cowloop - cannot get space for cowhead %d\n",
2269 MAPUNIT);
2270 return -ENOMEM;
2271 }
2272
2273 memset(cowdev->cowhead, 0, MAPUNIT);
2274
2275 DEBUGP(DCOW"cowloop - prepare cowhead....\n");
2276
2277 /*
2278 ** check if the cowfile exists or should be created
2279 */
2280 if (inode->i_size != 0) {
2281 /*
2282 ** existing cowfile: read the cow head
2283 */
2284 if (inode->i_size < MAPUNIT) {
2285 printk(KERN_ERR
2286 "cowloop - existing cowfile %s too small\n",
2287 cowf);
2288 return -EINVAL;
2289 }
2290
2291 cowlo_readcowraw(cowdev, cowdev->cowhead, MAPUNIT, (loff_t) 0);
2292
2293 /*
2294 ** verify if the existing file is really a cowfile
2295 */
2296 if (cowdev->cowhead->magic != COWMAGIC) {
2297 printk(KERN_ERR
2298 "cowloop - cowfile %s has incorrect format\n",
2299 cowf);
2300 return -EINVAL;
2301 }
2302
2303 /*
2304 ** verify the cowhead version of the cowfile
2305 */
2306 if (cowdev->cowhead->version > COWVERSION) {
2307 printk(KERN_ERR
2308 "cowloop - cowfile %s newer than this driver\n",
2309 cowf);
2310 return -EINVAL;
2311 }
2312
2313 /*
2314 ** make sure that this is not a packed cowfile
2315 */
2316 if (cowdev->cowhead->flags & COWPACKED) {
2317 printk(KERN_ERR
2318 "cowloop - packed cowfile %s not accepted\n", cowf);
2319 return -EINVAL;
2320 }
2321
2322 /*
2323 ** verify if the cowfile has been properly closed
2324 */
2325 if (cowdev->cowhead->flags & COWDIRTY) {
2326 /*
2327 ** cowfile was not properly closed;
2328 ** check if automatic recovery is required
2329 ** (actual recovery will be done later on)
2330 */
2331 if (!autorecover) {
2332 printk(KERN_ERR
2333 "cowloop - cowfile %s is dirty "
2334 "(not properly closed by rmmod?)\n",
2335 cowf);
2336 printk(KERN_ERR
2337 "cowloop - run cowrepair or specify "
2338 "'option=r' to recover\n");
2339 return -EINVAL;
2340 }
2341 }
2342
2343 /*
2344 ** verify if the cowfile is really related to this rdofile
2345 */
2346 if (cowdev->cowhead->rdoblocks != cowdev->numblocks) {
2347 printk(KERN_ERR
2348 "cowloop - cowfile %s (size %lld) not related "
2349 "to rdofile (size %lld)\n",
2350 cowf,
2351 (long long)cowdev->cowhead->rdoblocks <<MUSHIFT,
2352 (long long)cowdev->numblocks <<MUSHIFT);
2353 return -EINVAL;
2354 }
2355
2356 if (cowdev->cowhead->rdofingerprint != cowdev->fingerprint) {
2357 printk(KERN_ERR
2358 "cowloop - cowfile %s not related to rdofile "
2359 " (fingerprint err - rdofile modified?)\n", cowf);
2360 return -EINVAL;
2361 }
2362 } else {
2363 /*
2364 ** new cowfile: determine the minimal size (cowhead+bitmap)
2365 */
2366 offset = (loff_t) MAPUNIT + cowdev->mapsize - 1;
2367
2368 if ( cowlo_writecowraw(cowdev, "", 1, offset) < 1) {
2369 printk(KERN_ERR
2370 "cowloop - cannot set cowfile to size %lld\n",
2371 offset+1);
2372 return -EINVAL;
2373 }
2374
2375 /*
2376 ** prepare new cowhead
2377 */
2378 cowdev->cowhead->magic = COWMAGIC;
2379 cowdev->cowhead->version = COWVERSION;
2380 cowdev->cowhead->mapunit = MAPUNIT;
2381 cowdev->cowhead->mapsize = cowdev->mapsize;
2382 cowdev->cowhead->rdoblocks = cowdev->numblocks;
2383 cowdev->cowhead->rdofingerprint = cowdev->fingerprint;
2384 cowdev->cowhead->cowused = 0;
2385
2386 /*
2387 ** calculate start offset of data in cowfile,
2388 ** rounded up to multiple of 4K to avoid
2389 ** unnecessary disk-usage for written datablocks in
2390 ** the sparsed cowfile on e.g. 4K filesystems
2391 */
2392 cowdev->cowhead->doffset =
2393 ((MAPUNIT+cowdev->mapsize+4095)>>12)<<12;
2394 }
2395
2396 cowdev->cowhead->flags = 0;
2397
2398 DEBUGP(DCOW"cowloop - reserve space bitmap....\n");
2399
2400 /*
2401 ** reserve space in memory for the entire bitmap and
2402 ** fill it with the bitmap-data from disk; the entire
2403 ** bitmap is allocated in several chunks because kmalloc
2404 ** has restrictions regarding the allowed size per kmalloc
2405 */
2406 cowdev->mapcount = (cowdev->mapsize+MAPCHUNKSZ-1)/MAPCHUNKSZ;
2407
2408 /*
2409 ** the size of every bitmap chunk will be MAPCHUNKSZ bytes, except for
2410 ** the last bitmap chunk: calculate remaining size for this chunk
2411 */
2412 if (cowdev->mapsize % MAPCHUNKSZ == 0)
2413 cowdev->mapremain = MAPCHUNKSZ;
2414 else
2415 cowdev->mapremain = cowdev->mapsize % MAPCHUNKSZ;
2416
2417 /*
2418 ** allocate space to store all pointers for the bitmap-chunks
2419 ** (initialize area with zeroes to allow proper undo)
2420 */
2421 cowdev->mapcache = kmalloc(cowdev->mapcount * sizeof(char *),
2422 GFP_KERNEL);
2423 if (!cowdev->mapcache) {
2424 printk(KERN_ERR
2425 "cowloop - can not allocate space for bitmap ptrs\n");
2426 return -ENOMEM;
2427 }
2428
2429 memset(cowdev->mapcache, 0, cowdev->mapcount * sizeof(char *));
2430
2431 /*
2432 ** allocate space to store the bitmap-chunks themselves
2433 */
2434 for (i=0; i < cowdev->mapcount; i++) {
2435 if (i < (cowdev->mapcount-1))
2436 *(cowdev->mapcache+i) = kmalloc(MAPCHUNKSZ, GFP_KERNEL);
2437 else
2438 *(cowdev->mapcache+i) = kmalloc(cowdev->mapremain,
2439 GFP_KERNEL);
2440
2441 if (*(cowdev->mapcache+i) == NULL) {
2442 printk(KERN_ERR "cowloop - no space for bitmapchunk %ld"
2443 " totmapsz=%ld, mapcnt=%d mapunit=%d\n",
2444 i, cowdev->mapsize, cowdev->mapcount,
2445 MAPUNIT);
2446 return -ENOMEM;
2447 }
2448 }
2449
2450 DEBUGP(DCOW"cowloop - read bitmap from cow....\n");
2451
2452 /*
2453 ** read the entire bitmap from the cowfile into the in-memory cache;
2454 ** count the number of blocks that are in use already
2455 ** (statistical purposes)
2456 */
2457 for (i=0, offset=MAPUNIT; i < cowdev->mapcount;
2458 i++, offset+=MAPCHUNKSZ) {
2459 unsigned long numbytes;
2460
2461 if (i < (cowdev->mapcount-1))
2462 /*
2463 ** full bitmap chunk
2464 */
2465 numbytes = MAPCHUNKSZ;
2466 else
2467 /*
2468 ** last bitmap chunk: might be partly filled
2469 */
2470 numbytes = cowdev->mapremain;
2471
2472 cowlo_readcowraw(cowdev, *(cowdev->mapcache+i),
2473 numbytes, offset);
2474 }
2475
2476 /*
2477 ** if the cowfile was dirty and automatic recovery is required,
2478 ** reconstruct a proper bitmap in memory now
2479 */
2480 if (cowdev->cowhead->flags & COWDIRTY) {
2481 unsigned long long blocknum;
2482 char databuf[MAPUNIT];
2483 unsigned long mapnum, mapbyte, mapbit;
2484
2485 printk(KERN_NOTICE "cowloop - recover dirty cowfile %s....\n",
2486 cowf);
2487
2488 /*
2489 ** read all data blocks
2490 */
2491 for (blocknum=0, rv=1, offset=0;
2492 cowlo_readcow(cowdev, databuf, MAPUNIT, offset) > 0;
2493 blocknum++, offset += MAPUNIT) {
2494
2495 /*
2496 ** if this datablock contains real data (not binary
2497 ** zeroes), set the corresponding bit in the bitmap
2498 */
2499 if ( memcmp(databuf, allzeroes, MAPUNIT) == 0)
2500 continue;
2501
2502 mapnum = CALCMAP (blocknum);
2503 mapbyte = CALCBYTE(blocknum);
2504 mapbit = CALCBIT (blocknum);
2505
2506 *(*(cowdev->mapcache+mapnum)+mapbyte) |= (1<<mapbit);
2507 }
2508
2509 printk(KERN_NOTICE "cowloop - cowfile recovery completed\n");
2510 }
2511
2512 /*
2513 ** count all bits set in the bitmaps for statistical purposes
2514 */
2515 for (i=0, cowdev->nrcowblocks = 0; i < cowdev->mapcount; i++) {
2516 long numbytes;
2517 char *p;
2518
2519 if (i < (cowdev->mapcount-1))
2520 numbytes = MAPCHUNKSZ;
2521 else
2522 numbytes = cowdev->mapremain;
2523
2524 p = *(cowdev->mapcache+i);
2525
2526 for (numbytes--; numbytes >= 0; numbytes--, p++) {
2527 /*
2528 ** for only eight checks the following construction
2529 ** is faster than a loop-construction
2530 */
2531 if ((*p) & 0x01) cowdev->nrcowblocks++;
2532 if ((*p) & 0x02) cowdev->nrcowblocks++;
2533 if ((*p) & 0x04) cowdev->nrcowblocks++;
2534 if ((*p) & 0x08) cowdev->nrcowblocks++;
2535 if ((*p) & 0x10) cowdev->nrcowblocks++;
2536 if ((*p) & 0x20) cowdev->nrcowblocks++;
2537 if ((*p) & 0x40) cowdev->nrcowblocks++;
2538 if ((*p) & 0x80) cowdev->nrcowblocks++;
2539 }
2540 }
2541
2542 /*
2543 ** consistency-check for number of bits set in bitmap
2544 */
2545 if ( !(cowdev->cowhead->flags & COWDIRTY) &&
2546 (cowdev->cowhead->cowused != cowdev->nrcowblocks) ) {
2547 printk(KERN_ERR "cowloop - inconsistent cowfile admi\n");
2548 return -EINVAL;
2549 }
2550
2551 return 0;
2552}
2553
2554/*
2555** undo memory allocs and file opens issued so far
2556** related to the cowfile
2557*/
2558static void
2559cowlo_undo_opencow(struct cowloop_device *cowdev)
2560{
2561 int i;
2562
2563 if (cowdev->mapcache) {
2564 for (i=0; i < cowdev->mapcount; i++) {
2565 if (*(cowdev->mapcache+i) != NULL)
2566 kfree( *(cowdev->mapcache+i) );
2567 }
2568
2569 kfree(cowdev->mapcache);
2570 }
2571
2572 if (cowdev->cowhead)
2573 kfree(cowdev->cowhead);
2574
2575 if ( (cowdev->state & COWCOWOPEN) && (cowdev->cowfp) )
2576 filp_close(cowdev->cowfp, 0);
2577
2578 /*
2579 ** mark cowfile closed
2580 */
2581 cowdev->state &= ~COWCOWOPEN;
2582}
2583
2584/*
2585** flush the entire bitmap and the cowhead (clean) to the cowfile
2586**
2587** must be called with the cowdevices-lock set
2588*/
2589static void
2590cowlo_sync(void)
2591{
2592 int i, minor;
2593 loff_t offset;
2594 struct cowloop_device *cowdev;
2595
2596 for (minor=0; minor < maxcows; minor++) {
2597 cowdev = cowdevall[minor];
2598 if ( ! (cowdev->state & COWRWCOWOPEN) )
2599 continue;
2600
2601 for (i=0, offset=MAPUNIT; i < cowdev->mapcount;
2602 i++, offset += MAPCHUNKSZ) {
2603 unsigned long numbytes;
2604
2605 if (i < (cowdev->mapcount-1))
2606 /*
2607 ** full bitmap chunk
2608 */
2609 numbytes = MAPCHUNKSZ;
2610 else
2611 /*
2612 ** last bitmap chunk: might be partly filled
2613 */
2614 numbytes = cowdev->mapremain;
2615
2616 DEBUGP(DCOW
2617 "cowloop - flushing bitmap %2d (%3ld Kb)\n",
2618 i, numbytes/1024);
2619
2620 if (cowlo_writecowraw(cowdev, *(cowdev->mapcache+i),
2621 numbytes, offset) < numbytes) {
2622 break;
2623 }
2624 }
2625
2626 /*
2627 ** flush clean up-to-date cowhead to cowfile
2628 */
2629 cowdev->cowhead->cowused = cowdev->nrcowblocks;
2630 cowdev->cowhead->flags &= ~COWDIRTY;
2631
2632 DEBUGP(DCOW "cowloop - flushing cowhead (%3d Kb)\n",
2633 MAPUNIT/1024);
2634
2635 cowlo_writecowraw(cowdev, cowdev->cowhead, MAPUNIT, (loff_t) 0);
2636 }
2637}
2638
2639/*****************************************************************************/
2640/* Module loading/unloading */
2641/*****************************************************************************/
2642
2643/*
2644** called during insmod/modprobe
2645*/
2646static int __init
2647cowlo_init_module(void)
2648{
2649 int rv;
2650 int minor, uptocows;
2651
2652 revision[sizeof revision - 3] = '\0';
2653
2654 printk(KERN_NOTICE "cowloop - (C) 2009 ATComputing.nl - version: %s\n", &revision[11]);
2655 printk(KERN_NOTICE "cowloop - info: www.ATComputing.nl/cowloop\n");
2656
2657 memset(allzeroes, 0, MAPUNIT);
2658
2659 /*
2660 ** Setup administration for all possible cowdevices.
2661 ** Note that their minor numbers go from 0 to MAXCOWS-1 inclusive
2662 ** and minor == MAXCOWS-1 is reserved for the control device.
2663 */
2664 if ((maxcows < 1) || (maxcows > MAXCOWS)) {
2665 printk(KERN_WARNING
2666 "cowloop - maxcows exceeds maximum of %d\n", MAXCOWS);
2667
2668 maxcows = DFLCOWS;
2669 }
2670
2671 /* allocate room for a table with a pointer to each cowloop_device: */
2672 if ( (cowdevall = kmalloc(maxcows * sizeof(struct cowloop_device *),
2673 GFP_KERNEL)) == NULL) {
2674 printk(KERN_WARNING
2675 "cowloop - can not alloc table for %d devs\n", maxcows);
2676 uptocows = 0;
2677 rv = -ENOMEM;
2678 goto error_out;
2679 }
2680 memset(cowdevall, 0, maxcows * sizeof(struct cowloop_device *));
2681 /* then hook an actual cowloop_device struct to each pointer: */
2682 for (minor=0; minor < maxcows; minor++) {
2683 if ((cowdevall[minor] = kmalloc(sizeof(struct cowloop_device),
2684 GFP_KERNEL)) == NULL) {
2685 printk(KERN_WARNING
2686 "cowloop - can not alloc admin-struct for dev no %d\n", minor);
2687
2688 uptocows = minor; /* this is how far we got.... */
2689 rv = -ENOMEM;
2690 goto error_out;
2691 }
2692 memset(cowdevall[minor], 0, sizeof(struct cowloop_device));
2693 }
2694 uptocows = maxcows; /* we got all devices */
2695
2696 sema_init(&cowdevlock, 1);
2697
2698 /*
2699 ** register cowloop module
2700 */
2701 if ( register_blkdev(COWMAJOR, DEVICE_NAME) < 0) {
2702 printk(KERN_WARNING
2703 "cowloop - unable to get major %d for cowloop\n", COWMAJOR);
2704 rv = -EIO;
2705 goto error_out;
2706 }
2707
2708 /*
2709 ** create a directory below /proc to allocate a file
2710 ** for each cowdevice that is allocated later on
2711 */
2712 cowlo_procdir = proc_mkdir("cow", NULL);
2713
2714 /*
2715 ** check if a cowdevice has to be opened during insmod/modprobe;
2716 ** two parameters should be specified then: rdofile= and cowfile=
2717 */
2718 if( (rdofile[0] != '\0') && (cowfile[0] != '\0') ) {
2719 char *po = option;
2720 int wantrecover = 0;
2721
2722 /*
2723 ** check if automatic recovery is wanted
2724 */
2725 while (*po) {
2726 if (*po == 'r') {
2727 wantrecover = 1;
2728 break;
2729 }
2730 po++;
2731 }
2732
2733 /*
2734 ** open new cowdevice with minor number 0
2735 */
2736 if ( (rv = cowlo_openpair(rdofile, cowfile, wantrecover, 0))) {
2737 remove_proc_entry("cow", NULL);
2738 unregister_blkdev(COWMAJOR, DEVICE_NAME);
2739 goto error_out;
2740 }
2741 } else {
2742 /*
2743 ** check if only one parameter has been specified
2744 */
2745 if( (rdofile[0] != '\0') || (cowfile[0] != '\0') ) {
2746 printk(KERN_ERR
2747 "cowloop - only one filename specified\n");
2748 remove_proc_entry("cow", NULL);
2749 unregister_blkdev(COWMAJOR, DEVICE_NAME);
2750 rv = -EINVAL;
2751 goto error_out;
2752 }
2753 }
2754
2755 /*
2756 ** allocate fake disk as control channel to handle the requests
2757 ** to activate and deactivate cowdevices dynamically
2758 */
2759 if (!(cowctlgd = alloc_disk(1))) {
2760 printk(KERN_WARNING
2761 "cowloop - unable to alloc_disk for cowctl\n");
2762
2763 remove_proc_entry("cow", NULL);
2764 (void) cowlo_closepair(cowdevall[0]);
2765 unregister_blkdev(COWMAJOR, DEVICE_NAME);
2766 rv = -ENOMEM;
2767 goto error_out;
2768 }
2769
2770 spin_lock_init(&cowctlrqlock);
2771 cowctlgd->major = COWMAJOR;
2772 cowctlgd->first_minor = COWCTL;
2773 cowctlgd->minors = 1;
2774 cowctlgd->fops = &cowlo_fops;
2775 cowctlgd->private_data = NULL;
2776 /* the device has capacity 0, so there will be no q-requests */
2777 cowctlgd->queue = blk_init_queue(NULL, &cowctlrqlock);
2778 sprintf(cowctlgd->disk_name, "cowctl");
2779 set_capacity(cowctlgd, 0);
2780
2781 add_disk(cowctlgd);
2782
2783 printk(KERN_NOTICE "cowloop - number of configured cowdevices: %d\n",
2784 maxcows);
2785 if (rdofile[0] != '\0') {
2786 printk(KERN_NOTICE "cowloop - initialized on rdofile=%s\n",
2787 rdofile);
2788 } else {
2789 printk(KERN_NOTICE "cowloop - initialized without rdofile yet\n");
2790 }
2791 return 0;
2792
2793error_out:
2794 for (minor=0; minor < uptocows ; minor++) {
2795 kfree(cowdevall[minor]);
2796 }
2797 kfree(cowdevall);
2798 return rv;
2799}
2800
2801/*
2802** called during rmmod
2803*/
2804static void __exit
2805cowlo_cleanup_module(void)
2806{
2807 int minor;
2808
2809 /*
2810 ** flush bitmaps and cowheads to the cowfiles
2811 */
2812 down(&cowdevlock);
2813 cowlo_sync();
2814 up(&cowdevlock);
2815
2816 /*
2817 ** close all cowdevices
2818 */
2819 for (minor=0; minor < maxcows; minor++)
2820 (void) cowlo_closepair(cowdevall[minor]);
2821
2822 unregister_blkdev(COWMAJOR, DEVICE_NAME);
2823
2824 /*
2825 ** get rid of /proc/cow and unregister the driver
2826 */
2827 remove_proc_entry("cow", NULL);
2828
2829 for (minor = 0; minor < maxcows; minor++) {
2830 kfree(cowdevall[minor]);
2831 }
2832 kfree(cowdevall);
2833
2834 del_gendisk(cowctlgd); /* revert the alloc_disk() */
2835 put_disk (cowctlgd); /* revert the add_disk() */
2836 blk_cleanup_queue(cowctlgd->queue); /* cleanup the empty queue */
2837
2838 printk(KERN_NOTICE "cowloop - unloaded\n");
2839}
2840
2841module_init(cowlo_init_module);
2842module_exit(cowlo_cleanup_module);
diff --git a/drivers/staging/cowloop/cowloop.h b/drivers/staging/cowloop/cowloop.h
deleted file mode 100644
index bbd4a35ac667..000000000000
--- a/drivers/staging/cowloop/cowloop.h
+++ /dev/null
@@ -1,66 +0,0 @@
1/*
2** DO NOT MODIFY THESE VALUES (would make old cowfiles unusable)
3*/
4#define MAPUNIT 1024 /* blocksize for bit in bitmap */
5#define MUSHIFT 10 /* bitshift for bit in bitmap */
6#define MUMASK 0x3ff /* bitmask for bit in bitmap */
7
8#define COWMAGIC 0x574f437f /* byte-swapped '7f C O W' */
9#define COWDIRTY 0x01
10#define COWPACKED 0x02
11#define COWVERSION 1
12
13struct cowhead
14{
15 int magic; /* identifies a cowfile */
16 short version; /* version of cowhead */
17 short flags; /* flags indicating status */
18 unsigned long mapunit; /* blocksize per bit in bitmap */
19 unsigned long mapsize; /* total size of bitmap (bytes) */
20 unsigned long doffset; /* start-offset datablocks in cow */
21 unsigned long rdoblocks; /* size of related read-only file */
22 unsigned long rdofingerprint; /* fingerprint of read-only file */
23 unsigned long cowused; /* number of datablocks used in cow */
24};
25
26#define COWDEVDIR "/dev/cow/"
27#define COWDEVICE COWDEVDIR "%ld"
28#define COWCONTROL COWDEVDIR "ctl"
29
30#define MAXCOWS 1024
31#define COWCTL (MAXCOWS-1) /* minor number of /dev/cow/ctl */
32
33#define COWPROCDIR "/proc/cow/"
34#define COWPROCFILE COWPROCDIR "%d"
35
36/*
37** ioctl related stuff
38*/
39#define ANYDEV ((unsigned long)-1)
40
41struct cowpair
42{
43 unsigned char *rdofile; /* pathname of the rdofile */
44 unsigned char *cowfile; /* pathname of the cowfile */
45 unsigned short rdoflen; /* length of rdofile pathname */
46 unsigned short cowflen; /* length of cowfile pathname */
47 unsigned long device; /* requested/returned device number */
48};
49
50struct cowwatch
51{
52 int flags; /* request flags */
53 unsigned long device; /* requested device number */
54 unsigned long threshold; /* continue if free Kb < threshold */
55 unsigned long totalkb; /* ret: total filesystem size (Kb) */
56 unsigned long availkb; /* ret: free filesystem size (Kb) */
57};
58
59#define WATCHWAIT 0x01 /* block until threshold reached */
60
61#define COWSYNC _IO ('C', 1)
62#define COWMKPAIR _IOW ('C', 2, struct cowpair)
63#define COWRMPAIR _IOW ('C', 3, unsigned long)
64#define COWWATCH _IOW ('C', 4, struct cowwatch)
65#define COWCLOSE _IOW ('C', 5, unsigned long)
66#define COWRDOPEN _IOW ('C', 6, unsigned long)
diff --git a/drivers/staging/dst/dcore.c b/drivers/staging/dst/dcore.c
index ac8577358ba0..c24e4e0367a2 100644
--- a/drivers/staging/dst/dcore.c
+++ b/drivers/staging/dst/dcore.c
@@ -102,7 +102,7 @@ static int dst_request(struct request_queue *q, struct bio *bio)
102 struct dst_node *n = q->queuedata; 102 struct dst_node *n = q->queuedata;
103 int err = -EIO; 103 int err = -EIO;
104 104
105 if (bio_empty_barrier(bio) && !q->prepare_discard_fn) { 105 if (bio_empty_barrier(bio) && !blk_queue_discard(q)) {
106 /* 106 /*
107 * This is a dirty^Wnice hack, but if we complete this 107 * This is a dirty^Wnice hack, but if we complete this
108 * operation with -EOPNOTSUPP like intended, XFS 108 * operation with -EOPNOTSUPP like intended, XFS
@@ -847,7 +847,7 @@ static dst_command_func dst_commands[] = {
847/* 847/*
848 * Configuration parser. 848 * Configuration parser.
849 */ 849 */
850static void cn_dst_callback(struct cn_msg *msg) 850static void cn_dst_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
851{ 851{
852 struct dst_ctl *ctl; 852 struct dst_ctl *ctl;
853 int err; 853 int err;
@@ -855,6 +855,11 @@ static void cn_dst_callback(struct cn_msg *msg)
855 struct dst_node *n = NULL, *tmp; 855 struct dst_node *n = NULL, *tmp;
856 unsigned int hash; 856 unsigned int hash;
857 857
858 if (!cap_raised(nsp->eff_cap, CAP_SYS_ADMIN)) {
859 err = -EPERM;
860 goto out;
861 }
862
858 if (msg->len < sizeof(struct dst_ctl)) { 863 if (msg->len < sizeof(struct dst_ctl)) {
859 err = -EBADMSG; 864 err = -EBADMSG;
860 goto out; 865 goto out;
diff --git a/drivers/staging/et131x/et1310_address_map.h b/drivers/staging/et131x/et1310_address_map.h
index 6294d3814e72..2c3d65a622a7 100644
--- a/drivers/staging/et131x/et1310_address_map.h
+++ b/drivers/staging/et131x/et1310_address_map.h
@@ -223,7 +223,7 @@ typedef union _TXDMA_PR_NUM_DES_t {
223 223
224extern inline void add_10bit(u32 *v, int n) 224extern inline void add_10bit(u32 *v, int n)
225{ 225{
226 *v = INDEX10(*v + n); 226 *v = INDEX10(*v + n) | (*v & ET_DMA10_WRAP);
227} 227}
228 228
229/* 229/*
diff --git a/drivers/staging/et131x/et1310_rx.c b/drivers/staging/et131x/et1310_rx.c
index 8f2e91fa0a86..10e21db57ac3 100644
--- a/drivers/staging/et131x/et1310_rx.c
+++ b/drivers/staging/et131x/et1310_rx.c
@@ -1177,12 +1177,20 @@ void et131x_handle_recv_interrupt(struct et131x_adapter *etdev)
1177 1177
1178static inline u32 bump_fbr(u32 *fbr, u32 limit) 1178static inline u32 bump_fbr(u32 *fbr, u32 limit)
1179{ 1179{
1180 u32 v = *fbr; 1180 u32 v = *fbr;
1181 add_10bit(&v, 1); 1181 v++;
1182 if (v > limit) 1182 /* This works for all cases where limit < 1024. The 1023 case
1183 v = (*fbr & ~ET_DMA10_MASK) ^ ET_DMA10_WRAP; 1183 works because 1023++ is 1024 which means the if condition is not
1184 *fbr = v; 1184 taken but the carry of the bit into the wrap bit toggles the wrap
1185 return v; 1185 value correctly */
1186 if ((v & ET_DMA10_MASK) > limit) {
1187 v &= ~ET_DMA10_MASK;
1188 v ^= ET_DMA10_WRAP;
1189 }
1190 /* For the 1023 case */
1191 v &= (ET_DMA10_MASK|ET_DMA10_WRAP);
1192 *fbr = v;
1193 return v;
1186} 1194}
1187 1195
1188/** 1196/**
diff --git a/drivers/staging/hv/osd.c b/drivers/staging/hv/osd.c
index 8fe543bd9910..3a4793a0fd05 100644
--- a/drivers/staging/hv/osd.c
+++ b/drivers/staging/hv/osd.c
@@ -30,6 +30,7 @@
30#include <linux/ioport.h> 30#include <linux/ioport.h>
31#include <linux/irq.h> 31#include <linux/irq.h>
32#include <linux/interrupt.h> 32#include <linux/interrupt.h>
33#include <linux/sched.h>
33#include <linux/wait.h> 34#include <linux/wait.h>
34#include <linux/spinlock.h> 35#include <linux/spinlock.h>
35#include <linux/workqueue.h> 36#include <linux/workqueue.h>
diff --git a/drivers/staging/iio/Kconfig b/drivers/staging/iio/Kconfig
index beb99a547f09..4586650d65c3 100644
--- a/drivers/staging/iio/Kconfig
+++ b/drivers/staging/iio/Kconfig
@@ -4,6 +4,7 @@
4 4
5menuconfig IIO 5menuconfig IIO
6 tristate "Industrial I/O support" 6 tristate "Industrial I/O support"
7 depends on !S390
7 ---help--- 8 ---help---
8 The industrial I/O subsystem provides a unified framework for 9 The industrial I/O subsystem provides a unified framework for
9 drivers for many different types of embedded sensors using a 10 drivers for many different types of embedded sensors using a
diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c
index 1fa18f255814..768f44894d08 100644
--- a/drivers/staging/iio/industrialio-core.c
+++ b/drivers/staging/iio/industrialio-core.c
@@ -18,6 +18,8 @@
18#include <linux/fs.h> 18#include <linux/fs.h>
19#include <linux/interrupt.h> 19#include <linux/interrupt.h>
20#include <linux/poll.h> 20#include <linux/poll.h>
21#include <linux/sched.h>
22#include <linux/wait.h>
21#include <linux/cdev.h> 23#include <linux/cdev.h>
22#include "iio.h" 24#include "iio.h"
23#include "trigger_consumer.h" 25#include "trigger_consumer.h"
diff --git a/drivers/staging/iio/light/tsl2561.c b/drivers/staging/iio/light/tsl2561.c
index ea8a5efc19bc..fc2107f4c049 100644
--- a/drivers/staging/iio/light/tsl2561.c
+++ b/drivers/staging/iio/light/tsl2561.c
@@ -239,10 +239,6 @@ static int __devexit tsl2561_remove(struct i2c_client *client)
239 return tsl2561_powerdown(client); 239 return tsl2561_powerdown(client);
240} 240}
241 241
242static unsigned short normal_i2c[] = { 0x29, 0x39, 0x49, I2C_CLIENT_END };
243
244I2C_CLIENT_INSMOD;
245
246static const struct i2c_device_id tsl2561_id[] = { 242static const struct i2c_device_id tsl2561_id[] = {
247 { "tsl2561", 0 }, 243 { "tsl2561", 0 },
248 { } 244 { }
diff --git a/drivers/staging/p9auth/p9auth.c b/drivers/staging/p9auth/p9auth.c
index 9111dcba37a1..8ccfff723eec 100644
--- a/drivers/staging/p9auth/p9auth.c
+++ b/drivers/staging/p9auth/p9auth.c
@@ -183,7 +183,7 @@ static ssize_t cap_write(struct file *filp, const char __user *buf,
183 user_buf_running = NULL; 183 user_buf_running = NULL;
184 hash_str = NULL; 184 hash_str = NULL;
185 node_ptr = kmalloc(sizeof(struct cap_node), GFP_KERNEL); 185 node_ptr = kmalloc(sizeof(struct cap_node), GFP_KERNEL);
186 user_buf = kzalloc(count, GFP_KERNEL); 186 user_buf = kzalloc(count+1, GFP_KERNEL);
187 if (!node_ptr || !user_buf) 187 if (!node_ptr || !user_buf)
188 goto out; 188 goto out;
189 189
@@ -207,6 +207,7 @@ static ssize_t cap_write(struct file *filp, const char __user *buf,
207 list_add(&(node_ptr->list), &(dev->head->list)); 207 list_add(&(node_ptr->list), &(dev->head->list));
208 node_ptr = NULL; 208 node_ptr = NULL;
209 } else { 209 } else {
210 char *tmpu;
210 if (!cap_devices[0].head || 211 if (!cap_devices[0].head ||
211 list_empty(&(cap_devices[0].head->list))) { 212 list_empty(&(cap_devices[0].head->list))) {
212 retval = -EINVAL; 213 retval = -EINVAL;
@@ -218,10 +219,10 @@ static ssize_t cap_write(struct file *filp, const char __user *buf,
218 * need to split it and hash 'user1@user2' using 'randomstring' 219 * need to split it and hash 'user1@user2' using 'randomstring'
219 * as the key. 220 * as the key.
220 */ 221 */
221 user_buf_running = kstrdup(user_buf, GFP_KERNEL); 222 tmpu = user_buf_running = kstrdup(user_buf, GFP_KERNEL);
222 source_user = strsep(&user_buf_running, "@"); 223 source_user = strsep(&tmpu, "@");
223 target_user = strsep(&user_buf_running, "@"); 224 target_user = strsep(&tmpu, "@");
224 rand_str = strsep(&user_buf_running, "@"); 225 rand_str = tmpu;
225 if (!source_user || !target_user || !rand_str) { 226 if (!source_user || !target_user || !rand_str) {
226 retval = -EINVAL; 227 retval = -EINVAL;
227 goto out; 228 goto out;
@@ -229,7 +230,8 @@ static ssize_t cap_write(struct file *filp, const char __user *buf,
229 230
230 /* hash the string user1@user2 with rand_str as the key */ 231 /* hash the string user1@user2 with rand_str as the key */
231 len = strlen(source_user) + strlen(target_user) + 1; 232 len = strlen(source_user) + strlen(target_user) + 1;
232 hash_str = kzalloc(len, GFP_KERNEL); 233 /* src, @, len, \0 */
234 hash_str = kzalloc(len+1, GFP_KERNEL);
233 strcat(hash_str, source_user); 235 strcat(hash_str, source_user);
234 strcat(hash_str, "@"); 236 strcat(hash_str, "@");
235 strcat(hash_str, target_user); 237 strcat(hash_str, target_user);
diff --git a/drivers/staging/poch/poch.c b/drivers/staging/poch/poch.c
index 0d111ddfabb2..2eb8e3d43c4d 100644
--- a/drivers/staging/poch/poch.c
+++ b/drivers/staging/poch/poch.c
@@ -20,6 +20,7 @@
20#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/ioctl.h> 21#include <linux/ioctl.h>
22#include <linux/io.h> 22#include <linux/io.h>
23#include <linux/sched.h>
23 24
24#include "poch.h" 25#include "poch.h"
25 26
diff --git a/drivers/staging/pohmelfs/config.c b/drivers/staging/pohmelfs/config.c
index 90f962ee5fd8..5d04bf5b021a 100644
--- a/drivers/staging/pohmelfs/config.c
+++ b/drivers/staging/pohmelfs/config.c
@@ -527,10 +527,13 @@ out_unlock:
527 return err; 527 return err;
528} 528}
529 529
530static void pohmelfs_cn_callback(struct cn_msg *msg) 530static void pohmelfs_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
531{ 531{
532 int err; 532 int err;
533 533
534 if (!cap_raised(nsp->eff_cap, CAP_SYS_ADMIN))
535 return;
536
534 switch (msg->flags) { 537 switch (msg->flags) {
535 case POHMELFS_FLAGS_ADD: 538 case POHMELFS_FLAGS_ADD:
536 case POHMELFS_FLAGS_DEL: 539 case POHMELFS_FLAGS_DEL:
diff --git a/drivers/staging/rt2860/common/cmm_data_2860.c b/drivers/staging/rt2860/common/cmm_data_2860.c
index fb1735533b74..857ff450b6c9 100644
--- a/drivers/staging/rt2860/common/cmm_data_2860.c
+++ b/drivers/staging/rt2860/common/cmm_data_2860.c
@@ -363,6 +363,8 @@ int RtmpPCIMgmtKickOut(
363 ULONG SwIdx = pAd->MgmtRing.TxCpuIdx; 363 ULONG SwIdx = pAd->MgmtRing.TxCpuIdx;
364 364
365 pTxD = (PTXD_STRUC) pAd->MgmtRing.Cell[SwIdx].AllocVa; 365 pTxD = (PTXD_STRUC) pAd->MgmtRing.Cell[SwIdx].AllocVa;
366 if (!pTxD)
367 return 0;
366 368
367 pAd->MgmtRing.Cell[SwIdx].pNdisPacket = pPacket; 369 pAd->MgmtRing.Cell[SwIdx].pNdisPacket = pPacket;
368 pAd->MgmtRing.Cell[SwIdx].pNextNdisPacket = NULL; 370 pAd->MgmtRing.Cell[SwIdx].pNextNdisPacket = NULL;
diff --git a/drivers/staging/rt2860/common/cmm_info.c b/drivers/staging/rt2860/common/cmm_info.c
index 9d589c240ed0..019cc4474ce8 100644
--- a/drivers/staging/rt2860/common/cmm_info.c
+++ b/drivers/staging/rt2860/common/cmm_info.c
@@ -25,6 +25,7 @@
25 ************************************************************************* 25 *************************************************************************
26*/ 26*/
27 27
28#include <linux/sched.h>
28#include "../rt_config.h" 29#include "../rt_config.h"
29 30
30INT Show_SSID_Proc( 31INT Show_SSID_Proc(
diff --git a/drivers/staging/rt2860/rt_linux.c b/drivers/staging/rt2860/rt_linux.c
index b396a9b570e2..ed27b8545a1b 100644
--- a/drivers/staging/rt2860/rt_linux.c
+++ b/drivers/staging/rt2860/rt_linux.c
@@ -25,6 +25,7 @@
25 ************************************************************************* 25 *************************************************************************
26 */ 26 */
27 27
28#include <linux/sched.h>
28#include "rt_config.h" 29#include "rt_config.h"
29 30
30ULONG RTDebugLevel = RT_DEBUG_ERROR; 31ULONG RTDebugLevel = RT_DEBUG_ERROR;
diff --git a/drivers/staging/rt3090/common/cmm_info.c b/drivers/staging/rt3090/common/cmm_info.c
index 5be0714666cb..3e51e98b474c 100644
--- a/drivers/staging/rt3090/common/cmm_info.c
+++ b/drivers/staging/rt3090/common/cmm_info.c
@@ -34,6 +34,7 @@
34 --------- ---------- ---------------------------------------------- 34 --------- ---------- ----------------------------------------------
35 */ 35 */
36 36
37#include <linux/sched.h>
37#include "../rt_config.h" 38#include "../rt_config.h"
38 39
39 40
diff --git a/drivers/staging/rt3090/rt_linux.c b/drivers/staging/rt3090/rt_linux.c
index d2241ecdf583..9b94aa6eb904 100644
--- a/drivers/staging/rt3090/rt_linux.c
+++ b/drivers/staging/rt3090/rt_linux.c
@@ -25,6 +25,7 @@
25 ************************************************************************* 25 *************************************************************************
26 */ 26 */
27 27
28#include <linux/sched.h>
28#include "rt_config.h" 29#include "rt_config.h"
29 30
30ULONG RTDebugLevel = RT_DEBUG_ERROR; 31ULONG RTDebugLevel = RT_DEBUG_ERROR;
diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c
index d4fa65489655..b0802a7aeb5f 100644
--- a/drivers/staging/rtl8192e/r8192E_core.c
+++ b/drivers/staging/rtl8192e/r8192E_core.c
@@ -46,6 +46,7 @@
46#undef DEBUG_TX_DESC 46#undef DEBUG_TX_DESC
47 47
48//#define CONFIG_RTL8192_IO_MAP 48//#define CONFIG_RTL8192_IO_MAP
49#include <linux/vmalloc.h>
49#include <asm/uaccess.h> 50#include <asm/uaccess.h>
50#include "r8192E_hw.h" 51#include "r8192E_hw.h"
51#include "r8192E.h" 52#include "r8192E.h"
diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c
index 87f8a1192762..f890a16096c0 100644
--- a/drivers/staging/sep/sep_driver.c
+++ b/drivers/staging/sep/sep_driver.c
@@ -38,6 +38,7 @@
38#include <linux/mm.h> 38#include <linux/mm.h>
39#include <linux/poll.h> 39#include <linux/poll.h>
40#include <linux/wait.h> 40#include <linux/wait.h>
41#include <linux/sched.h>
41#include <linux/pci.h> 42#include <linux/pci.h>
42#include <linux/firmware.h> 43#include <linux/firmware.h>
43#include <asm/ioctl.h> 44#include <asm/ioctl.h>
diff --git a/drivers/staging/vme/bridges/vme_ca91cx42.c b/drivers/staging/vme/bridges/vme_ca91cx42.c
index 3d2a84c45829..e139eaeaa174 100644
--- a/drivers/staging/vme/bridges/vme_ca91cx42.c
+++ b/drivers/staging/vme/bridges/vme_ca91cx42.c
@@ -25,6 +25,7 @@
25#include <linux/poll.h> 25#include <linux/poll.h>
26#include <linux/interrupt.h> 26#include <linux/interrupt.h>
27#include <linux/spinlock.h> 27#include <linux/spinlock.h>
28#include <linux/sched.h>
28#include <asm/time.h> 29#include <asm/time.h>
29#include <asm/io.h> 30#include <asm/io.h>
30#include <asm/uaccess.h> 31#include <asm/uaccess.h>
diff --git a/drivers/staging/vme/bridges/vme_tsi148.c b/drivers/staging/vme/bridges/vme_tsi148.c
index 8960fa9ee7aa..00fe0803c21c 100644
--- a/drivers/staging/vme/bridges/vme_tsi148.c
+++ b/drivers/staging/vme/bridges/vme_tsi148.c
@@ -25,6 +25,7 @@
25#include <linux/dma-mapping.h> 25#include <linux/dma-mapping.h>
26#include <linux/interrupt.h> 26#include <linux/interrupt.h>
27#include <linux/spinlock.h> 27#include <linux/spinlock.h>
28#include <linux/sched.h>
28#include <asm/time.h> 29#include <asm/time.h>
29#include <asm/io.h> 30#include <asm/io.h>
30#include <asm/uaccess.h> 31#include <asm/uaccess.h>
diff --git a/drivers/staging/winbond/wbusb.c b/drivers/staging/winbond/wbusb.c
index 8950724f168e..067082a7d759 100644
--- a/drivers/staging/winbond/wbusb.c
+++ b/drivers/staging/winbond/wbusb.c
@@ -51,10 +51,26 @@ static struct ieee80211_supported_band wbsoft_band_2GHz = {
51 .n_bitrates = ARRAY_SIZE(wbsoft_rates), 51 .n_bitrates = ARRAY_SIZE(wbsoft_rates),
52}; 52};
53 53
54static void hal_set_beacon_period(struct hw_data *pHwData, u16 beacon_period)
55{
56 u32 tmp;
57
58 if (pHwData->SurpriseRemove)
59 return;
60
61 pHwData->BeaconPeriod = beacon_period;
62 tmp = pHwData->BeaconPeriod << 16;
63 tmp |= pHwData->ProbeDelay;
64 Wb35Reg_Write(pHwData, 0x0848, tmp);
65}
66
54static int wbsoft_add_interface(struct ieee80211_hw *dev, 67static int wbsoft_add_interface(struct ieee80211_hw *dev,
55 struct ieee80211_if_init_conf *conf) 68 struct ieee80211_if_init_conf *conf)
56{ 69{
57 printk("wbsoft_add interface called\n"); 70 struct wbsoft_priv *priv = dev->priv;
71
72 hal_set_beacon_period(&priv->sHwData, conf->vif->bss_conf.beacon_int);
73
58 return 0; 74 return 0;
59} 75}
60 76
@@ -83,10 +99,16 @@ static int wbsoft_get_tx_stats(struct ieee80211_hw *hw,
83 return 0; 99 return 0;
84} 100}
85 101
102static u64 wbsoft_prepare_multicast(struct ieee80211_hw *hw, int mc_count,
103 struct dev_addr_list *mc_list)
104{
105 return mc_count;
106}
107
86static void wbsoft_configure_filter(struct ieee80211_hw *dev, 108static void wbsoft_configure_filter(struct ieee80211_hw *dev,
87 unsigned int changed_flags, 109 unsigned int changed_flags,
88 unsigned int *total_flags, 110 unsigned int *total_flags,
89 int mc_count, struct dev_mc_list *mclist) 111 u64 multicast)
90{ 112{
91 unsigned int new_flags; 113 unsigned int new_flags;
92 114
@@ -94,7 +116,7 @@ static void wbsoft_configure_filter(struct ieee80211_hw *dev,
94 116
95 if (*total_flags & FIF_PROMISC_IN_BSS) 117 if (*total_flags & FIF_PROMISC_IN_BSS)
96 new_flags |= FIF_PROMISC_IN_BSS; 118 new_flags |= FIF_PROMISC_IN_BSS;
97 else if ((*total_flags & FIF_ALLMULTI) || (mc_count > 32)) 119 else if ((*total_flags & FIF_ALLMULTI) || (multicast > 32))
98 new_flags |= FIF_ALLMULTI; 120 new_flags |= FIF_ALLMULTI;
99 121
100 dev->flags &= ~IEEE80211_HW_RX_INCLUDES_FCS; 122 dev->flags &= ~IEEE80211_HW_RX_INCLUDES_FCS;
@@ -138,19 +160,6 @@ static void hal_set_radio_mode(struct hw_data *pHwData, unsigned char radio_off)
138 Wb35Reg_Write(pHwData, 0x0824, reg->M24_MacControl); 160 Wb35Reg_Write(pHwData, 0x0824, reg->M24_MacControl);
139} 161}
140 162
141static void hal_set_beacon_period(struct hw_data *pHwData, u16 beacon_period)
142{
143 u32 tmp;
144
145 if (pHwData->SurpriseRemove)
146 return;
147
148 pHwData->BeaconPeriod = beacon_period;
149 tmp = pHwData->BeaconPeriod << 16;
150 tmp |= pHwData->ProbeDelay;
151 Wb35Reg_Write(pHwData, 0x0848, tmp);
152}
153
154static void 163static void
155hal_set_current_channel_ex(struct hw_data *pHwData, ChanInfo channel) 164hal_set_current_channel_ex(struct hw_data *pHwData, ChanInfo channel)
156{ 165{
@@ -244,7 +253,6 @@ static void hal_set_accept_beacon(struct hw_data *pHwData, u8 enable)
244static int wbsoft_config(struct ieee80211_hw *dev, u32 changed) 253static int wbsoft_config(struct ieee80211_hw *dev, u32 changed)
245{ 254{
246 struct wbsoft_priv *priv = dev->priv; 255 struct wbsoft_priv *priv = dev->priv;
247 struct ieee80211_conf *conf = &dev->conf;
248 ChanInfo ch; 256 ChanInfo ch;
249 257
250 printk("wbsoft_config called\n"); 258 printk("wbsoft_config called\n");
@@ -254,7 +262,6 @@ static int wbsoft_config(struct ieee80211_hw *dev, u32 changed)
254 ch.ChanNo = 1; 262 ch.ChanNo = 1;
255 263
256 hal_set_current_channel(&priv->sHwData, ch); 264 hal_set_current_channel(&priv->sHwData, ch);
257 hal_set_beacon_period(&priv->sHwData, conf->beacon_int);
258 hal_set_accept_broadcast(&priv->sHwData, 1); 265 hal_set_accept_broadcast(&priv->sHwData, 1);
259 hal_set_accept_promiscuous(&priv->sHwData, 1); 266 hal_set_accept_promiscuous(&priv->sHwData, 1);
260 hal_set_accept_multicast(&priv->sHwData, 1); 267 hal_set_accept_multicast(&priv->sHwData, 1);
@@ -277,6 +284,7 @@ static const struct ieee80211_ops wbsoft_ops = {
277 .add_interface = wbsoft_add_interface, 284 .add_interface = wbsoft_add_interface,
278 .remove_interface = wbsoft_remove_interface, 285 .remove_interface = wbsoft_remove_interface,
279 .config = wbsoft_config, 286 .config = wbsoft_config,
287 .prepare_multicast = wbsoft_prepare_multicast,
280 .configure_filter = wbsoft_configure_filter, 288 .configure_filter = wbsoft_configure_filter,
281 .get_stats = wbsoft_get_stats, 289 .get_stats = wbsoft_get_stats,
282 .get_tx_stats = wbsoft_get_tx_stats, 290 .get_tx_stats = wbsoft_get_tx_stats,
diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
index a9d707047202..e941367dd28f 100644
--- a/drivers/uio/uio.c
+++ b/drivers/uio/uio.c
@@ -19,6 +19,7 @@
19#include <linux/device.h> 19#include <linux/device.h>
20#include <linux/mm.h> 20#include <linux/mm.h>
21#include <linux/idr.h> 21#include <linux/idr.h>
22#include <linux/sched.h>
22#include <linux/string.h> 23#include <linux/string.h>
23#include <linux/kobject.h> 24#include <linux/kobject.h>
24#include <linux/uio_driver.h> 25#include <linux/uio_driver.h>
diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c
index 333ee02e7b2b..2473cf0c6b1d 100644
--- a/drivers/usb/class/usbtmc.c
+++ b/drivers/usb/class/usbtmc.c
@@ -39,7 +39,7 @@
39#define USBTMC_SIZE_IOBUFFER 2048 39#define USBTMC_SIZE_IOBUFFER 2048
40 40
41/* Default USB timeout (in milliseconds) */ 41/* Default USB timeout (in milliseconds) */
42#define USBTMC_TIMEOUT 10 42#define USBTMC_TIMEOUT 5000
43 43
44/* 44/*
45 * Maximum number of read cycles to empty bulk in endpoint during CLEAR and 45 * Maximum number of read cycles to empty bulk in endpoint during CLEAR and
@@ -993,7 +993,7 @@ skip_io_on_zombie:
993 return retval; 993 return retval;
994} 994}
995 995
996static struct file_operations fops = { 996static const struct file_operations fops = {
997 .owner = THIS_MODULE, 997 .owner = THIS_MODULE,
998 .read = usbtmc_read, 998 .read = usbtmc_read,
999 .write = usbtmc_write, 999 .write = usbtmc_write,
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index f37de283d0ab..167cb2a8ecef 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -61,11 +61,6 @@
61 * simpler, Microsoft pushes their own approach: RNDIS. The published 61 * simpler, Microsoft pushes their own approach: RNDIS. The published
62 * RNDIS specs are ambiguous and appear to be incomplete, and are also 62 * RNDIS specs are ambiguous and appear to be incomplete, and are also
63 * needlessly complex. They borrow more from CDC ACM than CDC ECM. 63 * needlessly complex. They borrow more from CDC ACM than CDC ECM.
64 *
65 * While CDC ECM, CDC Subset, and RNDIS are designed to extend the ethernet
66 * interface to the target, CDC EEM was designed to use ethernet over the USB
67 * link between the host and target. CDC EEM is implemented as an alternative
68 * to those other protocols when that communication model is more appropriate
69 */ 64 */
70 65
71#define DRIVER_DESC "Ethernet Gadget" 66#define DRIVER_DESC "Ethernet Gadget"
@@ -157,8 +152,8 @@ static inline bool has_rndis(void)
157#define RNDIS_PRODUCT_NUM 0xa4a2 /* Ethernet/RNDIS Gadget */ 152#define RNDIS_PRODUCT_NUM 0xa4a2 /* Ethernet/RNDIS Gadget */
158 153
159/* For EEM gadgets */ 154/* For EEM gadgets */
160#define EEM_VENDOR_NUM 0x0525 /* INVALID - NEEDS TO BE ALLOCATED */ 155#define EEM_VENDOR_NUM 0x1d6b /* Linux Foundation */
161#define EEM_PRODUCT_NUM 0xa4a1 /* INVALID - NEEDS TO BE ALLOCATED */ 156#define EEM_PRODUCT_NUM 0x0102 /* EEM Gadget */
162 157
163/*-------------------------------------------------------------------------*/ 158/*-------------------------------------------------------------------------*/
164 159
diff --git a/drivers/usb/gadget/imx_udc.c b/drivers/usb/gadget/imx_udc.c
index c52a681f376c..01ee0b9bc957 100644
--- a/drivers/usb/gadget/imx_udc.c
+++ b/drivers/usb/gadget/imx_udc.c
@@ -1402,7 +1402,8 @@ static int __init imx_udc_probe(struct platform_device *pdev)
1402 struct clk *clk; 1402 struct clk *clk;
1403 void __iomem *base; 1403 void __iomem *base;
1404 int ret = 0; 1404 int ret = 0;
1405 int i, res_size; 1405 int i;
1406 resource_size_t res_size;
1406 1407
1407 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1408 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1408 if (!res) { 1409 if (!res) {
@@ -1416,7 +1417,7 @@ static int __init imx_udc_probe(struct platform_device *pdev)
1416 return -ENODEV; 1417 return -ENODEV;
1417 } 1418 }
1418 1419
1419 res_size = res->end - res->start + 1; 1420 res_size = resource_size(res);
1420 if (!request_mem_region(res->start, res_size, res->name)) { 1421 if (!request_mem_region(res->start, res_size, res->name)) {
1421 dev_err(&pdev->dev, "can't allocate %d bytes at %d address\n", 1422 dev_err(&pdev->dev, "can't allocate %d bytes at %d address\n",
1422 res_size, res->start); 1423 res_size, res->start);
@@ -1527,8 +1528,7 @@ static int __exit imx_udc_remove(struct platform_device *pdev)
1527 clk_disable(imx_usb->clk); 1528 clk_disable(imx_usb->clk);
1528 iounmap(imx_usb->base); 1529 iounmap(imx_usb->base);
1529 1530
1530 release_mem_region(imx_usb->res->start, 1531 release_mem_region(imx_usb->res->start, resource_size(imx_usb->res));
1531 imx_usb->res->end - imx_usb->res->start + 1);
1532 1532
1533 if (pdata->exit) 1533 if (pdata->exit)
1534 pdata->exit(&pdev->dev); 1534 pdata->exit(&pdev->dev);
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c
index c44367fea185..bf0f6520c6df 100644
--- a/drivers/usb/gadget/inode.c
+++ b/drivers/usb/gadget/inode.c
@@ -30,6 +30,7 @@
30#include <linux/wait.h> 30#include <linux/wait.h>
31#include <linux/compiler.h> 31#include <linux/compiler.h>
32#include <asm/uaccess.h> 32#include <asm/uaccess.h>
33#include <linux/sched.h>
33#include <linux/slab.h> 34#include <linux/slab.h>
34#include <linux/poll.h> 35#include <linux/poll.h>
35#include <linux/smp_lock.h> 36#include <linux/smp_lock.h>
diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c
index 29500154d00c..2d867fd22413 100644
--- a/drivers/usb/gadget/printer.c
+++ b/drivers/usb/gadget/printer.c
@@ -875,7 +875,7 @@ printer_ioctl(struct file *fd, unsigned int code, unsigned long arg)
875} 875}
876 876
877/* used after endpoint configuration */ 877/* used after endpoint configuration */
878static struct file_operations printer_io_operations = { 878static const struct file_operations printer_io_operations = {
879 .owner = THIS_MODULE, 879 .owner = THIS_MODULE,
880 .open = printer_open, 880 .open = printer_open,
881 .read = printer_read, 881 .read = printer_read,
diff --git a/drivers/usb/gadget/r8a66597-udc.h b/drivers/usb/gadget/r8a66597-udc.h
index 03087e7b9190..9a537aa07968 100644
--- a/drivers/usb/gadget/r8a66597-udc.h
+++ b/drivers/usb/gadget/r8a66597-udc.h
@@ -131,31 +131,48 @@ static inline u16 r8a66597_read(struct r8a66597 *r8a66597, unsigned long offset)
131} 131}
132 132
133static inline void r8a66597_read_fifo(struct r8a66597 *r8a66597, 133static inline void r8a66597_read_fifo(struct r8a66597 *r8a66597,
134 unsigned long offset, u16 *buf, 134 unsigned long offset,
135 unsigned char *buf,
135 int len) 136 int len)
136{ 137{
138 unsigned long fifoaddr = r8a66597->reg + offset;
139 unsigned int data;
140 int i;
141
137 if (r8a66597->pdata->on_chip) { 142 if (r8a66597->pdata->on_chip) {
138 unsigned long fifoaddr = r8a66597->reg + offset; 143 /* 32-bit accesses for on_chip controllers */
139 unsigned long count; 144
140 union { 145 /* aligned buf case */
141 unsigned long dword; 146 if (len >= 4 && !((unsigned long)buf & 0x03)) {
142 unsigned char byte[4]; 147 insl(fifoaddr, buf, len / 4);
143 } data; 148 buf += len & ~0x03;
144 unsigned char *pb; 149 len &= 0x03;
145 int i; 150 }
146 151
147 count = len / 4; 152 /* unaligned buf case */
148 insl(fifoaddr, buf, count); 153 for (i = 0; i < len; i++) {
149 154 if (!(i & 0x03))
150 if (len & 0x00000003) { 155 data = inl(fifoaddr);
151 data.dword = inl(fifoaddr); 156
152 pb = (unsigned char *)buf + count * 4; 157 buf[i] = (data >> ((i & 0x03) * 8)) & 0xff;
153 for (i = 0; i < (len & 0x00000003); i++)
154 pb[i] = data.byte[i];
155 } 158 }
156 } else { 159 } else {
157 len = (len + 1) / 2; 160 /* 16-bit accesses for external controllers */
158 insw(r8a66597->reg + offset, buf, len); 161
162 /* aligned buf case */
163 if (len >= 2 && !((unsigned long)buf & 0x01)) {
164 insw(fifoaddr, buf, len / 2);
165 buf += len & ~0x01;
166 len &= 0x01;
167 }
168
169 /* unaligned buf case */
170 for (i = 0; i < len; i++) {
171 if (!(i & 0x01))
172 data = inw(fifoaddr);
173
174 buf[i] = (data >> ((i & 0x01) * 8)) & 0xff;
175 }
159 } 176 }
160} 177}
161 178
@@ -166,38 +183,40 @@ static inline void r8a66597_write(struct r8a66597 *r8a66597, u16 val,
166} 183}
167 184
168static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597, 185static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597,
169 unsigned long offset, u16 *buf, 186 unsigned long offset,
187 unsigned char *buf,
170 int len) 188 int len)
171{ 189{
172 unsigned long fifoaddr = r8a66597->reg + offset; 190 unsigned long fifoaddr = r8a66597->reg + offset;
191 int adj = 0;
192 int i;
173 193
174 if (r8a66597->pdata->on_chip) { 194 if (r8a66597->pdata->on_chip) {
175 unsigned long count; 195 /* 32-bit access only if buf is 32-bit aligned */
176 unsigned char *pb; 196 if (len >= 4 && !((unsigned long)buf & 0x03)) {
177 int i; 197 outsl(fifoaddr, buf, len / 4);
178 198 buf += len & ~0x03;
179 count = len / 4; 199 len &= 0x03;
180 outsl(fifoaddr, buf, count);
181
182 if (len & 0x00000003) {
183 pb = (unsigned char *)buf + count * 4;
184 for (i = 0; i < (len & 0x00000003); i++) {
185 if (r8a66597_read(r8a66597, CFIFOSEL) & BIGEND)
186 outb(pb[i], fifoaddr + i);
187 else
188 outb(pb[i], fifoaddr + 3 - i);
189 }
190 } 200 }
191 } else { 201 } else {
192 int odd = len & 0x0001; 202 /* 16-bit access only if buf is 16-bit aligned */
193 203 if (len >= 2 && !((unsigned long)buf & 0x01)) {
194 len = len / 2; 204 outsw(fifoaddr, buf, len / 2);
195 outsw(fifoaddr, buf, len); 205 buf += len & ~0x01;
196 if (unlikely(odd)) { 206 len &= 0x01;
197 buf = &buf[len];
198 outb((unsigned char)*buf, fifoaddr);
199 } 207 }
200 } 208 }
209
210 /* adjust fifo address in the little endian case */
211 if (!(r8a66597_read(r8a66597, CFIFOSEL) & BIGEND)) {
212 if (r8a66597->pdata->on_chip)
213 adj = 0x03; /* 32-bit wide */
214 else
215 adj = 0x01; /* 16-bit wide */
216 }
217
218 for (i = 0; i < len; i++)
219 outb(buf[i], fifoaddr + adj - (i & adj));
201} 220}
202 221
203static inline void r8a66597_mdfy(struct r8a66597 *r8a66597, 222static inline void r8a66597_mdfy(struct r8a66597 *r8a66597,
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index 3ea05936851f..b25cdea93a1f 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -1400,6 +1400,10 @@ iso_stream_schedule (
1400 goto fail; 1400 goto fail;
1401 } 1401 }
1402 1402
1403 period = urb->interval;
1404 if (!stream->highspeed)
1405 period <<= 3;
1406
1403 now = ehci_readl(ehci, &ehci->regs->frame_index) % mod; 1407 now = ehci_readl(ehci, &ehci->regs->frame_index) % mod;
1404 1408
1405 /* when's the last uframe this urb could start? */ 1409 /* when's the last uframe this urb could start? */
@@ -1417,14 +1421,15 @@ iso_stream_schedule (
1417 1421
1418 /* Fell behind (by up to twice the slop amount)? */ 1422 /* Fell behind (by up to twice the slop amount)? */
1419 if (start >= max - 2 * 8 * SCHEDULE_SLOP) 1423 if (start >= max - 2 * 8 * SCHEDULE_SLOP)
1420 start += stream->interval * DIV_ROUND_UP( 1424 start += period * DIV_ROUND_UP(
1421 max - start, stream->interval) - mod; 1425 max - start, period) - mod;
1422 1426
1423 /* Tried to schedule too far into the future? */ 1427 /* Tried to schedule too far into the future? */
1424 if (unlikely((start + sched->span) >= max)) { 1428 if (unlikely((start + sched->span) >= max)) {
1425 status = -EFBIG; 1429 status = -EFBIG;
1426 goto fail; 1430 goto fail;
1427 } 1431 }
1432 stream->next_uframe = start;
1428 goto ready; 1433 goto ready;
1429 } 1434 }
1430 1435
@@ -1440,10 +1445,6 @@ iso_stream_schedule (
1440 1445
1441 /* NOTE: assumes URB_ISO_ASAP, to limit complexity/bugs */ 1446 /* NOTE: assumes URB_ISO_ASAP, to limit complexity/bugs */
1442 1447
1443 period = urb->interval;
1444 if (!stream->highspeed)
1445 period <<= 3;
1446
1447 /* find a uframe slot with enough bandwidth */ 1448 /* find a uframe slot with enough bandwidth */
1448 for (; start < (stream->next_uframe + period); start++) { 1449 for (; start < (stream->next_uframe + period); start++) {
1449 int enough_space; 1450 int enough_space;
diff --git a/drivers/usb/host/isp1362-hcd.c b/drivers/usb/host/isp1362-hcd.c
index e35d82808bab..5c774ab98252 100644
--- a/drivers/usb/host/isp1362-hcd.c
+++ b/drivers/usb/host/isp1362-hcd.c
@@ -2284,10 +2284,10 @@ static int isp1362_mem_config(struct usb_hcd *hcd)
2284 dev_info(hcd->self.controller, "ISP1362 Memory usage:\n"); 2284 dev_info(hcd->self.controller, "ISP1362 Memory usage:\n");
2285 dev_info(hcd->self.controller, " ISTL: 2 * %4d: %4d @ $%04x:$%04x\n", 2285 dev_info(hcd->self.controller, " ISTL: 2 * %4d: %4d @ $%04x:$%04x\n",
2286 istl_size / 2, istl_size, 0, istl_size / 2); 2286 istl_size / 2, istl_size, 0, istl_size / 2);
2287 dev_info(hcd->self.controller, " INTL: %4d * (%3u+8): %4d @ $%04x\n", 2287 dev_info(hcd->self.controller, " INTL: %4d * (%3lu+8): %4d @ $%04x\n",
2288 ISP1362_INTL_BUFFERS, intl_blksize - PTD_HEADER_SIZE, 2288 ISP1362_INTL_BUFFERS, intl_blksize - PTD_HEADER_SIZE,
2289 intl_size, istl_size); 2289 intl_size, istl_size);
2290 dev_info(hcd->self.controller, " ATL : %4d * (%3u+8): %4d @ $%04x\n", 2290 dev_info(hcd->self.controller, " ATL : %4d * (%3lu+8): %4d @ $%04x\n",
2291 atl_buffers, atl_blksize - PTD_HEADER_SIZE, 2291 atl_buffers, atl_blksize - PTD_HEADER_SIZE,
2292 atl_size, istl_size + intl_size); 2292 atl_size, istl_size + intl_size);
2293 dev_info(hcd->self.controller, " USED/FREE: %4d %4d\n", total, 2293 dev_info(hcd->self.controller, " USED/FREE: %4d %4d\n", total,
@@ -2677,12 +2677,12 @@ static int __devexit isp1362_remove(struct platform_device *pdev)
2677 DBG(0, "%s: Removing HCD\n", __func__); 2677 DBG(0, "%s: Removing HCD\n", __func__);
2678 usb_remove_hcd(hcd); 2678 usb_remove_hcd(hcd);
2679 2679
2680 DBG(0, "%s: Unmapping data_reg @ %08x\n", __func__, 2680 DBG(0, "%s: Unmapping data_reg @ %p\n", __func__,
2681 (u32)isp1362_hcd->data_reg); 2681 isp1362_hcd->data_reg);
2682 iounmap(isp1362_hcd->data_reg); 2682 iounmap(isp1362_hcd->data_reg);
2683 2683
2684 DBG(0, "%s: Unmapping addr_reg @ %08x\n", __func__, 2684 DBG(0, "%s: Unmapping addr_reg @ %p\n", __func__,
2685 (u32)isp1362_hcd->addr_reg); 2685 isp1362_hcd->addr_reg);
2686 iounmap(isp1362_hcd->addr_reg); 2686 iounmap(isp1362_hcd->addr_reg);
2687 2687
2688 res = platform_get_resource(pdev, IORESOURCE_MEM, 1); 2688 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
@@ -2810,16 +2810,16 @@ static int __init isp1362_probe(struct platform_device *pdev)
2810 return 0; 2810 return 0;
2811 2811
2812 err6: 2812 err6:
2813 DBG(0, "%s: Freeing dev %08x\n", __func__, (u32)isp1362_hcd); 2813 DBG(0, "%s: Freeing dev %p\n", __func__, isp1362_hcd);
2814 usb_put_hcd(hcd); 2814 usb_put_hcd(hcd);
2815 err5: 2815 err5:
2816 DBG(0, "%s: Unmapping data_reg @ %08x\n", __func__, (u32)data_reg); 2816 DBG(0, "%s: Unmapping data_reg @ %p\n", __func__, data_reg);
2817 iounmap(data_reg); 2817 iounmap(data_reg);
2818 err4: 2818 err4:
2819 DBG(0, "%s: Releasing mem region %08lx\n", __func__, (long unsigned int)data->start); 2819 DBG(0, "%s: Releasing mem region %08lx\n", __func__, (long unsigned int)data->start);
2820 release_mem_region(data->start, resource_len(data)); 2820 release_mem_region(data->start, resource_len(data));
2821 err3: 2821 err3:
2822 DBG(0, "%s: Unmapping addr_reg @ %08x\n", __func__, (u32)addr_reg); 2822 DBG(0, "%s: Unmapping addr_reg @ %p\n", __func__, addr_reg);
2823 iounmap(addr_reg); 2823 iounmap(addr_reg);
2824 err2: 2824 err2:
2825 DBG(0, "%s: Releasing mem region %08lx\n", __func__, (long unsigned int)addr->start); 2825 DBG(0, "%s: Releasing mem region %08lx\n", __func__, (long unsigned int)addr->start);
diff --git a/drivers/usb/host/isp1362.h b/drivers/usb/host/isp1362.h
index fe60f62a32f3..1a253ebf7e50 100644
--- a/drivers/usb/host/isp1362.h
+++ b/drivers/usb/host/isp1362.h
@@ -580,7 +580,7 @@ static inline const char *ISP1362_INT_NAME(int n)
580 580
581static inline void ALIGNSTAT(struct isp1362_hcd *isp1362_hcd, void *ptr) 581static inline void ALIGNSTAT(struct isp1362_hcd *isp1362_hcd, void *ptr)
582{ 582{
583 unsigned p = (unsigned)ptr; 583 unsigned long p = (unsigned long)ptr;
584 if (!(p & 0xf)) 584 if (!(p & 0xf))
585 isp1362_hcd->stat16++; 585 isp1362_hcd->stat16++;
586 else if (!(p & 0x7)) 586 else if (!(p & 0x7))
@@ -770,7 +770,7 @@ static void isp1362_write_fifo(struct isp1362_hcd *isp1362_hcd, void *buf, u16 l
770 if (!len) 770 if (!len)
771 return; 771 return;
772 772
773 if ((unsigned)dp & 0x1) { 773 if ((unsigned long)dp & 0x1) {
774 /* not aligned */ 774 /* not aligned */
775 for (; len > 1; len -= 2) { 775 for (; len > 1; len -= 2) {
776 data = *dp++; 776 data = *dp++;
@@ -962,8 +962,8 @@ static void isp1362_read_buffer(struct isp1362_hcd *isp1362_hcd, void *buf, u16
962 962
963 isp1362_write_diraddr(isp1362_hcd, offset, len); 963 isp1362_write_diraddr(isp1362_hcd, offset, len);
964 964
965 DBG(3, "%s: Reading %d byte from buffer @%04x to memory @ %08x\n", __func__, 965 DBG(3, "%s: Reading %d byte from buffer @%04x to memory @ %p\n",
966 len, offset, (u32)buf); 966 __func__, len, offset, buf);
967 967
968 isp1362_write_reg16(isp1362_hcd, HCuPINT, HCuPINT_EOT); 968 isp1362_write_reg16(isp1362_hcd, HCuPINT, HCuPINT_EOT);
969 _WARN_ON((isp1362_read_reg16(isp1362_hcd, HCuPINT) & HCuPINT_EOT)); 969 _WARN_ON((isp1362_read_reg16(isp1362_hcd, HCuPINT) & HCuPINT_EOT));
@@ -982,8 +982,8 @@ static void isp1362_write_buffer(struct isp1362_hcd *isp1362_hcd, void *buf, u16
982 982
983 isp1362_write_diraddr(isp1362_hcd, offset, len); 983 isp1362_write_diraddr(isp1362_hcd, offset, len);
984 984
985 DBG(3, "%s: Writing %d byte to buffer @%04x from memory @ %08x\n", __func__, 985 DBG(3, "%s: Writing %d byte to buffer @%04x from memory @ %p\n",
986 len, offset, (u32)buf); 986 __func__, len, offset, buf);
987 987
988 isp1362_write_reg16(isp1362_hcd, HCuPINT, HCuPINT_EOT); 988 isp1362_write_reg16(isp1362_hcd, HCuPINT, HCuPINT_EOT);
989 _WARN_ON((isp1362_read_reg16(isp1362_hcd, HCuPINT) & HCuPINT_EOT)); 989 _WARN_ON((isp1362_read_reg16(isp1362_hcd, HCuPINT) & HCuPINT_EOT));
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
index 23cf3bde4762..83b5f9cea85a 100644
--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -475,4 +475,4 @@ static void __devinit quirk_usb_early_handoff(struct pci_dev *pdev)
475 else if (pdev->class == PCI_CLASS_SERIAL_USB_XHCI) 475 else if (pdev->class == PCI_CLASS_SERIAL_USB_XHCI)
476 quirk_usb_handoff_xhci(pdev); 476 quirk_usb_handoff_xhci(pdev);
477} 477}
478DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, quirk_usb_early_handoff); 478DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, quirk_usb_early_handoff);
diff --git a/drivers/usb/host/whci/asl.c b/drivers/usb/host/whci/asl.c
index c632437c7649..562eba108816 100644
--- a/drivers/usb/host/whci/asl.c
+++ b/drivers/usb/host/whci/asl.c
@@ -115,6 +115,10 @@ static uint32_t process_qset(struct whc *whc, struct whc_qset *qset)
115 if (status & QTD_STS_HALTED) { 115 if (status & QTD_STS_HALTED) {
116 /* Ug, an error. */ 116 /* Ug, an error. */
117 process_halted_qtd(whc, qset, td); 117 process_halted_qtd(whc, qset, td);
118 /* A halted qTD always triggers an update
119 because the qset was either removed or
120 reactivated. */
121 update |= WHC_UPDATE_UPDATED;
118 goto done; 122 goto done;
119 } 123 }
120 124
@@ -305,6 +309,7 @@ int asl_urb_dequeue(struct whc *whc, struct urb *urb, int status)
305 struct whc_urb *wurb = urb->hcpriv; 309 struct whc_urb *wurb = urb->hcpriv;
306 struct whc_qset *qset = wurb->qset; 310 struct whc_qset *qset = wurb->qset;
307 struct whc_std *std, *t; 311 struct whc_std *std, *t;
312 bool has_qtd = false;
308 int ret; 313 int ret;
309 unsigned long flags; 314 unsigned long flags;
310 315
@@ -315,17 +320,21 @@ int asl_urb_dequeue(struct whc *whc, struct urb *urb, int status)
315 goto out; 320 goto out;
316 321
317 list_for_each_entry_safe(std, t, &qset->stds, list_node) { 322 list_for_each_entry_safe(std, t, &qset->stds, list_node) {
318 if (std->urb == urb) 323 if (std->urb == urb) {
324 if (std->qtd)
325 has_qtd = true;
319 qset_free_std(whc, std); 326 qset_free_std(whc, std);
320 else 327 } else
321 std->qtd = NULL; /* so this std is re-added when the qset is */ 328 std->qtd = NULL; /* so this std is re-added when the qset is */
322 } 329 }
323 330
324 asl_qset_remove(whc, qset); 331 if (has_qtd) {
325 wurb->status = status; 332 asl_qset_remove(whc, qset);
326 wurb->is_async = true; 333 wurb->status = status;
327 queue_work(whc->workqueue, &wurb->dequeue_work); 334 wurb->is_async = true;
328 335 queue_work(whc->workqueue, &wurb->dequeue_work);
336 } else
337 qset_remove_urb(whc, qset, urb, status);
329out: 338out:
330 spin_unlock_irqrestore(&whc->lock, flags); 339 spin_unlock_irqrestore(&whc->lock, flags);
331 340
diff --git a/drivers/usb/host/whci/debug.c b/drivers/usb/host/whci/debug.c
index cf2d45946c57..2273c815941f 100644
--- a/drivers/usb/host/whci/debug.c
+++ b/drivers/usb/host/whci/debug.c
@@ -134,7 +134,7 @@ static int pzl_open(struct inode *inode, struct file *file)
134 return single_open(file, pzl_print, inode->i_private); 134 return single_open(file, pzl_print, inode->i_private);
135} 135}
136 136
137static struct file_operations di_fops = { 137static const struct file_operations di_fops = {
138 .open = di_open, 138 .open = di_open,
139 .read = seq_read, 139 .read = seq_read,
140 .llseek = seq_lseek, 140 .llseek = seq_lseek,
@@ -142,7 +142,7 @@ static struct file_operations di_fops = {
142 .owner = THIS_MODULE, 142 .owner = THIS_MODULE,
143}; 143};
144 144
145static struct file_operations asl_fops = { 145static const struct file_operations asl_fops = {
146 .open = asl_open, 146 .open = asl_open,
147 .read = seq_read, 147 .read = seq_read,
148 .llseek = seq_lseek, 148 .llseek = seq_lseek,
@@ -150,7 +150,7 @@ static struct file_operations asl_fops = {
150 .owner = THIS_MODULE, 150 .owner = THIS_MODULE,
151}; 151};
152 152
153static struct file_operations pzl_fops = { 153static const struct file_operations pzl_fops = {
154 .open = pzl_open, 154 .open = pzl_open,
155 .read = seq_read, 155 .read = seq_read,
156 .llseek = seq_lseek, 156 .llseek = seq_lseek,
diff --git a/drivers/usb/host/whci/pzl.c b/drivers/usb/host/whci/pzl.c
index a9e05bac6646..0db3fb2dc03a 100644
--- a/drivers/usb/host/whci/pzl.c
+++ b/drivers/usb/host/whci/pzl.c
@@ -121,6 +121,10 @@ static enum whc_update pzl_process_qset(struct whc *whc, struct whc_qset *qset)
121 if (status & QTD_STS_HALTED) { 121 if (status & QTD_STS_HALTED) {
122 /* Ug, an error. */ 122 /* Ug, an error. */
123 process_halted_qtd(whc, qset, td); 123 process_halted_qtd(whc, qset, td);
124 /* A halted qTD always triggers an update
125 because the qset was either removed or
126 reactivated. */
127 update |= WHC_UPDATE_UPDATED;
124 goto done; 128 goto done;
125 } 129 }
126 130
@@ -333,6 +337,7 @@ int pzl_urb_dequeue(struct whc *whc, struct urb *urb, int status)
333 struct whc_urb *wurb = urb->hcpriv; 337 struct whc_urb *wurb = urb->hcpriv;
334 struct whc_qset *qset = wurb->qset; 338 struct whc_qset *qset = wurb->qset;
335 struct whc_std *std, *t; 339 struct whc_std *std, *t;
340 bool has_qtd = false;
336 int ret; 341 int ret;
337 unsigned long flags; 342 unsigned long flags;
338 343
@@ -343,17 +348,22 @@ int pzl_urb_dequeue(struct whc *whc, struct urb *urb, int status)
343 goto out; 348 goto out;
344 349
345 list_for_each_entry_safe(std, t, &qset->stds, list_node) { 350 list_for_each_entry_safe(std, t, &qset->stds, list_node) {
346 if (std->urb == urb) 351 if (std->urb == urb) {
352 if (std->qtd)
353 has_qtd = true;
347 qset_free_std(whc, std); 354 qset_free_std(whc, std);
348 else 355 } else
349 std->qtd = NULL; /* so this std is re-added when the qset is */ 356 std->qtd = NULL; /* so this std is re-added when the qset is */
350 } 357 }
351 358
352 pzl_qset_remove(whc, qset); 359 if (has_qtd) {
353 wurb->status = status; 360 pzl_qset_remove(whc, qset);
354 wurb->is_async = false; 361 update_pzl_hw_view(whc);
355 queue_work(whc->workqueue, &wurb->dequeue_work); 362 wurb->status = status;
356 363 wurb->is_async = false;
364 queue_work(whc->workqueue, &wurb->dequeue_work);
365 } else
366 qset_remove_urb(whc, qset, urb, status);
357out: 367out:
358 spin_unlock_irqrestore(&whc->lock, flags); 368 spin_unlock_irqrestore(&whc->lock, flags);
359 369
diff --git a/drivers/usb/host/xhci-hcd.c b/drivers/usb/host/xhci-hcd.c
index 99911e727e0b..932f99938481 100644
--- a/drivers/usb/host/xhci-hcd.c
+++ b/drivers/usb/host/xhci-hcd.c
@@ -335,6 +335,12 @@ void xhci_event_ring_work(unsigned long arg)
335 spin_lock_irqsave(&xhci->lock, flags); 335 spin_lock_irqsave(&xhci->lock, flags);
336 temp = xhci_readl(xhci, &xhci->op_regs->status); 336 temp = xhci_readl(xhci, &xhci->op_regs->status);
337 xhci_dbg(xhci, "op reg status = 0x%x\n", temp); 337 xhci_dbg(xhci, "op reg status = 0x%x\n", temp);
338 if (temp == 0xffffffff) {
339 xhci_dbg(xhci, "HW died, polling stopped.\n");
340 spin_unlock_irqrestore(&xhci->lock, flags);
341 return;
342 }
343
338 temp = xhci_readl(xhci, &xhci->ir_set->irq_pending); 344 temp = xhci_readl(xhci, &xhci->ir_set->irq_pending);
339 xhci_dbg(xhci, "ir_set 0 pending = 0x%x\n", temp); 345 xhci_dbg(xhci, "ir_set 0 pending = 0x%x\n", temp);
340 xhci_dbg(xhci, "No-op commands handled = %d\n", xhci->noops_handled); 346 xhci_dbg(xhci, "No-op commands handled = %d\n", xhci->noops_handled);
@@ -776,6 +782,7 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
776{ 782{
777 unsigned long flags; 783 unsigned long flags;
778 int ret; 784 int ret;
785 u32 temp;
779 struct xhci_hcd *xhci; 786 struct xhci_hcd *xhci;
780 struct xhci_td *td; 787 struct xhci_td *td;
781 unsigned int ep_index; 788 unsigned int ep_index;
@@ -788,6 +795,17 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
788 ret = usb_hcd_check_unlink_urb(hcd, urb, status); 795 ret = usb_hcd_check_unlink_urb(hcd, urb, status);
789 if (ret || !urb->hcpriv) 796 if (ret || !urb->hcpriv)
790 goto done; 797 goto done;
798 temp = xhci_readl(xhci, &xhci->op_regs->status);
799 if (temp == 0xffffffff) {
800 xhci_dbg(xhci, "HW died, freeing TD.\n");
801 td = (struct xhci_td *) urb->hcpriv;
802
803 usb_hcd_unlink_urb_from_ep(hcd, urb);
804 spin_unlock_irqrestore(&xhci->lock, flags);
805 usb_hcd_giveback_urb(xhci_to_hcd(xhci), urb, -ESHUTDOWN);
806 kfree(td);
807 return ret;
808 }
791 809
792 xhci_dbg(xhci, "Cancel URB %p\n", urb); 810 xhci_dbg(xhci, "Cancel URB %p\n", urb);
793 xhci_dbg(xhci, "Event ring:\n"); 811 xhci_dbg(xhci, "Event ring:\n");
@@ -877,7 +895,7 @@ int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
877 ctrl_ctx->drop_flags |= drop_flag; 895 ctrl_ctx->drop_flags |= drop_flag;
878 new_drop_flags = ctrl_ctx->drop_flags; 896 new_drop_flags = ctrl_ctx->drop_flags;
879 897
880 ctrl_ctx->add_flags = ~drop_flag; 898 ctrl_ctx->add_flags &= ~drop_flag;
881 new_add_flags = ctrl_ctx->add_flags; 899 new_add_flags = ctrl_ctx->add_flags;
882 900
883 last_ctx = xhci_last_valid_endpoint(ctrl_ctx->add_flags); 901 last_ctx = xhci_last_valid_endpoint(ctrl_ctx->add_flags);
@@ -1410,11 +1428,20 @@ void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev)
1410{ 1428{
1411 struct xhci_hcd *xhci = hcd_to_xhci(hcd); 1429 struct xhci_hcd *xhci = hcd_to_xhci(hcd);
1412 unsigned long flags; 1430 unsigned long flags;
1431 u32 state;
1413 1432
1414 if (udev->slot_id == 0) 1433 if (udev->slot_id == 0)
1415 return; 1434 return;
1416 1435
1417 spin_lock_irqsave(&xhci->lock, flags); 1436 spin_lock_irqsave(&xhci->lock, flags);
1437 /* Don't disable the slot if the host controller is dead. */
1438 state = xhci_readl(xhci, &xhci->op_regs->status);
1439 if (state == 0xffffffff) {
1440 xhci_free_virt_device(xhci, udev->slot_id);
1441 spin_unlock_irqrestore(&xhci->lock, flags);
1442 return;
1443 }
1444
1418 if (xhci_queue_slot_control(xhci, TRB_DISABLE_SLOT, udev->slot_id)) { 1445 if (xhci_queue_slot_control(xhci, TRB_DISABLE_SLOT, udev->slot_id)) {
1419 spin_unlock_irqrestore(&xhci->lock, flags); 1446 spin_unlock_irqrestore(&xhci->lock, flags);
1420 xhci_dbg(xhci, "FIXME: allocate a command ring segment\n"); 1447 xhci_dbg(xhci, "FIXME: allocate a command ring segment\n");
diff --git a/drivers/usb/misc/rio500.c b/drivers/usb/misc/rio500.c
index d645f3899fe1..32d0199d0c32 100644
--- a/drivers/usb/misc/rio500.c
+++ b/drivers/usb/misc/rio500.c
@@ -429,8 +429,7 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
429 return read_count; 429 return read_count;
430} 430}
431 431
432static struct 432static const struct file_operations usb_rio_fops = {
433file_operations usb_rio_fops = {
434 .owner = THIS_MODULE, 433 .owner = THIS_MODULE,
435 .read = read_rio, 434 .read = read_rio,
436 .write = write_rio, 435 .write = write_rio,
diff --git a/drivers/usb/misc/usblcd.c b/drivers/usb/misc/usblcd.c
index 29092b8e59ce..4fb120357c55 100644
--- a/drivers/usb/misc/usblcd.c
+++ b/drivers/usb/misc/usblcd.c
@@ -313,7 +313,8 @@ static int lcd_probe(struct usb_interface *interface, const struct usb_device_id
313 313
314 if (le16_to_cpu(dev->udev->descriptor.idProduct) != 0x0001) { 314 if (le16_to_cpu(dev->udev->descriptor.idProduct) != 0x0001) {
315 dev_warn(&interface->dev, "USBLCD model not supported.\n"); 315 dev_warn(&interface->dev, "USBLCD model not supported.\n");
316 return -ENODEV; 316 retval = -ENODEV;
317 goto error;
317 } 318 }
318 319
319 /* set up the endpoint information */ 320 /* set up the endpoint information */
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig
index 803adcb5ac1d..b84abd8ee8a5 100644
--- a/drivers/usb/musb/Kconfig
+++ b/drivers/usb/musb/Kconfig
@@ -8,8 +8,8 @@ comment "Enable Host or Gadget support to see Inventra options"
8 8
9# (M)HDRC = (Multipoint) Highspeed Dual-Role Controller 9# (M)HDRC = (Multipoint) Highspeed Dual-Role Controller
10config USB_MUSB_HDRC 10config USB_MUSB_HDRC
11 depends on (USB || USB_GADGET) && HAVE_CLK 11 depends on (USB || USB_GADGET)
12 depends on !SUPERH 12 depends on (ARM || BLACKFIN)
13 select NOP_USB_XCEIV if ARCH_DAVINCI 13 select NOP_USB_XCEIV if ARCH_DAVINCI
14 select TWL4030_USB if MACH_OMAP_3430SDP 14 select TWL4030_USB if MACH_OMAP_3430SDP
15 select NOP_USB_XCEIV if MACH_OMAP3EVM 15 select NOP_USB_XCEIV if MACH_OMAP3EVM
diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c
index f2f66ebc7362..fcec87ea709e 100644
--- a/drivers/usb/musb/blackfin.c
+++ b/drivers/usb/musb/blackfin.c
@@ -14,7 +14,6 @@
14#include <linux/slab.h> 14#include <linux/slab.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/list.h> 16#include <linux/list.h>
17#include <linux/clk.h>
18#include <linux/gpio.h> 17#include <linux/gpio.h>
19#include <linux/io.h> 18#include <linux/io.h>
20 19
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index 381d648a36b8..6aa5f22e5274 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -95,6 +95,13 @@ struct musb_ep;
95#endif 95#endif
96#endif /* need MUSB gadget selection */ 96#endif /* need MUSB gadget selection */
97 97
98#ifndef CONFIG_HAVE_CLK
99/* Dummy stub for clk framework */
100#define clk_get(dev, id) NULL
101#define clk_put(clock) do {} while (0)
102#define clk_enable(clock) do {} while (0)
103#define clk_disable(clock) do {} while (0)
104#endif
98 105
99#ifdef CONFIG_PROC_FS 106#ifdef CONFIG_PROC_FS
100#include <linux/fs.h> 107#include <linux/fs.h>
diff --git a/drivers/usb/musb/musb_regs.h b/drivers/usb/musb/musb_regs.h
index fbfd3fd9ce1f..cc1d71b57d3c 100644
--- a/drivers/usb/musb/musb_regs.h
+++ b/drivers/usb/musb/musb_regs.h
@@ -439,15 +439,6 @@ static inline void musb_write_txhubport(void __iomem *mbase, u8 epnum,
439/* Not implemented - HW has seperate Tx/Rx FIFO */ 439/* Not implemented - HW has seperate Tx/Rx FIFO */
440#define MUSB_TXCSR_MODE 0x0000 440#define MUSB_TXCSR_MODE 0x0000
441 441
442/*
443 * Dummy stub for clk framework, it will be removed
444 * until Blackfin supports clk framework
445 */
446#define clk_get(dev, id) NULL
447#define clk_put(clock) do {} while (0)
448#define clk_enable(clock) do {} while (0)
449#define clk_disable(clock) do {} while (0)
450
451static inline void musb_write_txfifosz(void __iomem *mbase, u8 c_size) 442static inline void musb_write_txfifosz(void __iomem *mbase, u8 c_size)
452{ 443{
453} 444}
diff --git a/drivers/usb/serial/aircable.c b/drivers/usb/serial/aircable.c
index 2cbfab3716e5..b10ac8409411 100644
--- a/drivers/usb/serial/aircable.c
+++ b/drivers/usb/serial/aircable.c
@@ -554,13 +554,12 @@ static void aircable_throttle(struct tty_struct *tty)
554{ 554{
555 struct usb_serial_port *port = tty->driver_data; 555 struct usb_serial_port *port = tty->driver_data;
556 struct aircable_private *priv = usb_get_serial_port_data(port); 556 struct aircable_private *priv = usb_get_serial_port_data(port);
557 unsigned long flags;
558 557
559 dbg("%s - port %d", __func__, port->number); 558 dbg("%s - port %d", __func__, port->number);
560 559
561 spin_lock_irqsave(&priv->rx_lock, flags); 560 spin_lock_irq(&priv->rx_lock);
562 priv->rx_flags |= THROTTLED; 561 priv->rx_flags |= THROTTLED;
563 spin_unlock_irqrestore(&priv->rx_lock, flags); 562 spin_unlock_irq(&priv->rx_lock);
564} 563}
565 564
566/* Based on ftdi_sio.c unthrottle */ 565/* Based on ftdi_sio.c unthrottle */
@@ -569,14 +568,13 @@ static void aircable_unthrottle(struct tty_struct *tty)
569 struct usb_serial_port *port = tty->driver_data; 568 struct usb_serial_port *port = tty->driver_data;
570 struct aircable_private *priv = usb_get_serial_port_data(port); 569 struct aircable_private *priv = usb_get_serial_port_data(port);
571 int actually_throttled; 570 int actually_throttled;
572 unsigned long flags;
573 571
574 dbg("%s - port %d", __func__, port->number); 572 dbg("%s - port %d", __func__, port->number);
575 573
576 spin_lock_irqsave(&priv->rx_lock, flags); 574 spin_lock_irq(&priv->rx_lock);
577 actually_throttled = priv->rx_flags & ACTUALLY_THROTTLED; 575 actually_throttled = priv->rx_flags & ACTUALLY_THROTTLED;
578 priv->rx_flags &= ~(THROTTLED | ACTUALLY_THROTTLED); 576 priv->rx_flags &= ~(THROTTLED | ACTUALLY_THROTTLED);
579 spin_unlock_irqrestore(&priv->rx_lock, flags); 577 spin_unlock_irq(&priv->rx_lock);
580 578
581 if (actually_throttled) 579 if (actually_throttled)
582 schedule_work(&priv->rx_work); 580 schedule_work(&priv->rx_work);
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index 4a208fe85bc9..698252a4dc5d 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -113,6 +113,7 @@ static struct usb_device_id id_table [] = {
113 { USB_DEVICE(0x166A, 0x0303) }, /* Clipsal 5500PCU C-Bus USB interface */ 113 { USB_DEVICE(0x166A, 0x0303) }, /* Clipsal 5500PCU C-Bus USB interface */
114 { USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */ 114 { USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */
115 { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */ 115 { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */
116 { USB_DEVICE(0x413C, 0x9500) }, /* DW700 GPS USB interface */
116 { } /* Terminating Entry */ 117 { } /* Terminating Entry */
117}; 118};
118 119
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
index e0a8b715f2f2..a591ebec0f89 100644
--- a/drivers/usb/serial/cypress_m8.c
+++ b/drivers/usb/serial/cypress_m8.c
@@ -1155,13 +1155,12 @@ static void cypress_throttle(struct tty_struct *tty)
1155{ 1155{
1156 struct usb_serial_port *port = tty->driver_data; 1156 struct usb_serial_port *port = tty->driver_data;
1157 struct cypress_private *priv = usb_get_serial_port_data(port); 1157 struct cypress_private *priv = usb_get_serial_port_data(port);
1158 unsigned long flags;
1159 1158
1160 dbg("%s - port %d", __func__, port->number); 1159 dbg("%s - port %d", __func__, port->number);
1161 1160
1162 spin_lock_irqsave(&priv->lock, flags); 1161 spin_lock_irq(&priv->lock);
1163 priv->rx_flags = THROTTLED; 1162 priv->rx_flags = THROTTLED;
1164 spin_unlock_irqrestore(&priv->lock, flags); 1163 spin_unlock_irq(&priv->lock);
1165} 1164}
1166 1165
1167 1166
@@ -1170,14 +1169,13 @@ static void cypress_unthrottle(struct tty_struct *tty)
1170 struct usb_serial_port *port = tty->driver_data; 1169 struct usb_serial_port *port = tty->driver_data;
1171 struct cypress_private *priv = usb_get_serial_port_data(port); 1170 struct cypress_private *priv = usb_get_serial_port_data(port);
1172 int actually_throttled, result; 1171 int actually_throttled, result;
1173 unsigned long flags;
1174 1172
1175 dbg("%s - port %d", __func__, port->number); 1173 dbg("%s - port %d", __func__, port->number);
1176 1174
1177 spin_lock_irqsave(&priv->lock, flags); 1175 spin_lock_irq(&priv->lock);
1178 actually_throttled = priv->rx_flags & ACTUALLY_THROTTLED; 1176 actually_throttled = priv->rx_flags & ACTUALLY_THROTTLED;
1179 priv->rx_flags = 0; 1177 priv->rx_flags = 0;
1180 spin_unlock_irqrestore(&priv->lock, flags); 1178 spin_unlock_irq(&priv->lock);
1181 1179
1182 if (!priv->comm_is_ok) 1180 if (!priv->comm_is_ok)
1183 return; 1181 return;
@@ -1185,7 +1183,7 @@ static void cypress_unthrottle(struct tty_struct *tty)
1185 if (actually_throttled) { 1183 if (actually_throttled) {
1186 port->interrupt_in_urb->dev = port->serial->dev; 1184 port->interrupt_in_urb->dev = port->serial->dev;
1187 1185
1188 result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); 1186 result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
1189 if (result) { 1187 if (result) {
1190 dev_err(&port->dev, "%s - failed submitting read urb, " 1188 dev_err(&port->dev, "%s - failed submitting read urb, "
1191 "error %d\n", __func__, result); 1189 "error %d\n", __func__, result);
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c
index ab3dd991586b..68e80be6b9e1 100644
--- a/drivers/usb/serial/digi_acceleport.c
+++ b/drivers/usb/serial/digi_acceleport.c
@@ -898,16 +898,16 @@ static void digi_rx_unthrottle(struct tty_struct *tty)
898 898
899 spin_lock_irqsave(&priv->dp_port_lock, flags); 899 spin_lock_irqsave(&priv->dp_port_lock, flags);
900 900
901 /* turn throttle off */
902 priv->dp_throttled = 0;
903 priv->dp_throttle_restart = 0;
904
905 /* restart read chain */ 901 /* restart read chain */
906 if (priv->dp_throttle_restart) { 902 if (priv->dp_throttle_restart) {
907 port->read_urb->dev = port->serial->dev; 903 port->read_urb->dev = port->serial->dev;
908 ret = usb_submit_urb(port->read_urb, GFP_ATOMIC); 904 ret = usb_submit_urb(port->read_urb, GFP_ATOMIC);
909 } 905 }
910 906
907 /* turn throttle off */
908 priv->dp_throttled = 0;
909 priv->dp_throttle_restart = 0;
910
911 spin_unlock_irqrestore(&priv->dp_port_lock, flags); 911 spin_unlock_irqrestore(&priv->dp_port_lock, flags);
912 912
913 if (ret) 913 if (ret)
diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c
index 33c9e9cf9eb2..7dd0e3eadbe6 100644
--- a/drivers/usb/serial/empeg.c
+++ b/drivers/usb/serial/empeg.c
@@ -391,7 +391,7 @@ static void empeg_unthrottle(struct tty_struct *tty)
391 dbg("%s - port %d", __func__, port->number); 391 dbg("%s - port %d", __func__, port->number);
392 392
393 port->read_urb->dev = port->serial->dev; 393 port->read_urb->dev = port->serial->dev;
394 result = usb_submit_urb(port->read_urb, GFP_ATOMIC); 394 result = usb_submit_urb(port->read_urb, GFP_KERNEL);
395 if (result) 395 if (result)
396 dev_err(&port->dev, 396 dev_err(&port->dev,
397 "%s - failed submitting read urb, error %d\n", 397 "%s - failed submitting read urb, error %d\n",
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 4f883b1773d0..9c60d6d4908a 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -76,13 +76,7 @@ struct ftdi_private {
76 unsigned long last_dtr_rts; /* saved modem control outputs */ 76 unsigned long last_dtr_rts; /* saved modem control outputs */
77 wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */ 77 wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */
78 char prev_status, diff_status; /* Used for TIOCMIWAIT */ 78 char prev_status, diff_status; /* Used for TIOCMIWAIT */
79 __u8 rx_flags; /* receive state flags (throttling) */
80 spinlock_t rx_lock; /* spinlock for receive state */
81 struct delayed_work rx_work;
82 struct usb_serial_port *port; 79 struct usb_serial_port *port;
83 int rx_processed;
84 unsigned long rx_bytes;
85
86 __u16 interface; /* FT2232C, FT2232H or FT4232H port interface 80 __u16 interface; /* FT2232C, FT2232H or FT4232H port interface
87 (0 for FT232/245) */ 81 (0 for FT232/245) */
88 82
@@ -737,10 +731,6 @@ static const char *ftdi_chip_name[] = {
737/* Constants for read urb and write urb */ 731/* Constants for read urb and write urb */
738#define BUFSZ 512 732#define BUFSZ 512
739 733
740/* rx_flags */
741#define THROTTLED 0x01
742#define ACTUALLY_THROTTLED 0x02
743
744/* Used for TIOCMIWAIT */ 734/* Used for TIOCMIWAIT */
745#define FTDI_STATUS_B0_MASK (FTDI_RS0_CTS | FTDI_RS0_DSR | FTDI_RS0_RI | FTDI_RS0_RLSD) 735#define FTDI_STATUS_B0_MASK (FTDI_RS0_CTS | FTDI_RS0_DSR | FTDI_RS0_RI | FTDI_RS0_RLSD)
746#define FTDI_STATUS_B1_MASK (FTDI_RS_BI) 736#define FTDI_STATUS_B1_MASK (FTDI_RS_BI)
@@ -763,7 +753,7 @@ static int ftdi_write_room(struct tty_struct *tty);
763static int ftdi_chars_in_buffer(struct tty_struct *tty); 753static int ftdi_chars_in_buffer(struct tty_struct *tty);
764static void ftdi_write_bulk_callback(struct urb *urb); 754static void ftdi_write_bulk_callback(struct urb *urb);
765static void ftdi_read_bulk_callback(struct urb *urb); 755static void ftdi_read_bulk_callback(struct urb *urb);
766static void ftdi_process_read(struct work_struct *work); 756static void ftdi_process_read(struct usb_serial_port *port);
767static void ftdi_set_termios(struct tty_struct *tty, 757static void ftdi_set_termios(struct tty_struct *tty,
768 struct usb_serial_port *port, struct ktermios *old); 758 struct usb_serial_port *port, struct ktermios *old);
769static int ftdi_tiocmget(struct tty_struct *tty, struct file *file); 759static int ftdi_tiocmget(struct tty_struct *tty, struct file *file);
@@ -1234,7 +1224,6 @@ static int set_serial_info(struct tty_struct *tty,
1234 (new_serial.flags & ASYNC_FLAGS)); 1224 (new_serial.flags & ASYNC_FLAGS));
1235 priv->custom_divisor = new_serial.custom_divisor; 1225 priv->custom_divisor = new_serial.custom_divisor;
1236 1226
1237 tty->low_latency = (priv->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
1238 write_latency_timer(port); 1227 write_latency_timer(port);
1239 1228
1240check_and_exit: 1229check_and_exit:
@@ -1527,7 +1516,6 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port)
1527 } 1516 }
1528 1517
1529 kref_init(&priv->kref); 1518 kref_init(&priv->kref);
1530 spin_lock_init(&priv->rx_lock);
1531 spin_lock_init(&priv->tx_lock); 1519 spin_lock_init(&priv->tx_lock);
1532 init_waitqueue_head(&priv->delta_msr_wait); 1520 init_waitqueue_head(&priv->delta_msr_wait);
1533 /* This will push the characters through immediately rather 1521 /* This will push the characters through immediately rather
@@ -1549,7 +1537,6 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port)
1549 port->read_urb->transfer_buffer_length = BUFSZ; 1537 port->read_urb->transfer_buffer_length = BUFSZ;
1550 } 1538 }
1551 1539
1552 INIT_DELAYED_WORK(&priv->rx_work, ftdi_process_read);
1553 priv->port = port; 1540 priv->port = port;
1554 1541
1555 /* Free port's existing write urb and transfer buffer. */ 1542 /* Free port's existing write urb and transfer buffer. */
@@ -1686,6 +1673,26 @@ static int ftdi_sio_port_remove(struct usb_serial_port *port)
1686 return 0; 1673 return 0;
1687} 1674}
1688 1675
1676static int ftdi_submit_read_urb(struct usb_serial_port *port, gfp_t mem_flags)
1677{
1678 struct urb *urb = port->read_urb;
1679 struct usb_serial *serial = port->serial;
1680 int result;
1681
1682 usb_fill_bulk_urb(urb, serial->dev,
1683 usb_rcvbulkpipe(serial->dev,
1684 port->bulk_in_endpointAddress),
1685 urb->transfer_buffer,
1686 urb->transfer_buffer_length,
1687 ftdi_read_bulk_callback, port);
1688 result = usb_submit_urb(urb, mem_flags);
1689 if (result)
1690 dev_err(&port->dev,
1691 "%s - failed submitting read urb, error %d\n",
1692 __func__, result);
1693 return result;
1694}
1695
1689static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port) 1696static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port)
1690{ /* ftdi_open */ 1697{ /* ftdi_open */
1691 struct usb_device *dev = port->serial->dev; 1698 struct usb_device *dev = port->serial->dev;
@@ -1700,12 +1707,6 @@ static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port)
1700 spin_lock_irqsave(&priv->tx_lock, flags); 1707 spin_lock_irqsave(&priv->tx_lock, flags);
1701 priv->tx_bytes = 0; 1708 priv->tx_bytes = 0;
1702 spin_unlock_irqrestore(&priv->tx_lock, flags); 1709 spin_unlock_irqrestore(&priv->tx_lock, flags);
1703 spin_lock_irqsave(&priv->rx_lock, flags);
1704 priv->rx_bytes = 0;
1705 spin_unlock_irqrestore(&priv->rx_lock, flags);
1706
1707 if (tty)
1708 tty->low_latency = (priv->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
1709 1710
1710 write_latency_timer(port); 1711 write_latency_timer(port);
1711 1712
@@ -1725,23 +1726,14 @@ static int ftdi_open(struct tty_struct *tty, struct usb_serial_port *port)
1725 ftdi_set_termios(tty, port, tty->termios); 1726 ftdi_set_termios(tty, port, tty->termios);
1726 1727
1727 /* Not throttled */ 1728 /* Not throttled */
1728 spin_lock_irqsave(&priv->rx_lock, flags); 1729 spin_lock_irqsave(&port->lock, flags);
1729 priv->rx_flags &= ~(THROTTLED | ACTUALLY_THROTTLED); 1730 port->throttled = 0;
1730 spin_unlock_irqrestore(&priv->rx_lock, flags); 1731 port->throttle_req = 0;
1732 spin_unlock_irqrestore(&port->lock, flags);
1731 1733
1732 /* Start reading from the device */ 1734 /* Start reading from the device */
1733 priv->rx_processed = 0; 1735 result = ftdi_submit_read_urb(port, GFP_KERNEL);
1734 usb_fill_bulk_urb(port->read_urb, dev, 1736 if (!result)
1735 usb_rcvbulkpipe(dev, port->bulk_in_endpointAddress),
1736 port->read_urb->transfer_buffer,
1737 port->read_urb->transfer_buffer_length,
1738 ftdi_read_bulk_callback, port);
1739 result = usb_submit_urb(port->read_urb, GFP_KERNEL);
1740 if (result)
1741 dev_err(&port->dev,
1742 "%s - failed submitting read urb, error %d\n",
1743 __func__, result);
1744 else
1745 kref_get(&priv->kref); 1737 kref_get(&priv->kref);
1746 1738
1747 return result; 1739 return result;
@@ -1787,10 +1779,6 @@ static void ftdi_close(struct usb_serial_port *port)
1787 1779
1788 dbg("%s", __func__); 1780 dbg("%s", __func__);
1789 1781
1790
1791 /* cancel any scheduled reading */
1792 cancel_delayed_work_sync(&priv->rx_work);
1793
1794 /* shutdown our bulk read */ 1782 /* shutdown our bulk read */
1795 usb_kill_urb(port->read_urb); 1783 usb_kill_urb(port->read_urb);
1796 kref_put(&priv->kref, ftdi_sio_priv_release); 1784 kref_put(&priv->kref, ftdi_sio_priv_release);
@@ -2013,271 +2001,121 @@ static int ftdi_chars_in_buffer(struct tty_struct *tty)
2013 return buffered; 2001 return buffered;
2014} 2002}
2015 2003
2016static void ftdi_read_bulk_callback(struct urb *urb) 2004static int ftdi_process_packet(struct tty_struct *tty,
2005 struct usb_serial_port *port, struct ftdi_private *priv,
2006 char *packet, int len)
2017{ 2007{
2018 struct usb_serial_port *port = urb->context; 2008 int i;
2019 struct tty_struct *tty; 2009 char status;
2020 struct ftdi_private *priv; 2010 char flag;
2021 unsigned long countread; 2011 char *ch;
2022 unsigned long flags;
2023 int status = urb->status;
2024
2025 if (urb->number_of_packets > 0) {
2026 dev_err(&port->dev, "%s transfer_buffer_length %d "
2027 "actual_length %d number of packets %d\n", __func__,
2028 urb->transfer_buffer_length,
2029 urb->actual_length, urb->number_of_packets);
2030 dev_err(&port->dev, "%s transfer_flags %x\n", __func__,
2031 urb->transfer_flags);
2032 }
2033 2012
2034 dbg("%s - port %d", __func__, port->number); 2013 dbg("%s - port %d", __func__, port->number);
2035 2014
2036 if (port->port.count <= 0) 2015 if (len < 2) {
2037 return; 2016 dbg("malformed packet");
2038 2017 return 0;
2039 tty = tty_port_tty_get(&port->port);
2040 if (!tty) {
2041 dbg("%s - bad tty pointer - exiting", __func__);
2042 return;
2043 } 2018 }
2044 2019
2045 priv = usb_get_serial_port_data(port); 2020 /* Compare new line status to the old one, signal if different/
2046 if (!priv) { 2021 N.B. packet may be processed more than once, but differences
2047 dbg("%s - bad port private data pointer - exiting", __func__); 2022 are only processed once. */
2048 goto out; 2023 status = packet[0] & FTDI_STATUS_B0_MASK;
2024 if (status != priv->prev_status) {
2025 priv->diff_status |= status ^ priv->prev_status;
2026 wake_up_interruptible(&priv->delta_msr_wait);
2027 priv->prev_status = status;
2049 } 2028 }
2050 2029
2051 if (urb != port->read_urb) 2030 /*
2052 dev_err(&port->dev, "%s - Not my urb!\n", __func__); 2031 * Although the device uses a bitmask and hence can have multiple
2053 2032 * errors on a packet - the order here sets the priority the error is
2054 if (status) { 2033 * returned to the tty layer.
2055 /* This will happen at close every time so it is a dbg not an 2034 */
2056 err */ 2035 flag = TTY_NORMAL;
2057 dbg("(this is ok on close) nonzero read bulk status received: %d", status); 2036 if (packet[1] & FTDI_RS_OE) {
2058 goto out; 2037 flag = TTY_OVERRUN;
2038 dbg("OVERRRUN error");
2039 }
2040 if (packet[1] & FTDI_RS_BI) {
2041 flag = TTY_BREAK;
2042 dbg("BREAK received");
2043 usb_serial_handle_break(port);
2044 }
2045 if (packet[1] & FTDI_RS_PE) {
2046 flag = TTY_PARITY;
2047 dbg("PARITY error");
2048 }
2049 if (packet[1] & FTDI_RS_FE) {
2050 flag = TTY_FRAME;
2051 dbg("FRAMING error");
2059 } 2052 }
2060 2053
2061 /* count data bytes, but not status bytes */ 2054 len -= 2;
2062 countread = urb->actual_length; 2055 if (!len)
2063 countread -= 2 * DIV_ROUND_UP(countread, priv->max_packet_size); 2056 return 0; /* status only */
2064 spin_lock_irqsave(&priv->rx_lock, flags); 2057 ch = packet + 2;
2065 priv->rx_bytes += countread; 2058
2066 spin_unlock_irqrestore(&priv->rx_lock, flags); 2059 if (!(port->console && port->sysrq) && flag == TTY_NORMAL)
2067 2060 tty_insert_flip_string(tty, ch, len);
2068 ftdi_process_read(&priv->rx_work.work); 2061 else {
2069out: 2062 for (i = 0; i < len; i++, ch++) {
2070 tty_kref_put(tty); 2063 if (!usb_serial_handle_sysrq_char(tty, port, *ch))
2071} /* ftdi_read_bulk_callback */ 2064 tty_insert_flip_char(tty, *ch, flag);
2072 2065 }
2066 }
2067 return len;
2068}
2073 2069
2074static void ftdi_process_read(struct work_struct *work) 2070static void ftdi_process_read(struct usb_serial_port *port)
2075{ /* ftdi_process_read */ 2071{
2076 struct ftdi_private *priv = 2072 struct urb *urb = port->read_urb;
2077 container_of(work, struct ftdi_private, rx_work.work);
2078 struct usb_serial_port *port = priv->port;
2079 struct urb *urb;
2080 struct tty_struct *tty; 2073 struct tty_struct *tty;
2081 char error_flag; 2074 struct ftdi_private *priv = usb_get_serial_port_data(port);
2082 unsigned char *data; 2075 char *data = (char *)urb->transfer_buffer;
2083
2084 int i; 2076 int i;
2085 int result; 2077 int len;
2086 int need_flip; 2078 int count = 0;
2087 int packet_offset;
2088 unsigned long flags;
2089
2090 dbg("%s - port %d", __func__, port->number);
2091
2092 if (port->port.count <= 0)
2093 return;
2094 2079
2095 tty = tty_port_tty_get(&port->port); 2080 tty = tty_port_tty_get(&port->port);
2096 if (!tty) { 2081 if (!tty)
2097 dbg("%s - bad tty pointer - exiting", __func__);
2098 return; 2082 return;
2099 }
2100
2101 priv = usb_get_serial_port_data(port);
2102 if (!priv) {
2103 dbg("%s - bad port private data pointer - exiting", __func__);
2104 goto out;
2105 }
2106
2107 urb = port->read_urb;
2108 if (!urb) {
2109 dbg("%s - bad read_urb pointer - exiting", __func__);
2110 goto out;
2111 }
2112
2113 data = urb->transfer_buffer;
2114 2083
2115 if (priv->rx_processed) { 2084 for (i = 0; i < urb->actual_length; i += priv->max_packet_size) {
2116 dbg("%s - already processed: %d bytes, %d remain", __func__, 2085 len = min_t(int, urb->actual_length - i, priv->max_packet_size);
2117 priv->rx_processed, 2086 count += ftdi_process_packet(tty, port, priv, &data[i], len);
2118 urb->actual_length - priv->rx_processed);
2119 } else {
2120 /* The first two bytes of every read packet are status */
2121 if (urb->actual_length > 2)
2122 usb_serial_debug_data(debug, &port->dev, __func__,
2123 urb->actual_length, data);
2124 else
2125 dbg("Status only: %03oo %03oo", data[0], data[1]);
2126 } 2087 }
2127 2088
2128 2089 if (count)
2129 /* TO DO -- check for hung up line and handle appropriately: */
2130 /* send hangup */
2131 /* See acm.c - you do a tty_hangup - eg tty_hangup(tty) */
2132 /* if CD is dropped and the line is not CLOCAL then we should hangup */
2133
2134 need_flip = 0;
2135 for (packet_offset = priv->rx_processed;
2136 packet_offset < urb->actual_length; packet_offset += priv->max_packet_size) {
2137 int length;
2138
2139 /* Compare new line status to the old one, signal if different/
2140 N.B. packet may be processed more than once, but differences
2141 are only processed once. */
2142 char new_status = data[packet_offset + 0] &
2143 FTDI_STATUS_B0_MASK;
2144 if (new_status != priv->prev_status) {
2145 priv->diff_status |=
2146 new_status ^ priv->prev_status;
2147 wake_up_interruptible(&priv->delta_msr_wait);
2148 priv->prev_status = new_status;
2149 }
2150
2151 length = min_t(u32, priv->max_packet_size, urb->actual_length-packet_offset)-2;
2152 if (length < 0) {
2153 dev_err(&port->dev, "%s - bad packet length: %d\n",
2154 __func__, length+2);
2155 length = 0;
2156 }
2157
2158 if (priv->rx_flags & THROTTLED) {
2159 dbg("%s - throttled", __func__);
2160 break;
2161 }
2162 if (tty_buffer_request_room(tty, length) < length) {
2163 /* break out & wait for throttling/unthrottling to
2164 happen */
2165 dbg("%s - receive room low", __func__);
2166 break;
2167 }
2168
2169 /* Handle errors and break */
2170 error_flag = TTY_NORMAL;
2171 /* Although the device uses a bitmask and hence can have
2172 multiple errors on a packet - the order here sets the
2173 priority the error is returned to the tty layer */
2174
2175 if (data[packet_offset+1] & FTDI_RS_OE) {
2176 error_flag = TTY_OVERRUN;
2177 dbg("OVERRRUN error");
2178 }
2179 if (data[packet_offset+1] & FTDI_RS_BI) {
2180 error_flag = TTY_BREAK;
2181 dbg("BREAK received");
2182 usb_serial_handle_break(port);
2183 }
2184 if (data[packet_offset+1] & FTDI_RS_PE) {
2185 error_flag = TTY_PARITY;
2186 dbg("PARITY error");
2187 }
2188 if (data[packet_offset+1] & FTDI_RS_FE) {
2189 error_flag = TTY_FRAME;
2190 dbg("FRAMING error");
2191 }
2192 if (length > 0) {
2193 for (i = 2; i < length+2; i++) {
2194 /* Note that the error flag is duplicated for
2195 every character received since we don't know
2196 which character it applied to */
2197 if (!usb_serial_handle_sysrq_char(tty, port,
2198 data[packet_offset + i]))
2199 tty_insert_flip_char(tty,
2200 data[packet_offset + i],
2201 error_flag);
2202 }
2203 need_flip = 1;
2204 }
2205
2206#ifdef NOT_CORRECT_BUT_KEEPING_IT_FOR_NOW
2207 /* if a parity error is detected you get status packets forever
2208 until a character is sent without a parity error.
2209 This doesn't work well since the application receives a
2210 never ending stream of bad data - even though new data
2211 hasn't been sent. Therefore I (bill) have taken this out.
2212 However - this might make sense for framing errors and so on
2213 so I am leaving the code in for now.
2214 */
2215 else {
2216 if (error_flag != TTY_NORMAL) {
2217 dbg("error_flag is not normal");
2218 /* In this case it is just status - if that is
2219 an error send a bad character */
2220 if (tty->flip.count >= TTY_FLIPBUF_SIZE)
2221 tty_flip_buffer_push(tty);
2222 tty_insert_flip_char(tty, 0xff, error_flag);
2223 need_flip = 1;
2224 }
2225 }
2226#endif
2227 } /* "for(packet_offset=0..." */
2228
2229 /* Low latency */
2230 if (need_flip)
2231 tty_flip_buffer_push(tty); 2090 tty_flip_buffer_push(tty);
2091 tty_kref_put(tty);
2092}
2232 2093
2233 if (packet_offset < urb->actual_length) { 2094static void ftdi_read_bulk_callback(struct urb *urb)
2234 /* not completely processed - record progress */ 2095{
2235 priv->rx_processed = packet_offset; 2096 struct usb_serial_port *port = urb->context;
2236 dbg("%s - incomplete, %d bytes processed, %d remain", 2097 unsigned long flags;
2237 __func__, packet_offset,
2238 urb->actual_length - packet_offset);
2239 /* check if we were throttled while processing */
2240 spin_lock_irqsave(&priv->rx_lock, flags);
2241 if (priv->rx_flags & THROTTLED) {
2242 priv->rx_flags |= ACTUALLY_THROTTLED;
2243 spin_unlock_irqrestore(&priv->rx_lock, flags);
2244 dbg("%s - deferring remainder until unthrottled",
2245 __func__);
2246 goto out;
2247 }
2248 spin_unlock_irqrestore(&priv->rx_lock, flags);
2249 /* if the port is closed stop trying to read */
2250 if (port->port.count > 0)
2251 /* delay processing of remainder */
2252 schedule_delayed_work(&priv->rx_work, 1);
2253 else
2254 dbg("%s - port is closed", __func__);
2255 goto out;
2256 }
2257
2258 /* urb is completely processed */
2259 priv->rx_processed = 0;
2260 2098
2261 /* if the port is closed stop trying to read */ 2099 dbg("%s - port %d", __func__, port->number);
2262 if (port->port.count > 0) {
2263 /* Continue trying to always read */
2264 usb_fill_bulk_urb(port->read_urb, port->serial->dev,
2265 usb_rcvbulkpipe(port->serial->dev,
2266 port->bulk_in_endpointAddress),
2267 port->read_urb->transfer_buffer,
2268 port->read_urb->transfer_buffer_length,
2269 ftdi_read_bulk_callback, port);
2270 2100
2271 result = usb_submit_urb(port->read_urb, GFP_ATOMIC); 2101 if (urb->status) {
2272 if (result) 2102 dbg("%s - nonzero read bulk status received: %d",
2273 dev_err(&port->dev, 2103 __func__, urb->status);
2274 "%s - failed resubmitting read urb, error %d\n", 2104 return;
2275 __func__, result);
2276 } 2105 }
2277out:
2278 tty_kref_put(tty);
2279} /* ftdi_process_read */
2280 2106
2107 usb_serial_debug_data(debug, &port->dev, __func__,
2108 urb->actual_length, urb->transfer_buffer);
2109 ftdi_process_read(port);
2110
2111 spin_lock_irqsave(&port->lock, flags);
2112 port->throttled = port->throttle_req;
2113 if (!port->throttled) {
2114 spin_unlock_irqrestore(&port->lock, flags);
2115 ftdi_submit_read_urb(port, GFP_ATOMIC);
2116 } else
2117 spin_unlock_irqrestore(&port->lock, flags);
2118}
2281 2119
2282static void ftdi_break_ctl(struct tty_struct *tty, int break_state) 2120static void ftdi_break_ctl(struct tty_struct *tty, int break_state)
2283{ 2121{
@@ -2609,33 +2447,31 @@ static int ftdi_ioctl(struct tty_struct *tty, struct file *file,
2609static void ftdi_throttle(struct tty_struct *tty) 2447static void ftdi_throttle(struct tty_struct *tty)
2610{ 2448{
2611 struct usb_serial_port *port = tty->driver_data; 2449 struct usb_serial_port *port = tty->driver_data;
2612 struct ftdi_private *priv = usb_get_serial_port_data(port);
2613 unsigned long flags; 2450 unsigned long flags;
2614 2451
2615 dbg("%s - port %d", __func__, port->number); 2452 dbg("%s - port %d", __func__, port->number);
2616 2453
2617 spin_lock_irqsave(&priv->rx_lock, flags); 2454 spin_lock_irqsave(&port->lock, flags);
2618 priv->rx_flags |= THROTTLED; 2455 port->throttle_req = 1;
2619 spin_unlock_irqrestore(&priv->rx_lock, flags); 2456 spin_unlock_irqrestore(&port->lock, flags);
2620} 2457}
2621 2458
2622 2459void ftdi_unthrottle(struct tty_struct *tty)
2623static void ftdi_unthrottle(struct tty_struct *tty)
2624{ 2460{
2625 struct usb_serial_port *port = tty->driver_data; 2461 struct usb_serial_port *port = tty->driver_data;
2626 struct ftdi_private *priv = usb_get_serial_port_data(port); 2462 int was_throttled;
2627 int actually_throttled;
2628 unsigned long flags; 2463 unsigned long flags;
2629 2464
2630 dbg("%s - port %d", __func__, port->number); 2465 dbg("%s - port %d", __func__, port->number);
2631 2466
2632 spin_lock_irqsave(&priv->rx_lock, flags); 2467 spin_lock_irqsave(&port->lock, flags);
2633 actually_throttled = priv->rx_flags & ACTUALLY_THROTTLED; 2468 was_throttled = port->throttled;
2634 priv->rx_flags &= ~(THROTTLED | ACTUALLY_THROTTLED); 2469 port->throttled = port->throttle_req = 0;
2635 spin_unlock_irqrestore(&priv->rx_lock, flags); 2470 spin_unlock_irqrestore(&port->lock, flags);
2636 2471
2637 if (actually_throttled) 2472 /* Resubmit urb if throttled and open. */
2638 schedule_delayed_work(&priv->rx_work, 0); 2473 if (was_throttled && test_bit(ASYNCB_INITIALIZED, &port->port.flags))
2474 ftdi_submit_read_urb(port, GFP_KERNEL);
2639} 2475}
2640 2476
2641static int __init ftdi_init(void) 2477static int __init ftdi_init(void)
diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c
index 20432d345529..5ac900e5a50e 100644
--- a/drivers/usb/serial/garmin_gps.c
+++ b/drivers/usb/serial/garmin_gps.c
@@ -1390,14 +1390,13 @@ static void garmin_throttle(struct tty_struct *tty)
1390{ 1390{
1391 struct usb_serial_port *port = tty->driver_data; 1391 struct usb_serial_port *port = tty->driver_data;
1392 struct garmin_data *garmin_data_p = usb_get_serial_port_data(port); 1392 struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
1393 unsigned long flags;
1394 1393
1395 dbg("%s - port %d", __func__, port->number); 1394 dbg("%s - port %d", __func__, port->number);
1396 /* set flag, data received will be put into a queue 1395 /* set flag, data received will be put into a queue
1397 for later processing */ 1396 for later processing */
1398 spin_lock_irqsave(&garmin_data_p->lock, flags); 1397 spin_lock_irq(&garmin_data_p->lock);
1399 garmin_data_p->flags |= FLAGS_QUEUING|FLAGS_THROTTLED; 1398 garmin_data_p->flags |= FLAGS_QUEUING|FLAGS_THROTTLED;
1400 spin_unlock_irqrestore(&garmin_data_p->lock, flags); 1399 spin_unlock_irq(&garmin_data_p->lock);
1401} 1400}
1402 1401
1403 1402
@@ -1405,13 +1404,12 @@ static void garmin_unthrottle(struct tty_struct *tty)
1405{ 1404{
1406 struct usb_serial_port *port = tty->driver_data; 1405 struct usb_serial_port *port = tty->driver_data;
1407 struct garmin_data *garmin_data_p = usb_get_serial_port_data(port); 1406 struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
1408 unsigned long flags;
1409 int status; 1407 int status;
1410 1408
1411 dbg("%s - port %d", __func__, port->number); 1409 dbg("%s - port %d", __func__, port->number);
1412 spin_lock_irqsave(&garmin_data_p->lock, flags); 1410 spin_lock_irq(&garmin_data_p->lock);
1413 garmin_data_p->flags &= ~FLAGS_THROTTLED; 1411 garmin_data_p->flags &= ~FLAGS_THROTTLED;
1414 spin_unlock_irqrestore(&garmin_data_p->lock, flags); 1412 spin_unlock_irq(&garmin_data_p->lock);
1415 1413
1416 /* in native mode send queued data to tty, in 1414 /* in native mode send queued data to tty, in
1417 serial mode nothing needs to be done here */ 1415 serial mode nothing needs to be done here */
@@ -1419,7 +1417,7 @@ static void garmin_unthrottle(struct tty_struct *tty)
1419 garmin_flush_queue(garmin_data_p); 1417 garmin_flush_queue(garmin_data_p);
1420 1418
1421 if (0 != (garmin_data_p->flags & FLAGS_BULK_IN_ACTIVE)) { 1419 if (0 != (garmin_data_p->flags & FLAGS_BULK_IN_ACTIVE)) {
1422 status = usb_submit_urb(port->read_urb, GFP_ATOMIC); 1420 status = usb_submit_urb(port->read_urb, GFP_KERNEL);
1423 if (status) 1421 if (status)
1424 dev_err(&port->dev, 1422 dev_err(&port->dev,
1425 "%s - failed resubmitting read urb, error %d\n", 1423 "%s - failed resubmitting read urb, error %d\n",
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
index deba08c7a015..bbe005cefcfb 100644
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -546,7 +546,7 @@ void usb_serial_generic_unthrottle(struct tty_struct *tty)
546 546
547 if (was_throttled) { 547 if (was_throttled) {
548 /* Resume reading from device */ 548 /* Resume reading from device */
549 usb_serial_generic_resubmit_read_urb(port, GFP_KERNEL); 549 flush_and_resubmit_read_urb(port);
550 } 550 }
551} 551}
552 552
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c
index 24fcc64b837d..d6231c38813e 100644
--- a/drivers/usb/serial/ipaq.c
+++ b/drivers/usb/serial/ipaq.c
@@ -966,6 +966,15 @@ static int ipaq_calc_num_ports(struct usb_serial *serial)
966static int ipaq_startup(struct usb_serial *serial) 966static int ipaq_startup(struct usb_serial *serial)
967{ 967{
968 dbg("%s", __func__); 968 dbg("%s", __func__);
969
970 /* Some of the devices in ipaq_id_table[] are composite, and we
971 * shouldn't bind to all the interfaces. This test will rule out
972 * some obviously invalid possibilities.
973 */
974 if (serial->num_bulk_in < serial->num_ports ||
975 serial->num_bulk_out < serial->num_ports)
976 return -ENODEV;
977
969 if (serial->dev->actconfig->desc.bConfigurationValue != 1) { 978 if (serial->dev->actconfig->desc.bConfigurationValue != 1) {
970 /* 979 /*
971 * FIXME: HP iPaq rx3715, possibly others, have 1 config that 980 * FIXME: HP iPaq rx3715, possibly others, have 1 config that
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c
index 257c16cc6b2a..1296a097f5c3 100644
--- a/drivers/usb/serial/keyspan_pda.c
+++ b/drivers/usb/serial/keyspan_pda.c
@@ -290,7 +290,7 @@ static void keyspan_pda_rx_unthrottle(struct tty_struct *tty)
290 /* just restart the receive interrupt URB */ 290 /* just restart the receive interrupt URB */
291 dbg("keyspan_pda_rx_unthrottle port %d", port->number); 291 dbg("keyspan_pda_rx_unthrottle port %d", port->number);
292 port->interrupt_in_urb->dev = port->serial->dev; 292 port->interrupt_in_urb->dev = port->serial->dev;
293 if (usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC)) 293 if (usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL))
294 dbg(" usb_submit_urb(read urb) failed"); 294 dbg(" usb_submit_urb(read urb) failed");
295 return; 295 return;
296} 296}
diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c
index f7373371b137..3a7873806f46 100644
--- a/drivers/usb/serial/kl5kusb105.c
+++ b/drivers/usb/serial/kl5kusb105.c
@@ -951,7 +951,7 @@ static void klsi_105_unthrottle(struct tty_struct *tty)
951 dbg("%s - port %d", __func__, port->number); 951 dbg("%s - port %d", __func__, port->number);
952 952
953 port->read_urb->dev = port->serial->dev; 953 port->read_urb->dev = port->serial->dev;
954 result = usb_submit_urb(port->read_urb, GFP_ATOMIC); 954 result = usb_submit_urb(port->read_urb, GFP_KERNEL);
955 if (result) 955 if (result)
956 dev_err(&port->dev, 956 dev_err(&port->dev,
957 "%s - failed submitting read urb, error %d\n", 957 "%s - failed submitting read urb, error %d\n",
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c
index ad4998bbf16f..cd009cb280a5 100644
--- a/drivers/usb/serial/mct_u232.c
+++ b/drivers/usb/serial/mct_u232.c
@@ -777,20 +777,19 @@ static void mct_u232_throttle(struct tty_struct *tty)
777{ 777{
778 struct usb_serial_port *port = tty->driver_data; 778 struct usb_serial_port *port = tty->driver_data;
779 struct mct_u232_private *priv = usb_get_serial_port_data(port); 779 struct mct_u232_private *priv = usb_get_serial_port_data(port);
780 unsigned long flags;
781 unsigned int control_state; 780 unsigned int control_state;
782 781
783 dbg("%s - port %d", __func__, port->number); 782 dbg("%s - port %d", __func__, port->number);
784 783
785 spin_lock_irqsave(&priv->lock, flags); 784 spin_lock_irq(&priv->lock);
786 priv->rx_flags |= THROTTLED; 785 priv->rx_flags |= THROTTLED;
787 if (C_CRTSCTS(tty)) { 786 if (C_CRTSCTS(tty)) {
788 priv->control_state &= ~TIOCM_RTS; 787 priv->control_state &= ~TIOCM_RTS;
789 control_state = priv->control_state; 788 control_state = priv->control_state;
790 spin_unlock_irqrestore(&priv->lock, flags); 789 spin_unlock_irq(&priv->lock);
791 (void) mct_u232_set_modem_ctrl(port->serial, control_state); 790 (void) mct_u232_set_modem_ctrl(port->serial, control_state);
792 } else { 791 } else {
793 spin_unlock_irqrestore(&priv->lock, flags); 792 spin_unlock_irq(&priv->lock);
794 } 793 }
795} 794}
796 795
@@ -799,20 +798,19 @@ static void mct_u232_unthrottle(struct tty_struct *tty)
799{ 798{
800 struct usb_serial_port *port = tty->driver_data; 799 struct usb_serial_port *port = tty->driver_data;
801 struct mct_u232_private *priv = usb_get_serial_port_data(port); 800 struct mct_u232_private *priv = usb_get_serial_port_data(port);
802 unsigned long flags;
803 unsigned int control_state; 801 unsigned int control_state;
804 802
805 dbg("%s - port %d", __func__, port->number); 803 dbg("%s - port %d", __func__, port->number);
806 804
807 spin_lock_irqsave(&priv->lock, flags); 805 spin_lock_irq(&priv->lock);
808 if ((priv->rx_flags & THROTTLED) && C_CRTSCTS(tty)) { 806 if ((priv->rx_flags & THROTTLED) && C_CRTSCTS(tty)) {
809 priv->rx_flags &= ~THROTTLED; 807 priv->rx_flags &= ~THROTTLED;
810 priv->control_state |= TIOCM_RTS; 808 priv->control_state |= TIOCM_RTS;
811 control_state = priv->control_state; 809 control_state = priv->control_state;
812 spin_unlock_irqrestore(&priv->lock, flags); 810 spin_unlock_irq(&priv->lock);
813 (void) mct_u232_set_modem_ctrl(port->serial, control_state); 811 (void) mct_u232_set_modem_ctrl(port->serial, control_state);
814 } else { 812 } else {
815 spin_unlock_irqrestore(&priv->lock, flags); 813 spin_unlock_irq(&priv->lock);
816 } 814 }
817} 815}
818 816
diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c
index 1085a577c5c1..80f59b6350cb 100644
--- a/drivers/usb/serial/opticon.c
+++ b/drivers/usb/serial/opticon.c
@@ -314,21 +314,24 @@ static void opticon_unthrottle(struct tty_struct *tty)
314 struct usb_serial_port *port = tty->driver_data; 314 struct usb_serial_port *port = tty->driver_data;
315 struct opticon_private *priv = usb_get_serial_data(port->serial); 315 struct opticon_private *priv = usb_get_serial_data(port->serial);
316 unsigned long flags; 316 unsigned long flags;
317 int result; 317 int result, was_throttled;
318 318
319 dbg("%s - port %d", __func__, port->number); 319 dbg("%s - port %d", __func__, port->number);
320 320
321 spin_lock_irqsave(&priv->lock, flags); 321 spin_lock_irqsave(&priv->lock, flags);
322 priv->throttled = false; 322 priv->throttled = false;
323 was_throttled = priv->actually_throttled;
323 priv->actually_throttled = false; 324 priv->actually_throttled = false;
324 spin_unlock_irqrestore(&priv->lock, flags); 325 spin_unlock_irqrestore(&priv->lock, flags);
325 326
326 priv->bulk_read_urb->dev = port->serial->dev; 327 priv->bulk_read_urb->dev = port->serial->dev;
327 result = usb_submit_urb(priv->bulk_read_urb, GFP_ATOMIC); 328 if (was_throttled) {
328 if (result) 329 result = usb_submit_urb(priv->bulk_read_urb, GFP_ATOMIC);
329 dev_err(&port->dev, 330 if (result)
330 "%s - failed submitting read urb, error %d\n", 331 dev_err(&port->dev,
332 "%s - failed submitting read urb, error %d\n",
331 __func__, result); 333 __func__, result);
334 }
332} 335}
333 336
334static int opticon_tiocmget(struct tty_struct *tty, struct file *file) 337static int opticon_tiocmget(struct tty_struct *tty, struct file *file)
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index f66e39883218..65d96b214f95 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -165,6 +165,7 @@ static int option_resume(struct usb_serial *serial);
165#define HUAWEI_PRODUCT_E143D 0x143D 165#define HUAWEI_PRODUCT_E143D 0x143D
166#define HUAWEI_PRODUCT_E143E 0x143E 166#define HUAWEI_PRODUCT_E143E 0x143E
167#define HUAWEI_PRODUCT_E143F 0x143F 167#define HUAWEI_PRODUCT_E143F 0x143F
168#define HUAWEI_PRODUCT_E14AC 0x14AC
168 169
169#define QUANTA_VENDOR_ID 0x0408 170#define QUANTA_VENDOR_ID 0x0408
170#define QUANTA_PRODUCT_Q101 0xEA02 171#define QUANTA_PRODUCT_Q101 0xEA02
@@ -318,6 +319,7 @@ static int option_resume(struct usb_serial *serial);
318/* TOSHIBA PRODUCTS */ 319/* TOSHIBA PRODUCTS */
319#define TOSHIBA_VENDOR_ID 0x0930 320#define TOSHIBA_VENDOR_ID 0x0930
320#define TOSHIBA_PRODUCT_HSDPA_MINICARD 0x1302 321#define TOSHIBA_PRODUCT_HSDPA_MINICARD 0x1302
322#define TOSHIBA_PRODUCT_G450 0x0d45
321 323
322#define ALINK_VENDOR_ID 0x1e0e 324#define ALINK_VENDOR_ID 0x1e0e
323#define ALINK_PRODUCT_3GU 0x9200 325#define ALINK_PRODUCT_3GU 0x9200
@@ -326,6 +328,9 @@ static int option_resume(struct usb_serial *serial);
326#define ALCATEL_VENDOR_ID 0x1bbb 328#define ALCATEL_VENDOR_ID 0x1bbb
327#define ALCATEL_PRODUCT_X060S 0x0000 329#define ALCATEL_PRODUCT_X060S 0x0000
328 330
331/* Airplus products */
332#define AIRPLUS_VENDOR_ID 0x1011
333#define AIRPLUS_PRODUCT_MCD650 0x3198
329 334
330static struct usb_device_id option_ids[] = { 335static struct usb_device_id option_ids[] = {
331 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, 336 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
@@ -424,6 +429,7 @@ static struct usb_device_id option_ids[] = {
424 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143D, 0xff, 0xff, 0xff) }, 429 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143D, 0xff, 0xff, 0xff) },
425 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143E, 0xff, 0xff, 0xff) }, 430 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143E, 0xff, 0xff, 0xff) },
426 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143F, 0xff, 0xff, 0xff) }, 431 { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143F, 0xff, 0xff, 0xff) },
432 { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E14AC) },
427 { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_9508) }, 433 { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_9508) },
428 { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) }, /* Novatel Merlin V640/XV620 */ 434 { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) }, /* Novatel Merlin V640/XV620 */
429 { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) }, /* Novatel Merlin V620/S620 */ 435 { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) }, /* Novatel Merlin V620/S620 */
@@ -581,10 +587,12 @@ static struct usb_device_id option_ids[] = {
581 { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4523) }, 587 { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4523) },
582 { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4515) }, 588 { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4515) },
583 { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4519) }, 589 { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4519) },
590 { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_G450) },
584 { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_HSDPA_MINICARD ) }, /* Toshiba 3G HSDPA == Novatel Expedite EU870D MiniCard */ 591 { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_HSDPA_MINICARD ) }, /* Toshiba 3G HSDPA == Novatel Expedite EU870D MiniCard */
585 { USB_DEVICE(ALINK_VENDOR_ID, 0x9000) }, 592 { USB_DEVICE(ALINK_VENDOR_ID, 0x9000) },
586 { USB_DEVICE_AND_INTERFACE_INFO(ALINK_VENDOR_ID, ALINK_PRODUCT_3GU, 0xff, 0xff, 0xff) }, 593 { USB_DEVICE_AND_INTERFACE_INFO(ALINK_VENDOR_ID, ALINK_PRODUCT_3GU, 0xff, 0xff, 0xff) },
587 { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S) }, 594 { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S) },
595 { USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) },
588 { } /* Terminating entry */ 596 { } /* Terminating entry */
589}; 597};
590MODULE_DEVICE_TABLE(usb, option_ids); 598MODULE_DEVICE_TABLE(usb, option_ids);
diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c
index 0f4a70ce3823..c644e26394b4 100644
--- a/drivers/usb/serial/oti6858.c
+++ b/drivers/usb/serial/oti6858.c
@@ -288,7 +288,7 @@ static void setup_line(struct work_struct *work)
288 288
289 dbg("%s(): submitting interrupt urb", __func__); 289 dbg("%s(): submitting interrupt urb", __func__);
290 port->interrupt_in_urb->dev = port->serial->dev; 290 port->interrupt_in_urb->dev = port->serial->dev;
291 result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); 291 result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
292 if (result != 0) { 292 if (result != 0) {
293 dev_err(&port->dev, "%s(): usb_submit_urb() failed" 293 dev_err(&port->dev, "%s(): usb_submit_urb() failed"
294 " with error %d\n", __func__, result); 294 " with error %d\n", __func__, result);
@@ -335,7 +335,7 @@ void send_data(struct work_struct *work)
335 335
336 dbg("%s(): submitting interrupt urb", __func__); 336 dbg("%s(): submitting interrupt urb", __func__);
337 port->interrupt_in_urb->dev = port->serial->dev; 337 port->interrupt_in_urb->dev = port->serial->dev;
338 result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); 338 result = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO);
339 if (result != 0) { 339 if (result != 0) {
340 dev_err(&port->dev, "%s(): usb_submit_urb() failed" 340 dev_err(&port->dev, "%s(): usb_submit_urb() failed"
341 " with error %d\n", __func__, result); 341 " with error %d\n", __func__, result);
@@ -349,7 +349,7 @@ void send_data(struct work_struct *work)
349 349
350 port->write_urb->transfer_buffer_length = count; 350 port->write_urb->transfer_buffer_length = count;
351 port->write_urb->dev = port->serial->dev; 351 port->write_urb->dev = port->serial->dev;
352 result = usb_submit_urb(port->write_urb, GFP_ATOMIC); 352 result = usb_submit_urb(port->write_urb, GFP_NOIO);
353 if (result != 0) { 353 if (result != 0) {
354 dev_err(&port->dev, "%s(): usb_submit_urb() failed" 354 dev_err(&port->dev, "%s(): usb_submit_urb() failed"
355 " with error %d\n", __func__, result); 355 " with error %d\n", __func__, result);
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index 1128e01525b1..9ec1a49e2362 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -1046,13 +1046,15 @@ static void pl2303_push_data(struct tty_struct *tty,
1046 /* overrun is special, not associated with a char */ 1046 /* overrun is special, not associated with a char */
1047 if (line_status & UART_OVERRUN_ERROR) 1047 if (line_status & UART_OVERRUN_ERROR)
1048 tty_insert_flip_char(tty, 0, TTY_OVERRUN); 1048 tty_insert_flip_char(tty, 0, TTY_OVERRUN);
1049 if (port->console && port->sysrq) { 1049
1050 if (tty_flag == TTY_NORMAL && !(port->console && port->sysrq))
1051 tty_insert_flip_string(tty, data, urb->actual_length);
1052 else {
1050 int i; 1053 int i;
1051 for (i = 0; i < urb->actual_length; ++i) 1054 for (i = 0; i < urb->actual_length; ++i)
1052 if (!usb_serial_handle_sysrq_char(tty, port, data[i])) 1055 if (!usb_serial_handle_sysrq_char(tty, port, data[i]))
1053 tty_insert_flip_char(tty, data[i], tty_flag); 1056 tty_insert_flip_char(tty, data[i], tty_flag);
1054 } else 1057 }
1055 tty_insert_flip_string(tty, data, urb->actual_length);
1056 tty_flip_buffer_push(tty); 1058 tty_flip_buffer_push(tty);
1057} 1059}
1058 1060
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index 8c075b2416bb..45883988a005 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -17,7 +17,7 @@
17 Whom based his on the Keyspan driver by Hugh Blemings <hugh@blemings.org> 17 Whom based his on the Keyspan driver by Hugh Blemings <hugh@blemings.org>
18*/ 18*/
19 19
20#define DRIVER_VERSION "v.1.3.7" 20#define DRIVER_VERSION "v.1.3.8"
21#define DRIVER_AUTHOR "Kevin Lloyd, Elina Pasheva, Matthew Safar, Rory Filer" 21#define DRIVER_AUTHOR "Kevin Lloyd, Elina Pasheva, Matthew Safar, Rory Filer"
22#define DRIVER_DESC "USB Driver for Sierra Wireless USB modems" 22#define DRIVER_DESC "USB Driver for Sierra Wireless USB modems"
23 23
diff --git a/drivers/usb/serial/symbolserial.c b/drivers/usb/serial/symbolserial.c
index cb7e95f9fcbf..b282c0f2d8e5 100644
--- a/drivers/usb/serial/symbolserial.c
+++ b/drivers/usb/serial/symbolserial.c
@@ -165,34 +165,36 @@ static void symbol_throttle(struct tty_struct *tty)
165{ 165{
166 struct usb_serial_port *port = tty->driver_data; 166 struct usb_serial_port *port = tty->driver_data;
167 struct symbol_private *priv = usb_get_serial_data(port->serial); 167 struct symbol_private *priv = usb_get_serial_data(port->serial);
168 unsigned long flags;
169 168
170 dbg("%s - port %d", __func__, port->number); 169 dbg("%s - port %d", __func__, port->number);
171 spin_lock_irqsave(&priv->lock, flags); 170 spin_lock_irq(&priv->lock);
172 priv->throttled = true; 171 priv->throttled = true;
173 spin_unlock_irqrestore(&priv->lock, flags); 172 spin_unlock_irq(&priv->lock);
174} 173}
175 174
176static void symbol_unthrottle(struct tty_struct *tty) 175static void symbol_unthrottle(struct tty_struct *tty)
177{ 176{
178 struct usb_serial_port *port = tty->driver_data; 177 struct usb_serial_port *port = tty->driver_data;
179 struct symbol_private *priv = usb_get_serial_data(port->serial); 178 struct symbol_private *priv = usb_get_serial_data(port->serial);
180 unsigned long flags;
181 int result; 179 int result;
180 bool was_throttled;
182 181
183 dbg("%s - port %d", __func__, port->number); 182 dbg("%s - port %d", __func__, port->number);
184 183
185 spin_lock_irqsave(&priv->lock, flags); 184 spin_lock_irq(&priv->lock);
186 priv->throttled = false; 185 priv->throttled = false;
186 was_throttled = priv->actually_throttled;
187 priv->actually_throttled = false; 187 priv->actually_throttled = false;
188 spin_unlock_irqrestore(&priv->lock, flags); 188 spin_unlock_irq(&priv->lock);
189 189
190 priv->int_urb->dev = port->serial->dev; 190 priv->int_urb->dev = port->serial->dev;
191 result = usb_submit_urb(priv->int_urb, GFP_ATOMIC); 191 if (was_throttled) {
192 if (result) 192 result = usb_submit_urb(priv->int_urb, GFP_KERNEL);
193 dev_err(&port->dev, 193 if (result)
194 "%s - failed submitting read urb, error %d\n", 194 dev_err(&port->dev,
195 "%s - failed submitting read urb, error %d\n",
195 __func__, result); 196 __func__, result);
197 }
196} 198}
197 199
198static int symbol_startup(struct usb_serial *serial) 200static int symbol_startup(struct usb_serial *serial)
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index aa6b2ae951ae..bd3fa7ff15b1 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -156,7 +156,8 @@ static void destroy_serial(struct kref *kref)
156 if (serial->minor != SERIAL_TTY_NO_MINOR) 156 if (serial->minor != SERIAL_TTY_NO_MINOR)
157 return_serial(serial); 157 return_serial(serial);
158 158
159 serial->type->release(serial); 159 if (serial->attached)
160 serial->type->release(serial);
160 161
161 /* Now that nothing is using the ports, they can be freed */ 162 /* Now that nothing is using the ports, they can be freed */
162 for (i = 0; i < serial->num_port_pointers; ++i) { 163 for (i = 0; i < serial->num_port_pointers; ++i) {
@@ -1059,12 +1060,15 @@ int usb_serial_probe(struct usb_interface *interface,
1059 module_put(type->driver.owner); 1060 module_put(type->driver.owner);
1060 if (retval < 0) 1061 if (retval < 0)
1061 goto probe_error; 1062 goto probe_error;
1063 serial->attached = 1;
1062 if (retval > 0) { 1064 if (retval > 0) {
1063 /* quietly accept this device, but don't bind to a 1065 /* quietly accept this device, but don't bind to a
1064 serial port as it's about to disappear */ 1066 serial port as it's about to disappear */
1065 serial->num_ports = 0; 1067 serial->num_ports = 0;
1066 goto exit; 1068 goto exit;
1067 } 1069 }
1070 } else {
1071 serial->attached = 1;
1068 } 1072 }
1069 1073
1070 if (get_free_serial(serial, num_ports, &minor) == NULL) { 1074 if (get_free_serial(serial, num_ports, &minor) == NULL) {
@@ -1164,8 +1168,10 @@ int usb_serial_suspend(struct usb_interface *intf, pm_message_t message)
1164 1168
1165 if (serial->type->suspend) { 1169 if (serial->type->suspend) {
1166 r = serial->type->suspend(serial, message); 1170 r = serial->type->suspend(serial, message);
1167 if (r < 0) 1171 if (r < 0) {
1172 serial->suspending = 0;
1168 goto err_out; 1173 goto err_out;
1174 }
1169 } 1175 }
1170 1176
1171 for (i = 0; i < serial->num_ports; ++i) { 1177 for (i = 0; i < serial->num_ports; ++i) {
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
index 1aa5d20a5d99..ad1f9232292d 100644
--- a/drivers/usb/serial/visor.c
+++ b/drivers/usb/serial/visor.c
@@ -513,7 +513,8 @@ static void visor_read_bulk_callback(struct urb *urb)
513 tty_kref_put(tty); 513 tty_kref_put(tty);
514 } 514 }
515 spin_lock(&priv->lock); 515 spin_lock(&priv->lock);
516 priv->bytes_in += available_room; 516 if (tty)
517 priv->bytes_in += available_room;
517 518
518 } else { 519 } else {
519 spin_lock(&priv->lock); 520 spin_lock(&priv->lock);
@@ -582,12 +583,11 @@ static void visor_throttle(struct tty_struct *tty)
582{ 583{
583 struct usb_serial_port *port = tty->driver_data; 584 struct usb_serial_port *port = tty->driver_data;
584 struct visor_private *priv = usb_get_serial_port_data(port); 585 struct visor_private *priv = usb_get_serial_port_data(port);
585 unsigned long flags;
586 586
587 dbg("%s - port %d", __func__, port->number); 587 dbg("%s - port %d", __func__, port->number);
588 spin_lock_irqsave(&priv->lock, flags); 588 spin_lock_irq(&priv->lock);
589 priv->throttled = 1; 589 priv->throttled = 1;
590 spin_unlock_irqrestore(&priv->lock, flags); 590 spin_unlock_irq(&priv->lock);
591} 591}
592 592
593 593
@@ -595,21 +595,23 @@ static void visor_unthrottle(struct tty_struct *tty)
595{ 595{
596 struct usb_serial_port *port = tty->driver_data; 596 struct usb_serial_port *port = tty->driver_data;
597 struct visor_private *priv = usb_get_serial_port_data(port); 597 struct visor_private *priv = usb_get_serial_port_data(port);
598 unsigned long flags; 598 int result, was_throttled;
599 int result;
600 599
601 dbg("%s - port %d", __func__, port->number); 600 dbg("%s - port %d", __func__, port->number);
602 spin_lock_irqsave(&priv->lock, flags); 601 spin_lock_irq(&priv->lock);
603 priv->throttled = 0; 602 priv->throttled = 0;
603 was_throttled = priv->actually_throttled;
604 priv->actually_throttled = 0; 604 priv->actually_throttled = 0;
605 spin_unlock_irqrestore(&priv->lock, flags); 605 spin_unlock_irq(&priv->lock);
606 606
607 port->read_urb->dev = port->serial->dev; 607 if (was_throttled) {
608 result = usb_submit_urb(port->read_urb, GFP_ATOMIC); 608 port->read_urb->dev = port->serial->dev;
609 if (result) 609 result = usb_submit_urb(port->read_urb, GFP_KERNEL);
610 dev_err(&port->dev, 610 if (result)
611 "%s - failed submitting read urb, error %d\n", 611 dev_err(&port->dev,
612 "%s - failed submitting read urb, error %d\n",
612 __func__, result); 613 __func__, result);
614 }
613} 615}
614 616
615static int palm_os_3_probe(struct usb_serial *serial, 617static int palm_os_3_probe(struct usb_serial *serial,
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c
index 62424eec33ec..1093d2eb046a 100644
--- a/drivers/usb/serial/whiteheat.c
+++ b/drivers/usb/serial/whiteheat.c
@@ -949,13 +949,12 @@ static void whiteheat_throttle(struct tty_struct *tty)
949{ 949{
950 struct usb_serial_port *port = tty->driver_data; 950 struct usb_serial_port *port = tty->driver_data;
951 struct whiteheat_private *info = usb_get_serial_port_data(port); 951 struct whiteheat_private *info = usb_get_serial_port_data(port);
952 unsigned long flags;
953 952
954 dbg("%s - port %d", __func__, port->number); 953 dbg("%s - port %d", __func__, port->number);
955 954
956 spin_lock_irqsave(&info->lock, flags); 955 spin_lock_irq(&info->lock);
957 info->flags |= THROTTLED; 956 info->flags |= THROTTLED;
958 spin_unlock_irqrestore(&info->lock, flags); 957 spin_unlock_irq(&info->lock);
959 958
960 return; 959 return;
961} 960}
@@ -966,14 +965,13 @@ static void whiteheat_unthrottle(struct tty_struct *tty)
966 struct usb_serial_port *port = tty->driver_data; 965 struct usb_serial_port *port = tty->driver_data;
967 struct whiteheat_private *info = usb_get_serial_port_data(port); 966 struct whiteheat_private *info = usb_get_serial_port_data(port);
968 int actually_throttled; 967 int actually_throttled;
969 unsigned long flags;
970 968
971 dbg("%s - port %d", __func__, port->number); 969 dbg("%s - port %d", __func__, port->number);
972 970
973 spin_lock_irqsave(&info->lock, flags); 971 spin_lock_irq(&info->lock);
974 actually_throttled = info->flags & ACTUALLY_THROTTLED; 972 actually_throttled = info->flags & ACTUALLY_THROTTLED;
975 info->flags &= ~(THROTTLED | ACTUALLY_THROTTLED); 973 info->flags &= ~(THROTTLED | ACTUALLY_THROTTLED);
976 spin_unlock_irqrestore(&info->lock, flags); 974 spin_unlock_irq(&info->lock);
977 975
978 if (actually_throttled) 976 if (actually_throttled)
979 rx_data_softint(&info->rx_work); 977 rx_data_softint(&info->rx_work);
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
index e20dc525d177..589f6b4404f0 100644
--- a/drivers/usb/storage/transport.c
+++ b/drivers/usb/storage/transport.c
@@ -696,7 +696,7 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
696 /* device supports and needs bigger sense buffer */ 696 /* device supports and needs bigger sense buffer */
697 if (us->fflags & US_FL_SANE_SENSE) 697 if (us->fflags & US_FL_SANE_SENSE)
698 sense_size = ~0; 698 sense_size = ~0;
699 699Retry_Sense:
700 US_DEBUGP("Issuing auto-REQUEST_SENSE\n"); 700 US_DEBUGP("Issuing auto-REQUEST_SENSE\n");
701 701
702 scsi_eh_prep_cmnd(srb, &ses, NULL, 0, sense_size); 702 scsi_eh_prep_cmnd(srb, &ses, NULL, 0, sense_size);
@@ -720,6 +720,21 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
720 srb->result = DID_ABORT << 16; 720 srb->result = DID_ABORT << 16;
721 goto Handle_Errors; 721 goto Handle_Errors;
722 } 722 }
723
724 /* Some devices claim to support larger sense but fail when
725 * trying to request it. When a transport failure happens
726 * using US_FS_SANE_SENSE, we always retry with a standard
727 * (small) sense request. This fixes some USB GSM modems
728 */
729 if (temp_result == USB_STOR_TRANSPORT_FAILED &&
730 (us->fflags & US_FL_SANE_SENSE) &&
731 sense_size != US_SENSE_SIZE) {
732 US_DEBUGP("-- auto-sense failure, retry small sense\n");
733 sense_size = US_SENSE_SIZE;
734 goto Retry_Sense;
735 }
736
737 /* Other failures */
723 if (temp_result != USB_STOR_TRANSPORT_GOOD) { 738 if (temp_result != USB_STOR_TRANSPORT_GOOD) {
724 US_DEBUGP("-- auto-sense failure\n"); 739 US_DEBUGP("-- auto-sense failure\n");
725 740
@@ -768,17 +783,32 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
768 /* set the result so the higher layers expect this data */ 783 /* set the result so the higher layers expect this data */
769 srb->result = SAM_STAT_CHECK_CONDITION; 784 srb->result = SAM_STAT_CHECK_CONDITION;
770 785
771 /* If things are really okay, then let's show that. Zero 786 /* We often get empty sense data. This could indicate that
772 * out the sense buffer so the higher layers won't realize 787 * everything worked or that there was an unspecified
773 * we did an unsolicited auto-sense. */ 788 * problem. We have to decide which.
774 if (result == USB_STOR_TRANSPORT_GOOD && 789 */
775 /* Filemark 0, ignore EOM, ILI 0, no sense */ 790 if ( /* Filemark 0, ignore EOM, ILI 0, no sense */
776 (srb->sense_buffer[2] & 0xaf) == 0 && 791 (srb->sense_buffer[2] & 0xaf) == 0 &&
777 /* No ASC or ASCQ */ 792 /* No ASC or ASCQ */
778 srb->sense_buffer[12] == 0 && 793 srb->sense_buffer[12] == 0 &&
779 srb->sense_buffer[13] == 0) { 794 srb->sense_buffer[13] == 0) {
780 srb->result = SAM_STAT_GOOD; 795
781 srb->sense_buffer[0] = 0x0; 796 /* If things are really okay, then let's show that.
797 * Zero out the sense buffer so the higher layers
798 * won't realize we did an unsolicited auto-sense.
799 */
800 if (result == USB_STOR_TRANSPORT_GOOD) {
801 srb->result = SAM_STAT_GOOD;
802 srb->sense_buffer[0] = 0x0;
803
804 /* If there was a problem, report an unspecified
805 * hardware error to prevent the higher layers from
806 * entering an infinite retry loop.
807 */
808 } else {
809 srb->result = DID_ERROR << 16;
810 srb->sense_buffer[2] = HARDWARE_ERROR;
811 }
782 } 812 }
783 } 813 }
784 814
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index 079ae0f7bec1..d4f034ebaa8a 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -1823,6 +1823,13 @@ UNUSUAL_DEV( 0x4102, 0x1020, 0x0100, 0x0100,
1823 US_SC_DEVICE, US_PR_DEVICE, NULL, 1823 US_SC_DEVICE, US_PR_DEVICE, NULL,
1824 US_FL_IGNORE_RESIDUE ), 1824 US_FL_IGNORE_RESIDUE ),
1825 1825
1826/* Reported by Sergey Pinaev <dfo@antex.ru> */
1827UNUSUAL_DEV( 0x4102, 0x1059, 0x0000, 0x0000,
1828 "iRiver",
1829 "P7K",
1830 US_SC_DEVICE, US_PR_DEVICE, NULL,
1831 US_FL_MAX_SECTORS_64 ),
1832
1826/* 1833/*
1827 * David Härdeman <david@2gen.com> 1834 * David Härdeman <david@2gen.com>
1828 * The key makes the SCSI stack print confusing (but harmless) messages 1835 * The key makes the SCSI stack print confusing (but harmless) messages
diff --git a/drivers/usb/wusbcore/security.c b/drivers/usb/wusbcore/security.c
index b2f149fedcc5..4516c36436e6 100644
--- a/drivers/usb/wusbcore/security.c
+++ b/drivers/usb/wusbcore/security.c
@@ -200,35 +200,40 @@ int wusb_dev_sec_add(struct wusbhc *wusbhc,
200{ 200{
201 int result, bytes, secd_size; 201 int result, bytes, secd_size;
202 struct device *dev = &usb_dev->dev; 202 struct device *dev = &usb_dev->dev;
203 struct usb_security_descriptor secd; 203 struct usb_security_descriptor *secd;
204 const struct usb_encryption_descriptor *etd, *ccm1_etd = NULL; 204 const struct usb_encryption_descriptor *etd, *ccm1_etd = NULL;
205 void *secd_buf;
206 const void *itr, *top; 205 const void *itr, *top;
207 char buf[64]; 206 char buf[64];
208 207
208 secd = kmalloc(sizeof(struct usb_security_descriptor), GFP_KERNEL);
209 if (secd == NULL) {
210 result = -ENOMEM;
211 goto out;
212 }
213
209 result = usb_get_descriptor(usb_dev, USB_DT_SECURITY, 214 result = usb_get_descriptor(usb_dev, USB_DT_SECURITY,
210 0, &secd, sizeof(secd)); 215 0, secd, sizeof(struct usb_security_descriptor));
211 if (result < sizeof(secd)) { 216 if (result < sizeof(secd)) {
212 dev_err(dev, "Can't read security descriptor or " 217 dev_err(dev, "Can't read security descriptor or "
213 "not enough data: %d\n", result); 218 "not enough data: %d\n", result);
214 goto error_secd; 219 goto out;
215 } 220 }
216 secd_size = le16_to_cpu(secd.wTotalLength); 221 secd_size = le16_to_cpu(secd->wTotalLength);
217 secd_buf = kmalloc(secd_size, GFP_KERNEL); 222 secd = krealloc(secd, secd_size, GFP_KERNEL);
218 if (secd_buf == NULL) { 223 if (secd == NULL) {
219 dev_err(dev, "Can't allocate space for security descriptors\n"); 224 dev_err(dev, "Can't allocate space for security descriptors\n");
220 goto error_secd_alloc; 225 goto out;
221 } 226 }
222 result = usb_get_descriptor(usb_dev, USB_DT_SECURITY, 227 result = usb_get_descriptor(usb_dev, USB_DT_SECURITY,
223 0, secd_buf, secd_size); 228 0, secd, secd_size);
224 if (result < secd_size) { 229 if (result < secd_size) {
225 dev_err(dev, "Can't read security descriptor or " 230 dev_err(dev, "Can't read security descriptor or "
226 "not enough data: %d\n", result); 231 "not enough data: %d\n", result);
227 goto error_secd_all; 232 goto out;
228 } 233 }
229 bytes = 0; 234 bytes = 0;
230 itr = secd_buf + sizeof(secd); 235 itr = &secd[1];
231 top = secd_buf + result; 236 top = (void *)secd + result;
232 while (itr < top) { 237 while (itr < top) {
233 etd = itr; 238 etd = itr;
234 if (top - itr < sizeof(*etd)) { 239 if (top - itr < sizeof(*etd)) {
@@ -259,24 +264,16 @@ int wusb_dev_sec_add(struct wusbhc *wusbhc,
259 dev_err(dev, "WUSB device doesn't support CCM1 encryption, " 264 dev_err(dev, "WUSB device doesn't support CCM1 encryption, "
260 "can't use!\n"); 265 "can't use!\n");
261 result = -EINVAL; 266 result = -EINVAL;
262 goto error_no_ccm1; 267 goto out;
263 } 268 }
264 wusb_dev->ccm1_etd = *ccm1_etd; 269 wusb_dev->ccm1_etd = *ccm1_etd;
265 dev_dbg(dev, "supported encryption: %s; using %s (0x%02x/%02x)\n", 270 dev_dbg(dev, "supported encryption: %s; using %s (0x%02x/%02x)\n",
266 buf, wusb_et_name(ccm1_etd->bEncryptionType), 271 buf, wusb_et_name(ccm1_etd->bEncryptionType),
267 ccm1_etd->bEncryptionValue, ccm1_etd->bAuthKeyIndex); 272 ccm1_etd->bEncryptionValue, ccm1_etd->bAuthKeyIndex);
268 result = 0; 273 result = 0;
269 kfree(secd_buf);
270out: 274out:
275 kfree(secd);
271 return result; 276 return result;
272
273
274error_no_ccm1:
275error_secd_all:
276 kfree(secd_buf);
277error_secd_alloc:
278error_secd:
279 goto out;
280} 277}
281 278
282void wusb_dev_sec_rm(struct wusb_dev *wusb_dev) 279void wusb_dev_sec_rm(struct wusb_dev *wusb_dev)
diff --git a/drivers/uwb/uwb-debug.c b/drivers/uwb/uwb-debug.c
index 4a42993700c1..2eecec0c13c9 100644
--- a/drivers/uwb/uwb-debug.c
+++ b/drivers/uwb/uwb-debug.c
@@ -205,7 +205,7 @@ static ssize_t command_write(struct file *file, const char __user *buf,
205 return ret < 0 ? ret : len; 205 return ret < 0 ? ret : len;
206} 206}
207 207
208static struct file_operations command_fops = { 208static const struct file_operations command_fops = {
209 .open = command_open, 209 .open = command_open,
210 .write = command_write, 210 .write = command_write,
211 .read = NULL, 211 .read = NULL,
@@ -255,7 +255,7 @@ static int reservations_open(struct inode *inode, struct file *file)
255 return single_open(file, reservations_print, inode->i_private); 255 return single_open(file, reservations_print, inode->i_private);
256} 256}
257 257
258static struct file_operations reservations_fops = { 258static const struct file_operations reservations_fops = {
259 .open = reservations_open, 259 .open = reservations_open,
260 .read = seq_read, 260 .read = seq_read,
261 .llseek = seq_lseek, 261 .llseek = seq_lseek,
@@ -283,7 +283,7 @@ static int drp_avail_open(struct inode *inode, struct file *file)
283 return single_open(file, drp_avail_print, inode->i_private); 283 return single_open(file, drp_avail_print, inode->i_private);
284} 284}
285 285
286static struct file_operations drp_avail_fops = { 286static const struct file_operations drp_avail_fops = {
287 .open = drp_avail_open, 287 .open = drp_avail_open,
288 .read = seq_read, 288 .read = seq_read,
289 .llseek = seq_lseek, 289 .llseek = seq_lseek,
diff --git a/drivers/uwb/whc-rc.c b/drivers/uwb/whc-rc.c
index 1d9a6f54658e..01950c62dc8d 100644
--- a/drivers/uwb/whc-rc.c
+++ b/drivers/uwb/whc-rc.c
@@ -42,6 +42,7 @@
42#include <linux/init.h> 42#include <linux/init.h>
43#include <linux/module.h> 43#include <linux/module.h>
44#include <linux/pci.h> 44#include <linux/pci.h>
45#include <linux/sched.h>
45#include <linux/dma-mapping.h> 46#include <linux/dma-mapping.h>
46#include <linux/interrupt.h> 47#include <linux/interrupt.h>
47#include <linux/workqueue.h> 48#include <linux/workqueue.h>
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 42e1005e2916..d065894ce38f 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -26,7 +26,6 @@
26#include <linux/device.h> 26#include <linux/device.h>
27#include <linux/platform_device.h> 27#include <linux/platform_device.h>
28#include <linux/uaccess.h> 28#include <linux/uaccess.h>
29#include <linux/device.h>
30#include <linux/interrupt.h> 29#include <linux/interrupt.h>
31#include <linux/clk.h> 30#include <linux/clk.h>
32#include <video/da8xx-fb.h> 31#include <video/da8xx-fb.h>
diff --git a/drivers/video/msm/mddi.c b/drivers/video/msm/mddi.c
index f2de5a1acd6d..5c5a1ad1d397 100644
--- a/drivers/video/msm/mddi.c
+++ b/drivers/video/msm/mddi.c
@@ -27,8 +27,6 @@
27#include <mach/msm_iomap.h> 27#include <mach/msm_iomap.h>
28#include <mach/irqs.h> 28#include <mach/irqs.h>
29#include <mach/board.h> 29#include <mach/board.h>
30#include <linux/delay.h>
31
32#include <mach/msm_fb.h> 30#include <mach/msm_fb.h>
33#include "mddi_hw.h" 31#include "mddi_hw.h"
34 32
diff --git a/drivers/video/omap/blizzard.c b/drivers/video/omap/blizzard.c
index d5e59556f9e2..70dadf9d2334 100644
--- a/drivers/video/omap/blizzard.c
+++ b/drivers/video/omap/blizzard.c
@@ -93,7 +93,7 @@ struct blizzard_reg_list {
93}; 93};
94 94
95/* These need to be saved / restored separately from the rest. */ 95/* These need to be saved / restored separately from the rest. */
96static struct blizzard_reg_list blizzard_pll_regs[] = { 96static const struct blizzard_reg_list blizzard_pll_regs[] = {
97 { 97 {
98 .start = 0x04, /* Don't save PLL ctrl (0x0C) */ 98 .start = 0x04, /* Don't save PLL ctrl (0x0C) */
99 .end = 0x0a, 99 .end = 0x0a,
@@ -104,7 +104,7 @@ static struct blizzard_reg_list blizzard_pll_regs[] = {
104 }, 104 },
105}; 105};
106 106
107static struct blizzard_reg_list blizzard_gen_regs[] = { 107static const struct blizzard_reg_list blizzard_gen_regs[] = {
108 { 108 {
109 .start = 0x18, /* SDRAM control */ 109 .start = 0x18, /* SDRAM control */
110 .end = 0x20, 110 .end = 0x20,
@@ -191,7 +191,7 @@ struct blizzard_struct {
191 191
192 struct omapfb_device *fbdev; 192 struct omapfb_device *fbdev;
193 struct lcd_ctrl_extif *extif; 193 struct lcd_ctrl_extif *extif;
194 struct lcd_ctrl *int_ctrl; 194 const struct lcd_ctrl *int_ctrl;
195 195
196 void (*power_up)(struct device *dev); 196 void (*power_up)(struct device *dev);
197 void (*power_down)(struct device *dev); 197 void (*power_down)(struct device *dev);
@@ -1372,7 +1372,7 @@ static void blizzard_get_caps(int plane, struct omapfb_caps *caps)
1372 (1 << OMAPFB_COLOR_YUV420); 1372 (1 << OMAPFB_COLOR_YUV420);
1373} 1373}
1374 1374
1375static void _save_regs(struct blizzard_reg_list *list, int cnt) 1375static void _save_regs(const struct blizzard_reg_list *list, int cnt)
1376{ 1376{
1377 int i; 1377 int i;
1378 1378
@@ -1383,7 +1383,7 @@ static void _save_regs(struct blizzard_reg_list *list, int cnt)
1383 } 1383 }
1384} 1384}
1385 1385
1386static void _restore_regs(struct blizzard_reg_list *list, int cnt) 1386static void _restore_regs(const struct blizzard_reg_list *list, int cnt)
1387{ 1387{
1388 int i; 1388 int i;
1389 1389
diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c
index 125e605b8c68..0d0c8c8b9b56 100644
--- a/drivers/video/omap/omapfb_main.c
+++ b/drivers/video/omap/omapfb_main.c
@@ -393,7 +393,7 @@ static void omapfb_sync(struct fb_info *fbi)
393 * Set fb_info.fix fields and also updates fbdev. 393 * Set fb_info.fix fields and also updates fbdev.
394 * When calling this fb_info.var must be set up already. 394 * When calling this fb_info.var must be set up already.
395 */ 395 */
396static void set_fb_fix(struct fb_info *fbi) 396static void set_fb_fix(struct fb_info *fbi, int from_init)
397{ 397{
398 struct fb_fix_screeninfo *fix = &fbi->fix; 398 struct fb_fix_screeninfo *fix = &fbi->fix;
399 struct fb_var_screeninfo *var = &fbi->var; 399 struct fb_var_screeninfo *var = &fbi->var;
@@ -403,10 +403,16 @@ static void set_fb_fix(struct fb_info *fbi)
403 403
404 rg = &plane->fbdev->mem_desc.region[plane->idx]; 404 rg = &plane->fbdev->mem_desc.region[plane->idx];
405 fbi->screen_base = rg->vaddr; 405 fbi->screen_base = rg->vaddr;
406 mutex_lock(&fbi->mm_lock); 406
407 fix->smem_start = rg->paddr; 407 if (!from_init) {
408 fix->smem_len = rg->size; 408 mutex_lock(&fbi->mm_lock);
409 mutex_unlock(&fbi->mm_lock); 409 fix->smem_start = rg->paddr;
410 fix->smem_len = rg->size;
411 mutex_unlock(&fbi->mm_lock);
412 } else {
413 fix->smem_start = rg->paddr;
414 fix->smem_len = rg->size;
415 }
410 416
411 fix->type = FB_TYPE_PACKED_PIXELS; 417 fix->type = FB_TYPE_PACKED_PIXELS;
412 bpp = var->bits_per_pixel; 418 bpp = var->bits_per_pixel;
@@ -704,7 +710,7 @@ static int omapfb_set_par(struct fb_info *fbi)
704 int r = 0; 710 int r = 0;
705 711
706 omapfb_rqueue_lock(fbdev); 712 omapfb_rqueue_lock(fbdev);
707 set_fb_fix(fbi); 713 set_fb_fix(fbi, 0);
708 r = ctrl_change_mode(fbi); 714 r = ctrl_change_mode(fbi);
709 omapfb_rqueue_unlock(fbdev); 715 omapfb_rqueue_unlock(fbdev);
710 716
@@ -904,7 +910,7 @@ static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
904 if (old_size != size) { 910 if (old_size != size) {
905 if (size) { 911 if (size) {
906 memcpy(&fbi->var, new_var, sizeof(fbi->var)); 912 memcpy(&fbi->var, new_var, sizeof(fbi->var));
907 set_fb_fix(fbi); 913 set_fb_fix(fbi, 0);
908 } else { 914 } else {
909 /* 915 /*
910 * Set these explicitly to indicate that the 916 * Set these explicitly to indicate that the
@@ -1504,7 +1510,7 @@ static int fbinfo_init(struct omapfb_device *fbdev, struct fb_info *info)
1504 var->bits_per_pixel = fbdev->panel->bpp; 1510 var->bits_per_pixel = fbdev->panel->bpp;
1505 1511
1506 set_fb_var(info, var); 1512 set_fb_var(info, var);
1507 set_fb_fix(info); 1513 set_fb_fix(info, 1);
1508 1514
1509 r = fb_alloc_cmap(&info->cmap, 16, 0); 1515 r = fb_alloc_cmap(&info->cmap, 16, 0);
1510 if (r != 0) 1516 if (r != 0)
diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
index e98baf6916b8..e35232a18571 100644
--- a/drivers/video/uvesafb.c
+++ b/drivers/video/uvesafb.c
@@ -67,11 +67,14 @@ static DEFINE_MUTEX(uvfb_lock);
67 * find the kernel part of the task struct, copy the registers and 67 * find the kernel part of the task struct, copy the registers and
68 * the buffer contents and then complete the task. 68 * the buffer contents and then complete the task.
69 */ 69 */
70static void uvesafb_cn_callback(struct cn_msg *msg) 70static void uvesafb_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
71{ 71{
72 struct uvesafb_task *utask; 72 struct uvesafb_task *utask;
73 struct uvesafb_ktask *task; 73 struct uvesafb_ktask *task;
74 74
75 if (!cap_raised(nsp->eff_cap, CAP_SYS_ADMIN))
76 return;
77
75 if (msg->seq >= UVESAFB_TASKS_MAX) 78 if (msg->seq >= UVESAFB_TASKS_MAX)
76 return; 79 return;
77 80
diff --git a/drivers/w1/masters/ds2482.c b/drivers/w1/masters/ds2482.c
index df52cb355f7d..406caa6a71cb 100644
--- a/drivers/w1/masters/ds2482.c
+++ b/drivers/w1/masters/ds2482.c
@@ -24,19 +24,6 @@
24#include "../w1_int.h" 24#include "../w1_int.h"
25 25
26/** 26/**
27 * Address is selected using 2 pins, resulting in 4 possible addresses.
28 * 0x18, 0x19, 0x1a, 0x1b
29 * However, the chip cannot be detected without doing an i2c write,
30 * so use the force module parameter.
31 */
32static const unsigned short normal_i2c[] = { I2C_CLIENT_END };
33
34/**
35 * Insmod parameters
36 */
37I2C_CLIENT_INSMOD_1(ds2482);
38
39/**
40 * The DS2482 registers - there are 3 registers that are addressed by a read 27 * The DS2482 registers - there are 3 registers that are addressed by a read
41 * pointer. The read pointer is set by the last command executed. 28 * pointer. The read pointer is set by the last command executed.
42 * 29 *
@@ -96,8 +83,6 @@ static const u8 ds2482_chan_rd[8] =
96 83
97static int ds2482_probe(struct i2c_client *client, 84static int ds2482_probe(struct i2c_client *client,
98 const struct i2c_device_id *id); 85 const struct i2c_device_id *id);
99static int ds2482_detect(struct i2c_client *client, int kind,
100 struct i2c_board_info *info);
101static int ds2482_remove(struct i2c_client *client); 86static int ds2482_remove(struct i2c_client *client);
102 87
103 88
@@ -117,8 +102,6 @@ static struct i2c_driver ds2482_driver = {
117 .probe = ds2482_probe, 102 .probe = ds2482_probe,
118 .remove = ds2482_remove, 103 .remove = ds2482_remove,
119 .id_table = ds2482_id, 104 .id_table = ds2482_id,
120 .detect = ds2482_detect,
121 .address_data = &addr_data,
122}; 105};
123 106
124/* 107/*
@@ -425,19 +408,6 @@ static u8 ds2482_w1_reset_bus(void *data)
425} 408}
426 409
427 410
428static int ds2482_detect(struct i2c_client *client, int kind,
429 struct i2c_board_info *info)
430{
431 if (!i2c_check_functionality(client->adapter,
432 I2C_FUNC_SMBUS_WRITE_BYTE_DATA |
433 I2C_FUNC_SMBUS_BYTE))
434 return -ENODEV;
435
436 strlcpy(info->type, "ds2482", I2C_NAME_SIZE);
437
438 return 0;
439}
440
441static int ds2482_probe(struct i2c_client *client, 411static int ds2482_probe(struct i2c_client *client,
442 const struct i2c_device_id *id) 412 const struct i2c_device_id *id)
443{ 413{
@@ -446,6 +416,11 @@ static int ds2482_probe(struct i2c_client *client,
446 int temp1; 416 int temp1;
447 int idx; 417 int idx;
448 418
419 if (!i2c_check_functionality(client->adapter,
420 I2C_FUNC_SMBUS_WRITE_BYTE_DATA |
421 I2C_FUNC_SMBUS_BYTE))
422 return -ENODEV;
423
449 if (!(data = kzalloc(sizeof(struct ds2482_data), GFP_KERNEL))) { 424 if (!(data = kzalloc(sizeof(struct ds2482_data), GFP_KERNEL))) {
450 err = -ENOMEM; 425 err = -ENOMEM;
451 goto exit; 426 goto exit;
diff --git a/drivers/w1/w1_netlink.c b/drivers/w1/w1_netlink.c
index 52ccb3d3a963..45c126fea31d 100644
--- a/drivers/w1/w1_netlink.c
+++ b/drivers/w1/w1_netlink.c
@@ -306,7 +306,7 @@ static int w1_netlink_send_error(struct cn_msg *rcmsg, struct w1_netlink_msg *rm
306 return error; 306 return error;
307} 307}
308 308
309static void w1_cn_callback(struct cn_msg *msg) 309static void w1_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
310{ 310{
311 struct w1_netlink_msg *m = (struct w1_netlink_msg *)(msg + 1); 311 struct w1_netlink_msg *m = (struct w1_netlink_msg *)(msg + 1);
312 struct w1_netlink_cmd *cmd; 312 struct w1_netlink_cmd *cmd;
diff --git a/drivers/watchdog/riowd.c b/drivers/watchdog/riowd.c
index 1e8f02f440e6..d3c824dc2358 100644
--- a/drivers/watchdog/riowd.c
+++ b/drivers/watchdog/riowd.c
@@ -206,7 +206,7 @@ static int __devinit riowd_probe(struct of_device *op,
206 206
207 dev_set_drvdata(&op->dev, p); 207 dev_set_drvdata(&op->dev, p);
208 riowd_device = p; 208 riowd_device = p;
209 err = 0; 209 return 0;
210 210
211out_iounmap: 211out_iounmap:
212 of_iounmap(&op->resource[0], p->regs, 2); 212 of_iounmap(&op->resource[0], p->regs, 2);
diff --git a/drivers/xen/xenfs/xenbus.c b/drivers/xen/xenfs/xenbus.c
index a9592d981b10..6c4269b836b7 100644
--- a/drivers/xen/xenfs/xenbus.c
+++ b/drivers/xen/xenfs/xenbus.c
@@ -43,6 +43,7 @@
43#include <linux/fs.h> 43#include <linux/fs.h>
44#include <linux/poll.h> 44#include <linux/poll.h>
45#include <linux/mutex.h> 45#include <linux/mutex.h>
46#include <linux/sched.h>
46#include <linux/spinlock.h> 47#include <linux/spinlock.h>
47#include <linux/mount.h> 48#include <linux/mount.h>
48#include <linux/pagemap.h> 49#include <linux/pagemap.h>
diff --git a/firmware/Makefile b/firmware/Makefile
index 5ea80b19785b..a6c7c3e47e42 100644
--- a/firmware/Makefile
+++ b/firmware/Makefile
@@ -67,10 +67,13 @@ fw-shipped-$(CONFIG_DVB_TTUSB_BUDGET) += ttusb-budget/dspbootcode.bin
67fw-shipped-$(CONFIG_E100) += e100/d101m_ucode.bin e100/d101s_ucode.bin \ 67fw-shipped-$(CONFIG_E100) += e100/d101m_ucode.bin e100/d101s_ucode.bin \
68 e100/d102e_ucode.bin 68 e100/d102e_ucode.bin
69fw-shipped-$(CONFIG_MYRI_SBUS) += myricom/lanai.bin 69fw-shipped-$(CONFIG_MYRI_SBUS) += myricom/lanai.bin
70fw-shipped-$(CONFIG_PCMCIA_PCNET) += cis/LA-PCM.cis cis/PCMLM28.cis 70fw-shipped-$(CONFIG_PCMCIA_PCNET) += cis/LA-PCM.cis cis/PCMLM28.cis \
71 cis/DP83903.cis cis/NE2K.cis \
72 cis/tamarack.cis
71fw-shipped-$(CONFIG_PCMCIA_3C589) += cis/3CXEM556.cis 73fw-shipped-$(CONFIG_PCMCIA_3C589) += cis/3CXEM556.cis
72fw-shipped-$(CONFIG_PCMCIA_3C574) += cis/3CCFEM556.cis 74fw-shipped-$(CONFIG_PCMCIA_3C574) += cis/3CCFEM556.cis
73fw-shipped-$(CONFIG_SERIAL_8250_CS) += cis/MT5634ZLX.cis cis/RS-COM-2P.cis 75fw-shipped-$(CONFIG_SERIAL_8250_CS) += cis/MT5634ZLX.cis cis/RS-COM-2P.cis \
76 cis/COMpad2.cis cis/COMpad4.cis
74fw-shipped-$(CONFIG_PCMCIA_SMC91C92) += ositech/Xilinx7OD.bin 77fw-shipped-$(CONFIG_PCMCIA_SMC91C92) += ositech/Xilinx7OD.bin
75fw-shipped-$(CONFIG_SCSI_ADVANSYS) += advansys/mcode.bin advansys/38C1600.bin \ 78fw-shipped-$(CONFIG_SCSI_ADVANSYS) += advansys/mcode.bin advansys/38C1600.bin \
76 advansys/3550.bin advansys/38C0800.bin 79 advansys/3550.bin advansys/38C0800.bin
diff --git a/firmware/WHENCE b/firmware/WHENCE
index 3f8c4f6bc43f..c437e14f0b11 100644
--- a/firmware/WHENCE
+++ b/firmware/WHENCE
@@ -597,6 +597,9 @@ Driver: PCMCIA_PCNET - NE2000 compatible PCMCIA adapter
597 597
598File: cis/LA-PCM.cis 598File: cis/LA-PCM.cis
599 cis/PCMLM28.cis 599 cis/PCMLM28.cis
600 cis/DP83903.cis
601 cis/NE2K.cis
602 cis/tamarack.cis
600 603
601Licence: GPL 604Licence: GPL
602 605
@@ -628,6 +631,8 @@ Driver: SERIAL_8250_CS - Serial PCMCIA adapter
628 631
629File: cis/MT5634ZLX.cis 632File: cis/MT5634ZLX.cis
630 cis/RS-COM-2P.cis 633 cis/RS-COM-2P.cis
634 cis/COMpad2.cis
635 cis/COMpad4.cis
631 636
632Licence: GPL 637Licence: GPL
633 638
diff --git a/firmware/cis/COMpad2.cis.ihex b/firmware/cis/COMpad2.cis.ihex
new file mode 100644
index 000000000000..1671c5e48caa
--- /dev/null
+++ b/firmware/cis/COMpad2.cis.ihex
@@ -0,0 +1,11 @@
1:1000000001030000FF151F0401414456414E5445B1
2:10001000434800434F4D7061642D33322F38350013
3:10002000312E300000FF210202011A0501050001F6
4:10003000031B0EC18118AA61E80207E8030730B864
5:100040009E1B08820108AA6030030F1B0883010869
6:10005000AA6040030F1B08840108AA6050030F1B0D
7:0D00600008850108AA6060030F1400FF006E
8:00000001FF
9#
10# Replacement CIS for Advantech COMpad-32/85
11#
diff --git a/firmware/cis/COMpad4.cis.ihex b/firmware/cis/COMpad4.cis.ihex
new file mode 100644
index 000000000000..27bbec1921b3
--- /dev/null
+++ b/firmware/cis/COMpad4.cis.ihex
@@ -0,0 +1,9 @@
1:1000000001030000FF151F0401414456414E5445B1
2:10001000434800434F4D7061642D33322F383542D1
3:100020002D34000000FF210202011A050102000127
4:10003000011B0BC18118AA6040021F30B89E1B082B
5:0C004000820108AA6040031F1400FF00AA
6:00000001FF
7#
8# Replacement CIS for Advantech COMpad-32/85B-4
9#
diff --git a/firmware/cis/DP83903.cis.ihex b/firmware/cis/DP83903.cis.ihex
new file mode 100644
index 000000000000..6d73ea3cf1b8
--- /dev/null
+++ b/firmware/cis/DP83903.cis.ihex
@@ -0,0 +1,14 @@
1:1000000001030000FF152904014D756C74696675C4
2:100010006E6374696F6E20436172640000004E531A
3:1000200043204D46204C414E2F4D6F64656D00FFBF
4:1000300020047501000021020000060B02004900A7
5:100040000000006A000000FF00130343495321022F
6:1000500006001A060517201077021B0C970179017C
7:10006000556530FFFF284000FF001303434953212B
8:100070000202001A060507401077021B09870119C2
9:0800800001552330FFFFFF00D2
10:00000001FF
11#
12# This CIS is for cards based on the National Semiconductor
13# DP83903 Multiple Function Interface Chip
14#
diff --git a/firmware/cis/NE2K.cis.ihex b/firmware/cis/NE2K.cis.ihex
new file mode 100644
index 000000000000..1bb40fc4759f
--- /dev/null
+++ b/firmware/cis/NE2K.cis.ihex
@@ -0,0 +1,8 @@
1:1000000001030000FF1515040150434D4349410011
2:1000100045746865726E6574000000FF2102060079
3:100020001A050120F803031B09E001190155653089
4:06003000FFFF1400FF00B9
5:00000001FF
6#
7# Replacement CIS for various busted NE2000-compatible cards
8#
diff --git a/firmware/cis/tamarack.cis.ihex b/firmware/cis/tamarack.cis.ihex
new file mode 100644
index 000000000000..1e86547fb361
--- /dev/null
+++ b/firmware/cis/tamarack.cis.ihex
@@ -0,0 +1,10 @@
1:100000000103D400FF17034100FF152404015441EC
2:100010004D415241434B0045746865726E657400F2
3:10002000410030303437343331313830303100FF33
4:10003000210206001A050120F803031B14E08119B0
5:100040003F554D5D06864626E551000F100F30FFE7
6:05005000FF1400FF0099
7:00000001FF
8#
9# Replacement CIS for Surecom, Tamarack NE2000 cards
10#
diff --git a/fs/afs/cache.h b/fs/afs/cache.h
deleted file mode 100644
index 5c4f6b499e90..000000000000
--- a/fs/afs/cache.h
+++ /dev/null
@@ -1,12 +0,0 @@
1/* AFS local cache management interface
2 *
3 * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#include <linux/fscache.h>
diff --git a/fs/afs/internal.h b/fs/afs/internal.h
index 106be66dafd2..6ece2a13bf71 100644
--- a/fs/afs/internal.h
+++ b/fs/afs/internal.h
@@ -18,10 +18,10 @@
18#include <linux/key.h> 18#include <linux/key.h>
19#include <linux/workqueue.h> 19#include <linux/workqueue.h>
20#include <linux/sched.h> 20#include <linux/sched.h>
21#include <linux/fscache.h>
21 22
22#include "afs.h" 23#include "afs.h"
23#include "afs_vl.h" 24#include "afs_vl.h"
24#include "cache.h"
25 25
26#define AFS_CELL_MAX_ADDRS 15 26#define AFS_CELL_MAX_ADDRS 15
27 27
diff --git a/fs/anon_inodes.c b/fs/anon_inodes.c
index d11c51fc2a3f..2ca7a7cafdbf 100644
--- a/fs/anon_inodes.c
+++ b/fs/anon_inodes.c
@@ -8,8 +8,10 @@
8 * 8 *
9 */ 9 */
10 10
11#include <linux/cred.h>
11#include <linux/file.h> 12#include <linux/file.h>
12#include <linux/poll.h> 13#include <linux/poll.h>
14#include <linux/sched.h>
13#include <linux/slab.h> 15#include <linux/slab.h>
14#include <linux/init.h> 16#include <linux/init.h>
15#include <linux/fs.h> 17#include <linux/fs.h>
diff --git a/fs/bio.c b/fs/bio.c
index 76738005c8e8..402cb84a92a1 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -249,6 +249,7 @@ void bio_free(struct bio *bio, struct bio_set *bs)
249 249
250 mempool_free(p, bs->bio_pool); 250 mempool_free(p, bs->bio_pool);
251} 251}
252EXPORT_SYMBOL(bio_free);
252 253
253void bio_init(struct bio *bio) 254void bio_init(struct bio *bio)
254{ 255{
@@ -257,6 +258,7 @@ void bio_init(struct bio *bio)
257 bio->bi_comp_cpu = -1; 258 bio->bi_comp_cpu = -1;
258 atomic_set(&bio->bi_cnt, 1); 259 atomic_set(&bio->bi_cnt, 1);
259} 260}
261EXPORT_SYMBOL(bio_init);
260 262
261/** 263/**
262 * bio_alloc_bioset - allocate a bio for I/O 264 * bio_alloc_bioset - allocate a bio for I/O
@@ -311,6 +313,7 @@ err_free:
311 mempool_free(p, bs->bio_pool); 313 mempool_free(p, bs->bio_pool);
312 return NULL; 314 return NULL;
313} 315}
316EXPORT_SYMBOL(bio_alloc_bioset);
314 317
315static void bio_fs_destructor(struct bio *bio) 318static void bio_fs_destructor(struct bio *bio)
316{ 319{
@@ -337,6 +340,7 @@ struct bio *bio_alloc(gfp_t gfp_mask, int nr_iovecs)
337 340
338 return bio; 341 return bio;
339} 342}
343EXPORT_SYMBOL(bio_alloc);
340 344
341static void bio_kmalloc_destructor(struct bio *bio) 345static void bio_kmalloc_destructor(struct bio *bio)
342{ 346{
@@ -380,6 +384,7 @@ struct bio *bio_kmalloc(gfp_t gfp_mask, int nr_iovecs)
380 384
381 return bio; 385 return bio;
382} 386}
387EXPORT_SYMBOL(bio_kmalloc);
383 388
384void zero_fill_bio(struct bio *bio) 389void zero_fill_bio(struct bio *bio)
385{ 390{
@@ -416,6 +421,7 @@ void bio_put(struct bio *bio)
416 bio->bi_destructor(bio); 421 bio->bi_destructor(bio);
417 } 422 }
418} 423}
424EXPORT_SYMBOL(bio_put);
419 425
420inline int bio_phys_segments(struct request_queue *q, struct bio *bio) 426inline int bio_phys_segments(struct request_queue *q, struct bio *bio)
421{ 427{
@@ -424,6 +430,7 @@ inline int bio_phys_segments(struct request_queue *q, struct bio *bio)
424 430
425 return bio->bi_phys_segments; 431 return bio->bi_phys_segments;
426} 432}
433EXPORT_SYMBOL(bio_phys_segments);
427 434
428/** 435/**
429 * __bio_clone - clone a bio 436 * __bio_clone - clone a bio
@@ -451,6 +458,7 @@ void __bio_clone(struct bio *bio, struct bio *bio_src)
451 bio->bi_size = bio_src->bi_size; 458 bio->bi_size = bio_src->bi_size;
452 bio->bi_idx = bio_src->bi_idx; 459 bio->bi_idx = bio_src->bi_idx;
453} 460}
461EXPORT_SYMBOL(__bio_clone);
454 462
455/** 463/**
456 * bio_clone - clone a bio 464 * bio_clone - clone a bio
@@ -482,6 +490,7 @@ struct bio *bio_clone(struct bio *bio, gfp_t gfp_mask)
482 490
483 return b; 491 return b;
484} 492}
493EXPORT_SYMBOL(bio_clone);
485 494
486/** 495/**
487 * bio_get_nr_vecs - return approx number of vecs 496 * bio_get_nr_vecs - return approx number of vecs
@@ -505,6 +514,7 @@ int bio_get_nr_vecs(struct block_device *bdev)
505 514
506 return nr_pages; 515 return nr_pages;
507} 516}
517EXPORT_SYMBOL(bio_get_nr_vecs);
508 518
509static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page 519static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page
510 *page, unsigned int len, unsigned int offset, 520 *page, unsigned int len, unsigned int offset,
@@ -635,6 +645,7 @@ int bio_add_pc_page(struct request_queue *q, struct bio *bio, struct page *page,
635 return __bio_add_page(q, bio, page, len, offset, 645 return __bio_add_page(q, bio, page, len, offset,
636 queue_max_hw_sectors(q)); 646 queue_max_hw_sectors(q));
637} 647}
648EXPORT_SYMBOL(bio_add_pc_page);
638 649
639/** 650/**
640 * bio_add_page - attempt to add page to bio 651 * bio_add_page - attempt to add page to bio
@@ -655,6 +666,7 @@ int bio_add_page(struct bio *bio, struct page *page, unsigned int len,
655 struct request_queue *q = bdev_get_queue(bio->bi_bdev); 666 struct request_queue *q = bdev_get_queue(bio->bi_bdev);
656 return __bio_add_page(q, bio, page, len, offset, queue_max_sectors(q)); 667 return __bio_add_page(q, bio, page, len, offset, queue_max_sectors(q));
657} 668}
669EXPORT_SYMBOL(bio_add_page);
658 670
659struct bio_map_data { 671struct bio_map_data {
660 struct bio_vec *iovecs; 672 struct bio_vec *iovecs;
@@ -776,6 +788,7 @@ int bio_uncopy_user(struct bio *bio)
776 bio_put(bio); 788 bio_put(bio);
777 return ret; 789 return ret;
778} 790}
791EXPORT_SYMBOL(bio_uncopy_user);
779 792
780/** 793/**
781 * bio_copy_user_iov - copy user data to bio 794 * bio_copy_user_iov - copy user data to bio
@@ -920,6 +933,7 @@ struct bio *bio_copy_user(struct request_queue *q, struct rq_map_data *map_data,
920 933
921 return bio_copy_user_iov(q, map_data, &iov, 1, write_to_vm, gfp_mask); 934 return bio_copy_user_iov(q, map_data, &iov, 1, write_to_vm, gfp_mask);
922} 935}
936EXPORT_SYMBOL(bio_copy_user);
923 937
924static struct bio *__bio_map_user_iov(struct request_queue *q, 938static struct bio *__bio_map_user_iov(struct request_queue *q,
925 struct block_device *bdev, 939 struct block_device *bdev,
@@ -1050,6 +1064,7 @@ struct bio *bio_map_user(struct request_queue *q, struct block_device *bdev,
1050 1064
1051 return bio_map_user_iov(q, bdev, &iov, 1, write_to_vm, gfp_mask); 1065 return bio_map_user_iov(q, bdev, &iov, 1, write_to_vm, gfp_mask);
1052} 1066}
1067EXPORT_SYMBOL(bio_map_user);
1053 1068
1054/** 1069/**
1055 * bio_map_user_iov - map user sg_iovec table into bio 1070 * bio_map_user_iov - map user sg_iovec table into bio
@@ -1117,13 +1132,13 @@ void bio_unmap_user(struct bio *bio)
1117 __bio_unmap_user(bio); 1132 __bio_unmap_user(bio);
1118 bio_put(bio); 1133 bio_put(bio);
1119} 1134}
1135EXPORT_SYMBOL(bio_unmap_user);
1120 1136
1121static void bio_map_kern_endio(struct bio *bio, int err) 1137static void bio_map_kern_endio(struct bio *bio, int err)
1122{ 1138{
1123 bio_put(bio); 1139 bio_put(bio);
1124} 1140}
1125 1141
1126
1127static struct bio *__bio_map_kern(struct request_queue *q, void *data, 1142static struct bio *__bio_map_kern(struct request_queue *q, void *data,
1128 unsigned int len, gfp_t gfp_mask) 1143 unsigned int len, gfp_t gfp_mask)
1129{ 1144{
@@ -1189,6 +1204,7 @@ struct bio *bio_map_kern(struct request_queue *q, void *data, unsigned int len,
1189 bio_put(bio); 1204 bio_put(bio);
1190 return ERR_PTR(-EINVAL); 1205 return ERR_PTR(-EINVAL);
1191} 1206}
1207EXPORT_SYMBOL(bio_map_kern);
1192 1208
1193static void bio_copy_kern_endio(struct bio *bio, int err) 1209static void bio_copy_kern_endio(struct bio *bio, int err)
1194{ 1210{
@@ -1250,6 +1266,7 @@ struct bio *bio_copy_kern(struct request_queue *q, void *data, unsigned int len,
1250 1266
1251 return bio; 1267 return bio;
1252} 1268}
1269EXPORT_SYMBOL(bio_copy_kern);
1253 1270
1254/* 1271/*
1255 * bio_set_pages_dirty() and bio_check_pages_dirty() are support functions 1272 * bio_set_pages_dirty() and bio_check_pages_dirty() are support functions
@@ -1400,6 +1417,7 @@ void bio_endio(struct bio *bio, int error)
1400 if (bio->bi_end_io) 1417 if (bio->bi_end_io)
1401 bio->bi_end_io(bio, error); 1418 bio->bi_end_io(bio, error);
1402} 1419}
1420EXPORT_SYMBOL(bio_endio);
1403 1421
1404void bio_pair_release(struct bio_pair *bp) 1422void bio_pair_release(struct bio_pair *bp)
1405{ 1423{
@@ -1410,6 +1428,7 @@ void bio_pair_release(struct bio_pair *bp)
1410 mempool_free(bp, bp->bio2.bi_private); 1428 mempool_free(bp, bp->bio2.bi_private);
1411 } 1429 }
1412} 1430}
1431EXPORT_SYMBOL(bio_pair_release);
1413 1432
1414static void bio_pair_end_1(struct bio *bi, int err) 1433static void bio_pair_end_1(struct bio *bi, int err)
1415{ 1434{
@@ -1477,6 +1496,7 @@ struct bio_pair *bio_split(struct bio *bi, int first_sectors)
1477 1496
1478 return bp; 1497 return bp;
1479} 1498}
1499EXPORT_SYMBOL(bio_split);
1480 1500
1481/** 1501/**
1482 * bio_sector_offset - Find hardware sector offset in bio 1502 * bio_sector_offset - Find hardware sector offset in bio
@@ -1547,6 +1567,7 @@ void bioset_free(struct bio_set *bs)
1547 1567
1548 kfree(bs); 1568 kfree(bs);
1549} 1569}
1570EXPORT_SYMBOL(bioset_free);
1550 1571
1551/** 1572/**
1552 * bioset_create - Create a bio_set 1573 * bioset_create - Create a bio_set
@@ -1592,6 +1613,7 @@ bad:
1592 bioset_free(bs); 1613 bioset_free(bs);
1593 return NULL; 1614 return NULL;
1594} 1615}
1616EXPORT_SYMBOL(bioset_create);
1595 1617
1596static void __init biovec_init_slabs(void) 1618static void __init biovec_init_slabs(void)
1597{ 1619{
@@ -1636,29 +1658,4 @@ static int __init init_bio(void)
1636 1658
1637 return 0; 1659 return 0;
1638} 1660}
1639
1640subsys_initcall(init_bio); 1661subsys_initcall(init_bio);
1641
1642EXPORT_SYMBOL(bio_alloc);
1643EXPORT_SYMBOL(bio_kmalloc);
1644EXPORT_SYMBOL(bio_put);
1645EXPORT_SYMBOL(bio_free);
1646EXPORT_SYMBOL(bio_endio);
1647EXPORT_SYMBOL(bio_init);
1648EXPORT_SYMBOL(__bio_clone);
1649EXPORT_SYMBOL(bio_clone);
1650EXPORT_SYMBOL(bio_phys_segments);
1651EXPORT_SYMBOL(bio_add_page);
1652EXPORT_SYMBOL(bio_add_pc_page);
1653EXPORT_SYMBOL(bio_get_nr_vecs);
1654EXPORT_SYMBOL(bio_map_user);
1655EXPORT_SYMBOL(bio_unmap_user);
1656EXPORT_SYMBOL(bio_map_kern);
1657EXPORT_SYMBOL(bio_copy_kern);
1658EXPORT_SYMBOL(bio_pair_release);
1659EXPORT_SYMBOL(bio_split);
1660EXPORT_SYMBOL(bio_copy_user);
1661EXPORT_SYMBOL(bio_uncopy_user);
1662EXPORT_SYMBOL(bioset_create);
1663EXPORT_SYMBOL(bioset_free);
1664EXPORT_SYMBOL(bio_alloc_bioset);
diff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c
index f128427b995b..361604244271 100644
--- a/fs/btrfs/acl.c
+++ b/fs/btrfs/acl.c
@@ -27,7 +27,7 @@
27#include "btrfs_inode.h" 27#include "btrfs_inode.h"
28#include "xattr.h" 28#include "xattr.h"
29 29
30#ifdef CONFIG_FS_POSIX_ACL 30#ifdef CONFIG_BTRFS_FS_POSIX_ACL
31 31
32static struct posix_acl *btrfs_get_acl(struct inode *inode, int type) 32static struct posix_acl *btrfs_get_acl(struct inode *inode, int type)
33{ 33{
@@ -313,7 +313,7 @@ struct xattr_handler btrfs_xattr_acl_access_handler = {
313 .set = btrfs_xattr_acl_access_set, 313 .set = btrfs_xattr_acl_access_set,
314}; 314};
315 315
316#else /* CONFIG_FS_POSIX_ACL */ 316#else /* CONFIG_BTRFS_FS_POSIX_ACL */
317 317
318int btrfs_acl_chmod(struct inode *inode) 318int btrfs_acl_chmod(struct inode *inode)
319{ 319{
@@ -325,4 +325,4 @@ int btrfs_init_acl(struct inode *inode, struct inode *dir)
325 return 0; 325 return 0;
326} 326}
327 327
328#endif /* CONFIG_FS_POSIX_ACL */ 328#endif /* CONFIG_BTRFS_FS_POSIX_ACL */
diff --git a/fs/btrfs/async-thread.c b/fs/btrfs/async-thread.c
index 282ca085c2fb..c0861e781cdb 100644
--- a/fs/btrfs/async-thread.c
+++ b/fs/btrfs/async-thread.c
@@ -64,6 +64,51 @@ struct btrfs_worker_thread {
64}; 64};
65 65
66/* 66/*
67 * btrfs_start_workers uses kthread_run, which can block waiting for memory
68 * for a very long time. It will actually throttle on page writeback,
69 * and so it may not make progress until after our btrfs worker threads
70 * process all of the pending work structs in their queue
71 *
72 * This means we can't use btrfs_start_workers from inside a btrfs worker
73 * thread that is used as part of cleaning dirty memory, which pretty much
74 * involves all of the worker threads.
75 *
76 * Instead we have a helper queue who never has more than one thread
77 * where we scheduler thread start operations. This worker_start struct
78 * is used to contain the work and hold a pointer to the queue that needs
79 * another worker.
80 */
81struct worker_start {
82 struct btrfs_work work;
83 struct btrfs_workers *queue;
84};
85
86static void start_new_worker_func(struct btrfs_work *work)
87{
88 struct worker_start *start;
89 start = container_of(work, struct worker_start, work);
90 btrfs_start_workers(start->queue, 1);
91 kfree(start);
92}
93
94static int start_new_worker(struct btrfs_workers *queue)
95{
96 struct worker_start *start;
97 int ret;
98
99 start = kzalloc(sizeof(*start), GFP_NOFS);
100 if (!start)
101 return -ENOMEM;
102
103 start->work.func = start_new_worker_func;
104 start->queue = queue;
105 ret = btrfs_queue_worker(queue->atomic_worker_start, &start->work);
106 if (ret)
107 kfree(start);
108 return ret;
109}
110
111/*
67 * helper function to move a thread onto the idle list after it 112 * helper function to move a thread onto the idle list after it
68 * has finished some requests. 113 * has finished some requests.
69 */ 114 */
@@ -118,11 +163,13 @@ static void check_pending_worker_creates(struct btrfs_worker_thread *worker)
118 goto out; 163 goto out;
119 164
120 workers->atomic_start_pending = 0; 165 workers->atomic_start_pending = 0;
121 if (workers->num_workers >= workers->max_workers) 166 if (workers->num_workers + workers->num_workers_starting >=
167 workers->max_workers)
122 goto out; 168 goto out;
123 169
170 workers->num_workers_starting += 1;
124 spin_unlock_irqrestore(&workers->lock, flags); 171 spin_unlock_irqrestore(&workers->lock, flags);
125 btrfs_start_workers(workers, 1); 172 start_new_worker(workers);
126 return; 173 return;
127 174
128out: 175out:
@@ -390,9 +437,11 @@ int btrfs_stop_workers(struct btrfs_workers *workers)
390/* 437/*
391 * simple init on struct btrfs_workers 438 * simple init on struct btrfs_workers
392 */ 439 */
393void btrfs_init_workers(struct btrfs_workers *workers, char *name, int max) 440void btrfs_init_workers(struct btrfs_workers *workers, char *name, int max,
441 struct btrfs_workers *async_helper)
394{ 442{
395 workers->num_workers = 0; 443 workers->num_workers = 0;
444 workers->num_workers_starting = 0;
396 INIT_LIST_HEAD(&workers->worker_list); 445 INIT_LIST_HEAD(&workers->worker_list);
397 INIT_LIST_HEAD(&workers->idle_list); 446 INIT_LIST_HEAD(&workers->idle_list);
398 INIT_LIST_HEAD(&workers->order_list); 447 INIT_LIST_HEAD(&workers->order_list);
@@ -404,14 +453,15 @@ void btrfs_init_workers(struct btrfs_workers *workers, char *name, int max)
404 workers->name = name; 453 workers->name = name;
405 workers->ordered = 0; 454 workers->ordered = 0;
406 workers->atomic_start_pending = 0; 455 workers->atomic_start_pending = 0;
407 workers->atomic_worker_start = 0; 456 workers->atomic_worker_start = async_helper;
408} 457}
409 458
410/* 459/*
411 * starts new worker threads. This does not enforce the max worker 460 * starts new worker threads. This does not enforce the max worker
412 * count in case you need to temporarily go past it. 461 * count in case you need to temporarily go past it.
413 */ 462 */
414int btrfs_start_workers(struct btrfs_workers *workers, int num_workers) 463static int __btrfs_start_workers(struct btrfs_workers *workers,
464 int num_workers)
415{ 465{
416 struct btrfs_worker_thread *worker; 466 struct btrfs_worker_thread *worker;
417 int ret = 0; 467 int ret = 0;
@@ -444,6 +494,8 @@ int btrfs_start_workers(struct btrfs_workers *workers, int num_workers)
444 list_add_tail(&worker->worker_list, &workers->idle_list); 494 list_add_tail(&worker->worker_list, &workers->idle_list);
445 worker->idle = 1; 495 worker->idle = 1;
446 workers->num_workers++; 496 workers->num_workers++;
497 workers->num_workers_starting--;
498 WARN_ON(workers->num_workers_starting < 0);
447 spin_unlock_irq(&workers->lock); 499 spin_unlock_irq(&workers->lock);
448 } 500 }
449 return 0; 501 return 0;
@@ -452,6 +504,14 @@ fail:
452 return ret; 504 return ret;
453} 505}
454 506
507int btrfs_start_workers(struct btrfs_workers *workers, int num_workers)
508{
509 spin_lock_irq(&workers->lock);
510 workers->num_workers_starting += num_workers;
511 spin_unlock_irq(&workers->lock);
512 return __btrfs_start_workers(workers, num_workers);
513}
514
455/* 515/*
456 * run through the list and find a worker thread that doesn't have a lot 516 * run through the list and find a worker thread that doesn't have a lot
457 * to do right now. This can return null if we aren't yet at the thread 517 * to do right now. This can return null if we aren't yet at the thread
@@ -461,7 +521,10 @@ static struct btrfs_worker_thread *next_worker(struct btrfs_workers *workers)
461{ 521{
462 struct btrfs_worker_thread *worker; 522 struct btrfs_worker_thread *worker;
463 struct list_head *next; 523 struct list_head *next;
464 int enforce_min = workers->num_workers < workers->max_workers; 524 int enforce_min;
525
526 enforce_min = (workers->num_workers + workers->num_workers_starting) <
527 workers->max_workers;
465 528
466 /* 529 /*
467 * if we find an idle thread, don't move it to the end of the 530 * if we find an idle thread, don't move it to the end of the
@@ -509,15 +572,17 @@ again:
509 worker = next_worker(workers); 572 worker = next_worker(workers);
510 573
511 if (!worker) { 574 if (!worker) {
512 if (workers->num_workers >= workers->max_workers) { 575 if (workers->num_workers + workers->num_workers_starting >=
576 workers->max_workers) {
513 goto fallback; 577 goto fallback;
514 } else if (workers->atomic_worker_start) { 578 } else if (workers->atomic_worker_start) {
515 workers->atomic_start_pending = 1; 579 workers->atomic_start_pending = 1;
516 goto fallback; 580 goto fallback;
517 } else { 581 } else {
582 workers->num_workers_starting++;
518 spin_unlock_irqrestore(&workers->lock, flags); 583 spin_unlock_irqrestore(&workers->lock, flags);
519 /* we're below the limit, start another worker */ 584 /* we're below the limit, start another worker */
520 btrfs_start_workers(workers, 1); 585 __btrfs_start_workers(workers, 1);
521 goto again; 586 goto again;
522 } 587 }
523 } 588 }
diff --git a/fs/btrfs/async-thread.h b/fs/btrfs/async-thread.h
index fc089b95ec14..5077746cf85e 100644
--- a/fs/btrfs/async-thread.h
+++ b/fs/btrfs/async-thread.h
@@ -64,6 +64,8 @@ struct btrfs_workers {
64 /* current number of running workers */ 64 /* current number of running workers */
65 int num_workers; 65 int num_workers;
66 66
67 int num_workers_starting;
68
67 /* max number of workers allowed. changed by btrfs_start_workers */ 69 /* max number of workers allowed. changed by btrfs_start_workers */
68 int max_workers; 70 int max_workers;
69 71
@@ -78,9 +80,10 @@ struct btrfs_workers {
78 80
79 /* 81 /*
80 * are we allowed to sleep while starting workers or are we required 82 * are we allowed to sleep while starting workers or are we required
81 * to start them at a later time? 83 * to start them at a later time? If we can't sleep, this indicates
84 * which queue we need to use to schedule thread creation.
82 */ 85 */
83 int atomic_worker_start; 86 struct btrfs_workers *atomic_worker_start;
84 87
85 /* list with all the work threads. The workers on the idle thread 88 /* list with all the work threads. The workers on the idle thread
86 * may be actively servicing jobs, but they haven't yet hit the 89 * may be actively servicing jobs, but they haven't yet hit the
@@ -109,7 +112,8 @@ struct btrfs_workers {
109int btrfs_queue_worker(struct btrfs_workers *workers, struct btrfs_work *work); 112int btrfs_queue_worker(struct btrfs_workers *workers, struct btrfs_work *work);
110int btrfs_start_workers(struct btrfs_workers *workers, int num_workers); 113int btrfs_start_workers(struct btrfs_workers *workers, int num_workers);
111int btrfs_stop_workers(struct btrfs_workers *workers); 114int btrfs_stop_workers(struct btrfs_workers *workers);
112void btrfs_init_workers(struct btrfs_workers *workers, char *name, int max); 115void btrfs_init_workers(struct btrfs_workers *workers, char *name, int max,
116 struct btrfs_workers *async_starter);
113int btrfs_requeue_work(struct btrfs_work *work); 117int btrfs_requeue_work(struct btrfs_work *work);
114void btrfs_set_work_high_prio(struct btrfs_work *work); 118void btrfs_set_work_high_prio(struct btrfs_work *work);
115#endif 119#endif
diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h
index 82ee56bba299..f6783a42f010 100644
--- a/fs/btrfs/btrfs_inode.h
+++ b/fs/btrfs/btrfs_inode.h
@@ -86,6 +86,12 @@ struct btrfs_inode {
86 * transid of the trans_handle that last modified this inode 86 * transid of the trans_handle that last modified this inode
87 */ 87 */
88 u64 last_trans; 88 u64 last_trans;
89
90 /*
91 * log transid when this inode was last modified
92 */
93 u64 last_sub_trans;
94
89 /* 95 /*
90 * transid that last logged this inode 96 * transid that last logged this inode
91 */ 97 */
@@ -128,6 +134,16 @@ struct btrfs_inode {
128 u64 last_unlink_trans; 134 u64 last_unlink_trans;
129 135
130 /* 136 /*
137 * Counters to keep track of the number of extent item's we may use due
138 * to delalloc and such. outstanding_extents is the number of extent
139 * items we think we'll end up using, and reserved_extents is the number
140 * of extent items we've reserved metadata for.
141 */
142 spinlock_t accounting_lock;
143 int reserved_extents;
144 int outstanding_extents;
145
146 /*
131 * ordered_data_close is set by truncate when a file that used 147 * ordered_data_close is set by truncate when a file that used
132 * to have good data has been truncated to zero. When it is set 148 * to have good data has been truncated to zero. When it is set
133 * the btrfs file release call will add this inode to the 149 * the btrfs file release call will add this inode to the
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 80599b4e42bd..444b3e9b92a4 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -675,21 +675,28 @@ struct btrfs_space_info {
675 current allocations */ 675 current allocations */
676 u64 bytes_readonly; /* total bytes that are read only */ 676 u64 bytes_readonly; /* total bytes that are read only */
677 u64 bytes_super; /* total bytes reserved for the super blocks */ 677 u64 bytes_super; /* total bytes reserved for the super blocks */
678 678 u64 bytes_root; /* the number of bytes needed to commit a
679 /* delalloc accounting */ 679 transaction */
680 u64 bytes_delalloc; /* number of bytes reserved for allocation,
681 this space is not necessarily reserved yet
682 by the allocator */
683 u64 bytes_may_use; /* number of bytes that may be used for 680 u64 bytes_may_use; /* number of bytes that may be used for
684 delalloc */ 681 delalloc/allocations */
682 u64 bytes_delalloc; /* number of bytes currently reserved for
683 delayed allocation */
685 684
686 int full; /* indicates that we cannot allocate any more 685 int full; /* indicates that we cannot allocate any more
687 chunks for this space */ 686 chunks for this space */
688 int force_alloc; /* set if we need to force a chunk alloc for 687 int force_alloc; /* set if we need to force a chunk alloc for
689 this space */ 688 this space */
689 int force_delalloc; /* make people start doing filemap_flush until
690 we're under a threshold */
690 691
691 struct list_head list; 692 struct list_head list;
692 693
694 /* for controlling how we free up space for allocations */
695 wait_queue_head_t allocate_wait;
696 wait_queue_head_t flush_wait;
697 int allocating_chunk;
698 int flushing;
699
693 /* for block groups in our same type */ 700 /* for block groups in our same type */
694 struct list_head block_groups; 701 struct list_head block_groups;
695 spinlock_t lock; 702 spinlock_t lock;
@@ -903,6 +910,7 @@ struct btrfs_fs_info {
903 * A third pool does submit_bio to avoid deadlocking with the other 910 * A third pool does submit_bio to avoid deadlocking with the other
904 * two 911 * two
905 */ 912 */
913 struct btrfs_workers generic_worker;
906 struct btrfs_workers workers; 914 struct btrfs_workers workers;
907 struct btrfs_workers delalloc_workers; 915 struct btrfs_workers delalloc_workers;
908 struct btrfs_workers endio_workers; 916 struct btrfs_workers endio_workers;
@@ -910,6 +918,7 @@ struct btrfs_fs_info {
910 struct btrfs_workers endio_meta_write_workers; 918 struct btrfs_workers endio_meta_write_workers;
911 struct btrfs_workers endio_write_workers; 919 struct btrfs_workers endio_write_workers;
912 struct btrfs_workers submit_workers; 920 struct btrfs_workers submit_workers;
921 struct btrfs_workers enospc_workers;
913 /* 922 /*
914 * fixup workers take dirty pages that didn't properly go through 923 * fixup workers take dirty pages that didn't properly go through
915 * the cow mechanism and make them safe to write. It happens 924 * the cow mechanism and make them safe to write. It happens
@@ -1000,7 +1009,10 @@ struct btrfs_root {
1000 atomic_t log_writers; 1009 atomic_t log_writers;
1001 atomic_t log_commit[2]; 1010 atomic_t log_commit[2];
1002 unsigned long log_transid; 1011 unsigned long log_transid;
1012 unsigned long last_log_commit;
1003 unsigned long log_batch; 1013 unsigned long log_batch;
1014 pid_t log_start_pid;
1015 bool log_multiple_pids;
1004 1016
1005 u64 objectid; 1017 u64 objectid;
1006 u64 last_trans; 1018 u64 last_trans;
@@ -1141,6 +1153,7 @@ struct btrfs_root {
1141#define BTRFS_MOUNT_FLUSHONCOMMIT (1 << 7) 1153#define BTRFS_MOUNT_FLUSHONCOMMIT (1 << 7)
1142#define BTRFS_MOUNT_SSD_SPREAD (1 << 8) 1154#define BTRFS_MOUNT_SSD_SPREAD (1 << 8)
1143#define BTRFS_MOUNT_NOSSD (1 << 9) 1155#define BTRFS_MOUNT_NOSSD (1 << 9)
1156#define BTRFS_MOUNT_DISCARD (1 << 10)
1144 1157
1145#define btrfs_clear_opt(o, opt) ((o) &= ~BTRFS_MOUNT_##opt) 1158#define btrfs_clear_opt(o, opt) ((o) &= ~BTRFS_MOUNT_##opt)
1146#define btrfs_set_opt(o, opt) ((o) |= BTRFS_MOUNT_##opt) 1159#define btrfs_set_opt(o, opt) ((o) |= BTRFS_MOUNT_##opt)
@@ -2022,7 +2035,12 @@ u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags);
2022void btrfs_set_inode_space_info(struct btrfs_root *root, struct inode *ionde); 2035void btrfs_set_inode_space_info(struct btrfs_root *root, struct inode *ionde);
2023void btrfs_clear_space_info_full(struct btrfs_fs_info *info); 2036void btrfs_clear_space_info_full(struct btrfs_fs_info *info);
2024 2037
2025int btrfs_check_metadata_free_space(struct btrfs_root *root); 2038int btrfs_reserve_metadata_space(struct btrfs_root *root, int num_items);
2039int btrfs_unreserve_metadata_space(struct btrfs_root *root, int num_items);
2040int btrfs_unreserve_metadata_for_delalloc(struct btrfs_root *root,
2041 struct inode *inode, int num_items);
2042int btrfs_reserve_metadata_for_delalloc(struct btrfs_root *root,
2043 struct inode *inode, int num_items);
2026int btrfs_check_data_free_space(struct btrfs_root *root, struct inode *inode, 2044int btrfs_check_data_free_space(struct btrfs_root *root, struct inode *inode,
2027 u64 bytes); 2045 u64 bytes);
2028void btrfs_free_reserved_data_space(struct btrfs_root *root, 2046void btrfs_free_reserved_data_space(struct btrfs_root *root,
@@ -2314,7 +2332,7 @@ int btrfs_orphan_del(struct btrfs_trans_handle *trans, struct inode *inode);
2314void btrfs_orphan_cleanup(struct btrfs_root *root); 2332void btrfs_orphan_cleanup(struct btrfs_root *root);
2315int btrfs_cont_expand(struct inode *inode, loff_t size); 2333int btrfs_cont_expand(struct inode *inode, loff_t size);
2316int btrfs_invalidate_inodes(struct btrfs_root *root); 2334int btrfs_invalidate_inodes(struct btrfs_root *root);
2317extern struct dentry_operations btrfs_dentry_operations; 2335extern const struct dentry_operations btrfs_dentry_operations;
2318 2336
2319/* ioctl.c */ 2337/* ioctl.c */
2320long btrfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg); 2338long btrfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
@@ -2326,7 +2344,7 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync);
2326int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end, 2344int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end,
2327 int skip_pinned); 2345 int skip_pinned);
2328int btrfs_check_file(struct btrfs_root *root, struct inode *inode); 2346int btrfs_check_file(struct btrfs_root *root, struct inode *inode);
2329extern struct file_operations btrfs_file_operations; 2347extern const struct file_operations btrfs_file_operations;
2330int btrfs_drop_extents(struct btrfs_trans_handle *trans, 2348int btrfs_drop_extents(struct btrfs_trans_handle *trans,
2331 struct btrfs_root *root, struct inode *inode, 2349 struct btrfs_root *root, struct inode *inode,
2332 u64 start, u64 end, u64 locked_end, 2350 u64 start, u64 end, u64 locked_end,
@@ -2357,7 +2375,7 @@ int btrfs_parse_options(struct btrfs_root *root, char *options);
2357int btrfs_sync_fs(struct super_block *sb, int wait); 2375int btrfs_sync_fs(struct super_block *sb, int wait);
2358 2376
2359/* acl.c */ 2377/* acl.c */
2360#ifdef CONFIG_FS_POSIX_ACL 2378#ifdef CONFIG_BTRFS_FS_POSIX_ACL
2361int btrfs_check_acl(struct inode *inode, int mask); 2379int btrfs_check_acl(struct inode *inode, int mask);
2362#else 2380#else
2363#define btrfs_check_acl NULL 2381#define btrfs_check_acl NULL
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 644e796fd643..02b6afbd7450 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -822,14 +822,14 @@ struct extent_buffer *btrfs_find_create_tree_block(struct btrfs_root *root,
822 822
823int btrfs_write_tree_block(struct extent_buffer *buf) 823int btrfs_write_tree_block(struct extent_buffer *buf)
824{ 824{
825 return btrfs_fdatawrite_range(buf->first_page->mapping, buf->start, 825 return filemap_fdatawrite_range(buf->first_page->mapping, buf->start,
826 buf->start + buf->len - 1, WB_SYNC_ALL); 826 buf->start + buf->len - 1);
827} 827}
828 828
829int btrfs_wait_tree_block_writeback(struct extent_buffer *buf) 829int btrfs_wait_tree_block_writeback(struct extent_buffer *buf)
830{ 830{
831 return btrfs_wait_on_page_writeback_range(buf->first_page->mapping, 831 return filemap_fdatawait_range(buf->first_page->mapping,
832 buf->start, buf->start + buf->len - 1); 832 buf->start, buf->start + buf->len - 1);
833} 833}
834 834
835struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr, 835struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr,
@@ -917,6 +917,7 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,
917 atomic_set(&root->log_writers, 0); 917 atomic_set(&root->log_writers, 0);
918 root->log_batch = 0; 918 root->log_batch = 0;
919 root->log_transid = 0; 919 root->log_transid = 0;
920 root->last_log_commit = 0;
920 extent_io_tree_init(&root->dirty_log_pages, 921 extent_io_tree_init(&root->dirty_log_pages,
921 fs_info->btree_inode->i_mapping, GFP_NOFS); 922 fs_info->btree_inode->i_mapping, GFP_NOFS);
922 923
@@ -1087,6 +1088,7 @@ int btrfs_add_log_tree(struct btrfs_trans_handle *trans,
1087 WARN_ON(root->log_root); 1088 WARN_ON(root->log_root);
1088 root->log_root = log_root; 1089 root->log_root = log_root;
1089 root->log_transid = 0; 1090 root->log_transid = 0;
1091 root->last_log_commit = 0;
1090 return 0; 1092 return 0;
1091} 1093}
1092 1094
@@ -1630,7 +1632,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
1630 fs_info->sb = sb; 1632 fs_info->sb = sb;
1631 fs_info->max_extent = (u64)-1; 1633 fs_info->max_extent = (u64)-1;
1632 fs_info->max_inline = 8192 * 1024; 1634 fs_info->max_inline = 8192 * 1024;
1633 fs_info->metadata_ratio = 8; 1635 fs_info->metadata_ratio = 0;
1634 1636
1635 fs_info->thread_pool_size = min_t(unsigned long, 1637 fs_info->thread_pool_size = min_t(unsigned long,
1636 num_online_cpus() + 2, 8); 1638 num_online_cpus() + 2, 8);
@@ -1746,21 +1748,25 @@ struct btrfs_root *open_ctree(struct super_block *sb,
1746 err = -EINVAL; 1748 err = -EINVAL;
1747 goto fail_iput; 1749 goto fail_iput;
1748 } 1750 }
1749printk("thread pool is %d\n", fs_info->thread_pool_size); 1751
1750 /* 1752 btrfs_init_workers(&fs_info->generic_worker,
1751 * we need to start all the end_io workers up front because the 1753 "genwork", 1, NULL);
1752 * queue work function gets called at interrupt time, and so it 1754
1753 * cannot dynamically grow.
1754 */
1755 btrfs_init_workers(&fs_info->workers, "worker", 1755 btrfs_init_workers(&fs_info->workers, "worker",
1756 fs_info->thread_pool_size); 1756 fs_info->thread_pool_size,
1757 &fs_info->generic_worker);
1757 1758
1758 btrfs_init_workers(&fs_info->delalloc_workers, "delalloc", 1759 btrfs_init_workers(&fs_info->delalloc_workers, "delalloc",
1759 fs_info->thread_pool_size); 1760 fs_info->thread_pool_size,
1761 &fs_info->generic_worker);
1760 1762
1761 btrfs_init_workers(&fs_info->submit_workers, "submit", 1763 btrfs_init_workers(&fs_info->submit_workers, "submit",
1762 min_t(u64, fs_devices->num_devices, 1764 min_t(u64, fs_devices->num_devices,
1763 fs_info->thread_pool_size)); 1765 fs_info->thread_pool_size),
1766 &fs_info->generic_worker);
1767 btrfs_init_workers(&fs_info->enospc_workers, "enospc",
1768 fs_info->thread_pool_size,
1769 &fs_info->generic_worker);
1764 1770
1765 /* a higher idle thresh on the submit workers makes it much more 1771 /* a higher idle thresh on the submit workers makes it much more
1766 * likely that bios will be send down in a sane order to the 1772 * likely that bios will be send down in a sane order to the
@@ -1774,15 +1780,20 @@ printk("thread pool is %d\n", fs_info->thread_pool_size);
1774 fs_info->delalloc_workers.idle_thresh = 2; 1780 fs_info->delalloc_workers.idle_thresh = 2;
1775 fs_info->delalloc_workers.ordered = 1; 1781 fs_info->delalloc_workers.ordered = 1;
1776 1782
1777 btrfs_init_workers(&fs_info->fixup_workers, "fixup", 1); 1783 btrfs_init_workers(&fs_info->fixup_workers, "fixup", 1,
1784 &fs_info->generic_worker);
1778 btrfs_init_workers(&fs_info->endio_workers, "endio", 1785 btrfs_init_workers(&fs_info->endio_workers, "endio",
1779 fs_info->thread_pool_size); 1786 fs_info->thread_pool_size,
1787 &fs_info->generic_worker);
1780 btrfs_init_workers(&fs_info->endio_meta_workers, "endio-meta", 1788 btrfs_init_workers(&fs_info->endio_meta_workers, "endio-meta",
1781 fs_info->thread_pool_size); 1789 fs_info->thread_pool_size,
1790 &fs_info->generic_worker);
1782 btrfs_init_workers(&fs_info->endio_meta_write_workers, 1791 btrfs_init_workers(&fs_info->endio_meta_write_workers,
1783 "endio-meta-write", fs_info->thread_pool_size); 1792 "endio-meta-write", fs_info->thread_pool_size,
1793 &fs_info->generic_worker);
1784 btrfs_init_workers(&fs_info->endio_write_workers, "endio-write", 1794 btrfs_init_workers(&fs_info->endio_write_workers, "endio-write",
1785 fs_info->thread_pool_size); 1795 fs_info->thread_pool_size,
1796 &fs_info->generic_worker);
1786 1797
1787 /* 1798 /*
1788 * endios are largely parallel and should have a very 1799 * endios are largely parallel and should have a very
@@ -1794,12 +1805,8 @@ printk("thread pool is %d\n", fs_info->thread_pool_size);
1794 fs_info->endio_write_workers.idle_thresh = 2; 1805 fs_info->endio_write_workers.idle_thresh = 2;
1795 fs_info->endio_meta_write_workers.idle_thresh = 2; 1806 fs_info->endio_meta_write_workers.idle_thresh = 2;
1796 1807
1797 fs_info->endio_workers.atomic_worker_start = 1;
1798 fs_info->endio_meta_workers.atomic_worker_start = 1;
1799 fs_info->endio_write_workers.atomic_worker_start = 1;
1800 fs_info->endio_meta_write_workers.atomic_worker_start = 1;
1801
1802 btrfs_start_workers(&fs_info->workers, 1); 1808 btrfs_start_workers(&fs_info->workers, 1);
1809 btrfs_start_workers(&fs_info->generic_worker, 1);
1803 btrfs_start_workers(&fs_info->submit_workers, 1); 1810 btrfs_start_workers(&fs_info->submit_workers, 1);
1804 btrfs_start_workers(&fs_info->delalloc_workers, 1); 1811 btrfs_start_workers(&fs_info->delalloc_workers, 1);
1805 btrfs_start_workers(&fs_info->fixup_workers, 1); 1812 btrfs_start_workers(&fs_info->fixup_workers, 1);
@@ -1807,6 +1814,7 @@ printk("thread pool is %d\n", fs_info->thread_pool_size);
1807 btrfs_start_workers(&fs_info->endio_meta_workers, 1); 1814 btrfs_start_workers(&fs_info->endio_meta_workers, 1);
1808 btrfs_start_workers(&fs_info->endio_meta_write_workers, 1); 1815 btrfs_start_workers(&fs_info->endio_meta_write_workers, 1);
1809 btrfs_start_workers(&fs_info->endio_write_workers, 1); 1816 btrfs_start_workers(&fs_info->endio_write_workers, 1);
1817 btrfs_start_workers(&fs_info->enospc_workers, 1);
1810 1818
1811 fs_info->bdi.ra_pages *= btrfs_super_num_devices(disk_super); 1819 fs_info->bdi.ra_pages *= btrfs_super_num_devices(disk_super);
1812 fs_info->bdi.ra_pages = max(fs_info->bdi.ra_pages, 1820 fs_info->bdi.ra_pages = max(fs_info->bdi.ra_pages,
@@ -2012,6 +2020,7 @@ fail_chunk_root:
2012 free_extent_buffer(chunk_root->node); 2020 free_extent_buffer(chunk_root->node);
2013 free_extent_buffer(chunk_root->commit_root); 2021 free_extent_buffer(chunk_root->commit_root);
2014fail_sb_buffer: 2022fail_sb_buffer:
2023 btrfs_stop_workers(&fs_info->generic_worker);
2015 btrfs_stop_workers(&fs_info->fixup_workers); 2024 btrfs_stop_workers(&fs_info->fixup_workers);
2016 btrfs_stop_workers(&fs_info->delalloc_workers); 2025 btrfs_stop_workers(&fs_info->delalloc_workers);
2017 btrfs_stop_workers(&fs_info->workers); 2026 btrfs_stop_workers(&fs_info->workers);
@@ -2020,6 +2029,7 @@ fail_sb_buffer:
2020 btrfs_stop_workers(&fs_info->endio_meta_write_workers); 2029 btrfs_stop_workers(&fs_info->endio_meta_write_workers);
2021 btrfs_stop_workers(&fs_info->endio_write_workers); 2030 btrfs_stop_workers(&fs_info->endio_write_workers);
2022 btrfs_stop_workers(&fs_info->submit_workers); 2031 btrfs_stop_workers(&fs_info->submit_workers);
2032 btrfs_stop_workers(&fs_info->enospc_workers);
2023fail_iput: 2033fail_iput:
2024 invalidate_inode_pages2(fs_info->btree_inode->i_mapping); 2034 invalidate_inode_pages2(fs_info->btree_inode->i_mapping);
2025 iput(fs_info->btree_inode); 2035 iput(fs_info->btree_inode);
@@ -2437,6 +2447,7 @@ int close_ctree(struct btrfs_root *root)
2437 2447
2438 iput(fs_info->btree_inode); 2448 iput(fs_info->btree_inode);
2439 2449
2450 btrfs_stop_workers(&fs_info->generic_worker);
2440 btrfs_stop_workers(&fs_info->fixup_workers); 2451 btrfs_stop_workers(&fs_info->fixup_workers);
2441 btrfs_stop_workers(&fs_info->delalloc_workers); 2452 btrfs_stop_workers(&fs_info->delalloc_workers);
2442 btrfs_stop_workers(&fs_info->workers); 2453 btrfs_stop_workers(&fs_info->workers);
@@ -2445,6 +2456,7 @@ int close_ctree(struct btrfs_root *root)
2445 btrfs_stop_workers(&fs_info->endio_meta_write_workers); 2456 btrfs_stop_workers(&fs_info->endio_meta_write_workers);
2446 btrfs_stop_workers(&fs_info->endio_write_workers); 2457 btrfs_stop_workers(&fs_info->endio_write_workers);
2447 btrfs_stop_workers(&fs_info->submit_workers); 2458 btrfs_stop_workers(&fs_info->submit_workers);
2459 btrfs_stop_workers(&fs_info->enospc_workers);
2448 2460
2449 btrfs_close_devices(fs_info->fs_devices); 2461 btrfs_close_devices(fs_info->fs_devices);
2450 btrfs_mapping_tree_free(&fs_info->mapping_tree); 2462 btrfs_mapping_tree_free(&fs_info->mapping_tree);
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 993f93ff7ba6..e238a0cdac67 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -68,6 +68,8 @@ static int pin_down_bytes(struct btrfs_trans_handle *trans,
68 struct extent_buffer **must_clean); 68 struct extent_buffer **must_clean);
69static int find_next_key(struct btrfs_path *path, int level, 69static int find_next_key(struct btrfs_path *path, int level,
70 struct btrfs_key *key); 70 struct btrfs_key *key);
71static void dump_space_info(struct btrfs_space_info *info, u64 bytes,
72 int dump_block_groups);
71 73
72static noinline int 74static noinline int
73block_group_cache_done(struct btrfs_block_group_cache *cache) 75block_group_cache_done(struct btrfs_block_group_cache *cache)
@@ -1566,23 +1568,23 @@ static int remove_extent_backref(struct btrfs_trans_handle *trans,
1566 return ret; 1568 return ret;
1567} 1569}
1568 1570
1569#ifdef BIO_RW_DISCARD
1570static void btrfs_issue_discard(struct block_device *bdev, 1571static void btrfs_issue_discard(struct block_device *bdev,
1571 u64 start, u64 len) 1572 u64 start, u64 len)
1572{ 1573{
1573 blkdev_issue_discard(bdev, start >> 9, len >> 9, GFP_KERNEL, 1574 blkdev_issue_discard(bdev, start >> 9, len >> 9, GFP_KERNEL,
1574 DISCARD_FL_BARRIER); 1575 DISCARD_FL_BARRIER);
1575} 1576}
1576#endif
1577 1577
1578static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr, 1578static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr,
1579 u64 num_bytes) 1579 u64 num_bytes)
1580{ 1580{
1581#ifdef BIO_RW_DISCARD
1582 int ret; 1581 int ret;
1583 u64 map_length = num_bytes; 1582 u64 map_length = num_bytes;
1584 struct btrfs_multi_bio *multi = NULL; 1583 struct btrfs_multi_bio *multi = NULL;
1585 1584
1585 if (!btrfs_test_opt(root, DISCARD))
1586 return 0;
1587
1586 /* Tell the block device(s) that the sectors can be discarded */ 1588 /* Tell the block device(s) that the sectors can be discarded */
1587 ret = btrfs_map_block(&root->fs_info->mapping_tree, READ, 1589 ret = btrfs_map_block(&root->fs_info->mapping_tree, READ,
1588 bytenr, &map_length, &multi, 0); 1590 bytenr, &map_length, &multi, 0);
@@ -1602,9 +1604,6 @@ static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr,
1602 } 1604 }
1603 1605
1604 return ret; 1606 return ret;
1605#else
1606 return 0;
1607#endif
1608} 1607}
1609 1608
1610int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, 1609int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
@@ -2765,67 +2764,448 @@ void btrfs_set_inode_space_info(struct btrfs_root *root, struct inode *inode)
2765 alloc_target); 2764 alloc_target);
2766} 2765}
2767 2766
2767static u64 calculate_bytes_needed(struct btrfs_root *root, int num_items)
2768{
2769 u64 num_bytes;
2770 int level;
2771
2772 level = BTRFS_MAX_LEVEL - 2;
2773 /*
2774 * NOTE: these calculations are absolutely the worst possible case.
2775 * This assumes that _every_ item we insert will require a new leaf, and
2776 * that the tree has grown to its maximum level size.
2777 */
2778
2779 /*
2780 * for every item we insert we could insert both an extent item and a
2781 * extent ref item. Then for ever item we insert, we will need to cow
2782 * both the original leaf, plus the leaf to the left and right of it.
2783 *
2784 * Unless we are talking about the extent root, then we just want the
2785 * number of items * 2, since we just need the extent item plus its ref.
2786 */
2787 if (root == root->fs_info->extent_root)
2788 num_bytes = num_items * 2;
2789 else
2790 num_bytes = (num_items + (2 * num_items)) * 3;
2791
2792 /*
2793 * num_bytes is total number of leaves we could need times the leaf
2794 * size, and then for every leaf we could end up cow'ing 2 nodes per
2795 * level, down to the leaf level.
2796 */
2797 num_bytes = (num_bytes * root->leafsize) +
2798 (num_bytes * (level * 2)) * root->nodesize;
2799
2800 return num_bytes;
2801}
2802
2768/* 2803/*
2769 * for now this just makes sure we have at least 5% of our metadata space free 2804 * Unreserve metadata space for delalloc. If we have less reserved credits than
2770 * for use. 2805 * we have extents, this function does nothing.
2771 */ 2806 */
2772int btrfs_check_metadata_free_space(struct btrfs_root *root) 2807int btrfs_unreserve_metadata_for_delalloc(struct btrfs_root *root,
2808 struct inode *inode, int num_items)
2773{ 2809{
2774 struct btrfs_fs_info *info = root->fs_info; 2810 struct btrfs_fs_info *info = root->fs_info;
2775 struct btrfs_space_info *meta_sinfo; 2811 struct btrfs_space_info *meta_sinfo;
2776 u64 alloc_target, thresh; 2812 u64 num_bytes;
2777 int committed = 0, ret; 2813 u64 alloc_target;
2814 bool bug = false;
2778 2815
2779 /* get the space info for where the metadata will live */ 2816 /* get the space info for where the metadata will live */
2780 alloc_target = btrfs_get_alloc_profile(root, 0); 2817 alloc_target = btrfs_get_alloc_profile(root, 0);
2781 meta_sinfo = __find_space_info(info, alloc_target); 2818 meta_sinfo = __find_space_info(info, alloc_target);
2782 if (!meta_sinfo)
2783 goto alloc;
2784 2819
2785again: 2820 num_bytes = calculate_bytes_needed(root->fs_info->extent_root,
2821 num_items);
2822
2786 spin_lock(&meta_sinfo->lock); 2823 spin_lock(&meta_sinfo->lock);
2787 if (!meta_sinfo->full) 2824 spin_lock(&BTRFS_I(inode)->accounting_lock);
2788 thresh = meta_sinfo->total_bytes * 80; 2825 if (BTRFS_I(inode)->reserved_extents <=
2789 else 2826 BTRFS_I(inode)->outstanding_extents) {
2790 thresh = meta_sinfo->total_bytes * 95; 2827 spin_unlock(&BTRFS_I(inode)->accounting_lock);
2828 spin_unlock(&meta_sinfo->lock);
2829 return 0;
2830 }
2831 spin_unlock(&BTRFS_I(inode)->accounting_lock);
2832
2833 BTRFS_I(inode)->reserved_extents--;
2834 BUG_ON(BTRFS_I(inode)->reserved_extents < 0);
2835
2836 if (meta_sinfo->bytes_delalloc < num_bytes) {
2837 bug = true;
2838 meta_sinfo->bytes_delalloc = 0;
2839 } else {
2840 meta_sinfo->bytes_delalloc -= num_bytes;
2841 }
2842 spin_unlock(&meta_sinfo->lock);
2791 2843
2844 BUG_ON(bug);
2845
2846 return 0;
2847}
2848
2849static void check_force_delalloc(struct btrfs_space_info *meta_sinfo)
2850{
2851 u64 thresh;
2852
2853 thresh = meta_sinfo->bytes_used + meta_sinfo->bytes_reserved +
2854 meta_sinfo->bytes_pinned + meta_sinfo->bytes_readonly +
2855 meta_sinfo->bytes_super + meta_sinfo->bytes_root +
2856 meta_sinfo->bytes_may_use;
2857
2858 thresh = meta_sinfo->total_bytes - thresh;
2859 thresh *= 80;
2792 do_div(thresh, 100); 2860 do_div(thresh, 100);
2861 if (thresh <= meta_sinfo->bytes_delalloc)
2862 meta_sinfo->force_delalloc = 1;
2863 else
2864 meta_sinfo->force_delalloc = 0;
2865}
2793 2866
2794 if (meta_sinfo->bytes_used + meta_sinfo->bytes_reserved + 2867struct async_flush {
2795 meta_sinfo->bytes_pinned + meta_sinfo->bytes_readonly + 2868 struct btrfs_root *root;
2796 meta_sinfo->bytes_super > thresh) { 2869 struct btrfs_space_info *info;
2797 struct btrfs_trans_handle *trans; 2870 struct btrfs_work work;
2798 if (!meta_sinfo->full) { 2871};
2799 meta_sinfo->force_alloc = 1; 2872
2873static noinline void flush_delalloc_async(struct btrfs_work *work)
2874{
2875 struct async_flush *async;
2876 struct btrfs_root *root;
2877 struct btrfs_space_info *info;
2878
2879 async = container_of(work, struct async_flush, work);
2880 root = async->root;
2881 info = async->info;
2882
2883 btrfs_start_delalloc_inodes(root);
2884 wake_up(&info->flush_wait);
2885 btrfs_wait_ordered_extents(root, 0);
2886
2887 spin_lock(&info->lock);
2888 info->flushing = 0;
2889 spin_unlock(&info->lock);
2890 wake_up(&info->flush_wait);
2891
2892 kfree(async);
2893}
2894
2895static void wait_on_flush(struct btrfs_space_info *info)
2896{
2897 DEFINE_WAIT(wait);
2898 u64 used;
2899
2900 while (1) {
2901 prepare_to_wait(&info->flush_wait, &wait,
2902 TASK_UNINTERRUPTIBLE);
2903 spin_lock(&info->lock);
2904 if (!info->flushing) {
2905 spin_unlock(&info->lock);
2906 break;
2907 }
2908
2909 used = info->bytes_used + info->bytes_reserved +
2910 info->bytes_pinned + info->bytes_readonly +
2911 info->bytes_super + info->bytes_root +
2912 info->bytes_may_use + info->bytes_delalloc;
2913 if (used < info->total_bytes) {
2914 spin_unlock(&info->lock);
2915 break;
2916 }
2917 spin_unlock(&info->lock);
2918 schedule();
2919 }
2920 finish_wait(&info->flush_wait, &wait);
2921}
2922
2923static void flush_delalloc(struct btrfs_root *root,
2924 struct btrfs_space_info *info)
2925{
2926 struct async_flush *async;
2927 bool wait = false;
2928
2929 spin_lock(&info->lock);
2930
2931 if (!info->flushing) {
2932 info->flushing = 1;
2933 init_waitqueue_head(&info->flush_wait);
2934 } else {
2935 wait = true;
2936 }
2937
2938 spin_unlock(&info->lock);
2939
2940 if (wait) {
2941 wait_on_flush(info);
2942 return;
2943 }
2944
2945 async = kzalloc(sizeof(*async), GFP_NOFS);
2946 if (!async)
2947 goto flush;
2948
2949 async->root = root;
2950 async->info = info;
2951 async->work.func = flush_delalloc_async;
2952
2953 btrfs_queue_worker(&root->fs_info->enospc_workers,
2954 &async->work);
2955 wait_on_flush(info);
2956 return;
2957
2958flush:
2959 btrfs_start_delalloc_inodes(root);
2960 btrfs_wait_ordered_extents(root, 0);
2961
2962 spin_lock(&info->lock);
2963 info->flushing = 0;
2964 spin_unlock(&info->lock);
2965 wake_up(&info->flush_wait);
2966}
2967
2968static int maybe_allocate_chunk(struct btrfs_root *root,
2969 struct btrfs_space_info *info)
2970{
2971 struct btrfs_super_block *disk_super = &root->fs_info->super_copy;
2972 struct btrfs_trans_handle *trans;
2973 bool wait = false;
2974 int ret = 0;
2975 u64 min_metadata;
2976 u64 free_space;
2977
2978 free_space = btrfs_super_total_bytes(disk_super);
2979 /*
2980 * we allow the metadata to grow to a max of either 5gb or 5% of the
2981 * space in the volume.
2982 */
2983 min_metadata = min((u64)5 * 1024 * 1024 * 1024,
2984 div64_u64(free_space * 5, 100));
2985 if (info->total_bytes >= min_metadata) {
2986 spin_unlock(&info->lock);
2987 return 0;
2988 }
2989
2990 if (info->full) {
2991 spin_unlock(&info->lock);
2992 return 0;
2993 }
2994
2995 if (!info->allocating_chunk) {
2996 info->force_alloc = 1;
2997 info->allocating_chunk = 1;
2998 init_waitqueue_head(&info->allocate_wait);
2999 } else {
3000 wait = true;
3001 }
3002
3003 spin_unlock(&info->lock);
3004
3005 if (wait) {
3006 wait_event(info->allocate_wait,
3007 !info->allocating_chunk);
3008 return 1;
3009 }
3010
3011 trans = btrfs_start_transaction(root, 1);
3012 if (!trans) {
3013 ret = -ENOMEM;
3014 goto out;
3015 }
3016
3017 ret = do_chunk_alloc(trans, root->fs_info->extent_root,
3018 4096 + 2 * 1024 * 1024,
3019 info->flags, 0);
3020 btrfs_end_transaction(trans, root);
3021 if (ret)
3022 goto out;
3023out:
3024 spin_lock(&info->lock);
3025 info->allocating_chunk = 0;
3026 spin_unlock(&info->lock);
3027 wake_up(&info->allocate_wait);
3028
3029 if (ret)
3030 return 0;
3031 return 1;
3032}
3033
3034/*
3035 * Reserve metadata space for delalloc.
3036 */
3037int btrfs_reserve_metadata_for_delalloc(struct btrfs_root *root,
3038 struct inode *inode, int num_items)
3039{
3040 struct btrfs_fs_info *info = root->fs_info;
3041 struct btrfs_space_info *meta_sinfo;
3042 u64 num_bytes;
3043 u64 used;
3044 u64 alloc_target;
3045 int flushed = 0;
3046 int force_delalloc;
3047
3048 /* get the space info for where the metadata will live */
3049 alloc_target = btrfs_get_alloc_profile(root, 0);
3050 meta_sinfo = __find_space_info(info, alloc_target);
3051
3052 num_bytes = calculate_bytes_needed(root->fs_info->extent_root,
3053 num_items);
3054again:
3055 spin_lock(&meta_sinfo->lock);
3056
3057 force_delalloc = meta_sinfo->force_delalloc;
3058
3059 if (unlikely(!meta_sinfo->bytes_root))
3060 meta_sinfo->bytes_root = calculate_bytes_needed(root, 6);
3061
3062 if (!flushed)
3063 meta_sinfo->bytes_delalloc += num_bytes;
3064
3065 used = meta_sinfo->bytes_used + meta_sinfo->bytes_reserved +
3066 meta_sinfo->bytes_pinned + meta_sinfo->bytes_readonly +
3067 meta_sinfo->bytes_super + meta_sinfo->bytes_root +
3068 meta_sinfo->bytes_may_use + meta_sinfo->bytes_delalloc;
3069
3070 if (used > meta_sinfo->total_bytes) {
3071 flushed++;
3072
3073 if (flushed == 1) {
3074 if (maybe_allocate_chunk(root, meta_sinfo))
3075 goto again;
3076 flushed++;
3077 } else {
2800 spin_unlock(&meta_sinfo->lock); 3078 spin_unlock(&meta_sinfo->lock);
2801alloc: 3079 }
2802 trans = btrfs_start_transaction(root, 1);
2803 if (!trans)
2804 return -ENOMEM;
2805 3080
2806 ret = do_chunk_alloc(trans, root->fs_info->extent_root, 3081 if (flushed == 2) {
2807 2 * 1024 * 1024, alloc_target, 0); 3082 filemap_flush(inode->i_mapping);
2808 btrfs_end_transaction(trans, root); 3083 goto again;
2809 if (!meta_sinfo) { 3084 } else if (flushed == 3) {
2810 meta_sinfo = __find_space_info(info, 3085 flush_delalloc(root, meta_sinfo);
2811 alloc_target);
2812 }
2813 goto again; 3086 goto again;
2814 } 3087 }
3088 spin_lock(&meta_sinfo->lock);
3089 meta_sinfo->bytes_delalloc -= num_bytes;
2815 spin_unlock(&meta_sinfo->lock); 3090 spin_unlock(&meta_sinfo->lock);
3091 printk(KERN_ERR "enospc, has %d, reserved %d\n",
3092 BTRFS_I(inode)->outstanding_extents,
3093 BTRFS_I(inode)->reserved_extents);
3094 dump_space_info(meta_sinfo, 0, 0);
3095 return -ENOSPC;
3096 }
2816 3097
2817 if (!committed) { 3098 BTRFS_I(inode)->reserved_extents++;
2818 committed = 1; 3099 check_force_delalloc(meta_sinfo);
2819 trans = btrfs_join_transaction(root, 1); 3100 spin_unlock(&meta_sinfo->lock);
2820 if (!trans) 3101
2821 return -ENOMEM; 3102 if (!flushed && force_delalloc)
2822 ret = btrfs_commit_transaction(trans, root); 3103 filemap_flush(inode->i_mapping);
2823 if (ret) 3104
2824 return ret; 3105 return 0;
3106}
3107
3108/*
3109 * unreserve num_items number of items worth of metadata space. This needs to
3110 * be paired with btrfs_reserve_metadata_space.
3111 *
3112 * NOTE: if you have the option, run this _AFTER_ you do a
3113 * btrfs_end_transaction, since btrfs_end_transaction will run delayed ref
3114 * oprations which will result in more used metadata, so we want to make sure we
3115 * can do that without issue.
3116 */
3117int btrfs_unreserve_metadata_space(struct btrfs_root *root, int num_items)
3118{
3119 struct btrfs_fs_info *info = root->fs_info;
3120 struct btrfs_space_info *meta_sinfo;
3121 u64 num_bytes;
3122 u64 alloc_target;
3123 bool bug = false;
3124
3125 /* get the space info for where the metadata will live */
3126 alloc_target = btrfs_get_alloc_profile(root, 0);
3127 meta_sinfo = __find_space_info(info, alloc_target);
3128
3129 num_bytes = calculate_bytes_needed(root, num_items);
3130
3131 spin_lock(&meta_sinfo->lock);
3132 if (meta_sinfo->bytes_may_use < num_bytes) {
3133 bug = true;
3134 meta_sinfo->bytes_may_use = 0;
3135 } else {
3136 meta_sinfo->bytes_may_use -= num_bytes;
3137 }
3138 spin_unlock(&meta_sinfo->lock);
3139
3140 BUG_ON(bug);
3141
3142 return 0;
3143}
3144
3145/*
3146 * Reserve some metadata space for use. We'll calculate the worste case number
3147 * of bytes that would be needed to modify num_items number of items. If we
3148 * have space, fantastic, if not, you get -ENOSPC. Please call
3149 * btrfs_unreserve_metadata_space when you are done for the _SAME_ number of
3150 * items you reserved, since whatever metadata you needed should have already
3151 * been allocated.
3152 *
3153 * This will commit the transaction to make more space if we don't have enough
3154 * metadata space. THe only time we don't do this is if we're reserving space
3155 * inside of a transaction, then we will just return -ENOSPC and it is the
3156 * callers responsibility to handle it properly.
3157 */
3158int btrfs_reserve_metadata_space(struct btrfs_root *root, int num_items)
3159{
3160 struct btrfs_fs_info *info = root->fs_info;
3161 struct btrfs_space_info *meta_sinfo;
3162 u64 num_bytes;
3163 u64 used;
3164 u64 alloc_target;
3165 int retries = 0;
3166
3167 /* get the space info for where the metadata will live */
3168 alloc_target = btrfs_get_alloc_profile(root, 0);
3169 meta_sinfo = __find_space_info(info, alloc_target);
3170
3171 num_bytes = calculate_bytes_needed(root, num_items);
3172again:
3173 spin_lock(&meta_sinfo->lock);
3174
3175 if (unlikely(!meta_sinfo->bytes_root))
3176 meta_sinfo->bytes_root = calculate_bytes_needed(root, 6);
3177
3178 if (!retries)
3179 meta_sinfo->bytes_may_use += num_bytes;
3180
3181 used = meta_sinfo->bytes_used + meta_sinfo->bytes_reserved +
3182 meta_sinfo->bytes_pinned + meta_sinfo->bytes_readonly +
3183 meta_sinfo->bytes_super + meta_sinfo->bytes_root +
3184 meta_sinfo->bytes_may_use + meta_sinfo->bytes_delalloc;
3185
3186 if (used > meta_sinfo->total_bytes) {
3187 retries++;
3188 if (retries == 1) {
3189 if (maybe_allocate_chunk(root, meta_sinfo))
3190 goto again;
3191 retries++;
3192 } else {
3193 spin_unlock(&meta_sinfo->lock);
3194 }
3195
3196 if (retries == 2) {
3197 flush_delalloc(root, meta_sinfo);
2825 goto again; 3198 goto again;
2826 } 3199 }
3200 spin_lock(&meta_sinfo->lock);
3201 meta_sinfo->bytes_may_use -= num_bytes;
3202 spin_unlock(&meta_sinfo->lock);
3203
3204 dump_space_info(meta_sinfo, 0, 0);
2827 return -ENOSPC; 3205 return -ENOSPC;
2828 } 3206 }
3207
3208 check_force_delalloc(meta_sinfo);
2829 spin_unlock(&meta_sinfo->lock); 3209 spin_unlock(&meta_sinfo->lock);
2830 3210
2831 return 0; 3211 return 0;
@@ -2888,7 +3268,7 @@ alloc:
2888 spin_unlock(&data_sinfo->lock); 3268 spin_unlock(&data_sinfo->lock);
2889 3269
2890 /* commit the current transaction and try again */ 3270 /* commit the current transaction and try again */
2891 if (!committed) { 3271 if (!committed && !root->fs_info->open_ioctl_trans) {
2892 committed = 1; 3272 committed = 1;
2893 trans = btrfs_join_transaction(root, 1); 3273 trans = btrfs_join_transaction(root, 1);
2894 if (!trans) 3274 if (!trans)
@@ -2916,7 +3296,7 @@ alloc:
2916 BTRFS_I(inode)->reserved_bytes += bytes; 3296 BTRFS_I(inode)->reserved_bytes += bytes;
2917 spin_unlock(&data_sinfo->lock); 3297 spin_unlock(&data_sinfo->lock);
2918 3298
2919 return btrfs_check_metadata_free_space(root); 3299 return 0;
2920} 3300}
2921 3301
2922/* 3302/*
@@ -3015,17 +3395,15 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans,
3015 BUG_ON(!space_info); 3395 BUG_ON(!space_info);
3016 3396
3017 spin_lock(&space_info->lock); 3397 spin_lock(&space_info->lock);
3018 if (space_info->force_alloc) { 3398 if (space_info->force_alloc)
3019 force = 1; 3399 force = 1;
3020 space_info->force_alloc = 0;
3021 }
3022 if (space_info->full) { 3400 if (space_info->full) {
3023 spin_unlock(&space_info->lock); 3401 spin_unlock(&space_info->lock);
3024 goto out; 3402 goto out;
3025 } 3403 }
3026 3404
3027 thresh = space_info->total_bytes - space_info->bytes_readonly; 3405 thresh = space_info->total_bytes - space_info->bytes_readonly;
3028 thresh = div_factor(thresh, 6); 3406 thresh = div_factor(thresh, 8);
3029 if (!force && 3407 if (!force &&
3030 (space_info->bytes_used + space_info->bytes_pinned + 3408 (space_info->bytes_used + space_info->bytes_pinned +
3031 space_info->bytes_reserved + alloc_bytes) < thresh) { 3409 space_info->bytes_reserved + alloc_bytes) < thresh) {
@@ -3039,7 +3417,7 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans,
3039 * we keep a reasonable number of metadata chunks allocated in the 3417 * we keep a reasonable number of metadata chunks allocated in the
3040 * FS as well. 3418 * FS as well.
3041 */ 3419 */
3042 if (flags & BTRFS_BLOCK_GROUP_DATA) { 3420 if (flags & BTRFS_BLOCK_GROUP_DATA && fs_info->metadata_ratio) {
3043 fs_info->data_chunk_allocations++; 3421 fs_info->data_chunk_allocations++;
3044 if (!(fs_info->data_chunk_allocations % 3422 if (!(fs_info->data_chunk_allocations %
3045 fs_info->metadata_ratio)) 3423 fs_info->metadata_ratio))
@@ -3047,8 +3425,11 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans,
3047 } 3425 }
3048 3426
3049 ret = btrfs_alloc_chunk(trans, extent_root, flags); 3427 ret = btrfs_alloc_chunk(trans, extent_root, flags);
3428 spin_lock(&space_info->lock);
3050 if (ret) 3429 if (ret)
3051 space_info->full = 1; 3430 space_info->full = 1;
3431 space_info->force_alloc = 0;
3432 spin_unlock(&space_info->lock);
3052out: 3433out:
3053 mutex_unlock(&extent_root->fs_info->chunk_mutex); 3434 mutex_unlock(&extent_root->fs_info->chunk_mutex);
3054 return ret; 3435 return ret;
@@ -3306,6 +3687,14 @@ static int pin_down_bytes(struct btrfs_trans_handle *trans,
3306 if (is_data) 3687 if (is_data)
3307 goto pinit; 3688 goto pinit;
3308 3689
3690 /*
3691 * discard is sloooow, and so triggering discards on
3692 * individual btree blocks isn't a good plan. Just
3693 * pin everything in discard mode.
3694 */
3695 if (btrfs_test_opt(root, DISCARD))
3696 goto pinit;
3697
3309 buf = btrfs_find_tree_block(root, bytenr, num_bytes); 3698 buf = btrfs_find_tree_block(root, bytenr, num_bytes);
3310 if (!buf) 3699 if (!buf)
3311 goto pinit; 3700 goto pinit;
@@ -3747,6 +4136,7 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans,
3747 int loop = 0; 4136 int loop = 0;
3748 bool found_uncached_bg = false; 4137 bool found_uncached_bg = false;
3749 bool failed_cluster_refill = false; 4138 bool failed_cluster_refill = false;
4139 bool failed_alloc = false;
3750 4140
3751 WARN_ON(num_bytes < root->sectorsize); 4141 WARN_ON(num_bytes < root->sectorsize);
3752 btrfs_set_key_type(ins, BTRFS_EXTENT_ITEM_KEY); 4142 btrfs_set_key_type(ins, BTRFS_EXTENT_ITEM_KEY);
@@ -3951,14 +4341,23 @@ refill_cluster:
3951 4341
3952 offset = btrfs_find_space_for_alloc(block_group, search_start, 4342 offset = btrfs_find_space_for_alloc(block_group, search_start,
3953 num_bytes, empty_size); 4343 num_bytes, empty_size);
3954 if (!offset && (cached || (!cached && 4344 /*
3955 loop == LOOP_CACHING_NOWAIT))) { 4345 * If we didn't find a chunk, and we haven't failed on this
3956 goto loop; 4346 * block group before, and this block group is in the middle of
3957 } else if (!offset && (!cached && 4347 * caching and we are ok with waiting, then go ahead and wait
3958 loop > LOOP_CACHING_NOWAIT)) { 4348 * for progress to be made, and set failed_alloc to true.
4349 *
4350 * If failed_alloc is true then we've already waited on this
4351 * block group once and should move on to the next block group.
4352 */
4353 if (!offset && !failed_alloc && !cached &&
4354 loop > LOOP_CACHING_NOWAIT) {
3959 wait_block_group_cache_progress(block_group, 4355 wait_block_group_cache_progress(block_group,
3960 num_bytes + empty_size); 4356 num_bytes + empty_size);
4357 failed_alloc = true;
3961 goto have_block_group; 4358 goto have_block_group;
4359 } else if (!offset) {
4360 goto loop;
3962 } 4361 }
3963checks: 4362checks:
3964 search_start = stripe_align(root, offset); 4363 search_start = stripe_align(root, offset);
@@ -4006,6 +4405,7 @@ checks:
4006 break; 4405 break;
4007loop: 4406loop:
4008 failed_cluster_refill = false; 4407 failed_cluster_refill = false;
4408 failed_alloc = false;
4009 btrfs_put_block_group(block_group); 4409 btrfs_put_block_group(block_group);
4010 } 4410 }
4011 up_read(&space_info->groups_sem); 4411 up_read(&space_info->groups_sem);
@@ -4063,21 +4463,32 @@ loop:
4063 return ret; 4463 return ret;
4064} 4464}
4065 4465
4066static void dump_space_info(struct btrfs_space_info *info, u64 bytes) 4466static void dump_space_info(struct btrfs_space_info *info, u64 bytes,
4467 int dump_block_groups)
4067{ 4468{
4068 struct btrfs_block_group_cache *cache; 4469 struct btrfs_block_group_cache *cache;
4069 4470
4471 spin_lock(&info->lock);
4070 printk(KERN_INFO "space_info has %llu free, is %sfull\n", 4472 printk(KERN_INFO "space_info has %llu free, is %sfull\n",
4071 (unsigned long long)(info->total_bytes - info->bytes_used - 4473 (unsigned long long)(info->total_bytes - info->bytes_used -
4072 info->bytes_pinned - info->bytes_reserved), 4474 info->bytes_pinned - info->bytes_reserved -
4475 info->bytes_super),
4073 (info->full) ? "" : "not "); 4476 (info->full) ? "" : "not ");
4074 printk(KERN_INFO "space_info total=%llu, pinned=%llu, delalloc=%llu," 4477 printk(KERN_INFO "space_info total=%llu, pinned=%llu, delalloc=%llu,"
4075 " may_use=%llu, used=%llu\n", 4478 " may_use=%llu, used=%llu, root=%llu, super=%llu, reserved=%llu"
4479 "\n",
4076 (unsigned long long)info->total_bytes, 4480 (unsigned long long)info->total_bytes,
4077 (unsigned long long)info->bytes_pinned, 4481 (unsigned long long)info->bytes_pinned,
4078 (unsigned long long)info->bytes_delalloc, 4482 (unsigned long long)info->bytes_delalloc,
4079 (unsigned long long)info->bytes_may_use, 4483 (unsigned long long)info->bytes_may_use,
4080 (unsigned long long)info->bytes_used); 4484 (unsigned long long)info->bytes_used,
4485 (unsigned long long)info->bytes_root,
4486 (unsigned long long)info->bytes_super,
4487 (unsigned long long)info->bytes_reserved);
4488 spin_unlock(&info->lock);
4489
4490 if (!dump_block_groups)
4491 return;
4081 4492
4082 down_read(&info->groups_sem); 4493 down_read(&info->groups_sem);
4083 list_for_each_entry(cache, &info->block_groups, list) { 4494 list_for_each_entry(cache, &info->block_groups, list) {
@@ -4145,7 +4556,7 @@ again:
4145 printk(KERN_ERR "btrfs allocation failed flags %llu, " 4556 printk(KERN_ERR "btrfs allocation failed flags %llu, "
4146 "wanted %llu\n", (unsigned long long)data, 4557 "wanted %llu\n", (unsigned long long)data,
4147 (unsigned long long)num_bytes); 4558 (unsigned long long)num_bytes);
4148 dump_space_info(sinfo, num_bytes); 4559 dump_space_info(sinfo, num_bytes, 1);
4149 } 4560 }
4150 4561
4151 return ret; 4562 return ret;
@@ -4506,6 +4917,7 @@ static noinline void reada_walk_down(struct btrfs_trans_handle *trans,
4506 u64 bytenr; 4917 u64 bytenr;
4507 u64 generation; 4918 u64 generation;
4508 u64 refs; 4919 u64 refs;
4920 u64 flags;
4509 u64 last = 0; 4921 u64 last = 0;
4510 u32 nritems; 4922 u32 nritems;
4511 u32 blocksize; 4923 u32 blocksize;
@@ -4543,15 +4955,19 @@ static noinline void reada_walk_down(struct btrfs_trans_handle *trans,
4543 generation <= root->root_key.offset) 4955 generation <= root->root_key.offset)
4544 continue; 4956 continue;
4545 4957
4958 /* We don't lock the tree block, it's OK to be racy here */
4959 ret = btrfs_lookup_extent_info(trans, root, bytenr, blocksize,
4960 &refs, &flags);
4961 BUG_ON(ret);
4962 BUG_ON(refs == 0);
4963
4546 if (wc->stage == DROP_REFERENCE) { 4964 if (wc->stage == DROP_REFERENCE) {
4547 ret = btrfs_lookup_extent_info(trans, root,
4548 bytenr, blocksize,
4549 &refs, NULL);
4550 BUG_ON(ret);
4551 BUG_ON(refs == 0);
4552 if (refs == 1) 4965 if (refs == 1)
4553 goto reada; 4966 goto reada;
4554 4967
4968 if (wc->level == 1 &&
4969 (flags & BTRFS_BLOCK_FLAG_FULL_BACKREF))
4970 continue;
4555 if (!wc->update_ref || 4971 if (!wc->update_ref ||
4556 generation <= root->root_key.offset) 4972 generation <= root->root_key.offset)
4557 continue; 4973 continue;
@@ -4560,6 +4976,10 @@ static noinline void reada_walk_down(struct btrfs_trans_handle *trans,
4560 &wc->update_progress); 4976 &wc->update_progress);
4561 if (ret < 0) 4977 if (ret < 0)
4562 continue; 4978 continue;
4979 } else {
4980 if (wc->level == 1 &&
4981 (flags & BTRFS_BLOCK_FLAG_FULL_BACKREF))
4982 continue;
4563 } 4983 }
4564reada: 4984reada:
4565 ret = readahead_tree_block(root, bytenr, blocksize, 4985 ret = readahead_tree_block(root, bytenr, blocksize,
@@ -4583,7 +5003,7 @@ reada:
4583static noinline int walk_down_proc(struct btrfs_trans_handle *trans, 5003static noinline int walk_down_proc(struct btrfs_trans_handle *trans,
4584 struct btrfs_root *root, 5004 struct btrfs_root *root,
4585 struct btrfs_path *path, 5005 struct btrfs_path *path,
4586 struct walk_control *wc) 5006 struct walk_control *wc, int lookup_info)
4587{ 5007{
4588 int level = wc->level; 5008 int level = wc->level;
4589 struct extent_buffer *eb = path->nodes[level]; 5009 struct extent_buffer *eb = path->nodes[level];
@@ -4598,8 +5018,9 @@ static noinline int walk_down_proc(struct btrfs_trans_handle *trans,
4598 * when reference count of tree block is 1, it won't increase 5018 * when reference count of tree block is 1, it won't increase
4599 * again. once full backref flag is set, we never clear it. 5019 * again. once full backref flag is set, we never clear it.
4600 */ 5020 */
4601 if ((wc->stage == DROP_REFERENCE && wc->refs[level] != 1) || 5021 if (lookup_info &&
4602 (wc->stage == UPDATE_BACKREF && !(wc->flags[level] & flag))) { 5022 ((wc->stage == DROP_REFERENCE && wc->refs[level] != 1) ||
5023 (wc->stage == UPDATE_BACKREF && !(wc->flags[level] & flag)))) {
4603 BUG_ON(!path->locks[level]); 5024 BUG_ON(!path->locks[level]);
4604 ret = btrfs_lookup_extent_info(trans, root, 5025 ret = btrfs_lookup_extent_info(trans, root,
4605 eb->start, eb->len, 5026 eb->start, eb->len,
@@ -4660,7 +5081,7 @@ static noinline int walk_down_proc(struct btrfs_trans_handle *trans,
4660static noinline int do_walk_down(struct btrfs_trans_handle *trans, 5081static noinline int do_walk_down(struct btrfs_trans_handle *trans,
4661 struct btrfs_root *root, 5082 struct btrfs_root *root,
4662 struct btrfs_path *path, 5083 struct btrfs_path *path,
4663 struct walk_control *wc) 5084 struct walk_control *wc, int *lookup_info)
4664{ 5085{
4665 u64 bytenr; 5086 u64 bytenr;
4666 u64 generation; 5087 u64 generation;
@@ -4680,8 +5101,10 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans,
4680 * for the subtree 5101 * for the subtree
4681 */ 5102 */
4682 if (wc->stage == UPDATE_BACKREF && 5103 if (wc->stage == UPDATE_BACKREF &&
4683 generation <= root->root_key.offset) 5104 generation <= root->root_key.offset) {
5105 *lookup_info = 1;
4684 return 1; 5106 return 1;
5107 }
4685 5108
4686 bytenr = btrfs_node_blockptr(path->nodes[level], path->slots[level]); 5109 bytenr = btrfs_node_blockptr(path->nodes[level], path->slots[level]);
4687 blocksize = btrfs_level_size(root, level - 1); 5110 blocksize = btrfs_level_size(root, level - 1);
@@ -4694,14 +5117,19 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans,
4694 btrfs_tree_lock(next); 5117 btrfs_tree_lock(next);
4695 btrfs_set_lock_blocking(next); 5118 btrfs_set_lock_blocking(next);
4696 5119
4697 if (wc->stage == DROP_REFERENCE) { 5120 ret = btrfs_lookup_extent_info(trans, root, bytenr, blocksize,
4698 ret = btrfs_lookup_extent_info(trans, root, bytenr, blocksize, 5121 &wc->refs[level - 1],
4699 &wc->refs[level - 1], 5122 &wc->flags[level - 1]);
4700 &wc->flags[level - 1]); 5123 BUG_ON(ret);
4701 BUG_ON(ret); 5124 BUG_ON(wc->refs[level - 1] == 0);
4702 BUG_ON(wc->refs[level - 1] == 0); 5125 *lookup_info = 0;
4703 5126
5127 if (wc->stage == DROP_REFERENCE) {
4704 if (wc->refs[level - 1] > 1) { 5128 if (wc->refs[level - 1] > 1) {
5129 if (level == 1 &&
5130 (wc->flags[0] & BTRFS_BLOCK_FLAG_FULL_BACKREF))
5131 goto skip;
5132
4705 if (!wc->update_ref || 5133 if (!wc->update_ref ||
4706 generation <= root->root_key.offset) 5134 generation <= root->root_key.offset)
4707 goto skip; 5135 goto skip;
@@ -4715,12 +5143,17 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans,
4715 wc->stage = UPDATE_BACKREF; 5143 wc->stage = UPDATE_BACKREF;
4716 wc->shared_level = level - 1; 5144 wc->shared_level = level - 1;
4717 } 5145 }
5146 } else {
5147 if (level == 1 &&
5148 (wc->flags[0] & BTRFS_BLOCK_FLAG_FULL_BACKREF))
5149 goto skip;
4718 } 5150 }
4719 5151
4720 if (!btrfs_buffer_uptodate(next, generation)) { 5152 if (!btrfs_buffer_uptodate(next, generation)) {
4721 btrfs_tree_unlock(next); 5153 btrfs_tree_unlock(next);
4722 free_extent_buffer(next); 5154 free_extent_buffer(next);
4723 next = NULL; 5155 next = NULL;
5156 *lookup_info = 1;
4724 } 5157 }
4725 5158
4726 if (!next) { 5159 if (!next) {
@@ -4743,21 +5176,22 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans,
4743skip: 5176skip:
4744 wc->refs[level - 1] = 0; 5177 wc->refs[level - 1] = 0;
4745 wc->flags[level - 1] = 0; 5178 wc->flags[level - 1] = 0;
5179 if (wc->stage == DROP_REFERENCE) {
5180 if (wc->flags[level] & BTRFS_BLOCK_FLAG_FULL_BACKREF) {
5181 parent = path->nodes[level]->start;
5182 } else {
5183 BUG_ON(root->root_key.objectid !=
5184 btrfs_header_owner(path->nodes[level]));
5185 parent = 0;
5186 }
4746 5187
4747 if (wc->flags[level] & BTRFS_BLOCK_FLAG_FULL_BACKREF) { 5188 ret = btrfs_free_extent(trans, root, bytenr, blocksize, parent,
4748 parent = path->nodes[level]->start; 5189 root->root_key.objectid, level - 1, 0);
4749 } else { 5190 BUG_ON(ret);
4750 BUG_ON(root->root_key.objectid !=
4751 btrfs_header_owner(path->nodes[level]));
4752 parent = 0;
4753 } 5191 }
4754
4755 ret = btrfs_free_extent(trans, root, bytenr, blocksize, parent,
4756 root->root_key.objectid, level - 1, 0);
4757 BUG_ON(ret);
4758
4759 btrfs_tree_unlock(next); 5192 btrfs_tree_unlock(next);
4760 free_extent_buffer(next); 5193 free_extent_buffer(next);
5194 *lookup_info = 1;
4761 return 1; 5195 return 1;
4762} 5196}
4763 5197
@@ -4871,6 +5305,7 @@ static noinline int walk_down_tree(struct btrfs_trans_handle *trans,
4871 struct walk_control *wc) 5305 struct walk_control *wc)
4872{ 5306{
4873 int level = wc->level; 5307 int level = wc->level;
5308 int lookup_info = 1;
4874 int ret; 5309 int ret;
4875 5310
4876 while (level >= 0) { 5311 while (level >= 0) {
@@ -4878,14 +5313,14 @@ static noinline int walk_down_tree(struct btrfs_trans_handle *trans,
4878 btrfs_header_nritems(path->nodes[level])) 5313 btrfs_header_nritems(path->nodes[level]))
4879 break; 5314 break;
4880 5315
4881 ret = walk_down_proc(trans, root, path, wc); 5316 ret = walk_down_proc(trans, root, path, wc, lookup_info);
4882 if (ret > 0) 5317 if (ret > 0)
4883 break; 5318 break;
4884 5319
4885 if (level == 0) 5320 if (level == 0)
4886 break; 5321 break;
4887 5322
4888 ret = do_walk_down(trans, root, path, wc); 5323 ret = do_walk_down(trans, root, path, wc, &lookup_info);
4889 if (ret > 0) { 5324 if (ret > 0) {
4890 path->slots[level]++; 5325 path->slots[level]++;
4891 continue; 5326 continue;
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index 0cb88f8146ea..96577e8bf9fd 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -280,6 +280,14 @@ static struct extent_buffer *buffer_search(struct extent_io_tree *tree,
280 return NULL; 280 return NULL;
281} 281}
282 282
283static void merge_cb(struct extent_io_tree *tree, struct extent_state *new,
284 struct extent_state *other)
285{
286 if (tree->ops && tree->ops->merge_extent_hook)
287 tree->ops->merge_extent_hook(tree->mapping->host, new,
288 other);
289}
290
283/* 291/*
284 * utility function to look for merge candidates inside a given range. 292 * utility function to look for merge candidates inside a given range.
285 * Any extents with matching state are merged together into a single 293 * Any extents with matching state are merged together into a single
@@ -303,6 +311,7 @@ static int merge_state(struct extent_io_tree *tree,
303 other = rb_entry(other_node, struct extent_state, rb_node); 311 other = rb_entry(other_node, struct extent_state, rb_node);
304 if (other->end == state->start - 1 && 312 if (other->end == state->start - 1 &&
305 other->state == state->state) { 313 other->state == state->state) {
314 merge_cb(tree, state, other);
306 state->start = other->start; 315 state->start = other->start;
307 other->tree = NULL; 316 other->tree = NULL;
308 rb_erase(&other->rb_node, &tree->state); 317 rb_erase(&other->rb_node, &tree->state);
@@ -314,33 +323,37 @@ static int merge_state(struct extent_io_tree *tree,
314 other = rb_entry(other_node, struct extent_state, rb_node); 323 other = rb_entry(other_node, struct extent_state, rb_node);
315 if (other->start == state->end + 1 && 324 if (other->start == state->end + 1 &&
316 other->state == state->state) { 325 other->state == state->state) {
326 merge_cb(tree, state, other);
317 other->start = state->start; 327 other->start = state->start;
318 state->tree = NULL; 328 state->tree = NULL;
319 rb_erase(&state->rb_node, &tree->state); 329 rb_erase(&state->rb_node, &tree->state);
320 free_extent_state(state); 330 free_extent_state(state);
331 state = NULL;
321 } 332 }
322 } 333 }
334
323 return 0; 335 return 0;
324} 336}
325 337
326static void set_state_cb(struct extent_io_tree *tree, 338static int set_state_cb(struct extent_io_tree *tree,
327 struct extent_state *state, 339 struct extent_state *state,
328 unsigned long bits) 340 unsigned long bits)
329{ 341{
330 if (tree->ops && tree->ops->set_bit_hook) { 342 if (tree->ops && tree->ops->set_bit_hook) {
331 tree->ops->set_bit_hook(tree->mapping->host, state->start, 343 return tree->ops->set_bit_hook(tree->mapping->host,
332 state->end, state->state, bits); 344 state->start, state->end,
345 state->state, bits);
333 } 346 }
347
348 return 0;
334} 349}
335 350
336static void clear_state_cb(struct extent_io_tree *tree, 351static void clear_state_cb(struct extent_io_tree *tree,
337 struct extent_state *state, 352 struct extent_state *state,
338 unsigned long bits) 353 unsigned long bits)
339{ 354{
340 if (tree->ops && tree->ops->clear_bit_hook) { 355 if (tree->ops && tree->ops->clear_bit_hook)
341 tree->ops->clear_bit_hook(tree->mapping->host, state->start, 356 tree->ops->clear_bit_hook(tree->mapping->host, state, bits);
342 state->end, state->state, bits);
343 }
344} 357}
345 358
346/* 359/*
@@ -358,6 +371,7 @@ static int insert_state(struct extent_io_tree *tree,
358 int bits) 371 int bits)
359{ 372{
360 struct rb_node *node; 373 struct rb_node *node;
374 int ret;
361 375
362 if (end < start) { 376 if (end < start) {
363 printk(KERN_ERR "btrfs end < start %llu %llu\n", 377 printk(KERN_ERR "btrfs end < start %llu %llu\n",
@@ -365,11 +379,14 @@ static int insert_state(struct extent_io_tree *tree,
365 (unsigned long long)start); 379 (unsigned long long)start);
366 WARN_ON(1); 380 WARN_ON(1);
367 } 381 }
368 if (bits & EXTENT_DIRTY)
369 tree->dirty_bytes += end - start + 1;
370 state->start = start; 382 state->start = start;
371 state->end = end; 383 state->end = end;
372 set_state_cb(tree, state, bits); 384 ret = set_state_cb(tree, state, bits);
385 if (ret)
386 return ret;
387
388 if (bits & EXTENT_DIRTY)
389 tree->dirty_bytes += end - start + 1;
373 state->state |= bits; 390 state->state |= bits;
374 node = tree_insert(&tree->state, end, &state->rb_node); 391 node = tree_insert(&tree->state, end, &state->rb_node);
375 if (node) { 392 if (node) {
@@ -387,6 +404,15 @@ static int insert_state(struct extent_io_tree *tree,
387 return 0; 404 return 0;
388} 405}
389 406
407static int split_cb(struct extent_io_tree *tree, struct extent_state *orig,
408 u64 split)
409{
410 if (tree->ops && tree->ops->split_extent_hook)
411 return tree->ops->split_extent_hook(tree->mapping->host,
412 orig, split);
413 return 0;
414}
415
390/* 416/*
391 * split a given extent state struct in two, inserting the preallocated 417 * split a given extent state struct in two, inserting the preallocated
392 * struct 'prealloc' as the newly created second half. 'split' indicates an 418 * struct 'prealloc' as the newly created second half. 'split' indicates an
@@ -405,6 +431,9 @@ static int split_state(struct extent_io_tree *tree, struct extent_state *orig,
405 struct extent_state *prealloc, u64 split) 431 struct extent_state *prealloc, u64 split)
406{ 432{
407 struct rb_node *node; 433 struct rb_node *node;
434
435 split_cb(tree, orig, split);
436
408 prealloc->start = orig->start; 437 prealloc->start = orig->start;
409 prealloc->end = split - 1; 438 prealloc->end = split - 1;
410 prealloc->state = orig->state; 439 prealloc->state = orig->state;
@@ -431,7 +460,8 @@ static int clear_state_bit(struct extent_io_tree *tree,
431 struct extent_state *state, int bits, int wake, 460 struct extent_state *state, int bits, int wake,
432 int delete) 461 int delete)
433{ 462{
434 int ret = state->state & bits; 463 int bits_to_clear = bits & ~EXTENT_DO_ACCOUNTING;
464 int ret = state->state & bits_to_clear;
435 465
436 if ((bits & EXTENT_DIRTY) && (state->state & EXTENT_DIRTY)) { 466 if ((bits & EXTENT_DIRTY) && (state->state & EXTENT_DIRTY)) {
437 u64 range = state->end - state->start + 1; 467 u64 range = state->end - state->start + 1;
@@ -439,7 +469,7 @@ static int clear_state_bit(struct extent_io_tree *tree,
439 tree->dirty_bytes -= range; 469 tree->dirty_bytes -= range;
440 } 470 }
441 clear_state_cb(tree, state, bits); 471 clear_state_cb(tree, state, bits);
442 state->state &= ~bits; 472 state->state &= ~bits_to_clear;
443 if (wake) 473 if (wake)
444 wake_up(&state->wq); 474 wake_up(&state->wq);
445 if (delete || state->state == 0) { 475 if (delete || state->state == 0) {
@@ -542,8 +572,8 @@ hit_next:
542 if (err) 572 if (err)
543 goto out; 573 goto out;
544 if (state->end <= end) { 574 if (state->end <= end) {
545 set |= clear_state_bit(tree, state, bits, 575 set |= clear_state_bit(tree, state, bits, wake,
546 wake, delete); 576 delete);
547 if (last_end == (u64)-1) 577 if (last_end == (u64)-1)
548 goto out; 578 goto out;
549 start = last_end + 1; 579 start = last_end + 1;
@@ -561,12 +591,11 @@ hit_next:
561 prealloc = alloc_extent_state(GFP_ATOMIC); 591 prealloc = alloc_extent_state(GFP_ATOMIC);
562 err = split_state(tree, state, prealloc, end + 1); 592 err = split_state(tree, state, prealloc, end + 1);
563 BUG_ON(err == -EEXIST); 593 BUG_ON(err == -EEXIST);
564
565 if (wake) 594 if (wake)
566 wake_up(&state->wq); 595 wake_up(&state->wq);
567 596
568 set |= clear_state_bit(tree, prealloc, bits, 597 set |= clear_state_bit(tree, prealloc, bits, wake, delete);
569 wake, delete); 598
570 prealloc = NULL; 599 prealloc = NULL;
571 goto out; 600 goto out;
572 } 601 }
@@ -667,16 +696,23 @@ out:
667 return 0; 696 return 0;
668} 697}
669 698
670static void set_state_bits(struct extent_io_tree *tree, 699static int set_state_bits(struct extent_io_tree *tree,
671 struct extent_state *state, 700 struct extent_state *state,
672 int bits) 701 int bits)
673{ 702{
703 int ret;
704
705 ret = set_state_cb(tree, state, bits);
706 if (ret)
707 return ret;
708
674 if ((bits & EXTENT_DIRTY) && !(state->state & EXTENT_DIRTY)) { 709 if ((bits & EXTENT_DIRTY) && !(state->state & EXTENT_DIRTY)) {
675 u64 range = state->end - state->start + 1; 710 u64 range = state->end - state->start + 1;
676 tree->dirty_bytes += range; 711 tree->dirty_bytes += range;
677 } 712 }
678 set_state_cb(tree, state, bits);
679 state->state |= bits; 713 state->state |= bits;
714
715 return 0;
680} 716}
681 717
682static void cache_state(struct extent_state *state, 718static void cache_state(struct extent_state *state,
@@ -758,7 +794,10 @@ hit_next:
758 goto out; 794 goto out;
759 } 795 }
760 796
761 set_state_bits(tree, state, bits); 797 err = set_state_bits(tree, state, bits);
798 if (err)
799 goto out;
800
762 cache_state(state, cached_state); 801 cache_state(state, cached_state);
763 merge_state(tree, state); 802 merge_state(tree, state);
764 if (last_end == (u64)-1) 803 if (last_end == (u64)-1)
@@ -805,7 +844,9 @@ hit_next:
805 if (err) 844 if (err)
806 goto out; 845 goto out;
807 if (state->end <= end) { 846 if (state->end <= end) {
808 set_state_bits(tree, state, bits); 847 err = set_state_bits(tree, state, bits);
848 if (err)
849 goto out;
809 cache_state(state, cached_state); 850 cache_state(state, cached_state);
810 merge_state(tree, state); 851 merge_state(tree, state);
811 if (last_end == (u64)-1) 852 if (last_end == (u64)-1)
@@ -829,11 +870,13 @@ hit_next:
829 this_end = last_start - 1; 870 this_end = last_start - 1;
830 err = insert_state(tree, prealloc, start, this_end, 871 err = insert_state(tree, prealloc, start, this_end,
831 bits); 872 bits);
832 cache_state(prealloc, cached_state);
833 prealloc = NULL;
834 BUG_ON(err == -EEXIST); 873 BUG_ON(err == -EEXIST);
835 if (err) 874 if (err) {
875 prealloc = NULL;
836 goto out; 876 goto out;
877 }
878 cache_state(prealloc, cached_state);
879 prealloc = NULL;
837 start = this_end + 1; 880 start = this_end + 1;
838 goto search_again; 881 goto search_again;
839 } 882 }
@@ -852,7 +895,11 @@ hit_next:
852 err = split_state(tree, state, prealloc, end + 1); 895 err = split_state(tree, state, prealloc, end + 1);
853 BUG_ON(err == -EEXIST); 896 BUG_ON(err == -EEXIST);
854 897
855 set_state_bits(tree, prealloc, bits); 898 err = set_state_bits(tree, prealloc, bits);
899 if (err) {
900 prealloc = NULL;
901 goto out;
902 }
856 cache_state(prealloc, cached_state); 903 cache_state(prealloc, cached_state);
857 merge_state(tree, prealloc); 904 merge_state(tree, prealloc);
858 prealloc = NULL; 905 prealloc = NULL;
@@ -910,7 +957,8 @@ int clear_extent_dirty(struct extent_io_tree *tree, u64 start, u64 end,
910 gfp_t mask) 957 gfp_t mask)
911{ 958{
912 return clear_extent_bit(tree, start, end, 959 return clear_extent_bit(tree, start, end,
913 EXTENT_DIRTY | EXTENT_DELALLOC, 0, 0, 960 EXTENT_DIRTY | EXTENT_DELALLOC |
961 EXTENT_DO_ACCOUNTING, 0, 0,
914 NULL, mask); 962 NULL, mask);
915} 963}
916 964
@@ -1355,12 +1403,7 @@ out_failed:
1355int extent_clear_unlock_delalloc(struct inode *inode, 1403int extent_clear_unlock_delalloc(struct inode *inode,
1356 struct extent_io_tree *tree, 1404 struct extent_io_tree *tree,
1357 u64 start, u64 end, struct page *locked_page, 1405 u64 start, u64 end, struct page *locked_page,
1358 int unlock_pages, 1406 unsigned long op)
1359 int clear_unlock,
1360 int clear_delalloc, int clear_dirty,
1361 int set_writeback,
1362 int end_writeback,
1363 int set_private2)
1364{ 1407{
1365 int ret; 1408 int ret;
1366 struct page *pages[16]; 1409 struct page *pages[16];
@@ -1370,17 +1413,21 @@ int extent_clear_unlock_delalloc(struct inode *inode,
1370 int i; 1413 int i;
1371 int clear_bits = 0; 1414 int clear_bits = 0;
1372 1415
1373 if (clear_unlock) 1416 if (op & EXTENT_CLEAR_UNLOCK)
1374 clear_bits |= EXTENT_LOCKED; 1417 clear_bits |= EXTENT_LOCKED;
1375 if (clear_dirty) 1418 if (op & EXTENT_CLEAR_DIRTY)
1376 clear_bits |= EXTENT_DIRTY; 1419 clear_bits |= EXTENT_DIRTY;
1377 1420
1378 if (clear_delalloc) 1421 if (op & EXTENT_CLEAR_DELALLOC)
1379 clear_bits |= EXTENT_DELALLOC; 1422 clear_bits |= EXTENT_DELALLOC;
1380 1423
1424 if (op & EXTENT_CLEAR_ACCOUNTING)
1425 clear_bits |= EXTENT_DO_ACCOUNTING;
1426
1381 clear_extent_bit(tree, start, end, clear_bits, 1, 0, NULL, GFP_NOFS); 1427 clear_extent_bit(tree, start, end, clear_bits, 1, 0, NULL, GFP_NOFS);
1382 if (!(unlock_pages || clear_dirty || set_writeback || end_writeback || 1428 if (!(op & (EXTENT_CLEAR_UNLOCK_PAGE | EXTENT_CLEAR_DIRTY |
1383 set_private2)) 1429 EXTENT_SET_WRITEBACK | EXTENT_END_WRITEBACK |
1430 EXTENT_SET_PRIVATE2)))
1384 return 0; 1431 return 0;
1385 1432
1386 while (nr_pages > 0) { 1433 while (nr_pages > 0) {
@@ -1389,20 +1436,20 @@ int extent_clear_unlock_delalloc(struct inode *inode,
1389 nr_pages, ARRAY_SIZE(pages)), pages); 1436 nr_pages, ARRAY_SIZE(pages)), pages);
1390 for (i = 0; i < ret; i++) { 1437 for (i = 0; i < ret; i++) {
1391 1438
1392 if (set_private2) 1439 if (op & EXTENT_SET_PRIVATE2)
1393 SetPagePrivate2(pages[i]); 1440 SetPagePrivate2(pages[i]);
1394 1441
1395 if (pages[i] == locked_page) { 1442 if (pages[i] == locked_page) {
1396 page_cache_release(pages[i]); 1443 page_cache_release(pages[i]);
1397 continue; 1444 continue;
1398 } 1445 }
1399 if (clear_dirty) 1446 if (op & EXTENT_CLEAR_DIRTY)
1400 clear_page_dirty_for_io(pages[i]); 1447 clear_page_dirty_for_io(pages[i]);
1401 if (set_writeback) 1448 if (op & EXTENT_SET_WRITEBACK)
1402 set_page_writeback(pages[i]); 1449 set_page_writeback(pages[i]);
1403 if (end_writeback) 1450 if (op & EXTENT_END_WRITEBACK)
1404 end_page_writeback(pages[i]); 1451 end_page_writeback(pages[i]);
1405 if (unlock_pages) 1452 if (op & EXTENT_CLEAR_UNLOCK_PAGE)
1406 unlock_page(pages[i]); 1453 unlock_page(pages[i]);
1407 page_cache_release(pages[i]); 1454 page_cache_release(pages[i]);
1408 } 1455 }
@@ -2668,7 +2715,8 @@ int extent_invalidatepage(struct extent_io_tree *tree,
2668 lock_extent(tree, start, end, GFP_NOFS); 2715 lock_extent(tree, start, end, GFP_NOFS);
2669 wait_on_page_writeback(page); 2716 wait_on_page_writeback(page);
2670 clear_extent_bit(tree, start, end, 2717 clear_extent_bit(tree, start, end,
2671 EXTENT_LOCKED | EXTENT_DIRTY | EXTENT_DELALLOC, 2718 EXTENT_LOCKED | EXTENT_DIRTY | EXTENT_DELALLOC |
2719 EXTENT_DO_ACCOUNTING,
2672 1, 1, NULL, GFP_NOFS); 2720 1, 1, NULL, GFP_NOFS);
2673 return 0; 2721 return 0;
2674} 2722}
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h
index 14ed16fd862d..36de250a7b2b 100644
--- a/fs/btrfs/extent_io.h
+++ b/fs/btrfs/extent_io.h
@@ -15,6 +15,7 @@
15#define EXTENT_BUFFER_FILLED (1 << 8) 15#define EXTENT_BUFFER_FILLED (1 << 8)
16#define EXTENT_BOUNDARY (1 << 9) 16#define EXTENT_BOUNDARY (1 << 9)
17#define EXTENT_NODATASUM (1 << 10) 17#define EXTENT_NODATASUM (1 << 10)
18#define EXTENT_DO_ACCOUNTING (1 << 11)
18#define EXTENT_IOBITS (EXTENT_LOCKED | EXTENT_WRITEBACK) 19#define EXTENT_IOBITS (EXTENT_LOCKED | EXTENT_WRITEBACK)
19 20
20/* flags for bio submission */ 21/* flags for bio submission */
@@ -25,6 +26,16 @@
25#define EXTENT_BUFFER_BLOCKING 1 26#define EXTENT_BUFFER_BLOCKING 1
26#define EXTENT_BUFFER_DIRTY 2 27#define EXTENT_BUFFER_DIRTY 2
27 28
29/* these are flags for extent_clear_unlock_delalloc */
30#define EXTENT_CLEAR_UNLOCK_PAGE 0x1
31#define EXTENT_CLEAR_UNLOCK 0x2
32#define EXTENT_CLEAR_DELALLOC 0x4
33#define EXTENT_CLEAR_DIRTY 0x8
34#define EXTENT_SET_WRITEBACK 0x10
35#define EXTENT_END_WRITEBACK 0x20
36#define EXTENT_SET_PRIVATE2 0x40
37#define EXTENT_CLEAR_ACCOUNTING 0x80
38
28/* 39/*
29 * page->private values. Every page that is controlled by the extent 40 * page->private values. Every page that is controlled by the extent
30 * map has page->private set to one. 41 * map has page->private set to one.
@@ -60,8 +71,13 @@ struct extent_io_ops {
60 struct extent_state *state, int uptodate); 71 struct extent_state *state, int uptodate);
61 int (*set_bit_hook)(struct inode *inode, u64 start, u64 end, 72 int (*set_bit_hook)(struct inode *inode, u64 start, u64 end,
62 unsigned long old, unsigned long bits); 73 unsigned long old, unsigned long bits);
63 int (*clear_bit_hook)(struct inode *inode, u64 start, u64 end, 74 int (*clear_bit_hook)(struct inode *inode, struct extent_state *state,
64 unsigned long old, unsigned long bits); 75 unsigned long bits);
76 int (*merge_extent_hook)(struct inode *inode,
77 struct extent_state *new,
78 struct extent_state *other);
79 int (*split_extent_hook)(struct inode *inode,
80 struct extent_state *orig, u64 split);
65 int (*write_cache_pages_lock_hook)(struct page *page); 81 int (*write_cache_pages_lock_hook)(struct page *page);
66}; 82};
67 83
@@ -79,10 +95,14 @@ struct extent_state {
79 u64 start; 95 u64 start;
80 u64 end; /* inclusive */ 96 u64 end; /* inclusive */
81 struct rb_node rb_node; 97 struct rb_node rb_node;
98
99 /* ADD NEW ELEMENTS AFTER THIS */
82 struct extent_io_tree *tree; 100 struct extent_io_tree *tree;
83 wait_queue_head_t wq; 101 wait_queue_head_t wq;
84 atomic_t refs; 102 atomic_t refs;
85 unsigned long state; 103 unsigned long state;
104 u64 split_start;
105 u64 split_end;
86 106
87 /* for use by the FS */ 107 /* for use by the FS */
88 u64 private; 108 u64 private;
@@ -279,10 +299,5 @@ int extent_range_uptodate(struct extent_io_tree *tree,
279int extent_clear_unlock_delalloc(struct inode *inode, 299int extent_clear_unlock_delalloc(struct inode *inode,
280 struct extent_io_tree *tree, 300 struct extent_io_tree *tree,
281 u64 start, u64 end, struct page *locked_page, 301 u64 start, u64 end, struct page *locked_page,
282 int unlock_page, 302 unsigned long op);
283 int clear_unlock,
284 int clear_delalloc, int clear_dirty,
285 int set_writeback,
286 int end_writeback,
287 int set_private2);
288#endif 303#endif
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index a3492a3ad96b..06550affbd27 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -123,7 +123,10 @@ static noinline int dirty_and_release_pages(struct btrfs_trans_handle *trans,
123 root->sectorsize - 1) & ~((u64)root->sectorsize - 1); 123 root->sectorsize - 1) & ~((u64)root->sectorsize - 1);
124 124
125 end_of_last_block = start_pos + num_bytes - 1; 125 end_of_last_block = start_pos + num_bytes - 1;
126 btrfs_set_extent_delalloc(inode, start_pos, end_of_last_block); 126 err = btrfs_set_extent_delalloc(inode, start_pos, end_of_last_block);
127 if (err)
128 return err;
129
127 for (i = 0; i < num_pages; i++) { 130 for (i = 0; i < num_pages; i++) {
128 struct page *p = pages[i]; 131 struct page *p = pages[i];
129 SetPageUptodate(p); 132 SetPageUptodate(p);
@@ -875,7 +878,8 @@ again:
875 btrfs_put_ordered_extent(ordered); 878 btrfs_put_ordered_extent(ordered);
876 879
877 clear_extent_bits(&BTRFS_I(inode)->io_tree, start_pos, 880 clear_extent_bits(&BTRFS_I(inode)->io_tree, start_pos,
878 last_pos - 1, EXTENT_DIRTY | EXTENT_DELALLOC, 881 last_pos - 1, EXTENT_DIRTY | EXTENT_DELALLOC |
882 EXTENT_DO_ACCOUNTING,
879 GFP_NOFS); 883 GFP_NOFS);
880 unlock_extent(&BTRFS_I(inode)->io_tree, 884 unlock_extent(&BTRFS_I(inode)->io_tree,
881 start_pos, last_pos - 1, GFP_NOFS); 885 start_pos, last_pos - 1, GFP_NOFS);
@@ -917,21 +921,35 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf,
917 start_pos = pos; 921 start_pos = pos;
918 922
919 vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE); 923 vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE);
924
925 /* do the reserve before the mutex lock in case we have to do some
926 * flushing. We wouldn't deadlock, but this is more polite.
927 */
928 err = btrfs_reserve_metadata_for_delalloc(root, inode, 1);
929 if (err)
930 goto out_nolock;
931
932 mutex_lock(&inode->i_mutex);
933
920 current->backing_dev_info = inode->i_mapping->backing_dev_info; 934 current->backing_dev_info = inode->i_mapping->backing_dev_info;
921 err = generic_write_checks(file, &pos, &count, S_ISBLK(inode->i_mode)); 935 err = generic_write_checks(file, &pos, &count, S_ISBLK(inode->i_mode));
922 if (err) 936 if (err)
923 goto out_nolock; 937 goto out;
938
924 if (count == 0) 939 if (count == 0)
925 goto out_nolock; 940 goto out;
926 941
927 err = file_remove_suid(file); 942 err = file_remove_suid(file);
928 if (err) 943 if (err)
929 goto out_nolock; 944 goto out;
945
930 file_update_time(file); 946 file_update_time(file);
931 947
932 pages = kmalloc(nrptrs * sizeof(struct page *), GFP_KERNEL); 948 pages = kmalloc(nrptrs * sizeof(struct page *), GFP_KERNEL);
933 949
934 mutex_lock(&inode->i_mutex); 950 /* generic_write_checks can change our pos */
951 start_pos = pos;
952
935 BTRFS_I(inode)->sequence++; 953 BTRFS_I(inode)->sequence++;
936 first_index = pos >> PAGE_CACHE_SHIFT; 954 first_index = pos >> PAGE_CACHE_SHIFT;
937 last_index = (pos + count) >> PAGE_CACHE_SHIFT; 955 last_index = (pos + count) >> PAGE_CACHE_SHIFT;
@@ -1005,9 +1023,8 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf,
1005 } 1023 }
1006 1024
1007 if (will_write) { 1025 if (will_write) {
1008 btrfs_fdatawrite_range(inode->i_mapping, pos, 1026 filemap_fdatawrite_range(inode->i_mapping, pos,
1009 pos + write_bytes - 1, 1027 pos + write_bytes - 1);
1010 WB_SYNC_ALL);
1011 } else { 1028 } else {
1012 balance_dirty_pages_ratelimited_nr(inode->i_mapping, 1029 balance_dirty_pages_ratelimited_nr(inode->i_mapping,
1013 num_pages); 1030 num_pages);
@@ -1028,6 +1045,7 @@ out:
1028 mutex_unlock(&inode->i_mutex); 1045 mutex_unlock(&inode->i_mutex);
1029 if (ret) 1046 if (ret)
1030 err = ret; 1047 err = ret;
1048 btrfs_unreserve_metadata_for_delalloc(root, inode, 1);
1031 1049
1032out_nolock: 1050out_nolock:
1033 kfree(pages); 1051 kfree(pages);
@@ -1068,8 +1086,10 @@ out_nolock:
1068 btrfs_end_transaction(trans, root); 1086 btrfs_end_transaction(trans, root);
1069 else 1087 else
1070 btrfs_commit_transaction(trans, root); 1088 btrfs_commit_transaction(trans, root);
1071 } else { 1089 } else if (ret != BTRFS_NO_LOG_SYNC) {
1072 btrfs_commit_transaction(trans, root); 1090 btrfs_commit_transaction(trans, root);
1091 } else {
1092 btrfs_end_transaction(trans, root);
1073 } 1093 }
1074 } 1094 }
1075 if (file->f_flags & O_DIRECT) { 1095 if (file->f_flags & O_DIRECT) {
@@ -1119,6 +1139,13 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync)
1119 int ret = 0; 1139 int ret = 0;
1120 struct btrfs_trans_handle *trans; 1140 struct btrfs_trans_handle *trans;
1121 1141
1142
1143 /* we wait first, since the writeback may change the inode */
1144 root->log_batch++;
1145 /* the VFS called filemap_fdatawrite for us */
1146 btrfs_wait_ordered_range(inode, 0, (u64)-1);
1147 root->log_batch++;
1148
1122 /* 1149 /*
1123 * check the transaction that last modified this inode 1150 * check the transaction that last modified this inode
1124 * and see if its already been committed 1151 * and see if its already been committed
@@ -1126,6 +1153,11 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync)
1126 if (!BTRFS_I(inode)->last_trans) 1153 if (!BTRFS_I(inode)->last_trans)
1127 goto out; 1154 goto out;
1128 1155
1156 /*
1157 * if the last transaction that changed this file was before
1158 * the current transaction, we can bail out now without any
1159 * syncing
1160 */
1129 mutex_lock(&root->fs_info->trans_mutex); 1161 mutex_lock(&root->fs_info->trans_mutex);
1130 if (BTRFS_I(inode)->last_trans <= 1162 if (BTRFS_I(inode)->last_trans <=
1131 root->fs_info->last_trans_committed) { 1163 root->fs_info->last_trans_committed) {
@@ -1135,13 +1167,6 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync)
1135 } 1167 }
1136 mutex_unlock(&root->fs_info->trans_mutex); 1168 mutex_unlock(&root->fs_info->trans_mutex);
1137 1169
1138 root->log_batch++;
1139 filemap_fdatawrite(inode->i_mapping);
1140 btrfs_wait_ordered_range(inode, 0, (u64)-1);
1141 root->log_batch++;
1142
1143 if (datasync && !(inode->i_state & I_DIRTY_PAGES))
1144 goto out;
1145 /* 1170 /*
1146 * ok we haven't committed the transaction yet, lets do a commit 1171 * ok we haven't committed the transaction yet, lets do a commit
1147 */ 1172 */
@@ -1170,14 +1195,18 @@ int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync)
1170 */ 1195 */
1171 mutex_unlock(&dentry->d_inode->i_mutex); 1196 mutex_unlock(&dentry->d_inode->i_mutex);
1172 1197
1173 if (ret > 0) { 1198 if (ret != BTRFS_NO_LOG_SYNC) {
1174 ret = btrfs_commit_transaction(trans, root); 1199 if (ret > 0) {
1175 } else {
1176 ret = btrfs_sync_log(trans, root);
1177 if (ret == 0)
1178 ret = btrfs_end_transaction(trans, root);
1179 else
1180 ret = btrfs_commit_transaction(trans, root); 1200 ret = btrfs_commit_transaction(trans, root);
1201 } else {
1202 ret = btrfs_sync_log(trans, root);
1203 if (ret == 0)
1204 ret = btrfs_end_transaction(trans, root);
1205 else
1206 ret = btrfs_commit_transaction(trans, root);
1207 }
1208 } else {
1209 ret = btrfs_end_transaction(trans, root);
1181 } 1210 }
1182 mutex_lock(&dentry->d_inode->i_mutex); 1211 mutex_lock(&dentry->d_inode->i_mutex);
1183out: 1212out:
@@ -1196,7 +1225,7 @@ static int btrfs_file_mmap(struct file *filp, struct vm_area_struct *vma)
1196 return 0; 1225 return 0;
1197} 1226}
1198 1227
1199struct file_operations btrfs_file_operations = { 1228const struct file_operations btrfs_file_operations = {
1200 .llseek = generic_file_llseek, 1229 .llseek = generic_file_llseek,
1201 .read = do_sync_read, 1230 .read = do_sync_read,
1202 .aio_read = generic_file_aio_read, 1231 .aio_read = generic_file_aio_read,
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index e9b76bcd1c12..dae12dc7e159 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -62,7 +62,7 @@ static const struct inode_operations btrfs_special_inode_operations;
62static const struct inode_operations btrfs_file_inode_operations; 62static const struct inode_operations btrfs_file_inode_operations;
63static const struct address_space_operations btrfs_aops; 63static const struct address_space_operations btrfs_aops;
64static const struct address_space_operations btrfs_symlink_aops; 64static const struct address_space_operations btrfs_symlink_aops;
65static struct file_operations btrfs_dir_file_operations; 65static const struct file_operations btrfs_dir_file_operations;
66static struct extent_io_ops btrfs_extent_io_ops; 66static struct extent_io_ops btrfs_extent_io_ops;
67 67
68static struct kmem_cache *btrfs_inode_cachep; 68static struct kmem_cache *btrfs_inode_cachep;
@@ -424,9 +424,12 @@ again:
424 * and free up our temp pages. 424 * and free up our temp pages.
425 */ 425 */
426 extent_clear_unlock_delalloc(inode, 426 extent_clear_unlock_delalloc(inode,
427 &BTRFS_I(inode)->io_tree, 427 &BTRFS_I(inode)->io_tree,
428 start, end, NULL, 1, 0, 428 start, end, NULL,
429 0, 1, 1, 1, 0); 429 EXTENT_CLEAR_UNLOCK_PAGE | EXTENT_CLEAR_DIRTY |
430 EXTENT_CLEAR_DELALLOC |
431 EXTENT_CLEAR_ACCOUNTING |
432 EXTENT_SET_WRITEBACK | EXTENT_END_WRITEBACK);
430 ret = 0; 433 ret = 0;
431 goto free_pages_out; 434 goto free_pages_out;
432 } 435 }
@@ -637,11 +640,14 @@ static noinline int submit_compressed_extents(struct inode *inode,
637 * clear dirty, set writeback and unlock the pages. 640 * clear dirty, set writeback and unlock the pages.
638 */ 641 */
639 extent_clear_unlock_delalloc(inode, 642 extent_clear_unlock_delalloc(inode,
640 &BTRFS_I(inode)->io_tree, 643 &BTRFS_I(inode)->io_tree,
641 async_extent->start, 644 async_extent->start,
642 async_extent->start + 645 async_extent->start +
643 async_extent->ram_size - 1, 646 async_extent->ram_size - 1,
644 NULL, 1, 1, 0, 1, 1, 0, 0); 647 NULL, EXTENT_CLEAR_UNLOCK_PAGE |
648 EXTENT_CLEAR_UNLOCK |
649 EXTENT_CLEAR_DELALLOC |
650 EXTENT_CLEAR_DIRTY | EXTENT_SET_WRITEBACK);
645 651
646 ret = btrfs_submit_compressed_write(inode, 652 ret = btrfs_submit_compressed_write(inode,
647 async_extent->start, 653 async_extent->start,
@@ -712,9 +718,15 @@ static noinline int cow_file_range(struct inode *inode,
712 start, end, 0, NULL); 718 start, end, 0, NULL);
713 if (ret == 0) { 719 if (ret == 0) {
714 extent_clear_unlock_delalloc(inode, 720 extent_clear_unlock_delalloc(inode,
715 &BTRFS_I(inode)->io_tree, 721 &BTRFS_I(inode)->io_tree,
716 start, end, NULL, 1, 1, 722 start, end, NULL,
717 1, 1, 1, 1, 0); 723 EXTENT_CLEAR_UNLOCK_PAGE |
724 EXTENT_CLEAR_UNLOCK |
725 EXTENT_CLEAR_DELALLOC |
726 EXTENT_CLEAR_ACCOUNTING |
727 EXTENT_CLEAR_DIRTY |
728 EXTENT_SET_WRITEBACK |
729 EXTENT_END_WRITEBACK);
718 *nr_written = *nr_written + 730 *nr_written = *nr_written +
719 (end - start + PAGE_CACHE_SIZE) / PAGE_CACHE_SIZE; 731 (end - start + PAGE_CACHE_SIZE) / PAGE_CACHE_SIZE;
720 *page_started = 1; 732 *page_started = 1;
@@ -738,6 +750,8 @@ static noinline int cow_file_range(struct inode *inode,
738 btrfs_drop_extent_cache(inode, start, start + num_bytes - 1, 0); 750 btrfs_drop_extent_cache(inode, start, start + num_bytes - 1, 0);
739 751
740 while (disk_num_bytes > 0) { 752 while (disk_num_bytes > 0) {
753 unsigned long op;
754
741 cur_alloc_size = min(disk_num_bytes, root->fs_info->max_extent); 755 cur_alloc_size = min(disk_num_bytes, root->fs_info->max_extent);
742 ret = btrfs_reserve_extent(trans, root, cur_alloc_size, 756 ret = btrfs_reserve_extent(trans, root, cur_alloc_size,
743 root->sectorsize, 0, alloc_hint, 757 root->sectorsize, 0, alloc_hint,
@@ -789,10 +803,13 @@ static noinline int cow_file_range(struct inode *inode,
789 * Do set the Private2 bit so we know this page was properly 803 * Do set the Private2 bit so we know this page was properly
790 * setup for writepage 804 * setup for writepage
791 */ 805 */
806 op = unlock ? EXTENT_CLEAR_UNLOCK_PAGE : 0;
807 op |= EXTENT_CLEAR_UNLOCK | EXTENT_CLEAR_DELALLOC |
808 EXTENT_SET_PRIVATE2;
809
792 extent_clear_unlock_delalloc(inode, &BTRFS_I(inode)->io_tree, 810 extent_clear_unlock_delalloc(inode, &BTRFS_I(inode)->io_tree,
793 start, start + ram_size - 1, 811 start, start + ram_size - 1,
794 locked_page, unlock, 1, 812 locked_page, op);
795 1, 0, 0, 0, 1);
796 disk_num_bytes -= cur_alloc_size; 813 disk_num_bytes -= cur_alloc_size;
797 num_bytes -= cur_alloc_size; 814 num_bytes -= cur_alloc_size;
798 alloc_hint = ins.objectid + ins.offset; 815 alloc_hint = ins.objectid + ins.offset;
@@ -864,8 +881,8 @@ static int cow_file_range_async(struct inode *inode, struct page *locked_page,
864 u64 cur_end; 881 u64 cur_end;
865 int limit = 10 * 1024 * 1042; 882 int limit = 10 * 1024 * 1042;
866 883
867 clear_extent_bit(&BTRFS_I(inode)->io_tree, start, end, EXTENT_LOCKED | 884 clear_extent_bit(&BTRFS_I(inode)->io_tree, start, end, EXTENT_LOCKED,
868 EXTENT_DELALLOC, 1, 0, NULL, GFP_NOFS); 885 1, 0, NULL, GFP_NOFS);
869 while (start < end) { 886 while (start < end) {
870 async_cow = kmalloc(sizeof(*async_cow), GFP_NOFS); 887 async_cow = kmalloc(sizeof(*async_cow), GFP_NOFS);
871 async_cow->inode = inode; 888 async_cow->inode = inode;
@@ -1006,6 +1023,7 @@ next_slot:
1006 1023
1007 if (found_key.offset > cur_offset) { 1024 if (found_key.offset > cur_offset) {
1008 extent_end = found_key.offset; 1025 extent_end = found_key.offset;
1026 extent_type = 0;
1009 goto out_check; 1027 goto out_check;
1010 } 1028 }
1011 1029
@@ -1112,8 +1130,10 @@ out_check:
1112 BUG_ON(ret); 1130 BUG_ON(ret);
1113 1131
1114 extent_clear_unlock_delalloc(inode, &BTRFS_I(inode)->io_tree, 1132 extent_clear_unlock_delalloc(inode, &BTRFS_I(inode)->io_tree,
1115 cur_offset, cur_offset + num_bytes - 1, 1133 cur_offset, cur_offset + num_bytes - 1,
1116 locked_page, 1, 1, 1, 0, 0, 0, 1); 1134 locked_page, EXTENT_CLEAR_UNLOCK_PAGE |
1135 EXTENT_CLEAR_UNLOCK | EXTENT_CLEAR_DELALLOC |
1136 EXTENT_SET_PRIVATE2);
1117 cur_offset = extent_end; 1137 cur_offset = extent_end;
1118 if (cur_offset > end) 1138 if (cur_offset > end)
1119 break; 1139 break;
@@ -1159,6 +1179,89 @@ static int run_delalloc_range(struct inode *inode, struct page *locked_page,
1159 return ret; 1179 return ret;
1160} 1180}
1161 1181
1182static int btrfs_split_extent_hook(struct inode *inode,
1183 struct extent_state *orig, u64 split)
1184{
1185 struct btrfs_root *root = BTRFS_I(inode)->root;
1186 u64 size;
1187
1188 if (!(orig->state & EXTENT_DELALLOC))
1189 return 0;
1190
1191 size = orig->end - orig->start + 1;
1192 if (size > root->fs_info->max_extent) {
1193 u64 num_extents;
1194 u64 new_size;
1195
1196 new_size = orig->end - split + 1;
1197 num_extents = div64_u64(size + root->fs_info->max_extent - 1,
1198 root->fs_info->max_extent);
1199
1200 /*
1201 * if we break a large extent up then leave oustanding_extents
1202 * be, since we've already accounted for the large extent.
1203 */
1204 if (div64_u64(new_size + root->fs_info->max_extent - 1,
1205 root->fs_info->max_extent) < num_extents)
1206 return 0;
1207 }
1208
1209 spin_lock(&BTRFS_I(inode)->accounting_lock);
1210 BTRFS_I(inode)->outstanding_extents++;
1211 spin_unlock(&BTRFS_I(inode)->accounting_lock);
1212
1213 return 0;
1214}
1215
1216/*
1217 * extent_io.c merge_extent_hook, used to track merged delayed allocation
1218 * extents so we can keep track of new extents that are just merged onto old
1219 * extents, such as when we are doing sequential writes, so we can properly
1220 * account for the metadata space we'll need.
1221 */
1222static int btrfs_merge_extent_hook(struct inode *inode,
1223 struct extent_state *new,
1224 struct extent_state *other)
1225{
1226 struct btrfs_root *root = BTRFS_I(inode)->root;
1227 u64 new_size, old_size;
1228 u64 num_extents;
1229
1230 /* not delalloc, ignore it */
1231 if (!(other->state & EXTENT_DELALLOC))
1232 return 0;
1233
1234 old_size = other->end - other->start + 1;
1235 if (new->start < other->start)
1236 new_size = other->end - new->start + 1;
1237 else
1238 new_size = new->end - other->start + 1;
1239
1240 /* we're not bigger than the max, unreserve the space and go */
1241 if (new_size <= root->fs_info->max_extent) {
1242 spin_lock(&BTRFS_I(inode)->accounting_lock);
1243 BTRFS_I(inode)->outstanding_extents--;
1244 spin_unlock(&BTRFS_I(inode)->accounting_lock);
1245 return 0;
1246 }
1247
1248 /*
1249 * If we grew by another max_extent, just return, we want to keep that
1250 * reserved amount.
1251 */
1252 num_extents = div64_u64(old_size + root->fs_info->max_extent - 1,
1253 root->fs_info->max_extent);
1254 if (div64_u64(new_size + root->fs_info->max_extent - 1,
1255 root->fs_info->max_extent) > num_extents)
1256 return 0;
1257
1258 spin_lock(&BTRFS_I(inode)->accounting_lock);
1259 BTRFS_I(inode)->outstanding_extents--;
1260 spin_unlock(&BTRFS_I(inode)->accounting_lock);
1261
1262 return 0;
1263}
1264
1162/* 1265/*
1163 * extent_io.c set_bit_hook, used to track delayed allocation 1266 * extent_io.c set_bit_hook, used to track delayed allocation
1164 * bytes in this file, and to maintain the list of inodes that 1267 * bytes in this file, and to maintain the list of inodes that
@@ -1167,6 +1270,7 @@ static int run_delalloc_range(struct inode *inode, struct page *locked_page,
1167static int btrfs_set_bit_hook(struct inode *inode, u64 start, u64 end, 1270static int btrfs_set_bit_hook(struct inode *inode, u64 start, u64 end,
1168 unsigned long old, unsigned long bits) 1271 unsigned long old, unsigned long bits)
1169{ 1272{
1273
1170 /* 1274 /*
1171 * set_bit and clear bit hooks normally require _irqsave/restore 1275 * set_bit and clear bit hooks normally require _irqsave/restore
1172 * but in this case, we are only testeing for the DELALLOC 1276 * but in this case, we are only testeing for the DELALLOC
@@ -1174,6 +1278,10 @@ static int btrfs_set_bit_hook(struct inode *inode, u64 start, u64 end,
1174 */ 1278 */
1175 if (!(old & EXTENT_DELALLOC) && (bits & EXTENT_DELALLOC)) { 1279 if (!(old & EXTENT_DELALLOC) && (bits & EXTENT_DELALLOC)) {
1176 struct btrfs_root *root = BTRFS_I(inode)->root; 1280 struct btrfs_root *root = BTRFS_I(inode)->root;
1281
1282 spin_lock(&BTRFS_I(inode)->accounting_lock);
1283 BTRFS_I(inode)->outstanding_extents++;
1284 spin_unlock(&BTRFS_I(inode)->accounting_lock);
1177 btrfs_delalloc_reserve_space(root, inode, end - start + 1); 1285 btrfs_delalloc_reserve_space(root, inode, end - start + 1);
1178 spin_lock(&root->fs_info->delalloc_lock); 1286 spin_lock(&root->fs_info->delalloc_lock);
1179 BTRFS_I(inode)->delalloc_bytes += end - start + 1; 1287 BTRFS_I(inode)->delalloc_bytes += end - start + 1;
@@ -1190,22 +1298,31 @@ static int btrfs_set_bit_hook(struct inode *inode, u64 start, u64 end,
1190/* 1298/*
1191 * extent_io.c clear_bit_hook, see set_bit_hook for why 1299 * extent_io.c clear_bit_hook, see set_bit_hook for why
1192 */ 1300 */
1193static int btrfs_clear_bit_hook(struct inode *inode, u64 start, u64 end, 1301static int btrfs_clear_bit_hook(struct inode *inode,
1194 unsigned long old, unsigned long bits) 1302 struct extent_state *state, unsigned long bits)
1195{ 1303{
1196 /* 1304 /*
1197 * set_bit and clear bit hooks normally require _irqsave/restore 1305 * set_bit and clear bit hooks normally require _irqsave/restore
1198 * but in this case, we are only testeing for the DELALLOC 1306 * but in this case, we are only testeing for the DELALLOC
1199 * bit, which is only set or cleared with irqs on 1307 * bit, which is only set or cleared with irqs on
1200 */ 1308 */
1201 if ((old & EXTENT_DELALLOC) && (bits & EXTENT_DELALLOC)) { 1309 if ((state->state & EXTENT_DELALLOC) && (bits & EXTENT_DELALLOC)) {
1202 struct btrfs_root *root = BTRFS_I(inode)->root; 1310 struct btrfs_root *root = BTRFS_I(inode)->root;
1203 1311
1312 if (bits & EXTENT_DO_ACCOUNTING) {
1313 spin_lock(&BTRFS_I(inode)->accounting_lock);
1314 BTRFS_I(inode)->outstanding_extents--;
1315 spin_unlock(&BTRFS_I(inode)->accounting_lock);
1316 btrfs_unreserve_metadata_for_delalloc(root, inode, 1);
1317 }
1318
1204 spin_lock(&root->fs_info->delalloc_lock); 1319 spin_lock(&root->fs_info->delalloc_lock);
1205 if (end - start + 1 > root->fs_info->delalloc_bytes) { 1320 if (state->end - state->start + 1 >
1321 root->fs_info->delalloc_bytes) {
1206 printk(KERN_INFO "btrfs warning: delalloc account " 1322 printk(KERN_INFO "btrfs warning: delalloc account "
1207 "%llu %llu\n", 1323 "%llu %llu\n",
1208 (unsigned long long)end - start + 1, 1324 (unsigned long long)
1325 state->end - state->start + 1,
1209 (unsigned long long) 1326 (unsigned long long)
1210 root->fs_info->delalloc_bytes); 1327 root->fs_info->delalloc_bytes);
1211 btrfs_delalloc_free_space(root, inode, (u64)-1); 1328 btrfs_delalloc_free_space(root, inode, (u64)-1);
@@ -1213,9 +1330,12 @@ static int btrfs_clear_bit_hook(struct inode *inode, u64 start, u64 end,
1213 BTRFS_I(inode)->delalloc_bytes = 0; 1330 BTRFS_I(inode)->delalloc_bytes = 0;
1214 } else { 1331 } else {
1215 btrfs_delalloc_free_space(root, inode, 1332 btrfs_delalloc_free_space(root, inode,
1216 end - start + 1); 1333 state->end -
1217 root->fs_info->delalloc_bytes -= end - start + 1; 1334 state->start + 1);
1218 BTRFS_I(inode)->delalloc_bytes -= end - start + 1; 1335 root->fs_info->delalloc_bytes -= state->end -
1336 state->start + 1;
1337 BTRFS_I(inode)->delalloc_bytes -= state->end -
1338 state->start + 1;
1219 } 1339 }
1220 if (BTRFS_I(inode)->delalloc_bytes == 0 && 1340 if (BTRFS_I(inode)->delalloc_bytes == 0 &&
1221 !list_empty(&BTRFS_I(inode)->delalloc_inodes)) { 1341 !list_empty(&BTRFS_I(inode)->delalloc_inodes)) {
@@ -2912,12 +3032,22 @@ static int btrfs_truncate_page(struct address_space *mapping, loff_t from)
2912 3032
2913 if ((offset & (blocksize - 1)) == 0) 3033 if ((offset & (blocksize - 1)) == 0)
2914 goto out; 3034 goto out;
3035 ret = btrfs_check_data_free_space(root, inode, PAGE_CACHE_SIZE);
3036 if (ret)
3037 goto out;
3038
3039 ret = btrfs_reserve_metadata_for_delalloc(root, inode, 1);
3040 if (ret)
3041 goto out;
2915 3042
2916 ret = -ENOMEM; 3043 ret = -ENOMEM;
2917again: 3044again:
2918 page = grab_cache_page(mapping, index); 3045 page = grab_cache_page(mapping, index);
2919 if (!page) 3046 if (!page) {
3047 btrfs_free_reserved_data_space(root, inode, PAGE_CACHE_SIZE);
3048 btrfs_unreserve_metadata_for_delalloc(root, inode, 1);
2920 goto out; 3049 goto out;
3050 }
2921 3051
2922 page_start = page_offset(page); 3052 page_start = page_offset(page);
2923 page_end = page_start + PAGE_CACHE_SIZE - 1; 3053 page_end = page_start + PAGE_CACHE_SIZE - 1;
@@ -2950,7 +3080,16 @@ again:
2950 goto again; 3080 goto again;
2951 } 3081 }
2952 3082
2953 btrfs_set_extent_delalloc(inode, page_start, page_end); 3083 clear_extent_bits(&BTRFS_I(inode)->io_tree, page_start, page_end,
3084 EXTENT_DIRTY | EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING,
3085 GFP_NOFS);
3086
3087 ret = btrfs_set_extent_delalloc(inode, page_start, page_end);
3088 if (ret) {
3089 unlock_extent(io_tree, page_start, page_end, GFP_NOFS);
3090 goto out_unlock;
3091 }
3092
2954 ret = 0; 3093 ret = 0;
2955 if (offset != PAGE_CACHE_SIZE) { 3094 if (offset != PAGE_CACHE_SIZE) {
2956 kaddr = kmap(page); 3095 kaddr = kmap(page);
@@ -2963,6 +3102,9 @@ again:
2963 unlock_extent(io_tree, page_start, page_end, GFP_NOFS); 3102 unlock_extent(io_tree, page_start, page_end, GFP_NOFS);
2964 3103
2965out_unlock: 3104out_unlock:
3105 if (ret)
3106 btrfs_free_reserved_data_space(root, inode, PAGE_CACHE_SIZE);
3107 btrfs_unreserve_metadata_for_delalloc(root, inode, 1);
2966 unlock_page(page); 3108 unlock_page(page);
2967 page_cache_release(page); 3109 page_cache_release(page);
2968out: 3110out:
@@ -2981,17 +3123,15 @@ int btrfs_cont_expand(struct inode *inode, loff_t size)
2981 u64 last_byte; 3123 u64 last_byte;
2982 u64 cur_offset; 3124 u64 cur_offset;
2983 u64 hole_size; 3125 u64 hole_size;
2984 int err; 3126 int err = 0;
2985 3127
2986 if (size <= hole_start) 3128 if (size <= hole_start)
2987 return 0; 3129 return 0;
2988 3130
2989 err = btrfs_check_metadata_free_space(root); 3131 err = btrfs_truncate_page(inode->i_mapping, inode->i_size);
2990 if (err) 3132 if (err)
2991 return err; 3133 return err;
2992 3134
2993 btrfs_truncate_page(inode->i_mapping, inode->i_size);
2994
2995 while (1) { 3135 while (1) {
2996 struct btrfs_ordered_extent *ordered; 3136 struct btrfs_ordered_extent *ordered;
2997 btrfs_wait_ordered_range(inode, hole_start, 3137 btrfs_wait_ordered_range(inode, hole_start,
@@ -3024,12 +3164,18 @@ int btrfs_cont_expand(struct inode *inode, loff_t size)
3024 cur_offset, &hint_byte, 1); 3164 cur_offset, &hint_byte, 1);
3025 if (err) 3165 if (err)
3026 break; 3166 break;
3167
3168 err = btrfs_reserve_metadata_space(root, 1);
3169 if (err)
3170 break;
3171
3027 err = btrfs_insert_file_extent(trans, root, 3172 err = btrfs_insert_file_extent(trans, root,
3028 inode->i_ino, cur_offset, 0, 3173 inode->i_ino, cur_offset, 0,
3029 0, hole_size, 0, hole_size, 3174 0, hole_size, 0, hole_size,
3030 0, 0, 0); 3175 0, 0, 0);
3031 btrfs_drop_extent_cache(inode, hole_start, 3176 btrfs_drop_extent_cache(inode, hole_start,
3032 last_byte - 1, 0); 3177 last_byte - 1, 0);
3178 btrfs_unreserve_metadata_space(root, 1);
3033 } 3179 }
3034 free_extent_map(em); 3180 free_extent_map(em);
3035 cur_offset = last_byte; 3181 cur_offset = last_byte;
@@ -3353,6 +3499,7 @@ static noinline void init_btrfs_i(struct inode *inode)
3353 bi->generation = 0; 3499 bi->generation = 0;
3354 bi->sequence = 0; 3500 bi->sequence = 0;
3355 bi->last_trans = 0; 3501 bi->last_trans = 0;
3502 bi->last_sub_trans = 0;
3356 bi->logged_trans = 0; 3503 bi->logged_trans = 0;
3357 bi->delalloc_bytes = 0; 3504 bi->delalloc_bytes = 0;
3358 bi->reserved_bytes = 0; 3505 bi->reserved_bytes = 0;
@@ -3503,12 +3650,14 @@ static int btrfs_dentry_delete(struct dentry *dentry)
3503{ 3650{
3504 struct btrfs_root *root; 3651 struct btrfs_root *root;
3505 3652
3506 if (!dentry->d_inode) 3653 if (!dentry->d_inode && !IS_ROOT(dentry))
3507 return 0; 3654 dentry = dentry->d_parent;
3508 3655
3509 root = BTRFS_I(dentry->d_inode)->root; 3656 if (dentry->d_inode) {
3510 if (btrfs_root_refs(&root->root_item) == 0) 3657 root = BTRFS_I(dentry->d_inode)->root;
3511 return 1; 3658 if (btrfs_root_refs(&root->root_item) == 0)
3659 return 1;
3660 }
3512 return 0; 3661 return 0;
3513} 3662}
3514 3663
@@ -3990,11 +4139,18 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry,
3990 if (!new_valid_dev(rdev)) 4139 if (!new_valid_dev(rdev))
3991 return -EINVAL; 4140 return -EINVAL;
3992 4141
3993 err = btrfs_check_metadata_free_space(root); 4142 /*
4143 * 2 for inode item and ref
4144 * 2 for dir items
4145 * 1 for xattr if selinux is on
4146 */
4147 err = btrfs_reserve_metadata_space(root, 5);
3994 if (err) 4148 if (err)
3995 goto fail; 4149 return err;
3996 4150
3997 trans = btrfs_start_transaction(root, 1); 4151 trans = btrfs_start_transaction(root, 1);
4152 if (!trans)
4153 goto fail;
3998 btrfs_set_trans_block_group(trans, dir); 4154 btrfs_set_trans_block_group(trans, dir);
3999 4155
4000 err = btrfs_find_free_objectid(trans, root, dir->i_ino, &objectid); 4156 err = btrfs_find_free_objectid(trans, root, dir->i_ino, &objectid);
@@ -4032,6 +4188,7 @@ out_unlock:
4032 nr = trans->blocks_used; 4188 nr = trans->blocks_used;
4033 btrfs_end_transaction_throttle(trans, root); 4189 btrfs_end_transaction_throttle(trans, root);
4034fail: 4190fail:
4191 btrfs_unreserve_metadata_space(root, 5);
4035 if (drop_inode) { 4192 if (drop_inode) {
4036 inode_dec_link_count(inode); 4193 inode_dec_link_count(inode);
4037 iput(inode); 4194 iput(inode);
@@ -4052,10 +4209,18 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry,
4052 u64 objectid; 4209 u64 objectid;
4053 u64 index = 0; 4210 u64 index = 0;
4054 4211
4055 err = btrfs_check_metadata_free_space(root); 4212 /*
4213 * 2 for inode item and ref
4214 * 2 for dir items
4215 * 1 for xattr if selinux is on
4216 */
4217 err = btrfs_reserve_metadata_space(root, 5);
4056 if (err) 4218 if (err)
4057 goto fail; 4219 return err;
4220
4058 trans = btrfs_start_transaction(root, 1); 4221 trans = btrfs_start_transaction(root, 1);
4222 if (!trans)
4223 goto fail;
4059 btrfs_set_trans_block_group(trans, dir); 4224 btrfs_set_trans_block_group(trans, dir);
4060 4225
4061 err = btrfs_find_free_objectid(trans, root, dir->i_ino, &objectid); 4226 err = btrfs_find_free_objectid(trans, root, dir->i_ino, &objectid);
@@ -4096,6 +4261,7 @@ out_unlock:
4096 nr = trans->blocks_used; 4261 nr = trans->blocks_used;
4097 btrfs_end_transaction_throttle(trans, root); 4262 btrfs_end_transaction_throttle(trans, root);
4098fail: 4263fail:
4264 btrfs_unreserve_metadata_space(root, 5);
4099 if (drop_inode) { 4265 if (drop_inode) {
4100 inode_dec_link_count(inode); 4266 inode_dec_link_count(inode);
4101 iput(inode); 4267 iput(inode);
@@ -4118,10 +4284,16 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
4118 if (inode->i_nlink == 0) 4284 if (inode->i_nlink == 0)
4119 return -ENOENT; 4285 return -ENOENT;
4120 4286
4121 btrfs_inc_nlink(inode); 4287 /*
4122 err = btrfs_check_metadata_free_space(root); 4288 * 1 item for inode ref
4289 * 2 items for dir items
4290 */
4291 err = btrfs_reserve_metadata_space(root, 3);
4123 if (err) 4292 if (err)
4124 goto fail; 4293 return err;
4294
4295 btrfs_inc_nlink(inode);
4296
4125 err = btrfs_set_inode_index(dir, &index); 4297 err = btrfs_set_inode_index(dir, &index);
4126 if (err) 4298 if (err)
4127 goto fail; 4299 goto fail;
@@ -4145,6 +4317,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
4145 nr = trans->blocks_used; 4317 nr = trans->blocks_used;
4146 btrfs_end_transaction_throttle(trans, root); 4318 btrfs_end_transaction_throttle(trans, root);
4147fail: 4319fail:
4320 btrfs_unreserve_metadata_space(root, 3);
4148 if (drop_inode) { 4321 if (drop_inode) {
4149 inode_dec_link_count(inode); 4322 inode_dec_link_count(inode);
4150 iput(inode); 4323 iput(inode);
@@ -4164,17 +4337,21 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
4164 u64 index = 0; 4337 u64 index = 0;
4165 unsigned long nr = 1; 4338 unsigned long nr = 1;
4166 4339
4167 err = btrfs_check_metadata_free_space(root); 4340 /*
4341 * 2 items for inode and ref
4342 * 2 items for dir items
4343 * 1 for xattr if selinux is on
4344 */
4345 err = btrfs_reserve_metadata_space(root, 5);
4168 if (err) 4346 if (err)
4169 goto out_unlock; 4347 return err;
4170 4348
4171 trans = btrfs_start_transaction(root, 1); 4349 trans = btrfs_start_transaction(root, 1);
4172 btrfs_set_trans_block_group(trans, dir); 4350 if (!trans) {
4173 4351 err = -ENOMEM;
4174 if (IS_ERR(trans)) {
4175 err = PTR_ERR(trans);
4176 goto out_unlock; 4352 goto out_unlock;
4177 } 4353 }
4354 btrfs_set_trans_block_group(trans, dir);
4178 4355
4179 err = btrfs_find_free_objectid(trans, root, dir->i_ino, &objectid); 4356 err = btrfs_find_free_objectid(trans, root, dir->i_ino, &objectid);
4180 if (err) { 4357 if (err) {
@@ -4223,6 +4400,7 @@ out_fail:
4223 btrfs_end_transaction_throttle(trans, root); 4400 btrfs_end_transaction_throttle(trans, root);
4224 4401
4225out_unlock: 4402out_unlock:
4403 btrfs_unreserve_metadata_space(root, 5);
4226 if (drop_on_err) 4404 if (drop_on_err)
4227 iput(inode); 4405 iput(inode);
4228 btrfs_btree_balance_dirty(root, nr); 4406 btrfs_btree_balance_dirty(root, nr);
@@ -4684,7 +4862,8 @@ static void btrfs_invalidatepage(struct page *page, unsigned long offset)
4684 */ 4862 */
4685 clear_extent_bit(tree, page_start, page_end, 4863 clear_extent_bit(tree, page_start, page_end,
4686 EXTENT_DIRTY | EXTENT_DELALLOC | 4864 EXTENT_DIRTY | EXTENT_DELALLOC |
4687 EXTENT_LOCKED, 1, 0, NULL, GFP_NOFS); 4865 EXTENT_LOCKED | EXTENT_DO_ACCOUNTING, 1, 0,
4866 NULL, GFP_NOFS);
4688 /* 4867 /*
4689 * whoever cleared the private bit is responsible 4868 * whoever cleared the private bit is responsible
4690 * for the finish_ordered_io 4869 * for the finish_ordered_io
@@ -4697,8 +4876,8 @@ static void btrfs_invalidatepage(struct page *page, unsigned long offset)
4697 lock_extent(tree, page_start, page_end, GFP_NOFS); 4876 lock_extent(tree, page_start, page_end, GFP_NOFS);
4698 } 4877 }
4699 clear_extent_bit(tree, page_start, page_end, 4878 clear_extent_bit(tree, page_start, page_end,
4700 EXTENT_LOCKED | EXTENT_DIRTY | EXTENT_DELALLOC, 4879 EXTENT_LOCKED | EXTENT_DIRTY | EXTENT_DELALLOC |
4701 1, 1, NULL, GFP_NOFS); 4880 EXTENT_DO_ACCOUNTING, 1, 1, NULL, GFP_NOFS);
4702 __btrfs_releasepage(page, GFP_NOFS); 4881 __btrfs_releasepage(page, GFP_NOFS);
4703 4882
4704 ClearPageChecked(page); 4883 ClearPageChecked(page);
@@ -4747,6 +4926,13 @@ int btrfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
4747 goto out; 4926 goto out;
4748 } 4927 }
4749 4928
4929 ret = btrfs_reserve_metadata_for_delalloc(root, inode, 1);
4930 if (ret) {
4931 btrfs_free_reserved_data_space(root, inode, PAGE_CACHE_SIZE);
4932 ret = VM_FAULT_SIGBUS;
4933 goto out;
4934 }
4935
4750 ret = VM_FAULT_NOPAGE; /* make the VM retry the fault */ 4936 ret = VM_FAULT_NOPAGE; /* make the VM retry the fault */
4751again: 4937again:
4752 lock_page(page); 4938 lock_page(page);
@@ -4778,7 +4964,24 @@ again:
4778 goto again; 4964 goto again;
4779 } 4965 }
4780 4966
4781 btrfs_set_extent_delalloc(inode, page_start, page_end); 4967 /*
4968 * XXX - page_mkwrite gets called every time the page is dirtied, even
4969 * if it was already dirty, so for space accounting reasons we need to
4970 * clear any delalloc bits for the range we are fixing to save. There
4971 * is probably a better way to do this, but for now keep consistent with
4972 * prepare_pages in the normal write path.
4973 */
4974 clear_extent_bits(&BTRFS_I(inode)->io_tree, page_start, page_end,
4975 EXTENT_DIRTY | EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING,
4976 GFP_NOFS);
4977
4978 ret = btrfs_set_extent_delalloc(inode, page_start, page_end);
4979 if (ret) {
4980 unlock_extent(io_tree, page_start, page_end, GFP_NOFS);
4981 ret = VM_FAULT_SIGBUS;
4982 btrfs_free_reserved_data_space(root, inode, PAGE_CACHE_SIZE);
4983 goto out_unlock;
4984 }
4782 ret = 0; 4985 ret = 0;
4783 4986
4784 /* page is wholly or partially inside EOF */ 4987 /* page is wholly or partially inside EOF */
@@ -4797,10 +5000,13 @@ again:
4797 set_page_dirty(page); 5000 set_page_dirty(page);
4798 SetPageUptodate(page); 5001 SetPageUptodate(page);
4799 5002
4800 BTRFS_I(inode)->last_trans = root->fs_info->generation + 1; 5003 BTRFS_I(inode)->last_trans = root->fs_info->generation;
5004 BTRFS_I(inode)->last_sub_trans = BTRFS_I(inode)->root->log_transid;
5005
4801 unlock_extent(io_tree, page_start, page_end, GFP_NOFS); 5006 unlock_extent(io_tree, page_start, page_end, GFP_NOFS);
4802 5007
4803out_unlock: 5008out_unlock:
5009 btrfs_unreserve_metadata_for_delalloc(root, inode, 1);
4804 if (!ret) 5010 if (!ret)
4805 return VM_FAULT_LOCKED; 5011 return VM_FAULT_LOCKED;
4806 unlock_page(page); 5012 unlock_page(page);
@@ -4821,7 +5027,9 @@ static void btrfs_truncate(struct inode *inode)
4821 if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) 5027 if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
4822 return; 5028 return;
4823 5029
4824 btrfs_truncate_page(inode->i_mapping, inode->i_size); 5030 ret = btrfs_truncate_page(inode->i_mapping, inode->i_size);
5031 if (ret)
5032 return;
4825 btrfs_wait_ordered_range(inode, inode->i_size & (~mask), (u64)-1); 5033 btrfs_wait_ordered_range(inode, inode->i_size & (~mask), (u64)-1);
4826 5034
4827 trans = btrfs_start_transaction(root, 1); 5035 trans = btrfs_start_transaction(root, 1);
@@ -4916,7 +5124,11 @@ struct inode *btrfs_alloc_inode(struct super_block *sb)
4916 if (!ei) 5124 if (!ei)
4917 return NULL; 5125 return NULL;
4918 ei->last_trans = 0; 5126 ei->last_trans = 0;
5127 ei->last_sub_trans = 0;
4919 ei->logged_trans = 0; 5128 ei->logged_trans = 0;
5129 ei->outstanding_extents = 0;
5130 ei->reserved_extents = 0;
5131 spin_lock_init(&ei->accounting_lock);
4920 btrfs_ordered_inode_tree_init(&ei->ordered_tree); 5132 btrfs_ordered_inode_tree_init(&ei->ordered_tree);
4921 INIT_LIST_HEAD(&ei->i_orphan); 5133 INIT_LIST_HEAD(&ei->i_orphan);
4922 INIT_LIST_HEAD(&ei->ordered_operations); 5134 INIT_LIST_HEAD(&ei->ordered_operations);
@@ -5070,7 +5282,12 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,
5070 new_inode->i_size > BTRFS_EMPTY_DIR_SIZE) 5282 new_inode->i_size > BTRFS_EMPTY_DIR_SIZE)
5071 return -ENOTEMPTY; 5283 return -ENOTEMPTY;
5072 5284
5073 ret = btrfs_check_metadata_free_space(root); 5285 /*
5286 * 2 items for dir items
5287 * 1 item for orphan entry
5288 * 1 item for ref
5289 */
5290 ret = btrfs_reserve_metadata_space(root, 4);
5074 if (ret) 5291 if (ret)
5075 return ret; 5292 return ret;
5076 5293
@@ -5185,6 +5402,8 @@ out_fail:
5185 5402
5186 if (old_inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) 5403 if (old_inode->i_ino == BTRFS_FIRST_FREE_OBJECTID)
5187 up_read(&root->fs_info->subvol_sem); 5404 up_read(&root->fs_info->subvol_sem);
5405
5406 btrfs_unreserve_metadata_space(root, 4);
5188 return ret; 5407 return ret;
5189} 5408}
5190 5409
@@ -5256,11 +5475,18 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
5256 if (name_len > BTRFS_MAX_INLINE_DATA_SIZE(root)) 5475 if (name_len > BTRFS_MAX_INLINE_DATA_SIZE(root))
5257 return -ENAMETOOLONG; 5476 return -ENAMETOOLONG;
5258 5477
5259 err = btrfs_check_metadata_free_space(root); 5478 /*
5479 * 2 items for inode item and ref
5480 * 2 items for dir items
5481 * 1 item for xattr if selinux is on
5482 */
5483 err = btrfs_reserve_metadata_space(root, 5);
5260 if (err) 5484 if (err)
5261 goto out_fail; 5485 return err;
5262 5486
5263 trans = btrfs_start_transaction(root, 1); 5487 trans = btrfs_start_transaction(root, 1);
5488 if (!trans)
5489 goto out_fail;
5264 btrfs_set_trans_block_group(trans, dir); 5490 btrfs_set_trans_block_group(trans, dir);
5265 5491
5266 err = btrfs_find_free_objectid(trans, root, dir->i_ino, &objectid); 5492 err = btrfs_find_free_objectid(trans, root, dir->i_ino, &objectid);
@@ -5341,6 +5567,7 @@ out_unlock:
5341 nr = trans->blocks_used; 5567 nr = trans->blocks_used;
5342 btrfs_end_transaction_throttle(trans, root); 5568 btrfs_end_transaction_throttle(trans, root);
5343out_fail: 5569out_fail:
5570 btrfs_unreserve_metadata_space(root, 5);
5344 if (drop_inode) { 5571 if (drop_inode) {
5345 inode_dec_link_count(inode); 5572 inode_dec_link_count(inode);
5346 iput(inode); 5573 iput(inode);
@@ -5362,6 +5589,11 @@ static int prealloc_file_range(struct btrfs_trans_handle *trans,
5362 5589
5363 while (num_bytes > 0) { 5590 while (num_bytes > 0) {
5364 alloc_size = min(num_bytes, root->fs_info->max_extent); 5591 alloc_size = min(num_bytes, root->fs_info->max_extent);
5592
5593 ret = btrfs_reserve_metadata_space(root, 1);
5594 if (ret)
5595 goto out;
5596
5365 ret = btrfs_reserve_extent(trans, root, alloc_size, 5597 ret = btrfs_reserve_extent(trans, root, alloc_size,
5366 root->sectorsize, 0, alloc_hint, 5598 root->sectorsize, 0, alloc_hint,
5367 (u64)-1, &ins, 1); 5599 (u64)-1, &ins, 1);
@@ -5381,6 +5613,7 @@ static int prealloc_file_range(struct btrfs_trans_handle *trans,
5381 num_bytes -= ins.offset; 5613 num_bytes -= ins.offset;
5382 cur_offset += ins.offset; 5614 cur_offset += ins.offset;
5383 alloc_hint = ins.objectid + ins.offset; 5615 alloc_hint = ins.objectid + ins.offset;
5616 btrfs_unreserve_metadata_space(root, 1);
5384 } 5617 }
5385out: 5618out:
5386 if (cur_offset > start) { 5619 if (cur_offset > start) {
@@ -5544,7 +5777,7 @@ static const struct inode_operations btrfs_dir_ro_inode_operations = {
5544 .permission = btrfs_permission, 5777 .permission = btrfs_permission,
5545}; 5778};
5546 5779
5547static struct file_operations btrfs_dir_file_operations = { 5780static const struct file_operations btrfs_dir_file_operations = {
5548 .llseek = generic_file_llseek, 5781 .llseek = generic_file_llseek,
5549 .read = generic_read_dir, 5782 .read = generic_read_dir,
5550 .readdir = btrfs_real_readdir, 5783 .readdir = btrfs_real_readdir,
@@ -5566,6 +5799,8 @@ static struct extent_io_ops btrfs_extent_io_ops = {
5566 .readpage_io_failed_hook = btrfs_io_failed_hook, 5799 .readpage_io_failed_hook = btrfs_io_failed_hook,
5567 .set_bit_hook = btrfs_set_bit_hook, 5800 .set_bit_hook = btrfs_set_bit_hook,
5568 .clear_bit_hook = btrfs_clear_bit_hook, 5801 .clear_bit_hook = btrfs_clear_bit_hook,
5802 .merge_extent_hook = btrfs_merge_extent_hook,
5803 .split_extent_hook = btrfs_split_extent_hook,
5569}; 5804};
5570 5805
5571/* 5806/*
@@ -5632,6 +5867,6 @@ static const struct inode_operations btrfs_symlink_inode_operations = {
5632 .removexattr = btrfs_removexattr, 5867 .removexattr = btrfs_removexattr,
5633}; 5868};
5634 5869
5635struct dentry_operations btrfs_dentry_operations = { 5870const struct dentry_operations btrfs_dentry_operations = {
5636 .d_delete = btrfs_dentry_delete, 5871 .d_delete = btrfs_dentry_delete,
5637}; 5872};
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index a8577a7f26ab..cdbb054102b9 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -239,7 +239,13 @@ static noinline int create_subvol(struct btrfs_root *root,
239 u64 index = 0; 239 u64 index = 0;
240 unsigned long nr = 1; 240 unsigned long nr = 1;
241 241
242 ret = btrfs_check_metadata_free_space(root); 242 /*
243 * 1 - inode item
244 * 2 - refs
245 * 1 - root item
246 * 2 - dir items
247 */
248 ret = btrfs_reserve_metadata_space(root, 6);
243 if (ret) 249 if (ret)
244 return ret; 250 return ret;
245 251
@@ -340,6 +346,9 @@ fail:
340 err = btrfs_commit_transaction(trans, root); 346 err = btrfs_commit_transaction(trans, root);
341 if (err && !ret) 347 if (err && !ret)
342 ret = err; 348 ret = err;
349
350 btrfs_unreserve_metadata_space(root, 6);
351 btrfs_btree_balance_dirty(root, nr);
343 return ret; 352 return ret;
344} 353}
345 354
@@ -355,19 +364,27 @@ static int create_snapshot(struct btrfs_root *root, struct dentry *dentry,
355 if (!root->ref_cows) 364 if (!root->ref_cows)
356 return -EINVAL; 365 return -EINVAL;
357 366
358 ret = btrfs_check_metadata_free_space(root); 367 /*
368 * 1 - inode item
369 * 2 - refs
370 * 1 - root item
371 * 2 - dir items
372 */
373 ret = btrfs_reserve_metadata_space(root, 6);
359 if (ret) 374 if (ret)
360 goto fail_unlock; 375 goto fail_unlock;
361 376
362 pending_snapshot = kzalloc(sizeof(*pending_snapshot), GFP_NOFS); 377 pending_snapshot = kzalloc(sizeof(*pending_snapshot), GFP_NOFS);
363 if (!pending_snapshot) { 378 if (!pending_snapshot) {
364 ret = -ENOMEM; 379 ret = -ENOMEM;
380 btrfs_unreserve_metadata_space(root, 6);
365 goto fail_unlock; 381 goto fail_unlock;
366 } 382 }
367 pending_snapshot->name = kmalloc(namelen + 1, GFP_NOFS); 383 pending_snapshot->name = kmalloc(namelen + 1, GFP_NOFS);
368 if (!pending_snapshot->name) { 384 if (!pending_snapshot->name) {
369 ret = -ENOMEM; 385 ret = -ENOMEM;
370 kfree(pending_snapshot); 386 kfree(pending_snapshot);
387 btrfs_unreserve_metadata_space(root, 6);
371 goto fail_unlock; 388 goto fail_unlock;
372 } 389 }
373 memcpy(pending_snapshot->name, name, namelen); 390 memcpy(pending_snapshot->name, name, namelen);
@@ -813,6 +830,7 @@ out_up_write:
813out_unlock: 830out_unlock:
814 mutex_unlock(&inode->i_mutex); 831 mutex_unlock(&inode->i_mutex);
815 if (!err) { 832 if (!err) {
833 shrink_dcache_sb(root->fs_info->sb);
816 btrfs_invalidate_inodes(dest); 834 btrfs_invalidate_inodes(dest);
817 d_delete(dentry); 835 d_delete(dentry);
818 } 836 }
@@ -1105,8 +1123,10 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
1105 datao += off - key.offset; 1123 datao += off - key.offset;
1106 datal -= off - key.offset; 1124 datal -= off - key.offset;
1107 } 1125 }
1108 if (key.offset + datao + datal > off + len) 1126
1109 datal = off + len - key.offset - datao; 1127 if (key.offset + datal > off + len)
1128 datal = off + len - key.offset;
1129
1110 /* disko == 0 means it's a hole */ 1130 /* disko == 0 means it's a hole */
1111 if (!disko) 1131 if (!disko)
1112 datao = 0; 1132 datao = 0;
@@ -1215,15 +1235,15 @@ static long btrfs_ioctl_trans_start(struct file *file)
1215 struct inode *inode = fdentry(file)->d_inode; 1235 struct inode *inode = fdentry(file)->d_inode;
1216 struct btrfs_root *root = BTRFS_I(inode)->root; 1236 struct btrfs_root *root = BTRFS_I(inode)->root;
1217 struct btrfs_trans_handle *trans; 1237 struct btrfs_trans_handle *trans;
1218 int ret = 0; 1238 int ret;
1219 1239
1240 ret = -EPERM;
1220 if (!capable(CAP_SYS_ADMIN)) 1241 if (!capable(CAP_SYS_ADMIN))
1221 return -EPERM; 1242 goto out;
1222 1243
1223 if (file->private_data) { 1244 ret = -EINPROGRESS;
1224 ret = -EINPROGRESS; 1245 if (file->private_data)
1225 goto out; 1246 goto out;
1226 }
1227 1247
1228 ret = mnt_want_write(file->f_path.mnt); 1248 ret = mnt_want_write(file->f_path.mnt);
1229 if (ret) 1249 if (ret)
@@ -1233,12 +1253,19 @@ static long btrfs_ioctl_trans_start(struct file *file)
1233 root->fs_info->open_ioctl_trans++; 1253 root->fs_info->open_ioctl_trans++;
1234 mutex_unlock(&root->fs_info->trans_mutex); 1254 mutex_unlock(&root->fs_info->trans_mutex);
1235 1255
1256 ret = -ENOMEM;
1236 trans = btrfs_start_ioctl_transaction(root, 0); 1257 trans = btrfs_start_ioctl_transaction(root, 0);
1237 if (trans) 1258 if (!trans)
1238 file->private_data = trans; 1259 goto out_drop;
1239 else 1260
1240 ret = -ENOMEM; 1261 file->private_data = trans;
1241 /*printk(KERN_INFO "btrfs_ioctl_trans_start on %p\n", file);*/ 1262 return 0;
1263
1264out_drop:
1265 mutex_lock(&root->fs_info->trans_mutex);
1266 root->fs_info->open_ioctl_trans--;
1267 mutex_unlock(&root->fs_info->trans_mutex);
1268 mnt_drop_write(file->f_path.mnt);
1242out: 1269out:
1243 return ret; 1270 return ret;
1244} 1271}
@@ -1254,24 +1281,20 @@ long btrfs_ioctl_trans_end(struct file *file)
1254 struct inode *inode = fdentry(file)->d_inode; 1281 struct inode *inode = fdentry(file)->d_inode;
1255 struct btrfs_root *root = BTRFS_I(inode)->root; 1282 struct btrfs_root *root = BTRFS_I(inode)->root;
1256 struct btrfs_trans_handle *trans; 1283 struct btrfs_trans_handle *trans;
1257 int ret = 0;
1258 1284
1259 trans = file->private_data; 1285 trans = file->private_data;
1260 if (!trans) { 1286 if (!trans)
1261 ret = -EINVAL; 1287 return -EINVAL;
1262 goto out;
1263 }
1264 btrfs_end_transaction(trans, root);
1265 file->private_data = NULL; 1288 file->private_data = NULL;
1266 1289
1290 btrfs_end_transaction(trans, root);
1291
1267 mutex_lock(&root->fs_info->trans_mutex); 1292 mutex_lock(&root->fs_info->trans_mutex);
1268 root->fs_info->open_ioctl_trans--; 1293 root->fs_info->open_ioctl_trans--;
1269 mutex_unlock(&root->fs_info->trans_mutex); 1294 mutex_unlock(&root->fs_info->trans_mutex);
1270 1295
1271 mnt_drop_write(file->f_path.mnt); 1296 mnt_drop_write(file->f_path.mnt);
1272 1297 return 0;
1273out:
1274 return ret;
1275} 1298}
1276 1299
1277long btrfs_ioctl(struct file *file, unsigned int 1300long btrfs_ioctl(struct file *file, unsigned int
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c
index b5d6d24726b0..5799bc46a309 100644
--- a/fs/btrfs/ordered-data.c
+++ b/fs/btrfs/ordered-data.c
@@ -306,6 +306,12 @@ int btrfs_remove_ordered_extent(struct inode *inode,
306 tree->last = NULL; 306 tree->last = NULL;
307 set_bit(BTRFS_ORDERED_COMPLETE, &entry->flags); 307 set_bit(BTRFS_ORDERED_COMPLETE, &entry->flags);
308 308
309 spin_lock(&BTRFS_I(inode)->accounting_lock);
310 BTRFS_I(inode)->outstanding_extents--;
311 spin_unlock(&BTRFS_I(inode)->accounting_lock);
312 btrfs_unreserve_metadata_for_delalloc(BTRFS_I(inode)->root,
313 inode, 1);
314
309 spin_lock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock); 315 spin_lock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock);
310 list_del_init(&entry->root_extent_list); 316 list_del_init(&entry->root_extent_list);
311 317
@@ -458,7 +464,7 @@ void btrfs_start_ordered_extent(struct inode *inode,
458 * start IO on any dirty ones so the wait doesn't stall waiting 464 * start IO on any dirty ones so the wait doesn't stall waiting
459 * for pdflush to find them 465 * for pdflush to find them
460 */ 466 */
461 btrfs_fdatawrite_range(inode->i_mapping, start, end, WB_SYNC_ALL); 467 filemap_fdatawrite_range(inode->i_mapping, start, end);
462 if (wait) { 468 if (wait) {
463 wait_event(entry->wait, test_bit(BTRFS_ORDERED_COMPLETE, 469 wait_event(entry->wait, test_bit(BTRFS_ORDERED_COMPLETE,
464 &entry->flags)); 470 &entry->flags));
@@ -488,17 +494,15 @@ again:
488 /* start IO across the range first to instantiate any delalloc 494 /* start IO across the range first to instantiate any delalloc
489 * extents 495 * extents
490 */ 496 */
491 btrfs_fdatawrite_range(inode->i_mapping, start, orig_end, WB_SYNC_ALL); 497 filemap_fdatawrite_range(inode->i_mapping, start, orig_end);
492 498
493 /* The compression code will leave pages locked but return from 499 /* The compression code will leave pages locked but return from
494 * writepage without setting the page writeback. Starting again 500 * writepage without setting the page writeback. Starting again
495 * with WB_SYNC_ALL will end up waiting for the IO to actually start. 501 * with WB_SYNC_ALL will end up waiting for the IO to actually start.
496 */ 502 */
497 btrfs_fdatawrite_range(inode->i_mapping, start, orig_end, WB_SYNC_ALL); 503 filemap_fdatawrite_range(inode->i_mapping, start, orig_end);
498 504
499 btrfs_wait_on_page_writeback_range(inode->i_mapping, 505 filemap_fdatawait_range(inode->i_mapping, start, orig_end);
500 start >> PAGE_CACHE_SHIFT,
501 orig_end >> PAGE_CACHE_SHIFT);
502 506
503 end = orig_end; 507 end = orig_end;
504 found = 0; 508 found = 0;
@@ -716,89 +720,6 @@ out:
716} 720}
717 721
718 722
719/**
720 * taken from mm/filemap.c because it isn't exported
721 *
722 * __filemap_fdatawrite_range - start writeback on mapping dirty pages in range
723 * @mapping: address space structure to write
724 * @start: offset in bytes where the range starts
725 * @end: offset in bytes where the range ends (inclusive)
726 * @sync_mode: enable synchronous operation
727 *
728 * Start writeback against all of a mapping's dirty pages that lie
729 * within the byte offsets <start, end> inclusive.
730 *
731 * If sync_mode is WB_SYNC_ALL then this is a "data integrity" operation, as
732 * opposed to a regular memory cleansing writeback. The difference between
733 * these two operations is that if a dirty page/buffer is encountered, it must
734 * be waited upon, and not just skipped over.
735 */
736int btrfs_fdatawrite_range(struct address_space *mapping, loff_t start,
737 loff_t end, int sync_mode)
738{
739 struct writeback_control wbc = {
740 .sync_mode = sync_mode,
741 .nr_to_write = mapping->nrpages * 2,
742 .range_start = start,
743 .range_end = end,
744 };
745 return btrfs_writepages(mapping, &wbc);
746}
747
748/**
749 * taken from mm/filemap.c because it isn't exported
750 *
751 * wait_on_page_writeback_range - wait for writeback to complete
752 * @mapping: target address_space
753 * @start: beginning page index
754 * @end: ending page index
755 *
756 * Wait for writeback to complete against pages indexed by start->end
757 * inclusive
758 */
759int btrfs_wait_on_page_writeback_range(struct address_space *mapping,
760 pgoff_t start, pgoff_t end)
761{
762 struct pagevec pvec;
763 int nr_pages;
764 int ret = 0;
765 pgoff_t index;
766
767 if (end < start)
768 return 0;
769
770 pagevec_init(&pvec, 0);
771 index = start;
772 while ((index <= end) &&
773 (nr_pages = pagevec_lookup_tag(&pvec, mapping, &index,
774 PAGECACHE_TAG_WRITEBACK,
775 min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1)) != 0) {
776 unsigned i;
777
778 for (i = 0; i < nr_pages; i++) {
779 struct page *page = pvec.pages[i];
780
781 /* until radix tree lookup accepts end_index */
782 if (page->index > end)
783 continue;
784
785 wait_on_page_writeback(page);
786 if (PageError(page))
787 ret = -EIO;
788 }
789 pagevec_release(&pvec);
790 cond_resched();
791 }
792
793 /* Check for outstanding write errors */
794 if (test_and_clear_bit(AS_ENOSPC, &mapping->flags))
795 ret = -ENOSPC;
796 if (test_and_clear_bit(AS_EIO, &mapping->flags))
797 ret = -EIO;
798
799 return ret;
800}
801
802/* 723/*
803 * add a given inode to the list of inodes that must be fully on 724 * add a given inode to the list of inodes that must be fully on
804 * disk before a transaction commit finishes. 725 * disk before a transaction commit finishes.
diff --git a/fs/btrfs/ordered-data.h b/fs/btrfs/ordered-data.h
index 993a7ea45c70..f82e87488ca8 100644
--- a/fs/btrfs/ordered-data.h
+++ b/fs/btrfs/ordered-data.h
@@ -153,10 +153,6 @@ btrfs_lookup_first_ordered_extent(struct inode * inode, u64 file_offset);
153int btrfs_ordered_update_i_size(struct inode *inode, 153int btrfs_ordered_update_i_size(struct inode *inode,
154 struct btrfs_ordered_extent *ordered); 154 struct btrfs_ordered_extent *ordered);
155int btrfs_find_ordered_sum(struct inode *inode, u64 offset, u64 disk_bytenr, u32 *sum); 155int btrfs_find_ordered_sum(struct inode *inode, u64 offset, u64 disk_bytenr, u32 *sum);
156int btrfs_wait_on_page_writeback_range(struct address_space *mapping,
157 pgoff_t start, pgoff_t end);
158int btrfs_fdatawrite_range(struct address_space *mapping, loff_t start,
159 loff_t end, int sync_mode);
160int btrfs_wait_ordered_extents(struct btrfs_root *root, int nocow_only); 156int btrfs_wait_ordered_extents(struct btrfs_root *root, int nocow_only);
161int btrfs_run_ordered_operations(struct btrfs_root *root, int wait); 157int btrfs_run_ordered_operations(struct btrfs_root *root, int wait);
162int btrfs_add_ordered_operation(struct btrfs_trans_handle *trans, 158int btrfs_add_ordered_operation(struct btrfs_trans_handle *trans,
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index 361ad323faac..cfcc93c93a7b 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -3518,7 +3518,7 @@ int btrfs_relocate_block_group(struct btrfs_root *extent_root, u64 group_start)
3518 BUG_ON(!rc->block_group); 3518 BUG_ON(!rc->block_group);
3519 3519
3520 btrfs_init_workers(&rc->workers, "relocate", 3520 btrfs_init_workers(&rc->workers, "relocate",
3521 fs_info->thread_pool_size); 3521 fs_info->thread_pool_size, NULL);
3522 3522
3523 rc->extent_root = extent_root; 3523 rc->extent_root = extent_root;
3524 btrfs_prepare_block_group_relocation(extent_root, rc->block_group); 3524 btrfs_prepare_block_group_relocation(extent_root, rc->block_group);
@@ -3701,7 +3701,7 @@ int btrfs_recover_relocation(struct btrfs_root *root)
3701 mapping_tree_init(&rc->reloc_root_tree); 3701 mapping_tree_init(&rc->reloc_root_tree);
3702 INIT_LIST_HEAD(&rc->reloc_roots); 3702 INIT_LIST_HEAD(&rc->reloc_roots);
3703 btrfs_init_workers(&rc->workers, "relocate", 3703 btrfs_init_workers(&rc->workers, "relocate",
3704 root->fs_info->thread_pool_size); 3704 root->fs_info->thread_pool_size, NULL);
3705 rc->extent_root = root->fs_info->extent_root; 3705 rc->extent_root = root->fs_info->extent_root;
3706 3706
3707 set_reloc_control(rc); 3707 set_reloc_control(rc);
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 67035385444c..752a5463bf53 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -66,7 +66,8 @@ enum {
66 Opt_degraded, Opt_subvol, Opt_device, Opt_nodatasum, Opt_nodatacow, 66 Opt_degraded, Opt_subvol, Opt_device, Opt_nodatasum, Opt_nodatacow,
67 Opt_max_extent, Opt_max_inline, Opt_alloc_start, Opt_nobarrier, 67 Opt_max_extent, Opt_max_inline, Opt_alloc_start, Opt_nobarrier,
68 Opt_ssd, Opt_nossd, Opt_ssd_spread, Opt_thread_pool, Opt_noacl, 68 Opt_ssd, Opt_nossd, Opt_ssd_spread, Opt_thread_pool, Opt_noacl,
69 Opt_compress, Opt_notreelog, Opt_ratio, Opt_flushoncommit, Opt_err, 69 Opt_compress, Opt_notreelog, Opt_ratio, Opt_flushoncommit,
70 Opt_discard, Opt_err,
70}; 71};
71 72
72static match_table_t tokens = { 73static match_table_t tokens = {
@@ -88,6 +89,7 @@ static match_table_t tokens = {
88 {Opt_notreelog, "notreelog"}, 89 {Opt_notreelog, "notreelog"},
89 {Opt_flushoncommit, "flushoncommit"}, 90 {Opt_flushoncommit, "flushoncommit"},
90 {Opt_ratio, "metadata_ratio=%d"}, 91 {Opt_ratio, "metadata_ratio=%d"},
92 {Opt_discard, "discard"},
91 {Opt_err, NULL}, 93 {Opt_err, NULL},
92}; 94};
93 95
@@ -257,6 +259,9 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
257 info->metadata_ratio); 259 info->metadata_ratio);
258 } 260 }
259 break; 261 break;
262 case Opt_discard:
263 btrfs_set_opt(info->mount_opt, DISCARD);
264 break;
260 default: 265 default:
261 break; 266 break;
262 } 267 }
@@ -344,7 +349,9 @@ static int btrfs_fill_super(struct super_block *sb,
344 sb->s_export_op = &btrfs_export_ops; 349 sb->s_export_op = &btrfs_export_ops;
345 sb->s_xattr = btrfs_xattr_handlers; 350 sb->s_xattr = btrfs_xattr_handlers;
346 sb->s_time_gran = 1; 351 sb->s_time_gran = 1;
352#ifdef CONFIG_BTRFS_FS_POSIX_ACL
347 sb->s_flags |= MS_POSIXACL; 353 sb->s_flags |= MS_POSIXACL;
354#endif
348 355
349 tree_root = open_ctree(sb, fs_devices, (char *)data); 356 tree_root = open_ctree(sb, fs_devices, (char *)data);
350 357
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 88f866f85e7a..bca82a4ca8e6 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -186,6 +186,9 @@ static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
186 h->alloc_exclude_start = 0; 186 h->alloc_exclude_start = 0;
187 h->delayed_ref_updates = 0; 187 h->delayed_ref_updates = 0;
188 188
189 if (!current->journal_info)
190 current->journal_info = h;
191
189 root->fs_info->running_transaction->use_count++; 192 root->fs_info->running_transaction->use_count++;
190 record_root_in_trans(h, root); 193 record_root_in_trans(h, root);
191 mutex_unlock(&root->fs_info->trans_mutex); 194 mutex_unlock(&root->fs_info->trans_mutex);
@@ -317,6 +320,9 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
317 wake_up(&cur_trans->writer_wait); 320 wake_up(&cur_trans->writer_wait);
318 put_transaction(cur_trans); 321 put_transaction(cur_trans);
319 mutex_unlock(&info->trans_mutex); 322 mutex_unlock(&info->trans_mutex);
323
324 if (current->journal_info == trans)
325 current->journal_info = NULL;
320 memset(trans, 0, sizeof(*trans)); 326 memset(trans, 0, sizeof(*trans));
321 kmem_cache_free(btrfs_trans_handle_cachep, trans); 327 kmem_cache_free(btrfs_trans_handle_cachep, trans);
322 328
@@ -338,10 +344,10 @@ int btrfs_end_transaction_throttle(struct btrfs_trans_handle *trans,
338/* 344/*
339 * when btree blocks are allocated, they have some corresponding bits set for 345 * when btree blocks are allocated, they have some corresponding bits set for
340 * them in one of two extent_io trees. This is used to make sure all of 346 * them in one of two extent_io trees. This is used to make sure all of
341 * those extents are on disk for transaction or log commit 347 * those extents are sent to disk but does not wait on them
342 */ 348 */
343int btrfs_write_and_wait_marked_extents(struct btrfs_root *root, 349int btrfs_write_marked_extents(struct btrfs_root *root,
344 struct extent_io_tree *dirty_pages) 350 struct extent_io_tree *dirty_pages)
345{ 351{
346 int ret; 352 int ret;
347 int err = 0; 353 int err = 0;
@@ -388,6 +394,29 @@ int btrfs_write_and_wait_marked_extents(struct btrfs_root *root,
388 page_cache_release(page); 394 page_cache_release(page);
389 } 395 }
390 } 396 }
397 if (err)
398 werr = err;
399 return werr;
400}
401
402/*
403 * when btree blocks are allocated, they have some corresponding bits set for
404 * them in one of two extent_io trees. This is used to make sure all of
405 * those extents are on disk for transaction or log commit. We wait
406 * on all the pages and clear them from the dirty pages state tree
407 */
408int btrfs_wait_marked_extents(struct btrfs_root *root,
409 struct extent_io_tree *dirty_pages)
410{
411 int ret;
412 int err = 0;
413 int werr = 0;
414 struct page *page;
415 struct inode *btree_inode = root->fs_info->btree_inode;
416 u64 start = 0;
417 u64 end;
418 unsigned long index;
419
391 while (1) { 420 while (1) {
392 ret = find_first_extent_bit(dirty_pages, 0, &start, &end, 421 ret = find_first_extent_bit(dirty_pages, 0, &start, &end,
393 EXTENT_DIRTY); 422 EXTENT_DIRTY);
@@ -418,6 +447,22 @@ int btrfs_write_and_wait_marked_extents(struct btrfs_root *root,
418 return werr; 447 return werr;
419} 448}
420 449
450/*
451 * when btree blocks are allocated, they have some corresponding bits set for
452 * them in one of two extent_io trees. This is used to make sure all of
453 * those extents are on disk for transaction or log commit
454 */
455int btrfs_write_and_wait_marked_extents(struct btrfs_root *root,
456 struct extent_io_tree *dirty_pages)
457{
458 int ret;
459 int ret2;
460
461 ret = btrfs_write_marked_extents(root, dirty_pages);
462 ret2 = btrfs_wait_marked_extents(root, dirty_pages);
463 return ret || ret2;
464}
465
421int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans, 466int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans,
422 struct btrfs_root *root) 467 struct btrfs_root *root)
423{ 468{
@@ -743,6 +788,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
743 memcpy(&pending->root_key, &key, sizeof(key)); 788 memcpy(&pending->root_key, &key, sizeof(key));
744fail: 789fail:
745 kfree(new_root_item); 790 kfree(new_root_item);
791 btrfs_unreserve_metadata_space(root, 6);
746 return ret; 792 return ret;
747} 793}
748 794
@@ -1059,6 +1105,9 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
1059 1105
1060 mutex_unlock(&root->fs_info->trans_mutex); 1106 mutex_unlock(&root->fs_info->trans_mutex);
1061 1107
1108 if (current->journal_info == trans)
1109 current->journal_info = NULL;
1110
1062 kmem_cache_free(btrfs_trans_handle_cachep, trans); 1111 kmem_cache_free(btrfs_trans_handle_cachep, trans);
1063 return ret; 1112 return ret;
1064} 1113}
diff --git a/fs/btrfs/transaction.h b/fs/btrfs/transaction.h
index 663c67404918..d4e3e7a6938c 100644
--- a/fs/btrfs/transaction.h
+++ b/fs/btrfs/transaction.h
@@ -79,6 +79,7 @@ static inline void btrfs_set_inode_last_trans(struct btrfs_trans_handle *trans,
79 struct inode *inode) 79 struct inode *inode)
80{ 80{
81 BTRFS_I(inode)->last_trans = trans->transaction->transid; 81 BTRFS_I(inode)->last_trans = trans->transaction->transid;
82 BTRFS_I(inode)->last_sub_trans = BTRFS_I(inode)->root->log_transid;
82} 83}
83 84
84int btrfs_end_transaction(struct btrfs_trans_handle *trans, 85int btrfs_end_transaction(struct btrfs_trans_handle *trans,
@@ -107,5 +108,9 @@ int btrfs_record_root_in_trans(struct btrfs_trans_handle *trans,
107 struct btrfs_root *root); 108 struct btrfs_root *root);
108int btrfs_write_and_wait_marked_extents(struct btrfs_root *root, 109int btrfs_write_and_wait_marked_extents(struct btrfs_root *root,
109 struct extent_io_tree *dirty_pages); 110 struct extent_io_tree *dirty_pages);
111int btrfs_write_marked_extents(struct btrfs_root *root,
112 struct extent_io_tree *dirty_pages);
113int btrfs_wait_marked_extents(struct btrfs_root *root,
114 struct extent_io_tree *dirty_pages);
110int btrfs_transaction_in_commit(struct btrfs_fs_info *info); 115int btrfs_transaction_in_commit(struct btrfs_fs_info *info);
111#endif 116#endif
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index 7827841b55cb..741666a7676a 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -137,11 +137,20 @@ static int start_log_trans(struct btrfs_trans_handle *trans,
137 137
138 mutex_lock(&root->log_mutex); 138 mutex_lock(&root->log_mutex);
139 if (root->log_root) { 139 if (root->log_root) {
140 if (!root->log_start_pid) {
141 root->log_start_pid = current->pid;
142 root->log_multiple_pids = false;
143 } else if (root->log_start_pid != current->pid) {
144 root->log_multiple_pids = true;
145 }
146
140 root->log_batch++; 147 root->log_batch++;
141 atomic_inc(&root->log_writers); 148 atomic_inc(&root->log_writers);
142 mutex_unlock(&root->log_mutex); 149 mutex_unlock(&root->log_mutex);
143 return 0; 150 return 0;
144 } 151 }
152 root->log_multiple_pids = false;
153 root->log_start_pid = current->pid;
145 mutex_lock(&root->fs_info->tree_log_mutex); 154 mutex_lock(&root->fs_info->tree_log_mutex);
146 if (!root->fs_info->log_root_tree) { 155 if (!root->fs_info->log_root_tree) {
147 ret = btrfs_init_log_root_tree(trans, root->fs_info); 156 ret = btrfs_init_log_root_tree(trans, root->fs_info);
@@ -1971,6 +1980,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
1971 int ret; 1980 int ret;
1972 struct btrfs_root *log = root->log_root; 1981 struct btrfs_root *log = root->log_root;
1973 struct btrfs_root *log_root_tree = root->fs_info->log_root_tree; 1982 struct btrfs_root *log_root_tree = root->fs_info->log_root_tree;
1983 u64 log_transid = 0;
1974 1984
1975 mutex_lock(&root->log_mutex); 1985 mutex_lock(&root->log_mutex);
1976 index1 = root->log_transid % 2; 1986 index1 = root->log_transid % 2;
@@ -1987,10 +1997,11 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
1987 1997
1988 while (1) { 1998 while (1) {
1989 unsigned long batch = root->log_batch; 1999 unsigned long batch = root->log_batch;
1990 mutex_unlock(&root->log_mutex); 2000 if (root->log_multiple_pids) {
1991 schedule_timeout_uninterruptible(1); 2001 mutex_unlock(&root->log_mutex);
1992 mutex_lock(&root->log_mutex); 2002 schedule_timeout_uninterruptible(1);
1993 2003 mutex_lock(&root->log_mutex);
2004 }
1994 wait_for_writer(trans, root); 2005 wait_for_writer(trans, root);
1995 if (batch == root->log_batch) 2006 if (batch == root->log_batch)
1996 break; 2007 break;
@@ -2003,14 +2014,19 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
2003 goto out; 2014 goto out;
2004 } 2015 }
2005 2016
2006 ret = btrfs_write_and_wait_marked_extents(log, &log->dirty_log_pages); 2017 /* we start IO on all the marked extents here, but we don't actually
2018 * wait for them until later.
2019 */
2020 ret = btrfs_write_marked_extents(log, &log->dirty_log_pages);
2007 BUG_ON(ret); 2021 BUG_ON(ret);
2008 2022
2009 btrfs_set_root_node(&log->root_item, log->node); 2023 btrfs_set_root_node(&log->root_item, log->node);
2010 2024
2011 root->log_batch = 0; 2025 root->log_batch = 0;
2026 log_transid = root->log_transid;
2012 root->log_transid++; 2027 root->log_transid++;
2013 log->log_transid = root->log_transid; 2028 log->log_transid = root->log_transid;
2029 root->log_start_pid = 0;
2014 smp_mb(); 2030 smp_mb();
2015 /* 2031 /*
2016 * log tree has been flushed to disk, new modifications of 2032 * log tree has been flushed to disk, new modifications of
@@ -2036,6 +2052,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
2036 2052
2037 index2 = log_root_tree->log_transid % 2; 2053 index2 = log_root_tree->log_transid % 2;
2038 if (atomic_read(&log_root_tree->log_commit[index2])) { 2054 if (atomic_read(&log_root_tree->log_commit[index2])) {
2055 btrfs_wait_marked_extents(log, &log->dirty_log_pages);
2039 wait_log_commit(trans, log_root_tree, 2056 wait_log_commit(trans, log_root_tree,
2040 log_root_tree->log_transid); 2057 log_root_tree->log_transid);
2041 mutex_unlock(&log_root_tree->log_mutex); 2058 mutex_unlock(&log_root_tree->log_mutex);
@@ -2055,6 +2072,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
2055 * check the full commit flag again 2072 * check the full commit flag again
2056 */ 2073 */
2057 if (root->fs_info->last_trans_log_full_commit == trans->transid) { 2074 if (root->fs_info->last_trans_log_full_commit == trans->transid) {
2075 btrfs_wait_marked_extents(log, &log->dirty_log_pages);
2058 mutex_unlock(&log_root_tree->log_mutex); 2076 mutex_unlock(&log_root_tree->log_mutex);
2059 ret = -EAGAIN; 2077 ret = -EAGAIN;
2060 goto out_wake_log_root; 2078 goto out_wake_log_root;
@@ -2063,6 +2081,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
2063 ret = btrfs_write_and_wait_marked_extents(log_root_tree, 2081 ret = btrfs_write_and_wait_marked_extents(log_root_tree,
2064 &log_root_tree->dirty_log_pages); 2082 &log_root_tree->dirty_log_pages);
2065 BUG_ON(ret); 2083 BUG_ON(ret);
2084 btrfs_wait_marked_extents(log, &log->dirty_log_pages);
2066 2085
2067 btrfs_set_super_log_root(&root->fs_info->super_for_commit, 2086 btrfs_set_super_log_root(&root->fs_info->super_for_commit,
2068 log_root_tree->node->start); 2087 log_root_tree->node->start);
@@ -2082,9 +2101,14 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
2082 * the running transaction open, so a full commit can't hop 2101 * the running transaction open, so a full commit can't hop
2083 * in and cause problems either. 2102 * in and cause problems either.
2084 */ 2103 */
2085 write_ctree_super(trans, root->fs_info->tree_root, 2); 2104 write_ctree_super(trans, root->fs_info->tree_root, 1);
2086 ret = 0; 2105 ret = 0;
2087 2106
2107 mutex_lock(&root->log_mutex);
2108 if (root->last_log_commit < log_transid)
2109 root->last_log_commit = log_transid;
2110 mutex_unlock(&root->log_mutex);
2111
2088out_wake_log_root: 2112out_wake_log_root:
2089 atomic_set(&log_root_tree->log_commit[index2], 0); 2113 atomic_set(&log_root_tree->log_commit[index2], 0);
2090 smp_mb(); 2114 smp_mb();
@@ -2852,6 +2876,21 @@ out:
2852 return ret; 2876 return ret;
2853} 2877}
2854 2878
2879static int inode_in_log(struct btrfs_trans_handle *trans,
2880 struct inode *inode)
2881{
2882 struct btrfs_root *root = BTRFS_I(inode)->root;
2883 int ret = 0;
2884
2885 mutex_lock(&root->log_mutex);
2886 if (BTRFS_I(inode)->logged_trans == trans->transid &&
2887 BTRFS_I(inode)->last_sub_trans <= root->last_log_commit)
2888 ret = 1;
2889 mutex_unlock(&root->log_mutex);
2890 return ret;
2891}
2892
2893
2855/* 2894/*
2856 * helper function around btrfs_log_inode to make sure newly created 2895 * helper function around btrfs_log_inode to make sure newly created
2857 * parent directories also end up in the log. A minimal inode and backref 2896 * parent directories also end up in the log. A minimal inode and backref
@@ -2891,6 +2930,11 @@ int btrfs_log_inode_parent(struct btrfs_trans_handle *trans,
2891 if (ret) 2930 if (ret)
2892 goto end_no_trans; 2931 goto end_no_trans;
2893 2932
2933 if (inode_in_log(trans, inode)) {
2934 ret = BTRFS_NO_LOG_SYNC;
2935 goto end_no_trans;
2936 }
2937
2894 start_log_trans(trans, root); 2938 start_log_trans(trans, root);
2895 2939
2896 ret = btrfs_log_inode(trans, root, inode, inode_only); 2940 ret = btrfs_log_inode(trans, root, inode, inode_only);
diff --git a/fs/btrfs/tree-log.h b/fs/btrfs/tree-log.h
index d09c7609e16b..0776eacb5083 100644
--- a/fs/btrfs/tree-log.h
+++ b/fs/btrfs/tree-log.h
@@ -19,6 +19,9 @@
19#ifndef __TREE_LOG_ 19#ifndef __TREE_LOG_
20#define __TREE_LOG_ 20#define __TREE_LOG_
21 21
22/* return value for btrfs_log_dentry_safe that means we don't need to log it at all */
23#define BTRFS_NO_LOG_SYNC 256
24
22int btrfs_sync_log(struct btrfs_trans_handle *trans, 25int btrfs_sync_log(struct btrfs_trans_handle *trans,
23 struct btrfs_root *root); 26 struct btrfs_root *root);
24int btrfs_free_log(struct btrfs_trans_handle *trans, struct btrfs_root *root); 27int btrfs_free_log(struct btrfs_trans_handle *trans, struct btrfs_root *root);
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 23e7d36ff325..7eda483d7b5a 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -446,8 +446,10 @@ static struct btrfs_fs_devices *clone_fs_devices(struct btrfs_fs_devices *orig)
446 goto error; 446 goto error;
447 447
448 device->name = kstrdup(orig_dev->name, GFP_NOFS); 448 device->name = kstrdup(orig_dev->name, GFP_NOFS);
449 if (!device->name) 449 if (!device->name) {
450 kfree(device);
450 goto error; 451 goto error;
452 }
451 453
452 device->devid = orig_dev->devid; 454 device->devid = orig_dev->devid;
453 device->work.func = pending_bios_fn; 455 device->work.func = pending_bios_fn;
diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c
index a9d3bf4d2689..b6dd5967c48a 100644
--- a/fs/btrfs/xattr.c
+++ b/fs/btrfs/xattr.c
@@ -260,7 +260,7 @@ err:
260 * attributes are handled directly. 260 * attributes are handled directly.
261 */ 261 */
262struct xattr_handler *btrfs_xattr_handlers[] = { 262struct xattr_handler *btrfs_xattr_handlers[] = {
263#ifdef CONFIG_FS_POSIX_ACL 263#ifdef CONFIG_BTRFS_FS_POSIX_ACL
264 &btrfs_xattr_acl_access_handler, 264 &btrfs_xattr_acl_access_handler,
265 &btrfs_xattr_acl_default_handler, 265 &btrfs_xattr_acl_default_handler,
266#endif 266#endif
diff --git a/fs/coda/psdev.c b/fs/coda/psdev.c
index 0376ac66c44a..be4392ca2098 100644
--- a/fs/coda/psdev.c
+++ b/fs/coda/psdev.c
@@ -22,6 +22,7 @@
22#include <linux/kernel.h> 22#include <linux/kernel.h>
23#include <linux/major.h> 23#include <linux/major.h>
24#include <linux/time.h> 24#include <linux/time.h>
25#include <linux/sched.h>
25#include <linux/slab.h> 26#include <linux/slab.h>
26#include <linux/ioport.h> 27#include <linux/ioport.h>
27#include <linux/fcntl.h> 28#include <linux/fcntl.h>
diff --git a/fs/ecryptfs/Kconfig b/fs/ecryptfs/Kconfig
index 8aadb99b7634..1cd6d9d3e29a 100644
--- a/fs/ecryptfs/Kconfig
+++ b/fs/ecryptfs/Kconfig
@@ -1,8 +1,9 @@
1config ECRYPT_FS 1config ECRYPT_FS
2 tristate "eCrypt filesystem layer support (EXPERIMENTAL)" 2 tristate "eCrypt filesystem layer support (EXPERIMENTAL)"
3 depends on EXPERIMENTAL && KEYS && NET 3 depends on EXPERIMENTAL && KEYS && CRYPTO
4 select CRYPTO_ECB 4 select CRYPTO_ECB
5 select CRYPTO_CBC 5 select CRYPTO_CBC
6 select CRYPTO_MD5
6 help 7 help
7 Encrypted filesystem that operates on the VFS layer. See 8 Encrypted filesystem that operates on the VFS layer. See
8 <file:Documentation/filesystems/ecryptfs.txt> to learn more about 9 <file:Documentation/filesystems/ecryptfs.txt> to learn more about
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
index 101fe4c7b1ee..c6ac85d6c701 100644
--- a/fs/ecryptfs/main.c
+++ b/fs/ecryptfs/main.c
@@ -35,6 +35,7 @@
35#include <linux/key.h> 35#include <linux/key.h>
36#include <linux/parser.h> 36#include <linux/parser.h>
37#include <linux/fs_stack.h> 37#include <linux/fs_stack.h>
38#include <linux/ima.h>
38#include "ecryptfs_kernel.h" 39#include "ecryptfs_kernel.h"
39 40
40/** 41/**
@@ -118,6 +119,7 @@ int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry)
118 const struct cred *cred = current_cred(); 119 const struct cred *cred = current_cred();
119 struct ecryptfs_inode_info *inode_info = 120 struct ecryptfs_inode_info *inode_info =
120 ecryptfs_inode_to_private(ecryptfs_dentry->d_inode); 121 ecryptfs_inode_to_private(ecryptfs_dentry->d_inode);
122 int opened_lower_file = 0;
121 int rc = 0; 123 int rc = 0;
122 124
123 mutex_lock(&inode_info->lower_file_mutex); 125 mutex_lock(&inode_info->lower_file_mutex);
@@ -134,9 +136,12 @@ int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry)
134 "for lower_dentry [0x%p] and lower_mnt [0x%p]; " 136 "for lower_dentry [0x%p] and lower_mnt [0x%p]; "
135 "rc = [%d]\n", lower_dentry, lower_mnt, rc); 137 "rc = [%d]\n", lower_dentry, lower_mnt, rc);
136 inode_info->lower_file = NULL; 138 inode_info->lower_file = NULL;
137 } 139 } else
140 opened_lower_file = 1;
138 } 141 }
139 mutex_unlock(&inode_info->lower_file_mutex); 142 mutex_unlock(&inode_info->lower_file_mutex);
143 if (opened_lower_file)
144 ima_counts_get(inode_info->lower_file);
140 return rc; 145 return rc;
141} 146}
142 147
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 72743d360509..7a520a862f49 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -2321,7 +2321,18 @@ static int ext3_commit_super(struct super_block *sb,
2321 2321
2322 if (!sbh) 2322 if (!sbh)
2323 return error; 2323 return error;
2324 es->s_wtime = cpu_to_le32(get_seconds()); 2324 /*
2325 * If the file system is mounted read-only, don't update the
2326 * superblock write time. This avoids updating the superblock
2327 * write time when we are mounting the root file system
2328 * read/only but we need to replay the journal; at that point,
2329 * for people who are east of GMT and who make their clock
2330 * tick in localtime for Windows bug-for-bug compatibility,
2331 * the clock is set in the future, and this will cause e2fsck
2332 * to complain and force a full file system check.
2333 */
2334 if (!(sb->s_flags & MS_RDONLY))
2335 es->s_wtime = cpu_to_le32(get_seconds());
2325 es->s_free_blocks_count = cpu_to_le32(ext3_count_free_blocks(sb)); 2336 es->s_free_blocks_count = cpu_to_le32(ext3_count_free_blocks(sb));
2326 es->s_free_inodes_count = cpu_to_le32(ext3_count_free_inodes(sb)); 2337 es->s_free_inodes_count = cpu_to_le32(ext3_count_free_inodes(sb));
2327 BUFFER_TRACE(sbh, "marking dirty"); 2338 BUFFER_TRACE(sbh, "marking dirty");
diff --git a/fs/ext4/Kconfig b/fs/ext4/Kconfig
index d5c0ea2e8f2d..9f2d45d75b1a 100644
--- a/fs/ext4/Kconfig
+++ b/fs/ext4/Kconfig
@@ -26,20 +26,6 @@ config EXT4_FS
26 26
27 If unsure, say N. 27 If unsure, say N.
28 28
29config EXT4DEV_COMPAT
30 bool "Enable ext4dev compatibility"
31 depends on EXT4_FS
32 help
33 Starting with 2.6.28, the name of the ext4 filesystem was
34 renamed from ext4dev to ext4. Unfortunately there are some
35 legacy userspace programs (such as klibc's fstype) have
36 "ext4dev" hardcoded.
37
38 To enable backwards compatibility so that systems that are
39 still expecting to mount ext4 filesystems using ext4dev,
40 choose Y here. This feature will go away by 2.6.31, so
41 please arrange to get your userspace programs fixed!
42
43config EXT4_FS_XATTR 29config EXT4_FS_XATTR
44 bool "Ext4 extended attributes" 30 bool "Ext4 extended attributes"
45 depends on EXT4_FS 31 depends on EXT4_FS
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index e227eea23f05..984ca0cb38c3 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -65,6 +65,12 @@ typedef __u32 ext4_lblk_t;
65/* data type for block group number */ 65/* data type for block group number */
66typedef unsigned int ext4_group_t; 66typedef unsigned int ext4_group_t;
67 67
68/*
69 * Flags used in mballoc's allocation_context flags field.
70 *
71 * Also used to show what's going on for debugging purposes when the
72 * flag field is exported via the traceport interface
73 */
68 74
69/* prefer goal again. length */ 75/* prefer goal again. length */
70#define EXT4_MB_HINT_MERGE 0x0001 76#define EXT4_MB_HINT_MERGE 0x0001
@@ -127,6 +133,16 @@ struct mpage_da_data {
127 int pages_written; 133 int pages_written;
128 int retval; 134 int retval;
129}; 135};
136#define DIO_AIO_UNWRITTEN 0x1
137typedef struct ext4_io_end {
138 struct list_head list; /* per-file finished AIO list */
139 struct inode *inode; /* file being written to */
140 unsigned int flag; /* unwritten or not */
141 int error; /* I/O error code */
142 ext4_lblk_t offset; /* offset in the file */
143 size_t size; /* size of the extent */
144 struct work_struct work; /* data work queue */
145} ext4_io_end_t;
130 146
131/* 147/*
132 * Special inodes numbers 148 * Special inodes numbers
@@ -347,7 +363,16 @@ struct ext4_new_group_data {
347 /* Call ext4_da_update_reserve_space() after successfully 363 /* Call ext4_da_update_reserve_space() after successfully
348 allocating the blocks */ 364 allocating the blocks */
349#define EXT4_GET_BLOCKS_UPDATE_RESERVE_SPACE 0x0008 365#define EXT4_GET_BLOCKS_UPDATE_RESERVE_SPACE 0x0008
350 366 /* caller is from the direct IO path, request to creation of an
367 unitialized extents if not allocated, split the uninitialized
368 extent if blocks has been preallocated already*/
369#define EXT4_GET_BLOCKS_DIO 0x0010
370#define EXT4_GET_BLOCKS_CONVERT 0x0020
371#define EXT4_GET_BLOCKS_DIO_CREATE_EXT (EXT4_GET_BLOCKS_DIO|\
372 EXT4_GET_BLOCKS_CREATE_UNINIT_EXT)
373 /* Convert extent to initialized after direct IO complete */
374#define EXT4_GET_BLOCKS_DIO_CONVERT_EXT (EXT4_GET_BLOCKS_CONVERT|\
375 EXT4_GET_BLOCKS_DIO_CREATE_EXT)
351 376
352/* 377/*
353 * ioctl commands 378 * ioctl commands
@@ -500,8 +525,8 @@ struct move_extent {
500static inline __le32 ext4_encode_extra_time(struct timespec *time) 525static inline __le32 ext4_encode_extra_time(struct timespec *time)
501{ 526{
502 return cpu_to_le32((sizeof(time->tv_sec) > 4 ? 527 return cpu_to_le32((sizeof(time->tv_sec) > 4 ?
503 time->tv_sec >> 32 : 0) | 528 (time->tv_sec >> 32) & EXT4_EPOCH_MASK : 0) |
504 ((time->tv_nsec << 2) & EXT4_NSEC_MASK)); 529 ((time->tv_nsec << EXT4_EPOCH_BITS) & EXT4_NSEC_MASK));
505} 530}
506 531
507static inline void ext4_decode_extra_time(struct timespec *time, __le32 extra) 532static inline void ext4_decode_extra_time(struct timespec *time, __le32 extra)
@@ -509,7 +534,7 @@ static inline void ext4_decode_extra_time(struct timespec *time, __le32 extra)
509 if (sizeof(time->tv_sec) > 4) 534 if (sizeof(time->tv_sec) > 4)
510 time->tv_sec |= (__u64)(le32_to_cpu(extra) & EXT4_EPOCH_MASK) 535 time->tv_sec |= (__u64)(le32_to_cpu(extra) & EXT4_EPOCH_MASK)
511 << 32; 536 << 32;
512 time->tv_nsec = (le32_to_cpu(extra) & EXT4_NSEC_MASK) >> 2; 537 time->tv_nsec = (le32_to_cpu(extra) & EXT4_NSEC_MASK) >> EXT4_EPOCH_BITS;
513} 538}
514 539
515#define EXT4_INODE_SET_XTIME(xtime, inode, raw_inode) \ 540#define EXT4_INODE_SET_XTIME(xtime, inode, raw_inode) \
@@ -672,6 +697,11 @@ struct ext4_inode_info {
672 __u16 i_extra_isize; 697 __u16 i_extra_isize;
673 698
674 spinlock_t i_block_reservation_lock; 699 spinlock_t i_block_reservation_lock;
700
701 /* completed async DIOs that might need unwritten extents handling */
702 struct list_head i_aio_dio_complete_list;
703 /* current io_end structure for async DIO write*/
704 ext4_io_end_t *cur_aio_dio;
675}; 705};
676 706
677/* 707/*
@@ -942,18 +972,11 @@ struct ext4_sb_info {
942 unsigned int s_mb_stats; 972 unsigned int s_mb_stats;
943 unsigned int s_mb_order2_reqs; 973 unsigned int s_mb_order2_reqs;
944 unsigned int s_mb_group_prealloc; 974 unsigned int s_mb_group_prealloc;
975 unsigned int s_max_writeback_mb_bump;
945 /* where last allocation was done - for stream allocation */ 976 /* where last allocation was done - for stream allocation */
946 unsigned long s_mb_last_group; 977 unsigned long s_mb_last_group;
947 unsigned long s_mb_last_start; 978 unsigned long s_mb_last_start;
948 979
949 /* history to debug policy */
950 struct ext4_mb_history *s_mb_history;
951 int s_mb_history_cur;
952 int s_mb_history_max;
953 int s_mb_history_num;
954 spinlock_t s_mb_history_lock;
955 int s_mb_history_filter;
956
957 /* stats for buddy allocator */ 980 /* stats for buddy allocator */
958 spinlock_t s_mb_pa_lock; 981 spinlock_t s_mb_pa_lock;
959 atomic_t s_bal_reqs; /* number of reqs with len > 1 */ 982 atomic_t s_bal_reqs; /* number of reqs with len > 1 */
@@ -980,6 +1003,9 @@ struct ext4_sb_info {
980 1003
981 unsigned int s_log_groups_per_flex; 1004 unsigned int s_log_groups_per_flex;
982 struct flex_groups *s_flex_groups; 1005 struct flex_groups *s_flex_groups;
1006
1007 /* workqueue for dio unwritten */
1008 struct workqueue_struct *dio_unwritten_wq;
983}; 1009};
984 1010
985static inline struct ext4_sb_info *EXT4_SB(struct super_block *sb) 1011static inline struct ext4_sb_info *EXT4_SB(struct super_block *sb)
@@ -1397,7 +1423,7 @@ extern int ext4_block_truncate_page(handle_t *handle,
1397 struct address_space *mapping, loff_t from); 1423 struct address_space *mapping, loff_t from);
1398extern int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf); 1424extern int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf);
1399extern qsize_t ext4_get_reserved_space(struct inode *inode); 1425extern qsize_t ext4_get_reserved_space(struct inode *inode);
1400 1426extern int flush_aio_dio_completed_IO(struct inode *inode);
1401/* ioctl.c */ 1427/* ioctl.c */
1402extern long ext4_ioctl(struct file *, unsigned int, unsigned long); 1428extern long ext4_ioctl(struct file *, unsigned int, unsigned long);
1403extern long ext4_compat_ioctl(struct file *, unsigned int, unsigned long); 1429extern long ext4_compat_ioctl(struct file *, unsigned int, unsigned long);
@@ -1699,6 +1725,8 @@ extern void ext4_ext_init(struct super_block *);
1699extern void ext4_ext_release(struct super_block *); 1725extern void ext4_ext_release(struct super_block *);
1700extern long ext4_fallocate(struct inode *inode, int mode, loff_t offset, 1726extern long ext4_fallocate(struct inode *inode, int mode, loff_t offset,
1701 loff_t len); 1727 loff_t len);
1728extern int ext4_convert_unwritten_extents(struct inode *inode, loff_t offset,
1729 loff_t len);
1702extern int ext4_get_blocks(handle_t *handle, struct inode *inode, 1730extern int ext4_get_blocks(handle_t *handle, struct inode *inode,
1703 sector_t block, unsigned int max_blocks, 1731 sector_t block, unsigned int max_blocks,
1704 struct buffer_head *bh, int flags); 1732 struct buffer_head *bh, int flags);
diff --git a/fs/ext4/ext4_extents.h b/fs/ext4/ext4_extents.h
index 61652f1d15e6..2ca686454e87 100644
--- a/fs/ext4/ext4_extents.h
+++ b/fs/ext4/ext4_extents.h
@@ -220,6 +220,11 @@ static inline int ext4_ext_get_actual_len(struct ext4_extent *ext)
220 (le16_to_cpu(ext->ee_len) - EXT_INIT_MAX_LEN)); 220 (le16_to_cpu(ext->ee_len) - EXT_INIT_MAX_LEN));
221} 221}
222 222
223static inline void ext4_ext_mark_initialized(struct ext4_extent *ext)
224{
225 ext->ee_len = cpu_to_le16(ext4_ext_get_actual_len(ext));
226}
227
223extern int ext4_ext_calc_metadata_amount(struct inode *inode, int blocks); 228extern int ext4_ext_calc_metadata_amount(struct inode *inode, int blocks);
224extern ext4_fsblk_t ext_pblock(struct ext4_extent *ex); 229extern ext4_fsblk_t ext_pblock(struct ext4_extent *ex);
225extern ext4_fsblk_t idx_pblock(struct ext4_extent_idx *); 230extern ext4_fsblk_t idx_pblock(struct ext4_extent_idx *);
@@ -235,7 +240,7 @@ extern int ext4_ext_try_to_merge(struct inode *inode,
235 struct ext4_ext_path *path, 240 struct ext4_ext_path *path,
236 struct ext4_extent *); 241 struct ext4_extent *);
237extern unsigned int ext4_ext_check_overlap(struct inode *, struct ext4_extent *, struct ext4_ext_path *); 242extern unsigned int ext4_ext_check_overlap(struct inode *, struct ext4_extent *, struct ext4_ext_path *);
238extern int ext4_ext_insert_extent(handle_t *, struct inode *, struct ext4_ext_path *, struct ext4_extent *); 243extern int ext4_ext_insert_extent(handle_t *, struct inode *, struct ext4_ext_path *, struct ext4_extent *, int);
239extern int ext4_ext_walk_space(struct inode *, ext4_lblk_t, ext4_lblk_t, 244extern int ext4_ext_walk_space(struct inode *, ext4_lblk_t, ext4_lblk_t,
240 ext_prepare_callback, void *); 245 ext_prepare_callback, void *);
241extern struct ext4_ext_path *ext4_ext_find_extent(struct inode *, ext4_lblk_t, 246extern struct ext4_ext_path *ext4_ext_find_extent(struct inode *, ext4_lblk_t,
diff --git a/fs/ext4/ext4_jbd2.h b/fs/ext4/ext4_jbd2.h
index 139fb8cb87e4..a2865980342f 100644
--- a/fs/ext4/ext4_jbd2.h
+++ b/fs/ext4/ext4_jbd2.h
@@ -161,11 +161,13 @@ int __ext4_handle_dirty_metadata(const char *where, handle_t *handle,
161handle_t *ext4_journal_start_sb(struct super_block *sb, int nblocks); 161handle_t *ext4_journal_start_sb(struct super_block *sb, int nblocks);
162int __ext4_journal_stop(const char *where, handle_t *handle); 162int __ext4_journal_stop(const char *where, handle_t *handle);
163 163
164#define EXT4_NOJOURNAL_HANDLE ((handle_t *) 0x1) 164#define EXT4_NOJOURNAL_MAX_REF_COUNT ((unsigned long) 4096)
165 165
166/* Note: Do not use this for NULL handles. This is only to determine if
167 * a properly allocated handle is using a journal or not. */
166static inline int ext4_handle_valid(handle_t *handle) 168static inline int ext4_handle_valid(handle_t *handle)
167{ 169{
168 if (handle == EXT4_NOJOURNAL_HANDLE) 170 if ((unsigned long)handle < EXT4_NOJOURNAL_MAX_REF_COUNT)
169 return 0; 171 return 0;
170 return 1; 172 return 1;
171} 173}
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 7a3832577923..10539e364283 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -723,7 +723,7 @@ err:
723 * insert new index [@logical;@ptr] into the block at @curp; 723 * insert new index [@logical;@ptr] into the block at @curp;
724 * check where to insert: before @curp or after @curp 724 * check where to insert: before @curp or after @curp
725 */ 725 */
726static int ext4_ext_insert_index(handle_t *handle, struct inode *inode, 726int ext4_ext_insert_index(handle_t *handle, struct inode *inode,
727 struct ext4_ext_path *curp, 727 struct ext4_ext_path *curp,
728 int logical, ext4_fsblk_t ptr) 728 int logical, ext4_fsblk_t ptr)
729{ 729{
@@ -1586,7 +1586,7 @@ out:
1586 */ 1586 */
1587int ext4_ext_insert_extent(handle_t *handle, struct inode *inode, 1587int ext4_ext_insert_extent(handle_t *handle, struct inode *inode,
1588 struct ext4_ext_path *path, 1588 struct ext4_ext_path *path,
1589 struct ext4_extent *newext) 1589 struct ext4_extent *newext, int flag)
1590{ 1590{
1591 struct ext4_extent_header *eh; 1591 struct ext4_extent_header *eh;
1592 struct ext4_extent *ex, *fex; 1592 struct ext4_extent *ex, *fex;
@@ -1602,7 +1602,8 @@ int ext4_ext_insert_extent(handle_t *handle, struct inode *inode,
1602 BUG_ON(path[depth].p_hdr == NULL); 1602 BUG_ON(path[depth].p_hdr == NULL);
1603 1603
1604 /* try to insert block into found extent and return */ 1604 /* try to insert block into found extent and return */
1605 if (ex && ext4_can_extents_be_merged(inode, ex, newext)) { 1605 if (ex && (flag != EXT4_GET_BLOCKS_DIO_CREATE_EXT)
1606 && ext4_can_extents_be_merged(inode, ex, newext)) {
1606 ext_debug("append [%d]%d block to %d:[%d]%d (from %llu)\n", 1607 ext_debug("append [%d]%d block to %d:[%d]%d (from %llu)\n",
1607 ext4_ext_is_uninitialized(newext), 1608 ext4_ext_is_uninitialized(newext),
1608 ext4_ext_get_actual_len(newext), 1609 ext4_ext_get_actual_len(newext),
@@ -1722,7 +1723,8 @@ has_space:
1722 1723
1723merge: 1724merge:
1724 /* try to merge extents to the right */ 1725 /* try to merge extents to the right */
1725 ext4_ext_try_to_merge(inode, path, nearex); 1726 if (flag != EXT4_GET_BLOCKS_DIO_CREATE_EXT)
1727 ext4_ext_try_to_merge(inode, path, nearex);
1726 1728
1727 /* try to merge extents to the left */ 1729 /* try to merge extents to the left */
1728 1730
@@ -2378,6 +2380,7 @@ void ext4_ext_init(struct super_block *sb)
2378 */ 2380 */
2379 2381
2380 if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS)) { 2382 if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_EXTENTS)) {
2383#if defined(AGGRESSIVE_TEST) || defined(CHECK_BINSEARCH) || defined(EXTENTS_STATS)
2381 printk(KERN_INFO "EXT4-fs: file extents enabled"); 2384 printk(KERN_INFO "EXT4-fs: file extents enabled");
2382#ifdef AGGRESSIVE_TEST 2385#ifdef AGGRESSIVE_TEST
2383 printk(", aggressive tests"); 2386 printk(", aggressive tests");
@@ -2389,6 +2392,7 @@ void ext4_ext_init(struct super_block *sb)
2389 printk(", stats"); 2392 printk(", stats");
2390#endif 2393#endif
2391 printk("\n"); 2394 printk("\n");
2395#endif
2392#ifdef EXTENTS_STATS 2396#ifdef EXTENTS_STATS
2393 spin_lock_init(&EXT4_SB(sb)->s_ext_stats_lock); 2397 spin_lock_init(&EXT4_SB(sb)->s_ext_stats_lock);
2394 EXT4_SB(sb)->s_ext_min = 1 << 30; 2398 EXT4_SB(sb)->s_ext_min = 1 << 30;
@@ -2490,7 +2494,6 @@ static int ext4_ext_zeroout(struct inode *inode, struct ext4_extent *ex)
2490} 2494}
2491 2495
2492#define EXT4_EXT_ZERO_LEN 7 2496#define EXT4_EXT_ZERO_LEN 7
2493
2494/* 2497/*
2495 * This function is called by ext4_ext_get_blocks() if someone tries to write 2498 * This function is called by ext4_ext_get_blocks() if someone tries to write
2496 * to an uninitialized extent. It may result in splitting the uninitialized 2499 * to an uninitialized extent. It may result in splitting the uninitialized
@@ -2583,7 +2586,8 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
2583 ex3->ee_block = cpu_to_le32(iblock); 2586 ex3->ee_block = cpu_to_le32(iblock);
2584 ext4_ext_store_pblock(ex3, newblock); 2587 ext4_ext_store_pblock(ex3, newblock);
2585 ex3->ee_len = cpu_to_le16(allocated); 2588 ex3->ee_len = cpu_to_le16(allocated);
2586 err = ext4_ext_insert_extent(handle, inode, path, ex3); 2589 err = ext4_ext_insert_extent(handle, inode, path,
2590 ex3, 0);
2587 if (err == -ENOSPC) { 2591 if (err == -ENOSPC) {
2588 err = ext4_ext_zeroout(inode, &orig_ex); 2592 err = ext4_ext_zeroout(inode, &orig_ex);
2589 if (err) 2593 if (err)
@@ -2639,7 +2643,7 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
2639 ext4_ext_store_pblock(ex3, newblock + max_blocks); 2643 ext4_ext_store_pblock(ex3, newblock + max_blocks);
2640 ex3->ee_len = cpu_to_le16(allocated - max_blocks); 2644 ex3->ee_len = cpu_to_le16(allocated - max_blocks);
2641 ext4_ext_mark_uninitialized(ex3); 2645 ext4_ext_mark_uninitialized(ex3);
2642 err = ext4_ext_insert_extent(handle, inode, path, ex3); 2646 err = ext4_ext_insert_extent(handle, inode, path, ex3, 0);
2643 if (err == -ENOSPC) { 2647 if (err == -ENOSPC) {
2644 err = ext4_ext_zeroout(inode, &orig_ex); 2648 err = ext4_ext_zeroout(inode, &orig_ex);
2645 if (err) 2649 if (err)
@@ -2757,7 +2761,7 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
2757 err = ext4_ext_dirty(handle, inode, path + depth); 2761 err = ext4_ext_dirty(handle, inode, path + depth);
2758 goto out; 2762 goto out;
2759insert: 2763insert:
2760 err = ext4_ext_insert_extent(handle, inode, path, &newex); 2764 err = ext4_ext_insert_extent(handle, inode, path, &newex, 0);
2761 if (err == -ENOSPC) { 2765 if (err == -ENOSPC) {
2762 err = ext4_ext_zeroout(inode, &orig_ex); 2766 err = ext4_ext_zeroout(inode, &orig_ex);
2763 if (err) 2767 if (err)
@@ -2785,6 +2789,324 @@ fix_extent_len:
2785} 2789}
2786 2790
2787/* 2791/*
2792 * This function is called by ext4_ext_get_blocks() from
2793 * ext4_get_blocks_dio_write() when DIO to write
2794 * to an uninitialized extent.
2795 *
2796 * Writing to an uninitized extent may result in splitting the uninitialized
2797 * extent into multiple /intialized unintialized extents (up to three)
2798 * There are three possibilities:
2799 * a> There is no split required: Entire extent should be uninitialized
2800 * b> Splits in two extents: Write is happening at either end of the extent
2801 * c> Splits in three extents: Somone is writing in middle of the extent
2802 *
2803 * One of more index blocks maybe needed if the extent tree grow after
2804 * the unintialized extent split. To prevent ENOSPC occur at the IO
2805 * complete, we need to split the uninitialized extent before DIO submit
2806 * the IO. The uninitilized extent called at this time will be split
2807 * into three uninitialized extent(at most). After IO complete, the part
2808 * being filled will be convert to initialized by the end_io callback function
2809 * via ext4_convert_unwritten_extents().
2810 */
2811static int ext4_split_unwritten_extents(handle_t *handle,
2812 struct inode *inode,
2813 struct ext4_ext_path *path,
2814 ext4_lblk_t iblock,
2815 unsigned int max_blocks,
2816 int flags)
2817{
2818 struct ext4_extent *ex, newex, orig_ex;
2819 struct ext4_extent *ex1 = NULL;
2820 struct ext4_extent *ex2 = NULL;
2821 struct ext4_extent *ex3 = NULL;
2822 struct ext4_extent_header *eh;
2823 ext4_lblk_t ee_block;
2824 unsigned int allocated, ee_len, depth;
2825 ext4_fsblk_t newblock;
2826 int err = 0;
2827 int ret = 0;
2828
2829 ext_debug("ext4_split_unwritten_extents: inode %lu,"
2830 "iblock %llu, max_blocks %u\n", inode->i_ino,
2831 (unsigned long long)iblock, max_blocks);
2832 depth = ext_depth(inode);
2833 eh = path[depth].p_hdr;
2834 ex = path[depth].p_ext;
2835 ee_block = le32_to_cpu(ex->ee_block);
2836 ee_len = ext4_ext_get_actual_len(ex);
2837 allocated = ee_len - (iblock - ee_block);
2838 newblock = iblock - ee_block + ext_pblock(ex);
2839 ex2 = ex;
2840 orig_ex.ee_block = ex->ee_block;
2841 orig_ex.ee_len = cpu_to_le16(ee_len);
2842 ext4_ext_store_pblock(&orig_ex, ext_pblock(ex));
2843
2844 /*
2845 * if the entire unintialized extent length less than
2846 * the size of extent to write, there is no need to split
2847 * uninitialized extent
2848 */
2849 if (allocated <= max_blocks)
2850 return ret;
2851
2852 err = ext4_ext_get_access(handle, inode, path + depth);
2853 if (err)
2854 goto out;
2855 /* ex1: ee_block to iblock - 1 : uninitialized */
2856 if (iblock > ee_block) {
2857 ex1 = ex;
2858 ex1->ee_len = cpu_to_le16(iblock - ee_block);
2859 ext4_ext_mark_uninitialized(ex1);
2860 ex2 = &newex;
2861 }
2862 /*
2863 * for sanity, update the length of the ex2 extent before
2864 * we insert ex3, if ex1 is NULL. This is to avoid temporary
2865 * overlap of blocks.
2866 */
2867 if (!ex1 && allocated > max_blocks)
2868 ex2->ee_len = cpu_to_le16(max_blocks);
2869 /* ex3: to ee_block + ee_len : uninitialised */
2870 if (allocated > max_blocks) {
2871 unsigned int newdepth;
2872 ex3 = &newex;
2873 ex3->ee_block = cpu_to_le32(iblock + max_blocks);
2874 ext4_ext_store_pblock(ex3, newblock + max_blocks);
2875 ex3->ee_len = cpu_to_le16(allocated - max_blocks);
2876 ext4_ext_mark_uninitialized(ex3);
2877 err = ext4_ext_insert_extent(handle, inode, path, ex3, flags);
2878 if (err == -ENOSPC) {
2879 err = ext4_ext_zeroout(inode, &orig_ex);
2880 if (err)
2881 goto fix_extent_len;
2882 /* update the extent length and mark as initialized */
2883 ex->ee_block = orig_ex.ee_block;
2884 ex->ee_len = orig_ex.ee_len;
2885 ext4_ext_store_pblock(ex, ext_pblock(&orig_ex));
2886 ext4_ext_dirty(handle, inode, path + depth);
2887 /* zeroed the full extent */
2888 /* blocks available from iblock */
2889 return allocated;
2890
2891 } else if (err)
2892 goto fix_extent_len;
2893 /*
2894 * The depth, and hence eh & ex might change
2895 * as part of the insert above.
2896 */
2897 newdepth = ext_depth(inode);
2898 /*
2899 * update the extent length after successful insert of the
2900 * split extent
2901 */
2902 orig_ex.ee_len = cpu_to_le16(ee_len -
2903 ext4_ext_get_actual_len(ex3));
2904 depth = newdepth;
2905 ext4_ext_drop_refs(path);
2906 path = ext4_ext_find_extent(inode, iblock, path);
2907 if (IS_ERR(path)) {
2908 err = PTR_ERR(path);
2909 goto out;
2910 }
2911 eh = path[depth].p_hdr;
2912 ex = path[depth].p_ext;
2913 if (ex2 != &newex)
2914 ex2 = ex;
2915
2916 err = ext4_ext_get_access(handle, inode, path + depth);
2917 if (err)
2918 goto out;
2919
2920 allocated = max_blocks;
2921 }
2922 /*
2923 * If there was a change of depth as part of the
2924 * insertion of ex3 above, we need to update the length
2925 * of the ex1 extent again here
2926 */
2927 if (ex1 && ex1 != ex) {
2928 ex1 = ex;
2929 ex1->ee_len = cpu_to_le16(iblock - ee_block);
2930 ext4_ext_mark_uninitialized(ex1);
2931 ex2 = &newex;
2932 }
2933 /*
2934 * ex2: iblock to iblock + maxblocks-1 : to be direct IO written,
2935 * uninitialised still.
2936 */
2937 ex2->ee_block = cpu_to_le32(iblock);
2938 ext4_ext_store_pblock(ex2, newblock);
2939 ex2->ee_len = cpu_to_le16(allocated);
2940 ext4_ext_mark_uninitialized(ex2);
2941 if (ex2 != ex)
2942 goto insert;
2943 /* Mark modified extent as dirty */
2944 err = ext4_ext_dirty(handle, inode, path + depth);
2945 ext_debug("out here\n");
2946 goto out;
2947insert:
2948 err = ext4_ext_insert_extent(handle, inode, path, &newex, flags);
2949 if (err == -ENOSPC) {
2950 err = ext4_ext_zeroout(inode, &orig_ex);
2951 if (err)
2952 goto fix_extent_len;
2953 /* update the extent length and mark as initialized */
2954 ex->ee_block = orig_ex.ee_block;
2955 ex->ee_len = orig_ex.ee_len;
2956 ext4_ext_store_pblock(ex, ext_pblock(&orig_ex));
2957 ext4_ext_dirty(handle, inode, path + depth);
2958 /* zero out the first half */
2959 return allocated;
2960 } else if (err)
2961 goto fix_extent_len;
2962out:
2963 ext4_ext_show_leaf(inode, path);
2964 return err ? err : allocated;
2965
2966fix_extent_len:
2967 ex->ee_block = orig_ex.ee_block;
2968 ex->ee_len = orig_ex.ee_len;
2969 ext4_ext_store_pblock(ex, ext_pblock(&orig_ex));
2970 ext4_ext_mark_uninitialized(ex);
2971 ext4_ext_dirty(handle, inode, path + depth);
2972 return err;
2973}
2974static int ext4_convert_unwritten_extents_dio(handle_t *handle,
2975 struct inode *inode,
2976 struct ext4_ext_path *path)
2977{
2978 struct ext4_extent *ex;
2979 struct ext4_extent_header *eh;
2980 int depth;
2981 int err = 0;
2982 int ret = 0;
2983
2984 depth = ext_depth(inode);
2985 eh = path[depth].p_hdr;
2986 ex = path[depth].p_ext;
2987
2988 err = ext4_ext_get_access(handle, inode, path + depth);
2989 if (err)
2990 goto out;
2991 /* first mark the extent as initialized */
2992 ext4_ext_mark_initialized(ex);
2993
2994 /*
2995 * We have to see if it can be merged with the extent
2996 * on the left.
2997 */
2998 if (ex > EXT_FIRST_EXTENT(eh)) {
2999 /*
3000 * To merge left, pass "ex - 1" to try_to_merge(),
3001 * since it merges towards right _only_.
3002 */
3003 ret = ext4_ext_try_to_merge(inode, path, ex - 1);
3004 if (ret) {
3005 err = ext4_ext_correct_indexes(handle, inode, path);
3006 if (err)
3007 goto out;
3008 depth = ext_depth(inode);
3009 ex--;
3010 }
3011 }
3012 /*
3013 * Try to Merge towards right.
3014 */
3015 ret = ext4_ext_try_to_merge(inode, path, ex);
3016 if (ret) {
3017 err = ext4_ext_correct_indexes(handle, inode, path);
3018 if (err)
3019 goto out;
3020 depth = ext_depth(inode);
3021 }
3022 /* Mark modified extent as dirty */
3023 err = ext4_ext_dirty(handle, inode, path + depth);
3024out:
3025 ext4_ext_show_leaf(inode, path);
3026 return err;
3027}
3028
3029static int
3030ext4_ext_handle_uninitialized_extents(handle_t *handle, struct inode *inode,
3031 ext4_lblk_t iblock, unsigned int max_blocks,
3032 struct ext4_ext_path *path, int flags,
3033 unsigned int allocated, struct buffer_head *bh_result,
3034 ext4_fsblk_t newblock)
3035{
3036 int ret = 0;
3037 int err = 0;
3038 ext4_io_end_t *io = EXT4_I(inode)->cur_aio_dio;
3039
3040 ext_debug("ext4_ext_handle_uninitialized_extents: inode %lu, logical"
3041 "block %llu, max_blocks %u, flags %d, allocated %u",
3042 inode->i_ino, (unsigned long long)iblock, max_blocks,
3043 flags, allocated);
3044 ext4_ext_show_leaf(inode, path);
3045
3046 /* DIO get_block() before submit the IO, split the extent */
3047 if (flags == EXT4_GET_BLOCKS_DIO_CREATE_EXT) {
3048 ret = ext4_split_unwritten_extents(handle,
3049 inode, path, iblock,
3050 max_blocks, flags);
3051 /* flag the io_end struct that we need convert when IO done */
3052 if (io)
3053 io->flag = DIO_AIO_UNWRITTEN;
3054 goto out;
3055 }
3056 /* DIO end_io complete, convert the filled extent to written */
3057 if (flags == EXT4_GET_BLOCKS_DIO_CONVERT_EXT) {
3058 ret = ext4_convert_unwritten_extents_dio(handle, inode,
3059 path);
3060 goto out2;
3061 }
3062 /* buffered IO case */
3063 /*
3064 * repeat fallocate creation request
3065 * we already have an unwritten extent
3066 */
3067 if (flags & EXT4_GET_BLOCKS_UNINIT_EXT)
3068 goto map_out;
3069
3070 /* buffered READ or buffered write_begin() lookup */
3071 if ((flags & EXT4_GET_BLOCKS_CREATE) == 0) {
3072 /*
3073 * We have blocks reserved already. We
3074 * return allocated blocks so that delalloc
3075 * won't do block reservation for us. But
3076 * the buffer head will be unmapped so that
3077 * a read from the block returns 0s.
3078 */
3079 set_buffer_unwritten(bh_result);
3080 goto out1;
3081 }
3082
3083 /* buffered write, writepage time, convert*/
3084 ret = ext4_ext_convert_to_initialized(handle, inode,
3085 path, iblock,
3086 max_blocks);
3087out:
3088 if (ret <= 0) {
3089 err = ret;
3090 goto out2;
3091 } else
3092 allocated = ret;
3093 set_buffer_new(bh_result);
3094map_out:
3095 set_buffer_mapped(bh_result);
3096out1:
3097 if (allocated > max_blocks)
3098 allocated = max_blocks;
3099 ext4_ext_show_leaf(inode, path);
3100 bh_result->b_bdev = inode->i_sb->s_bdev;
3101 bh_result->b_blocknr = newblock;
3102out2:
3103 if (path) {
3104 ext4_ext_drop_refs(path);
3105 kfree(path);
3106 }
3107 return err ? err : allocated;
3108}
3109/*
2788 * Block allocation/map/preallocation routine for extents based files 3110 * Block allocation/map/preallocation routine for extents based files
2789 * 3111 *
2790 * 3112 *
@@ -2814,6 +3136,7 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
2814 int err = 0, depth, ret, cache_type; 3136 int err = 0, depth, ret, cache_type;
2815 unsigned int allocated = 0; 3137 unsigned int allocated = 0;
2816 struct ext4_allocation_request ar; 3138 struct ext4_allocation_request ar;
3139 ext4_io_end_t *io = EXT4_I(inode)->cur_aio_dio;
2817 3140
2818 __clear_bit(BH_New, &bh_result->b_state); 3141 __clear_bit(BH_New, &bh_result->b_state);
2819 ext_debug("blocks %u/%u requested for inode %lu\n", 3142 ext_debug("blocks %u/%u requested for inode %lu\n",
@@ -2889,33 +3212,10 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
2889 EXT4_EXT_CACHE_EXTENT); 3212 EXT4_EXT_CACHE_EXTENT);
2890 goto out; 3213 goto out;
2891 } 3214 }
2892 if (flags & EXT4_GET_BLOCKS_UNINIT_EXT) 3215 ret = ext4_ext_handle_uninitialized_extents(handle,
2893 goto out; 3216 inode, iblock, max_blocks, path,
2894 if ((flags & EXT4_GET_BLOCKS_CREATE) == 0) { 3217 flags, allocated, bh_result, newblock);
2895 if (allocated > max_blocks) 3218 return ret;
2896 allocated = max_blocks;
2897 /*
2898 * We have blocks reserved already. We
2899 * return allocated blocks so that delalloc
2900 * won't do block reservation for us. But
2901 * the buffer head will be unmapped so that
2902 * a read from the block returns 0s.
2903 */
2904 set_buffer_unwritten(bh_result);
2905 bh_result->b_bdev = inode->i_sb->s_bdev;
2906 bh_result->b_blocknr = newblock;
2907 goto out2;
2908 }
2909
2910 ret = ext4_ext_convert_to_initialized(handle, inode,
2911 path, iblock,
2912 max_blocks);
2913 if (ret <= 0) {
2914 err = ret;
2915 goto out2;
2916 } else
2917 allocated = ret;
2918 goto outnew;
2919 } 3219 }
2920 } 3220 }
2921 3221
@@ -2986,9 +3286,21 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
2986 /* try to insert new extent into found leaf and return */ 3286 /* try to insert new extent into found leaf and return */
2987 ext4_ext_store_pblock(&newex, newblock); 3287 ext4_ext_store_pblock(&newex, newblock);
2988 newex.ee_len = cpu_to_le16(ar.len); 3288 newex.ee_len = cpu_to_le16(ar.len);
2989 if (flags & EXT4_GET_BLOCKS_UNINIT_EXT) /* Mark uninitialized */ 3289 /* Mark uninitialized */
3290 if (flags & EXT4_GET_BLOCKS_UNINIT_EXT){
2990 ext4_ext_mark_uninitialized(&newex); 3291 ext4_ext_mark_uninitialized(&newex);
2991 err = ext4_ext_insert_extent(handle, inode, path, &newex); 3292 /*
3293 * io_end structure was created for every async
3294 * direct IO write to the middle of the file.
3295 * To avoid unecessary convertion for every aio dio rewrite
3296 * to the mid of file, here we flag the IO that is really
3297 * need the convertion.
3298 *
3299 */
3300 if (io && flags == EXT4_GET_BLOCKS_DIO_CREATE_EXT)
3301 io->flag = DIO_AIO_UNWRITTEN;
3302 }
3303 err = ext4_ext_insert_extent(handle, inode, path, &newex, flags);
2992 if (err) { 3304 if (err) {
2993 /* free data blocks we just allocated */ 3305 /* free data blocks we just allocated */
2994 /* not a good idea to call discard here directly, 3306 /* not a good idea to call discard here directly,
@@ -3002,7 +3314,6 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
3002 /* previous routine could use block we allocated */ 3314 /* previous routine could use block we allocated */
3003 newblock = ext_pblock(&newex); 3315 newblock = ext_pblock(&newex);
3004 allocated = ext4_ext_get_actual_len(&newex); 3316 allocated = ext4_ext_get_actual_len(&newex);
3005outnew:
3006 set_buffer_new(bh_result); 3317 set_buffer_new(bh_result);
3007 3318
3008 /* Cache only when it is _not_ an uninitialized extent */ 3319 /* Cache only when it is _not_ an uninitialized extent */
@@ -3201,6 +3512,63 @@ retry:
3201} 3512}
3202 3513
3203/* 3514/*
3515 * This function convert a range of blocks to written extents
3516 * The caller of this function will pass the start offset and the size.
3517 * all unwritten extents within this range will be converted to
3518 * written extents.
3519 *
3520 * This function is called from the direct IO end io call back
3521 * function, to convert the fallocated extents after IO is completed.
3522 */
3523int ext4_convert_unwritten_extents(struct inode *inode, loff_t offset,
3524 loff_t len)
3525{
3526 handle_t *handle;
3527 ext4_lblk_t block;
3528 unsigned int max_blocks;
3529 int ret = 0;
3530 int ret2 = 0;
3531 struct buffer_head map_bh;
3532 unsigned int credits, blkbits = inode->i_blkbits;
3533
3534 block = offset >> blkbits;
3535 /*
3536 * We can't just convert len to max_blocks because
3537 * If blocksize = 4096 offset = 3072 and len = 2048
3538 */
3539 max_blocks = (EXT4_BLOCK_ALIGN(len + offset, blkbits) >> blkbits)
3540 - block;
3541 /*
3542 * credits to insert 1 extent into extent tree
3543 */
3544 credits = ext4_chunk_trans_blocks(inode, max_blocks);
3545 while (ret >= 0 && ret < max_blocks) {
3546 block = block + ret;
3547 max_blocks = max_blocks - ret;
3548 handle = ext4_journal_start(inode, credits);
3549 if (IS_ERR(handle)) {
3550 ret = PTR_ERR(handle);
3551 break;
3552 }
3553 map_bh.b_state = 0;
3554 ret = ext4_get_blocks(handle, inode, block,
3555 max_blocks, &map_bh,
3556 EXT4_GET_BLOCKS_DIO_CONVERT_EXT);
3557 if (ret <= 0) {
3558 WARN_ON(ret <= 0);
3559 printk(KERN_ERR "%s: ext4_ext_get_blocks "
3560 "returned error inode#%lu, block=%u, "
3561 "max_blocks=%u", __func__,
3562 inode->i_ino, block, max_blocks);
3563 }
3564 ext4_mark_inode_dirty(handle, inode);
3565 ret2 = ext4_journal_stop(handle);
3566 if (ret <= 0 || ret2 )
3567 break;
3568 }
3569 return ret > 0 ? ret2 : ret;
3570}
3571/*
3204 * Callback function called for each extent to gather FIEMAP information. 3572 * Callback function called for each extent to gather FIEMAP information.
3205 */ 3573 */
3206static int ext4_ext_fiemap_cb(struct inode *inode, struct ext4_ext_path *path, 3574static int ext4_ext_fiemap_cb(struct inode *inode, struct ext4_ext_path *path,
diff --git a/fs/ext4/fsync.c b/fs/ext4/fsync.c
index 07475740b512..2b1531266ee2 100644
--- a/fs/ext4/fsync.c
+++ b/fs/ext4/fsync.c
@@ -44,6 +44,8 @@
44 * 44 *
45 * What we do is just kick off a commit and wait on it. This will snapshot the 45 * What we do is just kick off a commit and wait on it. This will snapshot the
46 * inode to disk. 46 * inode to disk.
47 *
48 * i_mutex lock is held when entering and exiting this function
47 */ 49 */
48 50
49int ext4_sync_file(struct file *file, struct dentry *dentry, int datasync) 51int ext4_sync_file(struct file *file, struct dentry *dentry, int datasync)
@@ -56,6 +58,9 @@ int ext4_sync_file(struct file *file, struct dentry *dentry, int datasync)
56 58
57 trace_ext4_sync_file(file, dentry, datasync); 59 trace_ext4_sync_file(file, dentry, datasync);
58 60
61 ret = flush_aio_dio_completed_IO(inode);
62 if (ret < 0)
63 goto out;
59 /* 64 /*
60 * data=writeback: 65 * data=writeback:
61 * The caller's filemap_fdatawrite()/wait will sync the data. 66 * The caller's filemap_fdatawrite()/wait will sync the data.
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 064746fad581..5c5bc5dafff8 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -37,6 +37,7 @@
37#include <linux/namei.h> 37#include <linux/namei.h>
38#include <linux/uio.h> 38#include <linux/uio.h>
39#include <linux/bio.h> 39#include <linux/bio.h>
40#include <linux/workqueue.h>
40 41
41#include "ext4_jbd2.h" 42#include "ext4_jbd2.h"
42#include "xattr.h" 43#include "xattr.h"
@@ -1145,6 +1146,64 @@ static int check_block_validity(struct inode *inode, const char *msg,
1145} 1146}
1146 1147
1147/* 1148/*
1149 * Return the number of contiguous dirty pages in a given inode
1150 * starting at page frame idx.
1151 */
1152static pgoff_t ext4_num_dirty_pages(struct inode *inode, pgoff_t idx,
1153 unsigned int max_pages)
1154{
1155 struct address_space *mapping = inode->i_mapping;
1156 pgoff_t index;
1157 struct pagevec pvec;
1158 pgoff_t num = 0;
1159 int i, nr_pages, done = 0;
1160
1161 if (max_pages == 0)
1162 return 0;
1163 pagevec_init(&pvec, 0);
1164 while (!done) {
1165 index = idx;
1166 nr_pages = pagevec_lookup_tag(&pvec, mapping, &index,
1167 PAGECACHE_TAG_DIRTY,
1168 (pgoff_t)PAGEVEC_SIZE);
1169 if (nr_pages == 0)
1170 break;
1171 for (i = 0; i < nr_pages; i++) {
1172 struct page *page = pvec.pages[i];
1173 struct buffer_head *bh, *head;
1174
1175 lock_page(page);
1176 if (unlikely(page->mapping != mapping) ||
1177 !PageDirty(page) ||
1178 PageWriteback(page) ||
1179 page->index != idx) {
1180 done = 1;
1181 unlock_page(page);
1182 break;
1183 }
1184 if (page_has_buffers(page)) {
1185 bh = head = page_buffers(page);
1186 do {
1187 if (!buffer_delay(bh) &&
1188 !buffer_unwritten(bh))
1189 done = 1;
1190 bh = bh->b_this_page;
1191 } while (!done && (bh != head));
1192 }
1193 unlock_page(page);
1194 if (done)
1195 break;
1196 idx++;
1197 num++;
1198 if (num >= max_pages)
1199 break;
1200 }
1201 pagevec_release(&pvec);
1202 }
1203 return num;
1204}
1205
1206/*
1148 * The ext4_get_blocks() function tries to look up the requested blocks, 1207 * The ext4_get_blocks() function tries to look up the requested blocks,
1149 * and returns if the blocks are already mapped. 1208 * and returns if the blocks are already mapped.
1150 * 1209 *
@@ -1175,6 +1234,9 @@ int ext4_get_blocks(handle_t *handle, struct inode *inode, sector_t block,
1175 clear_buffer_mapped(bh); 1234 clear_buffer_mapped(bh);
1176 clear_buffer_unwritten(bh); 1235 clear_buffer_unwritten(bh);
1177 1236
1237 ext_debug("ext4_get_blocks(): inode %lu, flag %d, max_blocks %u,"
1238 "logical block %lu\n", inode->i_ino, flags, max_blocks,
1239 (unsigned long)block);
1178 /* 1240 /*
1179 * Try to see if we can get the block without requesting a new 1241 * Try to see if we can get the block without requesting a new
1180 * file system block. 1242 * file system block.
@@ -1796,11 +1858,11 @@ repeat:
1796 1858
1797 if (ext4_claim_free_blocks(sbi, total)) { 1859 if (ext4_claim_free_blocks(sbi, total)) {
1798 spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); 1860 spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
1861 vfs_dq_release_reservation_block(inode, total);
1799 if (ext4_should_retry_alloc(inode->i_sb, &retries)) { 1862 if (ext4_should_retry_alloc(inode->i_sb, &retries)) {
1800 yield(); 1863 yield();
1801 goto repeat; 1864 goto repeat;
1802 } 1865 }
1803 vfs_dq_release_reservation_block(inode, total);
1804 return -ENOSPC; 1866 return -ENOSPC;
1805 } 1867 }
1806 EXT4_I(inode)->i_reserved_data_blocks += nrblocks; 1868 EXT4_I(inode)->i_reserved_data_blocks += nrblocks;
@@ -2092,18 +2154,18 @@ static void ext4_da_block_invalidatepages(struct mpage_da_data *mpd,
2092static void ext4_print_free_blocks(struct inode *inode) 2154static void ext4_print_free_blocks(struct inode *inode)
2093{ 2155{
2094 struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); 2156 struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
2095 printk(KERN_EMERG "Total free blocks count %lld\n", 2157 printk(KERN_CRIT "Total free blocks count %lld\n",
2096 ext4_count_free_blocks(inode->i_sb)); 2158 ext4_count_free_blocks(inode->i_sb));
2097 printk(KERN_EMERG "Free/Dirty block details\n"); 2159 printk(KERN_CRIT "Free/Dirty block details\n");
2098 printk(KERN_EMERG "free_blocks=%lld\n", 2160 printk(KERN_CRIT "free_blocks=%lld\n",
2099 (long long)percpu_counter_sum(&sbi->s_freeblocks_counter)); 2161 (long long) percpu_counter_sum(&sbi->s_freeblocks_counter));
2100 printk(KERN_EMERG "dirty_blocks=%lld\n", 2162 printk(KERN_CRIT "dirty_blocks=%lld\n",
2101 (long long)percpu_counter_sum(&sbi->s_dirtyblocks_counter)); 2163 (long long) percpu_counter_sum(&sbi->s_dirtyblocks_counter));
2102 printk(KERN_EMERG "Block reservation details\n"); 2164 printk(KERN_CRIT "Block reservation details\n");
2103 printk(KERN_EMERG "i_reserved_data_blocks=%u\n", 2165 printk(KERN_CRIT "i_reserved_data_blocks=%u\n",
2104 EXT4_I(inode)->i_reserved_data_blocks); 2166 EXT4_I(inode)->i_reserved_data_blocks);
2105 printk(KERN_EMERG "i_reserved_meta_blocks=%u\n", 2167 printk(KERN_CRIT "i_reserved_meta_blocks=%u\n",
2106 EXT4_I(inode)->i_reserved_meta_blocks); 2168 EXT4_I(inode)->i_reserved_meta_blocks);
2107 return; 2169 return;
2108} 2170}
2109 2171
@@ -2189,14 +2251,14 @@ static int mpage_da_map_blocks(struct mpage_da_data *mpd)
2189 * writepage and writepages will again try to write 2251 * writepage and writepages will again try to write
2190 * the same. 2252 * the same.
2191 */ 2253 */
2192 printk(KERN_EMERG "%s block allocation failed for inode %lu " 2254 ext4_msg(mpd->inode->i_sb, KERN_CRIT,
2193 "at logical offset %llu with max blocks " 2255 "delayed block allocation failed for inode %lu at "
2194 "%zd with error %d\n", 2256 "logical offset %llu with max blocks %zd with "
2195 __func__, mpd->inode->i_ino, 2257 "error %d\n", mpd->inode->i_ino,
2196 (unsigned long long)next, 2258 (unsigned long long) next,
2197 mpd->b_size >> mpd->inode->i_blkbits, err); 2259 mpd->b_size >> mpd->inode->i_blkbits, err);
2198 printk(KERN_EMERG "This should not happen.!! " 2260 printk(KERN_CRIT "This should not happen!! "
2199 "Data will be lost\n"); 2261 "Data will be lost\n");
2200 if (err == -ENOSPC) { 2262 if (err == -ENOSPC) {
2201 ext4_print_free_blocks(mpd->inode); 2263 ext4_print_free_blocks(mpd->inode);
2202 } 2264 }
@@ -2743,8 +2805,10 @@ static int ext4_da_writepages(struct address_space *mapping,
2743 int no_nrwrite_index_update; 2805 int no_nrwrite_index_update;
2744 int pages_written = 0; 2806 int pages_written = 0;
2745 long pages_skipped; 2807 long pages_skipped;
2808 unsigned int max_pages;
2746 int range_cyclic, cycled = 1, io_done = 0; 2809 int range_cyclic, cycled = 1, io_done = 0;
2747 int needed_blocks, ret = 0, nr_to_writebump = 0; 2810 int needed_blocks, ret = 0;
2811 long desired_nr_to_write, nr_to_writebump = 0;
2748 loff_t range_start = wbc->range_start; 2812 loff_t range_start = wbc->range_start;
2749 struct ext4_sb_info *sbi = EXT4_SB(mapping->host->i_sb); 2813 struct ext4_sb_info *sbi = EXT4_SB(mapping->host->i_sb);
2750 2814
@@ -2771,16 +2835,6 @@ static int ext4_da_writepages(struct address_space *mapping,
2771 if (unlikely(sbi->s_mount_flags & EXT4_MF_FS_ABORTED)) 2835 if (unlikely(sbi->s_mount_flags & EXT4_MF_FS_ABORTED))
2772 return -EROFS; 2836 return -EROFS;
2773 2837
2774 /*
2775 * Make sure nr_to_write is >= sbi->s_mb_stream_request
2776 * This make sure small files blocks are allocated in
2777 * single attempt. This ensure that small files
2778 * get less fragmented.
2779 */
2780 if (wbc->nr_to_write < sbi->s_mb_stream_request) {
2781 nr_to_writebump = sbi->s_mb_stream_request - wbc->nr_to_write;
2782 wbc->nr_to_write = sbi->s_mb_stream_request;
2783 }
2784 if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX) 2838 if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX)
2785 range_whole = 1; 2839 range_whole = 1;
2786 2840
@@ -2795,6 +2849,36 @@ static int ext4_da_writepages(struct address_space *mapping,
2795 } else 2849 } else
2796 index = wbc->range_start >> PAGE_CACHE_SHIFT; 2850 index = wbc->range_start >> PAGE_CACHE_SHIFT;
2797 2851
2852 /*
2853 * This works around two forms of stupidity. The first is in
2854 * the writeback code, which caps the maximum number of pages
2855 * written to be 1024 pages. This is wrong on multiple
2856 * levels; different architectues have a different page size,
2857 * which changes the maximum amount of data which gets
2858 * written. Secondly, 4 megabytes is way too small. XFS
2859 * forces this value to be 16 megabytes by multiplying
2860 * nr_to_write parameter by four, and then relies on its
2861 * allocator to allocate larger extents to make them
2862 * contiguous. Unfortunately this brings us to the second
2863 * stupidity, which is that ext4's mballoc code only allocates
2864 * at most 2048 blocks. So we force contiguous writes up to
2865 * the number of dirty blocks in the inode, or
2866 * sbi->max_writeback_mb_bump whichever is smaller.
2867 */
2868 max_pages = sbi->s_max_writeback_mb_bump << (20 - PAGE_CACHE_SHIFT);
2869 if (!range_cyclic && range_whole)
2870 desired_nr_to_write = wbc->nr_to_write * 8;
2871 else
2872 desired_nr_to_write = ext4_num_dirty_pages(inode, index,
2873 max_pages);
2874 if (desired_nr_to_write > max_pages)
2875 desired_nr_to_write = max_pages;
2876
2877 if (wbc->nr_to_write < desired_nr_to_write) {
2878 nr_to_writebump = desired_nr_to_write - wbc->nr_to_write;
2879 wbc->nr_to_write = desired_nr_to_write;
2880 }
2881
2798 mpd.wbc = wbc; 2882 mpd.wbc = wbc;
2799 mpd.inode = mapping->host; 2883 mpd.inode = mapping->host;
2800 2884
@@ -2822,10 +2906,9 @@ retry:
2822 handle = ext4_journal_start(inode, needed_blocks); 2906 handle = ext4_journal_start(inode, needed_blocks);
2823 if (IS_ERR(handle)) { 2907 if (IS_ERR(handle)) {
2824 ret = PTR_ERR(handle); 2908 ret = PTR_ERR(handle);
2825 printk(KERN_CRIT "%s: jbd2_start: " 2909 ext4_msg(inode->i_sb, KERN_CRIT, "%s: jbd2_start: "
2826 "%ld pages, ino %lu; err %d\n", __func__, 2910 "%ld pages, ino %lu; err %d\n", __func__,
2827 wbc->nr_to_write, inode->i_ino, ret); 2911 wbc->nr_to_write, inode->i_ino, ret);
2828 dump_stack();
2829 goto out_writepages; 2912 goto out_writepages;
2830 } 2913 }
2831 2914
@@ -2897,9 +2980,10 @@ retry:
2897 goto retry; 2980 goto retry;
2898 } 2981 }
2899 if (pages_skipped != wbc->pages_skipped) 2982 if (pages_skipped != wbc->pages_skipped)
2900 printk(KERN_EMERG "This should not happen leaving %s " 2983 ext4_msg(inode->i_sb, KERN_CRIT,
2901 "with nr_to_write = %ld ret = %d\n", 2984 "This should not happen leaving %s "
2902 __func__, wbc->nr_to_write, ret); 2985 "with nr_to_write = %ld ret = %d\n",
2986 __func__, wbc->nr_to_write, ret);
2903 2987
2904 /* Update index */ 2988 /* Update index */
2905 index += pages_written; 2989 index += pages_written;
@@ -2914,7 +2998,8 @@ retry:
2914out_writepages: 2998out_writepages:
2915 if (!no_nrwrite_index_update) 2999 if (!no_nrwrite_index_update)
2916 wbc->no_nrwrite_index_update = 0; 3000 wbc->no_nrwrite_index_update = 0;
2917 wbc->nr_to_write -= nr_to_writebump; 3001 if (wbc->nr_to_write > nr_to_writebump)
3002 wbc->nr_to_write -= nr_to_writebump;
2918 wbc->range_start = range_start; 3003 wbc->range_start = range_start;
2919 trace_ext4_da_writepages_result(inode, wbc, ret, pages_written); 3004 trace_ext4_da_writepages_result(inode, wbc, ret, pages_written);
2920 return ret; 3005 return ret;
@@ -3272,6 +3357,8 @@ static int ext4_releasepage(struct page *page, gfp_t wait)
3272} 3357}
3273 3358
3274/* 3359/*
3360 * O_DIRECT for ext3 (or indirect map) based files
3361 *
3275 * If the O_DIRECT write will extend the file then add this inode to the 3362 * If the O_DIRECT write will extend the file then add this inode to the
3276 * orphan list. So recovery will truncate it back to the original size 3363 * orphan list. So recovery will truncate it back to the original size
3277 * if the machine crashes during the write. 3364 * if the machine crashes during the write.
@@ -3280,7 +3367,7 @@ static int ext4_releasepage(struct page *page, gfp_t wait)
3280 * crashes then stale disk data _may_ be exposed inside the file. But current 3367 * crashes then stale disk data _may_ be exposed inside the file. But current
3281 * VFS code falls back into buffered path in that case so we are safe. 3368 * VFS code falls back into buffered path in that case so we are safe.
3282 */ 3369 */
3283static ssize_t ext4_direct_IO(int rw, struct kiocb *iocb, 3370static ssize_t ext4_ind_direct_IO(int rw, struct kiocb *iocb,
3284 const struct iovec *iov, loff_t offset, 3371 const struct iovec *iov, loff_t offset,
3285 unsigned long nr_segs) 3372 unsigned long nr_segs)
3286{ 3373{
@@ -3291,6 +3378,7 @@ static ssize_t ext4_direct_IO(int rw, struct kiocb *iocb,
3291 ssize_t ret; 3378 ssize_t ret;
3292 int orphan = 0; 3379 int orphan = 0;
3293 size_t count = iov_length(iov, nr_segs); 3380 size_t count = iov_length(iov, nr_segs);
3381 int retries = 0;
3294 3382
3295 if (rw == WRITE) { 3383 if (rw == WRITE) {
3296 loff_t final_size = offset + count; 3384 loff_t final_size = offset + count;
@@ -3313,9 +3401,12 @@ static ssize_t ext4_direct_IO(int rw, struct kiocb *iocb,
3313 } 3401 }
3314 } 3402 }
3315 3403
3404retry:
3316 ret = blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov, 3405 ret = blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
3317 offset, nr_segs, 3406 offset, nr_segs,
3318 ext4_get_block, NULL); 3407 ext4_get_block, NULL);
3408 if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
3409 goto retry;
3319 3410
3320 if (orphan) { 3411 if (orphan) {
3321 int err; 3412 int err;
@@ -3354,6 +3445,359 @@ out:
3354 return ret; 3445 return ret;
3355} 3446}
3356 3447
3448/* Maximum number of blocks we map for direct IO at once. */
3449
3450static int ext4_get_block_dio_write(struct inode *inode, sector_t iblock,
3451 struct buffer_head *bh_result, int create)
3452{
3453 handle_t *handle = NULL;
3454 int ret = 0;
3455 unsigned max_blocks = bh_result->b_size >> inode->i_blkbits;
3456 int dio_credits;
3457
3458 ext4_debug("ext4_get_block_dio_write: inode %lu, create flag %d\n",
3459 inode->i_ino, create);
3460 /*
3461 * DIO VFS code passes create = 0 flag for write to
3462 * the middle of file. It does this to avoid block
3463 * allocation for holes, to prevent expose stale data
3464 * out when there is parallel buffered read (which does
3465 * not hold the i_mutex lock) while direct IO write has
3466 * not completed. DIO request on holes finally falls back
3467 * to buffered IO for this reason.
3468 *
3469 * For ext4 extent based file, since we support fallocate,
3470 * new allocated extent as uninitialized, for holes, we
3471 * could fallocate blocks for holes, thus parallel
3472 * buffered IO read will zero out the page when read on
3473 * a hole while parallel DIO write to the hole has not completed.
3474 *
3475 * when we come here, we know it's a direct IO write to
3476 * to the middle of file (<i_size)
3477 * so it's safe to override the create flag from VFS.
3478 */
3479 create = EXT4_GET_BLOCKS_DIO_CREATE_EXT;
3480
3481 if (max_blocks > DIO_MAX_BLOCKS)
3482 max_blocks = DIO_MAX_BLOCKS;
3483 dio_credits = ext4_chunk_trans_blocks(inode, max_blocks);
3484 handle = ext4_journal_start(inode, dio_credits);
3485 if (IS_ERR(handle)) {
3486 ret = PTR_ERR(handle);
3487 goto out;
3488 }
3489 ret = ext4_get_blocks(handle, inode, iblock, max_blocks, bh_result,
3490 create);
3491 if (ret > 0) {
3492 bh_result->b_size = (ret << inode->i_blkbits);
3493 ret = 0;
3494 }
3495 ext4_journal_stop(handle);
3496out:
3497 return ret;
3498}
3499
3500static void ext4_free_io_end(ext4_io_end_t *io)
3501{
3502 BUG_ON(!io);
3503 iput(io->inode);
3504 kfree(io);
3505}
3506static void dump_aio_dio_list(struct inode * inode)
3507{
3508#ifdef EXT4_DEBUG
3509 struct list_head *cur, *before, *after;
3510 ext4_io_end_t *io, *io0, *io1;
3511
3512 if (list_empty(&EXT4_I(inode)->i_aio_dio_complete_list)){
3513 ext4_debug("inode %lu aio dio list is empty\n", inode->i_ino);
3514 return;
3515 }
3516
3517 ext4_debug("Dump inode %lu aio_dio_completed_IO list \n", inode->i_ino);
3518 list_for_each_entry(io, &EXT4_I(inode)->i_aio_dio_complete_list, list){
3519 cur = &io->list;
3520 before = cur->prev;
3521 io0 = container_of(before, ext4_io_end_t, list);
3522 after = cur->next;
3523 io1 = container_of(after, ext4_io_end_t, list);
3524
3525 ext4_debug("io 0x%p from inode %lu,prev 0x%p,next 0x%p\n",
3526 io, inode->i_ino, io0, io1);
3527 }
3528#endif
3529}
3530
3531/*
3532 * check a range of space and convert unwritten extents to written.
3533 */
3534static int ext4_end_aio_dio_nolock(ext4_io_end_t *io)
3535{
3536 struct inode *inode = io->inode;
3537 loff_t offset = io->offset;
3538 size_t size = io->size;
3539 int ret = 0;
3540
3541 ext4_debug("end_aio_dio_onlock: io 0x%p from inode %lu,list->next 0x%p,"
3542 "list->prev 0x%p\n",
3543 io, inode->i_ino, io->list.next, io->list.prev);
3544
3545 if (list_empty(&io->list))
3546 return ret;
3547
3548 if (io->flag != DIO_AIO_UNWRITTEN)
3549 return ret;
3550
3551 if (offset + size <= i_size_read(inode))
3552 ret = ext4_convert_unwritten_extents(inode, offset, size);
3553
3554 if (ret < 0) {
3555 printk(KERN_EMERG "%s: failed to convert unwritten"
3556 "extents to written extents, error is %d"
3557 " io is still on inode %lu aio dio list\n",
3558 __func__, ret, inode->i_ino);
3559 return ret;
3560 }
3561
3562 /* clear the DIO AIO unwritten flag */
3563 io->flag = 0;
3564 return ret;
3565}
3566/*
3567 * work on completed aio dio IO, to convert unwritten extents to extents
3568 */
3569static void ext4_end_aio_dio_work(struct work_struct *work)
3570{
3571 ext4_io_end_t *io = container_of(work, ext4_io_end_t, work);
3572 struct inode *inode = io->inode;
3573 int ret = 0;
3574
3575 mutex_lock(&inode->i_mutex);
3576 ret = ext4_end_aio_dio_nolock(io);
3577 if (ret >= 0) {
3578 if (!list_empty(&io->list))
3579 list_del_init(&io->list);
3580 ext4_free_io_end(io);
3581 }
3582 mutex_unlock(&inode->i_mutex);
3583}
3584/*
3585 * This function is called from ext4_sync_file().
3586 *
3587 * When AIO DIO IO is completed, the work to convert unwritten
3588 * extents to written is queued on workqueue but may not get immediately
3589 * scheduled. When fsync is called, we need to ensure the
3590 * conversion is complete before fsync returns.
3591 * The inode keeps track of a list of completed AIO from DIO path
3592 * that might needs to do the conversion. This function walks through
3593 * the list and convert the related unwritten extents to written.
3594 */
3595int flush_aio_dio_completed_IO(struct inode *inode)
3596{
3597 ext4_io_end_t *io;
3598 int ret = 0;
3599 int ret2 = 0;
3600
3601 if (list_empty(&EXT4_I(inode)->i_aio_dio_complete_list))
3602 return ret;
3603
3604 dump_aio_dio_list(inode);
3605 while (!list_empty(&EXT4_I(inode)->i_aio_dio_complete_list)){
3606 io = list_entry(EXT4_I(inode)->i_aio_dio_complete_list.next,
3607 ext4_io_end_t, list);
3608 /*
3609 * Calling ext4_end_aio_dio_nolock() to convert completed
3610 * IO to written.
3611 *
3612 * When ext4_sync_file() is called, run_queue() may already
3613 * about to flush the work corresponding to this io structure.
3614 * It will be upset if it founds the io structure related
3615 * to the work-to-be schedule is freed.
3616 *
3617 * Thus we need to keep the io structure still valid here after
3618 * convertion finished. The io structure has a flag to
3619 * avoid double converting from both fsync and background work
3620 * queue work.
3621 */
3622 ret = ext4_end_aio_dio_nolock(io);
3623 if (ret < 0)
3624 ret2 = ret;
3625 else
3626 list_del_init(&io->list);
3627 }
3628 return (ret2 < 0) ? ret2 : 0;
3629}
3630
3631static ext4_io_end_t *ext4_init_io_end (struct inode *inode)
3632{
3633 ext4_io_end_t *io = NULL;
3634
3635 io = kmalloc(sizeof(*io), GFP_NOFS);
3636
3637 if (io) {
3638 igrab(inode);
3639 io->inode = inode;
3640 io->flag = 0;
3641 io->offset = 0;
3642 io->size = 0;
3643 io->error = 0;
3644 INIT_WORK(&io->work, ext4_end_aio_dio_work);
3645 INIT_LIST_HEAD(&io->list);
3646 }
3647
3648 return io;
3649}
3650
3651static void ext4_end_io_dio(struct kiocb *iocb, loff_t offset,
3652 ssize_t size, void *private)
3653{
3654 ext4_io_end_t *io_end = iocb->private;
3655 struct workqueue_struct *wq;
3656
3657 ext_debug("ext4_end_io_dio(): io_end 0x%p"
3658 "for inode %lu, iocb 0x%p, offset %llu, size %llu\n",
3659 iocb->private, io_end->inode->i_ino, iocb, offset,
3660 size);
3661 /* if not async direct IO or dio with 0 bytes write, just return */
3662 if (!io_end || !size)
3663 return;
3664
3665 /* if not aio dio with unwritten extents, just free io and return */
3666 if (io_end->flag != DIO_AIO_UNWRITTEN){
3667 ext4_free_io_end(io_end);
3668 iocb->private = NULL;
3669 return;
3670 }
3671
3672 io_end->offset = offset;
3673 io_end->size = size;
3674 wq = EXT4_SB(io_end->inode->i_sb)->dio_unwritten_wq;
3675
3676 /* queue the work to convert unwritten extents to written */
3677 queue_work(wq, &io_end->work);
3678
3679 /* Add the io_end to per-inode completed aio dio list*/
3680 list_add_tail(&io_end->list,
3681 &EXT4_I(io_end->inode)->i_aio_dio_complete_list);
3682 iocb->private = NULL;
3683}
3684/*
3685 * For ext4 extent files, ext4 will do direct-io write to holes,
3686 * preallocated extents, and those write extend the file, no need to
3687 * fall back to buffered IO.
3688 *
3689 * For holes, we fallocate those blocks, mark them as unintialized
3690 * If those blocks were preallocated, we mark sure they are splited, but
3691 * still keep the range to write as unintialized.
3692 *
3693 * The unwrritten extents will be converted to written when DIO is completed.
3694 * For async direct IO, since the IO may still pending when return, we
3695 * set up an end_io call back function, which will do the convertion
3696 * when async direct IO completed.
3697 *
3698 * If the O_DIRECT write will extend the file then add this inode to the
3699 * orphan list. So recovery will truncate it back to the original size
3700 * if the machine crashes during the write.
3701 *
3702 */
3703static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb,
3704 const struct iovec *iov, loff_t offset,
3705 unsigned long nr_segs)
3706{
3707 struct file *file = iocb->ki_filp;
3708 struct inode *inode = file->f_mapping->host;
3709 ssize_t ret;
3710 size_t count = iov_length(iov, nr_segs);
3711
3712 loff_t final_size = offset + count;
3713 if (rw == WRITE && final_size <= inode->i_size) {
3714 /*
3715 * We could direct write to holes and fallocate.
3716 *
3717 * Allocated blocks to fill the hole are marked as uninitialized
3718 * to prevent paralel buffered read to expose the stale data
3719 * before DIO complete the data IO.
3720 *
3721 * As to previously fallocated extents, ext4 get_block
3722 * will just simply mark the buffer mapped but still
3723 * keep the extents uninitialized.
3724 *
3725 * for non AIO case, we will convert those unwritten extents
3726 * to written after return back from blockdev_direct_IO.
3727 *
3728 * for async DIO, the conversion needs to be defered when
3729 * the IO is completed. The ext4 end_io callback function
3730 * will be called to take care of the conversion work.
3731 * Here for async case, we allocate an io_end structure to
3732 * hook to the iocb.
3733 */
3734 iocb->private = NULL;
3735 EXT4_I(inode)->cur_aio_dio = NULL;
3736 if (!is_sync_kiocb(iocb)) {
3737 iocb->private = ext4_init_io_end(inode);
3738 if (!iocb->private)
3739 return -ENOMEM;
3740 /*
3741 * we save the io structure for current async
3742 * direct IO, so that later ext4_get_blocks()
3743 * could flag the io structure whether there
3744 * is a unwritten extents needs to be converted
3745 * when IO is completed.
3746 */
3747 EXT4_I(inode)->cur_aio_dio = iocb->private;
3748 }
3749
3750 ret = blockdev_direct_IO(rw, iocb, inode,
3751 inode->i_sb->s_bdev, iov,
3752 offset, nr_segs,
3753 ext4_get_block_dio_write,
3754 ext4_end_io_dio);
3755 if (iocb->private)
3756 EXT4_I(inode)->cur_aio_dio = NULL;
3757 /*
3758 * The io_end structure takes a reference to the inode,
3759 * that structure needs to be destroyed and the
3760 * reference to the inode need to be dropped, when IO is
3761 * complete, even with 0 byte write, or failed.
3762 *
3763 * In the successful AIO DIO case, the io_end structure will be
3764 * desctroyed and the reference to the inode will be dropped
3765 * after the end_io call back function is called.
3766 *
3767 * In the case there is 0 byte write, or error case, since
3768 * VFS direct IO won't invoke the end_io call back function,
3769 * we need to free the end_io structure here.
3770 */
3771 if (ret != -EIOCBQUEUED && ret <= 0 && iocb->private) {
3772 ext4_free_io_end(iocb->private);
3773 iocb->private = NULL;
3774 } else if (ret > 0)
3775 /*
3776 * for non AIO case, since the IO is already
3777 * completed, we could do the convertion right here
3778 */
3779 ret = ext4_convert_unwritten_extents(inode,
3780 offset, ret);
3781 return ret;
3782 }
3783
3784 /* for write the the end of file case, we fall back to old way */
3785 return ext4_ind_direct_IO(rw, iocb, iov, offset, nr_segs);
3786}
3787
3788static ssize_t ext4_direct_IO(int rw, struct kiocb *iocb,
3789 const struct iovec *iov, loff_t offset,
3790 unsigned long nr_segs)
3791{
3792 struct file *file = iocb->ki_filp;
3793 struct inode *inode = file->f_mapping->host;
3794
3795 if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL)
3796 return ext4_ext_direct_IO(rw, iocb, iov, offset, nr_segs);
3797
3798 return ext4_ind_direct_IO(rw, iocb, iov, offset, nr_segs);
3799}
3800
3357/* 3801/*
3358 * Pages can be marked dirty completely asynchronously from ext4's journalling 3802 * Pages can be marked dirty completely asynchronously from ext4's journalling
3359 * activity. By filemap_sync_pte(), try_to_unmap_one(), etc. We cannot do 3803 * activity. By filemap_sync_pte(), try_to_unmap_one(), etc. We cannot do
@@ -4551,8 +4995,7 @@ static int ext4_inode_blocks_set(handle_t *handle,
4551 */ 4995 */
4552static int ext4_do_update_inode(handle_t *handle, 4996static int ext4_do_update_inode(handle_t *handle,
4553 struct inode *inode, 4997 struct inode *inode,
4554 struct ext4_iloc *iloc, 4998 struct ext4_iloc *iloc)
4555 int do_sync)
4556{ 4999{
4557 struct ext4_inode *raw_inode = ext4_raw_inode(iloc); 5000 struct ext4_inode *raw_inode = ext4_raw_inode(iloc);
4558 struct ext4_inode_info *ei = EXT4_I(inode); 5001 struct ext4_inode_info *ei = EXT4_I(inode);
@@ -4653,22 +5096,10 @@ static int ext4_do_update_inode(handle_t *handle,
4653 raw_inode->i_extra_isize = cpu_to_le16(ei->i_extra_isize); 5096 raw_inode->i_extra_isize = cpu_to_le16(ei->i_extra_isize);
4654 } 5097 }
4655 5098
4656 /* 5099 BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata");
4657 * If we're not using a journal and we were called from 5100 rc = ext4_handle_dirty_metadata(handle, inode, bh);
4658 * ext4_write_inode() to sync the inode (making do_sync true), 5101 if (!err)
4659 * we can just use sync_dirty_buffer() directly to do our dirty 5102 err = rc;
4660 * work. Testing s_journal here is a bit redundant but it's
4661 * worth it to avoid potential future trouble.
4662 */
4663 if (EXT4_SB(inode->i_sb)->s_journal == NULL && do_sync) {
4664 BUFFER_TRACE(bh, "call sync_dirty_buffer");
4665 sync_dirty_buffer(bh);
4666 } else {
4667 BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata");
4668 rc = ext4_handle_dirty_metadata(handle, inode, bh);
4669 if (!err)
4670 err = rc;
4671 }
4672 ei->i_state &= ~EXT4_STATE_NEW; 5103 ei->i_state &= ~EXT4_STATE_NEW;
4673 5104
4674out_brelse: 5105out_brelse:
@@ -4736,8 +5167,16 @@ int ext4_write_inode(struct inode *inode, int wait)
4736 err = ext4_get_inode_loc(inode, &iloc); 5167 err = ext4_get_inode_loc(inode, &iloc);
4737 if (err) 5168 if (err)
4738 return err; 5169 return err;
4739 err = ext4_do_update_inode(EXT4_NOJOURNAL_HANDLE, 5170 if (wait)
4740 inode, &iloc, wait); 5171 sync_dirty_buffer(iloc.bh);
5172 if (buffer_req(iloc.bh) && !buffer_uptodate(iloc.bh)) {
5173 ext4_error(inode->i_sb, __func__,
5174 "IO error syncing inode, "
5175 "inode=%lu, block=%llu",
5176 inode->i_ino,
5177 (unsigned long long)iloc.bh->b_blocknr);
5178 err = -EIO;
5179 }
4741 } 5180 }
4742 return err; 5181 return err;
4743} 5182}
@@ -5033,7 +5472,7 @@ int ext4_mark_iloc_dirty(handle_t *handle,
5033 get_bh(iloc->bh); 5472 get_bh(iloc->bh);
5034 5473
5035 /* ext4_do_update_inode() does jbd2_journal_dirty_metadata */ 5474 /* ext4_do_update_inode() does jbd2_journal_dirty_metadata */
5036 err = ext4_do_update_inode(handle, inode, iloc, 0); 5475 err = ext4_do_update_inode(handle, inode, iloc);
5037 put_bh(iloc->bh); 5476 put_bh(iloc->bh);
5038 return err; 5477 return err;
5039} 5478}
@@ -5177,27 +5616,14 @@ int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode)
5177 */ 5616 */
5178void ext4_dirty_inode(struct inode *inode) 5617void ext4_dirty_inode(struct inode *inode)
5179{ 5618{
5180 handle_t *current_handle = ext4_journal_current_handle();
5181 handle_t *handle; 5619 handle_t *handle;
5182 5620
5183 if (!ext4_handle_valid(current_handle)) {
5184 ext4_mark_inode_dirty(current_handle, inode);
5185 return;
5186 }
5187
5188 handle = ext4_journal_start(inode, 2); 5621 handle = ext4_journal_start(inode, 2);
5189 if (IS_ERR(handle)) 5622 if (IS_ERR(handle))
5190 goto out; 5623 goto out;
5191 if (current_handle && 5624
5192 current_handle->h_transaction != handle->h_transaction) { 5625 ext4_mark_inode_dirty(handle, inode);
5193 /* This task has a transaction open against a different fs */ 5626
5194 printk(KERN_EMERG "%s: transactions do not match!\n",
5195 __func__);
5196 } else {
5197 jbd_debug(5, "marking dirty. outer handle=%p\n",
5198 current_handle);
5199 ext4_mark_inode_dirty(handle, inode);
5200 }
5201 ext4_journal_stop(handle); 5627 ext4_journal_stop(handle);
5202out: 5628out:
5203 return; 5629 return;
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index e9c61896d605..bba12824defa 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -2096,207 +2096,6 @@ out:
2096 return err; 2096 return err;
2097} 2097}
2098 2098
2099#ifdef EXT4_MB_HISTORY
2100struct ext4_mb_proc_session {
2101 struct ext4_mb_history *history;
2102 struct super_block *sb;
2103 int start;
2104 int max;
2105};
2106
2107static void *ext4_mb_history_skip_empty(struct ext4_mb_proc_session *s,
2108 struct ext4_mb_history *hs,
2109 int first)
2110{
2111 if (hs == s->history + s->max)
2112 hs = s->history;
2113 if (!first && hs == s->history + s->start)
2114 return NULL;
2115 while (hs->orig.fe_len == 0) {
2116 hs++;
2117 if (hs == s->history + s->max)
2118 hs = s->history;
2119 if (hs == s->history + s->start)
2120 return NULL;
2121 }
2122 return hs;
2123}
2124
2125static void *ext4_mb_seq_history_start(struct seq_file *seq, loff_t *pos)
2126{
2127 struct ext4_mb_proc_session *s = seq->private;
2128 struct ext4_mb_history *hs;
2129 int l = *pos;
2130
2131 if (l == 0)
2132 return SEQ_START_TOKEN;
2133 hs = ext4_mb_history_skip_empty(s, s->history + s->start, 1);
2134 if (!hs)
2135 return NULL;
2136 while (--l && (hs = ext4_mb_history_skip_empty(s, ++hs, 0)) != NULL);
2137 return hs;
2138}
2139
2140static void *ext4_mb_seq_history_next(struct seq_file *seq, void *v,
2141 loff_t *pos)
2142{
2143 struct ext4_mb_proc_session *s = seq->private;
2144 struct ext4_mb_history *hs = v;
2145
2146 ++*pos;
2147 if (v == SEQ_START_TOKEN)
2148 return ext4_mb_history_skip_empty(s, s->history + s->start, 1);
2149 else
2150 return ext4_mb_history_skip_empty(s, ++hs, 0);
2151}
2152
2153static int ext4_mb_seq_history_show(struct seq_file *seq, void *v)
2154{
2155 char buf[25], buf2[25], buf3[25], *fmt;
2156 struct ext4_mb_history *hs = v;
2157
2158 if (v == SEQ_START_TOKEN) {
2159 seq_printf(seq, "%-5s %-8s %-23s %-23s %-23s %-5s "
2160 "%-5s %-2s %-6s %-5s %-5s %-6s\n",
2161 "pid", "inode", "original", "goal", "result", "found",
2162 "grps", "cr", "flags", "merge", "tail", "broken");
2163 return 0;
2164 }
2165
2166 if (hs->op == EXT4_MB_HISTORY_ALLOC) {
2167 fmt = "%-5u %-8u %-23s %-23s %-23s %-5u %-5u %-2u "
2168 "0x%04x %-5s %-5u %-6u\n";
2169 sprintf(buf2, "%u/%d/%u@%u", hs->result.fe_group,
2170 hs->result.fe_start, hs->result.fe_len,
2171 hs->result.fe_logical);
2172 sprintf(buf, "%u/%d/%u@%u", hs->orig.fe_group,
2173 hs->orig.fe_start, hs->orig.fe_len,
2174 hs->orig.fe_logical);
2175 sprintf(buf3, "%u/%d/%u@%u", hs->goal.fe_group,
2176 hs->goal.fe_start, hs->goal.fe_len,
2177 hs->goal.fe_logical);
2178 seq_printf(seq, fmt, hs->pid, hs->ino, buf, buf3, buf2,
2179 hs->found, hs->groups, hs->cr, hs->flags,
2180 hs->merged ? "M" : "", hs->tail,
2181 hs->buddy ? 1 << hs->buddy : 0);
2182 } else if (hs->op == EXT4_MB_HISTORY_PREALLOC) {
2183 fmt = "%-5u %-8u %-23s %-23s %-23s\n";
2184 sprintf(buf2, "%u/%d/%u@%u", hs->result.fe_group,
2185 hs->result.fe_start, hs->result.fe_len,
2186 hs->result.fe_logical);
2187 sprintf(buf, "%u/%d/%u@%u", hs->orig.fe_group,
2188 hs->orig.fe_start, hs->orig.fe_len,
2189 hs->orig.fe_logical);
2190 seq_printf(seq, fmt, hs->pid, hs->ino, buf, "", buf2);
2191 } else if (hs->op == EXT4_MB_HISTORY_DISCARD) {
2192 sprintf(buf2, "%u/%d/%u", hs->result.fe_group,
2193 hs->result.fe_start, hs->result.fe_len);
2194 seq_printf(seq, "%-5u %-8u %-23s discard\n",
2195 hs->pid, hs->ino, buf2);
2196 } else if (hs->op == EXT4_MB_HISTORY_FREE) {
2197 sprintf(buf2, "%u/%d/%u", hs->result.fe_group,
2198 hs->result.fe_start, hs->result.fe_len);
2199 seq_printf(seq, "%-5u %-8u %-23s free\n",
2200 hs->pid, hs->ino, buf2);
2201 }
2202 return 0;
2203}
2204
2205static void ext4_mb_seq_history_stop(struct seq_file *seq, void *v)
2206{
2207}
2208
2209static const struct seq_operations ext4_mb_seq_history_ops = {
2210 .start = ext4_mb_seq_history_start,
2211 .next = ext4_mb_seq_history_next,
2212 .stop = ext4_mb_seq_history_stop,
2213 .show = ext4_mb_seq_history_show,
2214};
2215
2216static int ext4_mb_seq_history_open(struct inode *inode, struct file *file)
2217{
2218 struct super_block *sb = PDE(inode)->data;
2219 struct ext4_sb_info *sbi = EXT4_SB(sb);
2220 struct ext4_mb_proc_session *s;
2221 int rc;
2222 int size;
2223
2224 if (unlikely(sbi->s_mb_history == NULL))
2225 return -ENOMEM;
2226 s = kmalloc(sizeof(*s), GFP_KERNEL);
2227 if (s == NULL)
2228 return -ENOMEM;
2229 s->sb = sb;
2230 size = sizeof(struct ext4_mb_history) * sbi->s_mb_history_max;
2231 s->history = kmalloc(size, GFP_KERNEL);
2232 if (s->history == NULL) {
2233 kfree(s);
2234 return -ENOMEM;
2235 }
2236
2237 spin_lock(&sbi->s_mb_history_lock);
2238 memcpy(s->history, sbi->s_mb_history, size);
2239 s->max = sbi->s_mb_history_max;
2240 s->start = sbi->s_mb_history_cur % s->max;
2241 spin_unlock(&sbi->s_mb_history_lock);
2242
2243 rc = seq_open(file, &ext4_mb_seq_history_ops);
2244 if (rc == 0) {
2245 struct seq_file *m = (struct seq_file *)file->private_data;
2246 m->private = s;
2247 } else {
2248 kfree(s->history);
2249 kfree(s);
2250 }
2251 return rc;
2252
2253}
2254
2255static int ext4_mb_seq_history_release(struct inode *inode, struct file *file)
2256{
2257 struct seq_file *seq = (struct seq_file *)file->private_data;
2258 struct ext4_mb_proc_session *s = seq->private;
2259 kfree(s->history);
2260 kfree(s);
2261 return seq_release(inode, file);
2262}
2263
2264static ssize_t ext4_mb_seq_history_write(struct file *file,
2265 const char __user *buffer,
2266 size_t count, loff_t *ppos)
2267{
2268 struct seq_file *seq = (struct seq_file *)file->private_data;
2269 struct ext4_mb_proc_session *s = seq->private;
2270 struct super_block *sb = s->sb;
2271 char str[32];
2272 int value;
2273
2274 if (count >= sizeof(str)) {
2275 printk(KERN_ERR "EXT4-fs: %s string too long, max %u bytes\n",
2276 "mb_history", (int)sizeof(str));
2277 return -EOVERFLOW;
2278 }
2279
2280 if (copy_from_user(str, buffer, count))
2281 return -EFAULT;
2282
2283 value = simple_strtol(str, NULL, 0);
2284 if (value < 0)
2285 return -ERANGE;
2286 EXT4_SB(sb)->s_mb_history_filter = value;
2287
2288 return count;
2289}
2290
2291static const struct file_operations ext4_mb_seq_history_fops = {
2292 .owner = THIS_MODULE,
2293 .open = ext4_mb_seq_history_open,
2294 .read = seq_read,
2295 .write = ext4_mb_seq_history_write,
2296 .llseek = seq_lseek,
2297 .release = ext4_mb_seq_history_release,
2298};
2299
2300static void *ext4_mb_seq_groups_start(struct seq_file *seq, loff_t *pos) 2099static void *ext4_mb_seq_groups_start(struct seq_file *seq, loff_t *pos)
2301{ 2100{
2302 struct super_block *sb = seq->private; 2101 struct super_block *sb = seq->private;
@@ -2396,82 +2195,6 @@ static const struct file_operations ext4_mb_seq_groups_fops = {
2396 .release = seq_release, 2195 .release = seq_release,
2397}; 2196};
2398 2197
2399static void ext4_mb_history_release(struct super_block *sb)
2400{
2401 struct ext4_sb_info *sbi = EXT4_SB(sb);
2402
2403 if (sbi->s_proc != NULL) {
2404 remove_proc_entry("mb_groups", sbi->s_proc);
2405 if (sbi->s_mb_history_max)
2406 remove_proc_entry("mb_history", sbi->s_proc);
2407 }
2408 kfree(sbi->s_mb_history);
2409}
2410
2411static void ext4_mb_history_init(struct super_block *sb)
2412{
2413 struct ext4_sb_info *sbi = EXT4_SB(sb);
2414 int i;
2415
2416 if (sbi->s_proc != NULL) {
2417 if (sbi->s_mb_history_max)
2418 proc_create_data("mb_history", S_IRUGO, sbi->s_proc,
2419 &ext4_mb_seq_history_fops, sb);
2420 proc_create_data("mb_groups", S_IRUGO, sbi->s_proc,
2421 &ext4_mb_seq_groups_fops, sb);
2422 }
2423
2424 sbi->s_mb_history_cur = 0;
2425 spin_lock_init(&sbi->s_mb_history_lock);
2426 i = sbi->s_mb_history_max * sizeof(struct ext4_mb_history);
2427 sbi->s_mb_history = i ? kzalloc(i, GFP_KERNEL) : NULL;
2428 /* if we can't allocate history, then we simple won't use it */
2429}
2430
2431static noinline_for_stack void
2432ext4_mb_store_history(struct ext4_allocation_context *ac)
2433{
2434 struct ext4_sb_info *sbi = EXT4_SB(ac->ac_sb);
2435 struct ext4_mb_history h;
2436
2437 if (sbi->s_mb_history == NULL)
2438 return;
2439
2440 if (!(ac->ac_op & sbi->s_mb_history_filter))
2441 return;
2442
2443 h.op = ac->ac_op;
2444 h.pid = current->pid;
2445 h.ino = ac->ac_inode ? ac->ac_inode->i_ino : 0;
2446 h.orig = ac->ac_o_ex;
2447 h.result = ac->ac_b_ex;
2448 h.flags = ac->ac_flags;
2449 h.found = ac->ac_found;
2450 h.groups = ac->ac_groups_scanned;
2451 h.cr = ac->ac_criteria;
2452 h.tail = ac->ac_tail;
2453 h.buddy = ac->ac_buddy;
2454 h.merged = 0;
2455 if (ac->ac_op == EXT4_MB_HISTORY_ALLOC) {
2456 if (ac->ac_g_ex.fe_start == ac->ac_b_ex.fe_start &&
2457 ac->ac_g_ex.fe_group == ac->ac_b_ex.fe_group)
2458 h.merged = 1;
2459 h.goal = ac->ac_g_ex;
2460 h.result = ac->ac_f_ex;
2461 }
2462
2463 spin_lock(&sbi->s_mb_history_lock);
2464 memcpy(sbi->s_mb_history + sbi->s_mb_history_cur, &h, sizeof(h));
2465 if (++sbi->s_mb_history_cur >= sbi->s_mb_history_max)
2466 sbi->s_mb_history_cur = 0;
2467 spin_unlock(&sbi->s_mb_history_lock);
2468}
2469
2470#else
2471#define ext4_mb_history_release(sb)
2472#define ext4_mb_history_init(sb)
2473#endif
2474
2475 2198
2476/* Create and initialize ext4_group_info data for the given group. */ 2199/* Create and initialize ext4_group_info data for the given group. */
2477int ext4_mb_add_groupinfo(struct super_block *sb, ext4_group_t group, 2200int ext4_mb_add_groupinfo(struct super_block *sb, ext4_group_t group,
@@ -2690,7 +2413,6 @@ int ext4_mb_init(struct super_block *sb, int needs_recovery)
2690 sbi->s_mb_stats = MB_DEFAULT_STATS; 2413 sbi->s_mb_stats = MB_DEFAULT_STATS;
2691 sbi->s_mb_stream_request = MB_DEFAULT_STREAM_THRESHOLD; 2414 sbi->s_mb_stream_request = MB_DEFAULT_STREAM_THRESHOLD;
2692 sbi->s_mb_order2_reqs = MB_DEFAULT_ORDER2_REQS; 2415 sbi->s_mb_order2_reqs = MB_DEFAULT_ORDER2_REQS;
2693 sbi->s_mb_history_filter = EXT4_MB_HISTORY_DEFAULT;
2694 sbi->s_mb_group_prealloc = MB_DEFAULT_GROUP_PREALLOC; 2416 sbi->s_mb_group_prealloc = MB_DEFAULT_GROUP_PREALLOC;
2695 2417
2696 sbi->s_locality_groups = alloc_percpu(struct ext4_locality_group); 2418 sbi->s_locality_groups = alloc_percpu(struct ext4_locality_group);
@@ -2708,12 +2430,12 @@ int ext4_mb_init(struct super_block *sb, int needs_recovery)
2708 spin_lock_init(&lg->lg_prealloc_lock); 2430 spin_lock_init(&lg->lg_prealloc_lock);
2709 } 2431 }
2710 2432
2711 ext4_mb_history_init(sb); 2433 if (sbi->s_proc)
2434 proc_create_data("mb_groups", S_IRUGO, sbi->s_proc,
2435 &ext4_mb_seq_groups_fops, sb);
2712 2436
2713 if (sbi->s_journal) 2437 if (sbi->s_journal)
2714 sbi->s_journal->j_commit_callback = release_blocks_on_commit; 2438 sbi->s_journal->j_commit_callback = release_blocks_on_commit;
2715
2716 printk(KERN_INFO "EXT4-fs: mballoc enabled\n");
2717 return 0; 2439 return 0;
2718} 2440}
2719 2441
@@ -2790,7 +2512,8 @@ int ext4_mb_release(struct super_block *sb)
2790 } 2512 }
2791 2513
2792 free_percpu(sbi->s_locality_groups); 2514 free_percpu(sbi->s_locality_groups);
2793 ext4_mb_history_release(sb); 2515 if (sbi->s_proc)
2516 remove_proc_entry("mb_groups", sbi->s_proc);
2794 2517
2795 return 0; 2518 return 0;
2796} 2519}
@@ -3276,7 +2999,10 @@ static void ext4_mb_collect_stats(struct ext4_allocation_context *ac)
3276 atomic_inc(&sbi->s_bal_breaks); 2999 atomic_inc(&sbi->s_bal_breaks);
3277 } 3000 }
3278 3001
3279 ext4_mb_store_history(ac); 3002 if (ac->ac_op == EXT4_MB_HISTORY_ALLOC)
3003 trace_ext4_mballoc_alloc(ac);
3004 else
3005 trace_ext4_mballoc_prealloc(ac);
3280} 3006}
3281 3007
3282/* 3008/*
@@ -3776,7 +3502,6 @@ ext4_mb_release_inode_pa(struct ext4_buddy *e4b, struct buffer_head *bitmap_bh,
3776 if (ac) { 3502 if (ac) {
3777 ac->ac_sb = sb; 3503 ac->ac_sb = sb;
3778 ac->ac_inode = pa->pa_inode; 3504 ac->ac_inode = pa->pa_inode;
3779 ac->ac_op = EXT4_MB_HISTORY_DISCARD;
3780 } 3505 }
3781 3506
3782 while (bit < end) { 3507 while (bit < end) {
@@ -3796,7 +3521,7 @@ ext4_mb_release_inode_pa(struct ext4_buddy *e4b, struct buffer_head *bitmap_bh,
3796 ac->ac_b_ex.fe_start = bit; 3521 ac->ac_b_ex.fe_start = bit;
3797 ac->ac_b_ex.fe_len = next - bit; 3522 ac->ac_b_ex.fe_len = next - bit;
3798 ac->ac_b_ex.fe_logical = 0; 3523 ac->ac_b_ex.fe_logical = 0;
3799 ext4_mb_store_history(ac); 3524 trace_ext4_mballoc_discard(ac);
3800 } 3525 }
3801 3526
3802 trace_ext4_mb_release_inode_pa(ac, pa, grp_blk_start + bit, 3527 trace_ext4_mb_release_inode_pa(ac, pa, grp_blk_start + bit,
@@ -3831,9 +3556,6 @@ ext4_mb_release_group_pa(struct ext4_buddy *e4b,
3831 ext4_group_t group; 3556 ext4_group_t group;
3832 ext4_grpblk_t bit; 3557 ext4_grpblk_t bit;
3833 3558
3834 if (ac)
3835 ac->ac_op = EXT4_MB_HISTORY_DISCARD;
3836
3837 trace_ext4_mb_release_group_pa(ac, pa); 3559 trace_ext4_mb_release_group_pa(ac, pa);
3838 BUG_ON(pa->pa_deleted == 0); 3560 BUG_ON(pa->pa_deleted == 0);
3839 ext4_get_group_no_and_offset(sb, pa->pa_pstart, &group, &bit); 3561 ext4_get_group_no_and_offset(sb, pa->pa_pstart, &group, &bit);
@@ -3848,7 +3570,7 @@ ext4_mb_release_group_pa(struct ext4_buddy *e4b,
3848 ac->ac_b_ex.fe_start = bit; 3570 ac->ac_b_ex.fe_start = bit;
3849 ac->ac_b_ex.fe_len = pa->pa_len; 3571 ac->ac_b_ex.fe_len = pa->pa_len;
3850 ac->ac_b_ex.fe_logical = 0; 3572 ac->ac_b_ex.fe_logical = 0;
3851 ext4_mb_store_history(ac); 3573 trace_ext4_mballoc_discard(ac);
3852 } 3574 }
3853 3575
3854 return 0; 3576 return 0;
@@ -4189,7 +3911,6 @@ static void ext4_mb_group_or_file(struct ext4_allocation_context *ac)
4189 size = ac->ac_o_ex.fe_logical + ac->ac_o_ex.fe_len; 3911 size = ac->ac_o_ex.fe_logical + ac->ac_o_ex.fe_len;
4190 isize = (i_size_read(ac->ac_inode) + ac->ac_sb->s_blocksize - 1) 3912 isize = (i_size_read(ac->ac_inode) + ac->ac_sb->s_blocksize - 1)
4191 >> bsbits; 3913 >> bsbits;
4192 size = max(size, isize);
4193 3914
4194 if ((size == isize) && 3915 if ((size == isize) &&
4195 !ext4_fs_is_busy(sbi) && 3916 !ext4_fs_is_busy(sbi) &&
@@ -4199,6 +3920,7 @@ static void ext4_mb_group_or_file(struct ext4_allocation_context *ac)
4199 } 3920 }
4200 3921
4201 /* don't use group allocation for large files */ 3922 /* don't use group allocation for large files */
3923 size = max(size, isize);
4202 if (size >= sbi->s_mb_stream_request) { 3924 if (size >= sbi->s_mb_stream_request) {
4203 ac->ac_flags |= EXT4_MB_STREAM_ALLOC; 3925 ac->ac_flags |= EXT4_MB_STREAM_ALLOC;
4204 return; 3926 return;
@@ -4739,7 +4461,6 @@ void ext4_mb_free_blocks(handle_t *handle, struct inode *inode,
4739 4461
4740 ac = kmem_cache_alloc(ext4_ac_cachep, GFP_NOFS); 4462 ac = kmem_cache_alloc(ext4_ac_cachep, GFP_NOFS);
4741 if (ac) { 4463 if (ac) {
4742 ac->ac_op = EXT4_MB_HISTORY_FREE;
4743 ac->ac_inode = inode; 4464 ac->ac_inode = inode;
4744 ac->ac_sb = sb; 4465 ac->ac_sb = sb;
4745 } 4466 }
@@ -4806,7 +4527,7 @@ do_more:
4806 ac->ac_b_ex.fe_group = block_group; 4527 ac->ac_b_ex.fe_group = block_group;
4807 ac->ac_b_ex.fe_start = bit; 4528 ac->ac_b_ex.fe_start = bit;
4808 ac->ac_b_ex.fe_len = count; 4529 ac->ac_b_ex.fe_len = count;
4809 ext4_mb_store_history(ac); 4530 trace_ext4_mballoc_free(ac);
4810 } 4531 }
4811 4532
4812 err = ext4_mb_load_buddy(sb, block_group, &e4b); 4533 err = ext4_mb_load_buddy(sb, block_group, &e4b);
diff --git a/fs/ext4/mballoc.h b/fs/ext4/mballoc.h
index 188d3d709b24..0ca811061bc7 100644
--- a/fs/ext4/mballoc.h
+++ b/fs/ext4/mballoc.h
@@ -52,18 +52,8 @@ extern u8 mb_enable_debug;
52#define mb_debug(n, fmt, a...) 52#define mb_debug(n, fmt, a...)
53#endif 53#endif
54 54
55/*
56 * with EXT4_MB_HISTORY mballoc stores last N allocations in memory
57 * and you can monitor it in /proc/fs/ext4/<dev>/mb_history
58 */
59#define EXT4_MB_HISTORY
60#define EXT4_MB_HISTORY_ALLOC 1 /* allocation */ 55#define EXT4_MB_HISTORY_ALLOC 1 /* allocation */
61#define EXT4_MB_HISTORY_PREALLOC 2 /* preallocated blocks used */ 56#define EXT4_MB_HISTORY_PREALLOC 2 /* preallocated blocks used */
62#define EXT4_MB_HISTORY_DISCARD 4 /* preallocation discarded */
63#define EXT4_MB_HISTORY_FREE 8 /* free */
64
65#define EXT4_MB_HISTORY_DEFAULT (EXT4_MB_HISTORY_ALLOC | \
66 EXT4_MB_HISTORY_PREALLOC)
67 57
68/* 58/*
69 * How long mballoc can look for a best extent (in found extents) 59 * How long mballoc can look for a best extent (in found extents)
@@ -84,7 +74,7 @@ extern u8 mb_enable_debug;
84 * with 'ext4_mb_stats' allocator will collect stats that will be 74 * with 'ext4_mb_stats' allocator will collect stats that will be
85 * shown at umount. The collecting costs though! 75 * shown at umount. The collecting costs though!
86 */ 76 */
87#define MB_DEFAULT_STATS 1 77#define MB_DEFAULT_STATS 0
88 78
89/* 79/*
90 * files smaller than MB_DEFAULT_STREAM_THRESHOLD are served 80 * files smaller than MB_DEFAULT_STREAM_THRESHOLD are served
@@ -217,22 +207,6 @@ struct ext4_allocation_context {
217#define AC_STATUS_FOUND 2 207#define AC_STATUS_FOUND 2
218#define AC_STATUS_BREAK 3 208#define AC_STATUS_BREAK 3
219 209
220struct ext4_mb_history {
221 struct ext4_free_extent orig; /* orig allocation */
222 struct ext4_free_extent goal; /* goal allocation */
223 struct ext4_free_extent result; /* result allocation */
224 unsigned pid;
225 unsigned ino;
226 __u16 found; /* how many extents have been found */
227 __u16 groups; /* how many groups have been scanned */
228 __u16 tail; /* what tail broke some buddy */
229 __u16 buddy; /* buddy the tail ^^^ broke */
230 __u16 flags;
231 __u8 cr:3; /* which phase the result extent was found at */
232 __u8 op:4;
233 __u8 merged:1;
234};
235
236struct ext4_buddy { 210struct ext4_buddy {
237 struct page *bd_buddy_page; 211 struct page *bd_buddy_page;
238 void *bd_buddy; 212 void *bd_buddy;
@@ -247,13 +221,6 @@ struct ext4_buddy {
247#define EXT4_MB_BITMAP(e4b) ((e4b)->bd_bitmap) 221#define EXT4_MB_BITMAP(e4b) ((e4b)->bd_bitmap)
248#define EXT4_MB_BUDDY(e4b) ((e4b)->bd_buddy) 222#define EXT4_MB_BUDDY(e4b) ((e4b)->bd_buddy)
249 223
250#ifndef EXT4_MB_HISTORY
251static inline void ext4_mb_store_history(struct ext4_allocation_context *ac)
252{
253 return;
254}
255#endif
256
257#define in_range(b, first, len) ((b) >= (first) && (b) <= (first) + (len) - 1) 224#define in_range(b, first, len) ((b) >= (first) && (b) <= (first) + (len) - 1)
258 225
259static inline ext4_fsblk_t ext4_grp_offs_to_block(struct super_block *sb, 226static inline ext4_fsblk_t ext4_grp_offs_to_block(struct super_block *sb,
diff --git a/fs/ext4/migrate.c b/fs/ext4/migrate.c
index bf519f239ae6..a93d5b80f3e2 100644
--- a/fs/ext4/migrate.c
+++ b/fs/ext4/migrate.c
@@ -75,7 +75,7 @@ static int finish_range(handle_t *handle, struct inode *inode,
75 goto err_out; 75 goto err_out;
76 } 76 }
77 } 77 }
78 retval = ext4_ext_insert_extent(handle, inode, path, &newext); 78 retval = ext4_ext_insert_extent(handle, inode, path, &newext, 0);
79err_out: 79err_out:
80 if (path) { 80 if (path) {
81 ext4_ext_drop_refs(path); 81 ext4_ext_drop_refs(path);
diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c
index c07a2915e40b..25b6b1457360 100644
--- a/fs/ext4/move_extent.c
+++ b/fs/ext4/move_extent.c
@@ -322,7 +322,7 @@ mext_insert_across_blocks(handle_t *handle, struct inode *orig_inode,
322 goto out; 322 goto out;
323 323
324 if (ext4_ext_insert_extent(handle, orig_inode, 324 if (ext4_ext_insert_extent(handle, orig_inode,
325 orig_path, new_ext)) 325 orig_path, new_ext, 0))
326 goto out; 326 goto out;
327 } 327 }
328 328
@@ -333,7 +333,7 @@ mext_insert_across_blocks(handle_t *handle, struct inode *orig_inode,
333 goto out; 333 goto out;
334 334
335 if (ext4_ext_insert_extent(handle, orig_inode, 335 if (ext4_ext_insert_extent(handle, orig_inode,
336 orig_path, end_ext)) 336 orig_path, end_ext, 0))
337 goto out; 337 goto out;
338 } 338 }
339out: 339out:
@@ -1001,14 +1001,6 @@ mext_check_arguments(struct inode *orig_inode,
1001 return -EINVAL; 1001 return -EINVAL;
1002 } 1002 }
1003 1003
1004 /* orig and donor should be different file */
1005 if (orig_inode->i_ino == donor_inode->i_ino) {
1006 ext4_debug("ext4 move extent: The argument files should not "
1007 "be same file [ino:orig %lu, donor %lu]\n",
1008 orig_inode->i_ino, donor_inode->i_ino);
1009 return -EINVAL;
1010 }
1011
1012 /* Ext4 move extent supports only extent based file */ 1004 /* Ext4 move extent supports only extent based file */
1013 if (!(EXT4_I(orig_inode)->i_flags & EXT4_EXTENTS_FL)) { 1005 if (!(EXT4_I(orig_inode)->i_flags & EXT4_EXTENTS_FL)) {
1014 ext4_debug("ext4 move extent: orig file is not extents " 1006 ext4_debug("ext4 move extent: orig file is not extents "
@@ -1232,6 +1224,14 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp,
1232 int block_len_in_page; 1224 int block_len_in_page;
1233 int uninit; 1225 int uninit;
1234 1226
1227 /* orig and donor should be different file */
1228 if (orig_inode->i_ino == donor_inode->i_ino) {
1229 ext4_debug("ext4 move extent: The argument files should not "
1230 "be same file [ino:orig %lu, donor %lu]\n",
1231 orig_inode->i_ino, donor_inode->i_ino);
1232 return -EINVAL;
1233 }
1234
1235 /* protect orig and donor against a truncate */ 1235 /* protect orig and donor against a truncate */
1236 ret1 = mext_inode_double_lock(orig_inode, donor_inode); 1236 ret1 = mext_inode_double_lock(orig_inode, donor_inode);
1237 if (ret1 < 0) 1237 if (ret1 < 0)
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 42f81d285cd5..7c8fe80bacdd 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -2076,7 +2076,8 @@ int ext4_orphan_del(handle_t *handle, struct inode *inode)
2076 struct ext4_iloc iloc; 2076 struct ext4_iloc iloc;
2077 int err = 0; 2077 int err = 0;
2078 2078
2079 if (!ext4_handle_valid(handle)) 2079 /* ext4_handle_valid() assumes a valid handle_t pointer */
2080 if (handle && !ext4_handle_valid(handle))
2080 return 0; 2081 return 0;
2081 2082
2082 mutex_lock(&EXT4_SB(inode->i_sb)->s_orphan_lock); 2083 mutex_lock(&EXT4_SB(inode->i_sb)->s_orphan_lock);
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index df539ba27779..312211ee05af 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -50,13 +50,6 @@
50#define CREATE_TRACE_POINTS 50#define CREATE_TRACE_POINTS
51#include <trace/events/ext4.h> 51#include <trace/events/ext4.h>
52 52
53static int default_mb_history_length = 1000;
54
55module_param_named(default_mb_history_length, default_mb_history_length,
56 int, 0644);
57MODULE_PARM_DESC(default_mb_history_length,
58 "Default number of entries saved for mb_history");
59
60struct proc_dir_entry *ext4_proc_root; 53struct proc_dir_entry *ext4_proc_root;
61static struct kset *ext4_kset; 54static struct kset *ext4_kset;
62 55
@@ -189,6 +182,36 @@ void ext4_itable_unused_set(struct super_block *sb,
189 bg->bg_itable_unused_hi = cpu_to_le16(count >> 16); 182 bg->bg_itable_unused_hi = cpu_to_le16(count >> 16);
190} 183}
191 184
185
186/* Just increment the non-pointer handle value */
187static handle_t *ext4_get_nojournal(void)
188{
189 handle_t *handle = current->journal_info;
190 unsigned long ref_cnt = (unsigned long)handle;
191
192 BUG_ON(ref_cnt >= EXT4_NOJOURNAL_MAX_REF_COUNT);
193
194 ref_cnt++;
195 handle = (handle_t *)ref_cnt;
196
197 current->journal_info = handle;
198 return handle;
199}
200
201
202/* Decrement the non-pointer handle value */
203static void ext4_put_nojournal(handle_t *handle)
204{
205 unsigned long ref_cnt = (unsigned long)handle;
206
207 BUG_ON(ref_cnt == 0);
208
209 ref_cnt--;
210 handle = (handle_t *)ref_cnt;
211
212 current->journal_info = handle;
213}
214
192/* 215/*
193 * Wrappers for jbd2_journal_start/end. 216 * Wrappers for jbd2_journal_start/end.
194 * 217 *
@@ -215,11 +238,7 @@ handle_t *ext4_journal_start_sb(struct super_block *sb, int nblocks)
215 } 238 }
216 return jbd2_journal_start(journal, nblocks); 239 return jbd2_journal_start(journal, nblocks);
217 } 240 }
218 /* 241 return ext4_get_nojournal();
219 * We're not journaling, return the appropriate indication.
220 */
221 current->journal_info = EXT4_NOJOURNAL_HANDLE;
222 return current->journal_info;
223} 242}
224 243
225/* 244/*
@@ -235,11 +254,7 @@ int __ext4_journal_stop(const char *where, handle_t *handle)
235 int rc; 254 int rc;
236 255
237 if (!ext4_handle_valid(handle)) { 256 if (!ext4_handle_valid(handle)) {
238 /* 257 ext4_put_nojournal(handle);
239 * Do this here since we don't call jbd2_journal_stop() in
240 * no-journal mode.
241 */
242 current->journal_info = NULL;
243 return 0; 258 return 0;
244 } 259 }
245 sb = handle->h_transaction->t_journal->j_private; 260 sb = handle->h_transaction->t_journal->j_private;
@@ -580,6 +595,9 @@ static void ext4_put_super(struct super_block *sb)
580 struct ext4_super_block *es = sbi->s_es; 595 struct ext4_super_block *es = sbi->s_es;
581 int i, err; 596 int i, err;
582 597
598 flush_workqueue(sbi->dio_unwritten_wq);
599 destroy_workqueue(sbi->dio_unwritten_wq);
600
583 lock_super(sb); 601 lock_super(sb);
584 lock_kernel(); 602 lock_kernel();
585 if (sb->s_dirt) 603 if (sb->s_dirt)
@@ -684,6 +702,8 @@ static struct inode *ext4_alloc_inode(struct super_block *sb)
684 ei->i_allocated_meta_blocks = 0; 702 ei->i_allocated_meta_blocks = 0;
685 ei->i_delalloc_reserved_flag = 0; 703 ei->i_delalloc_reserved_flag = 0;
686 spin_lock_init(&(ei->i_block_reservation_lock)); 704 spin_lock_init(&(ei->i_block_reservation_lock));
705 INIT_LIST_HEAD(&ei->i_aio_dio_complete_list);
706 ei->cur_aio_dio = NULL;
687 707
688 return &ei->vfs_inode; 708 return &ei->vfs_inode;
689} 709}
@@ -1052,7 +1072,7 @@ enum {
1052 Opt_journal_update, Opt_journal_dev, 1072 Opt_journal_update, Opt_journal_dev,
1053 Opt_journal_checksum, Opt_journal_async_commit, 1073 Opt_journal_checksum, Opt_journal_async_commit,
1054 Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback, 1074 Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback,
1055 Opt_data_err_abort, Opt_data_err_ignore, Opt_mb_history_length, 1075 Opt_data_err_abort, Opt_data_err_ignore,
1056 Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota, 1076 Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
1057 Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota, 1077 Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota,
1058 Opt_ignore, Opt_barrier, Opt_nobarrier, Opt_err, Opt_resize, 1078 Opt_ignore, Opt_barrier, Opt_nobarrier, Opt_err, Opt_resize,
@@ -1099,7 +1119,6 @@ static const match_table_t tokens = {
1099 {Opt_data_writeback, "data=writeback"}, 1119 {Opt_data_writeback, "data=writeback"},
1100 {Opt_data_err_abort, "data_err=abort"}, 1120 {Opt_data_err_abort, "data_err=abort"},
1101 {Opt_data_err_ignore, "data_err=ignore"}, 1121 {Opt_data_err_ignore, "data_err=ignore"},
1102 {Opt_mb_history_length, "mb_history_length=%u"},
1103 {Opt_offusrjquota, "usrjquota="}, 1122 {Opt_offusrjquota, "usrjquota="},
1104 {Opt_usrjquota, "usrjquota=%s"}, 1123 {Opt_usrjquota, "usrjquota=%s"},
1105 {Opt_offgrpjquota, "grpjquota="}, 1124 {Opt_offgrpjquota, "grpjquota="},
@@ -1340,13 +1359,6 @@ static int parse_options(char *options, struct super_block *sb,
1340 case Opt_data_err_ignore: 1359 case Opt_data_err_ignore:
1341 clear_opt(sbi->s_mount_opt, DATA_ERR_ABORT); 1360 clear_opt(sbi->s_mount_opt, DATA_ERR_ABORT);
1342 break; 1361 break;
1343 case Opt_mb_history_length:
1344 if (match_int(&args[0], &option))
1345 return 0;
1346 if (option < 0)
1347 return 0;
1348 sbi->s_mb_history_max = option;
1349 break;
1350#ifdef CONFIG_QUOTA 1362#ifdef CONFIG_QUOTA
1351 case Opt_usrjquota: 1363 case Opt_usrjquota:
1352 qtype = USRQUOTA; 1364 qtype = USRQUOTA;
@@ -1646,13 +1658,6 @@ static int ext4_setup_super(struct super_block *sb, struct ext4_super_block *es,
1646 EXT4_INODES_PER_GROUP(sb), 1658 EXT4_INODES_PER_GROUP(sb),
1647 sbi->s_mount_opt); 1659 sbi->s_mount_opt);
1648 1660
1649 if (EXT4_SB(sb)->s_journal) {
1650 ext4_msg(sb, KERN_INFO, "%s journal on %s",
1651 EXT4_SB(sb)->s_journal->j_inode ? "internal" :
1652 "external", EXT4_SB(sb)->s_journal->j_devname);
1653 } else {
1654 ext4_msg(sb, KERN_INFO, "no journal");
1655 }
1656 return res; 1661 return res;
1657} 1662}
1658 1663
@@ -2197,6 +2202,7 @@ EXT4_RW_ATTR_SBI_UI(mb_min_to_scan, s_mb_min_to_scan);
2197EXT4_RW_ATTR_SBI_UI(mb_order2_req, s_mb_order2_reqs); 2202EXT4_RW_ATTR_SBI_UI(mb_order2_req, s_mb_order2_reqs);
2198EXT4_RW_ATTR_SBI_UI(mb_stream_req, s_mb_stream_request); 2203EXT4_RW_ATTR_SBI_UI(mb_stream_req, s_mb_stream_request);
2199EXT4_RW_ATTR_SBI_UI(mb_group_prealloc, s_mb_group_prealloc); 2204EXT4_RW_ATTR_SBI_UI(mb_group_prealloc, s_mb_group_prealloc);
2205EXT4_RW_ATTR_SBI_UI(max_writeback_mb_bump, s_max_writeback_mb_bump);
2200 2206
2201static struct attribute *ext4_attrs[] = { 2207static struct attribute *ext4_attrs[] = {
2202 ATTR_LIST(delayed_allocation_blocks), 2208 ATTR_LIST(delayed_allocation_blocks),
@@ -2210,6 +2216,7 @@ static struct attribute *ext4_attrs[] = {
2210 ATTR_LIST(mb_order2_req), 2216 ATTR_LIST(mb_order2_req),
2211 ATTR_LIST(mb_stream_req), 2217 ATTR_LIST(mb_stream_req),
2212 ATTR_LIST(mb_group_prealloc), 2218 ATTR_LIST(mb_group_prealloc),
2219 ATTR_LIST(max_writeback_mb_bump),
2213 NULL, 2220 NULL,
2214}; 2221};
2215 2222
@@ -2413,7 +2420,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
2413 sbi->s_commit_interval = JBD2_DEFAULT_MAX_COMMIT_AGE * HZ; 2420 sbi->s_commit_interval = JBD2_DEFAULT_MAX_COMMIT_AGE * HZ;
2414 sbi->s_min_batch_time = EXT4_DEF_MIN_BATCH_TIME; 2421 sbi->s_min_batch_time = EXT4_DEF_MIN_BATCH_TIME;
2415 sbi->s_max_batch_time = EXT4_DEF_MAX_BATCH_TIME; 2422 sbi->s_max_batch_time = EXT4_DEF_MAX_BATCH_TIME;
2416 sbi->s_mb_history_max = default_mb_history_length;
2417 2423
2418 set_opt(sbi->s_mount_opt, BARRIER); 2424 set_opt(sbi->s_mount_opt, BARRIER);
2419 2425
@@ -2679,6 +2685,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
2679 } 2685 }
2680 2686
2681 sbi->s_stripe = ext4_get_stripe_size(sbi); 2687 sbi->s_stripe = ext4_get_stripe_size(sbi);
2688 sbi->s_max_writeback_mb_bump = 128;
2682 2689
2683 /* 2690 /*
2684 * set up enough so that it can read an inode 2691 * set up enough so that it can read an inode
@@ -2798,6 +2805,12 @@ no_journal:
2798 clear_opt(sbi->s_mount_opt, NOBH); 2805 clear_opt(sbi->s_mount_opt, NOBH);
2799 } 2806 }
2800 } 2807 }
2808 EXT4_SB(sb)->dio_unwritten_wq = create_workqueue("ext4-dio-unwritten");
2809 if (!EXT4_SB(sb)->dio_unwritten_wq) {
2810 printk(KERN_ERR "EXT4-fs: failed to create DIO workqueue\n");
2811 goto failed_mount_wq;
2812 }
2813
2801 /* 2814 /*
2802 * The jbd2_journal_load will have done any necessary log recovery, 2815 * The jbd2_journal_load will have done any necessary log recovery,
2803 * so we can safely mount the rest of the filesystem now. 2816 * so we can safely mount the rest of the filesystem now.
@@ -2849,12 +2862,12 @@ no_journal:
2849 "available"); 2862 "available");
2850 } 2863 }
2851 2864
2852 if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) { 2865 if (test_opt(sb, DELALLOC) &&
2866 (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA)) {
2853 ext4_msg(sb, KERN_WARNING, "Ignoring delalloc option - " 2867 ext4_msg(sb, KERN_WARNING, "Ignoring delalloc option - "
2854 "requested data journaling mode"); 2868 "requested data journaling mode");
2855 clear_opt(sbi->s_mount_opt, DELALLOC); 2869 clear_opt(sbi->s_mount_opt, DELALLOC);
2856 } else if (test_opt(sb, DELALLOC)) 2870 }
2857 ext4_msg(sb, KERN_INFO, "delayed allocation enabled");
2858 2871
2859 err = ext4_setup_system_zone(sb); 2872 err = ext4_setup_system_zone(sb);
2860 if (err) { 2873 if (err) {
@@ -2910,6 +2923,8 @@ cantfind_ext4:
2910 2923
2911failed_mount4: 2924failed_mount4:
2912 ext4_msg(sb, KERN_ERR, "mount failed"); 2925 ext4_msg(sb, KERN_ERR, "mount failed");
2926 destroy_workqueue(EXT4_SB(sb)->dio_unwritten_wq);
2927failed_mount_wq:
2913 ext4_release_system_zone(sb); 2928 ext4_release_system_zone(sb);
2914 if (sbi->s_journal) { 2929 if (sbi->s_journal) {
2915 jbd2_journal_destroy(sbi->s_journal); 2930 jbd2_journal_destroy(sbi->s_journal);
@@ -3164,9 +3179,7 @@ static int ext4_load_journal(struct super_block *sb,
3164 return -EINVAL; 3179 return -EINVAL;
3165 } 3180 }
3166 3181
3167 if (journal->j_flags & JBD2_BARRIER) 3182 if (!(journal->j_flags & JBD2_BARRIER))
3168 ext4_msg(sb, KERN_INFO, "barriers enabled");
3169 else
3170 ext4_msg(sb, KERN_INFO, "barriers disabled"); 3183 ext4_msg(sb, KERN_INFO, "barriers disabled");
3171 3184
3172 if (!really_read_only && test_opt(sb, UPDATE_JOURNAL)) { 3185 if (!really_read_only && test_opt(sb, UPDATE_JOURNAL)) {
@@ -3361,11 +3374,13 @@ static int ext4_sync_fs(struct super_block *sb, int wait)
3361{ 3374{
3362 int ret = 0; 3375 int ret = 0;
3363 tid_t target; 3376 tid_t target;
3377 struct ext4_sb_info *sbi = EXT4_SB(sb);
3364 3378
3365 trace_ext4_sync_fs(sb, wait); 3379 trace_ext4_sync_fs(sb, wait);
3366 if (jbd2_journal_start_commit(EXT4_SB(sb)->s_journal, &target)) { 3380 flush_workqueue(sbi->dio_unwritten_wq);
3381 if (jbd2_journal_start_commit(sbi->s_journal, &target)) {
3367 if (wait) 3382 if (wait)
3368 jbd2_log_wait_commit(EXT4_SB(sb)->s_journal, target); 3383 jbd2_log_wait_commit(sbi->s_journal, target);
3369 } 3384 }
3370 return ret; 3385 return ret;
3371} 3386}
@@ -3951,27 +3966,6 @@ static struct file_system_type ext4_fs_type = {
3951 .fs_flags = FS_REQUIRES_DEV, 3966 .fs_flags = FS_REQUIRES_DEV,
3952}; 3967};
3953 3968
3954#ifdef CONFIG_EXT4DEV_COMPAT
3955static int ext4dev_get_sb(struct file_system_type *fs_type, int flags,
3956 const char *dev_name, void *data,struct vfsmount *mnt)
3957{
3958 printk(KERN_WARNING "EXT4-fs (%s): Update your userspace programs "
3959 "to mount using ext4\n", dev_name);
3960 printk(KERN_WARNING "EXT4-fs (%s): ext4dev backwards compatibility "
3961 "will go away by 2.6.31\n", dev_name);
3962 return get_sb_bdev(fs_type, flags, dev_name, data, ext4_fill_super,mnt);
3963}
3964
3965static struct file_system_type ext4dev_fs_type = {
3966 .owner = THIS_MODULE,
3967 .name = "ext4dev",
3968 .get_sb = ext4dev_get_sb,
3969 .kill_sb = kill_block_super,
3970 .fs_flags = FS_REQUIRES_DEV,
3971};
3972MODULE_ALIAS("ext4dev");
3973#endif
3974
3975static int __init init_ext4_fs(void) 3969static int __init init_ext4_fs(void)
3976{ 3970{
3977 int err; 3971 int err;
@@ -3996,13 +3990,6 @@ static int __init init_ext4_fs(void)
3996 err = register_filesystem(&ext4_fs_type); 3990 err = register_filesystem(&ext4_fs_type);
3997 if (err) 3991 if (err)
3998 goto out; 3992 goto out;
3999#ifdef CONFIG_EXT4DEV_COMPAT
4000 err = register_filesystem(&ext4dev_fs_type);
4001 if (err) {
4002 unregister_filesystem(&ext4_fs_type);
4003 goto out;
4004 }
4005#endif
4006 return 0; 3993 return 0;
4007out: 3994out:
4008 destroy_inodecache(); 3995 destroy_inodecache();
@@ -4021,9 +4008,6 @@ out4:
4021static void __exit exit_ext4_fs(void) 4008static void __exit exit_ext4_fs(void)
4022{ 4009{
4023 unregister_filesystem(&ext4_fs_type); 4010 unregister_filesystem(&ext4_fs_type);
4024#ifdef CONFIG_EXT4DEV_COMPAT
4025 unregister_filesystem(&ext4dev_fs_type);
4026#endif
4027 destroy_inodecache(); 4011 destroy_inodecache();
4028 exit_ext4_xattr(); 4012 exit_ext4_xattr();
4029 exit_ext4_mballoc(); 4013 exit_ext4_mballoc();
diff --git a/fs/fat/fat.h b/fs/fat/fat.h
index adb0e72a176d..7db0979c6b72 100644
--- a/fs/fat/fat.h
+++ b/fs/fat/fat.h
@@ -323,7 +323,7 @@ extern int fat_flush_inodes(struct super_block *sb, struct inode *i1,
323/* fat/misc.c */ 323/* fat/misc.c */
324extern void fat_fs_error(struct super_block *s, const char *fmt, ...) 324extern void fat_fs_error(struct super_block *s, const char *fmt, ...)
325 __attribute__ ((format (printf, 2, 3))) __cold; 325 __attribute__ ((format (printf, 2, 3))) __cold;
326extern void fat_clusters_flush(struct super_block *sb); 326extern int fat_clusters_flush(struct super_block *sb);
327extern int fat_chain_add(struct inode *inode, int new_dclus, int nr_cluster); 327extern int fat_chain_add(struct inode *inode, int new_dclus, int nr_cluster);
328extern void fat_time_fat2unix(struct msdos_sb_info *sbi, struct timespec *ts, 328extern void fat_time_fat2unix(struct msdos_sb_info *sbi, struct timespec *ts,
329 __le16 __time, __le16 __date, u8 time_cs); 329 __le16 __time, __le16 __date, u8 time_cs);
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index 04629d1302fc..76b7961ab663 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -451,12 +451,16 @@ static void fat_write_super(struct super_block *sb)
451 451
452static int fat_sync_fs(struct super_block *sb, int wait) 452static int fat_sync_fs(struct super_block *sb, int wait)
453{ 453{
454 lock_super(sb); 454 int err = 0;
455 fat_clusters_flush(sb);
456 sb->s_dirt = 0;
457 unlock_super(sb);
458 455
459 return 0; 456 if (sb->s_dirt) {
457 lock_super(sb);
458 sb->s_dirt = 0;
459 err = fat_clusters_flush(sb);
460 unlock_super(sb);
461 }
462
463 return err;
460} 464}
461 465
462static void fat_put_super(struct super_block *sb) 466static void fat_put_super(struct super_block *sb)
@@ -812,7 +816,7 @@ static int fat_show_options(struct seq_file *m, struct vfsmount *mnt)
812 seq_puts(m, ",shortname=mixed"); 816 seq_puts(m, ",shortname=mixed");
813 break; 817 break;
814 case VFAT_SFN_DISPLAY_LOWER | VFAT_SFN_CREATE_WIN95: 818 case VFAT_SFN_DISPLAY_LOWER | VFAT_SFN_CREATE_WIN95:
815 /* seq_puts(m, ",shortname=lower"); */ 819 seq_puts(m, ",shortname=lower");
816 break; 820 break;
817 default: 821 default:
818 seq_puts(m, ",shortname=unknown"); 822 seq_puts(m, ",shortname=unknown");
@@ -963,7 +967,7 @@ static int parse_options(char *options, int is_vfat, int silent, int *debug,
963 opts->codepage = fat_default_codepage; 967 opts->codepage = fat_default_codepage;
964 opts->iocharset = fat_default_iocharset; 968 opts->iocharset = fat_default_iocharset;
965 if (is_vfat) { 969 if (is_vfat) {
966 opts->shortname = VFAT_SFN_DISPLAY_LOWER|VFAT_SFN_CREATE_WIN95; 970 opts->shortname = VFAT_SFN_DISPLAY_WINNT|VFAT_SFN_CREATE_WIN95;
967 opts->rodir = 0; 971 opts->rodir = 0;
968 } else { 972 } else {
969 opts->shortname = 0; 973 opts->shortname = 0;
diff --git a/fs/fat/misc.c b/fs/fat/misc.c
index 4e35be873e09..0f55f5cb732f 100644
--- a/fs/fat/misc.c
+++ b/fs/fat/misc.c
@@ -43,19 +43,19 @@ EXPORT_SYMBOL_GPL(fat_fs_error);
43 43
44/* Flushes the number of free clusters on FAT32 */ 44/* Flushes the number of free clusters on FAT32 */
45/* XXX: Need to write one per FSINFO block. Currently only writes 1 */ 45/* XXX: Need to write one per FSINFO block. Currently only writes 1 */
46void fat_clusters_flush(struct super_block *sb) 46int fat_clusters_flush(struct super_block *sb)
47{ 47{
48 struct msdos_sb_info *sbi = MSDOS_SB(sb); 48 struct msdos_sb_info *sbi = MSDOS_SB(sb);
49 struct buffer_head *bh; 49 struct buffer_head *bh;
50 struct fat_boot_fsinfo *fsinfo; 50 struct fat_boot_fsinfo *fsinfo;
51 51
52 if (sbi->fat_bits != 32) 52 if (sbi->fat_bits != 32)
53 return; 53 return 0;
54 54
55 bh = sb_bread(sb, sbi->fsinfo_sector); 55 bh = sb_bread(sb, sbi->fsinfo_sector);
56 if (bh == NULL) { 56 if (bh == NULL) {
57 printk(KERN_ERR "FAT: bread failed in fat_clusters_flush\n"); 57 printk(KERN_ERR "FAT: bread failed in fat_clusters_flush\n");
58 return; 58 return -EIO;
59 } 59 }
60 60
61 fsinfo = (struct fat_boot_fsinfo *)bh->b_data; 61 fsinfo = (struct fat_boot_fsinfo *)bh->b_data;
@@ -74,6 +74,8 @@ void fat_clusters_flush(struct super_block *sb)
74 mark_buffer_dirty(bh); 74 mark_buffer_dirty(bh);
75 } 75 }
76 brelse(bh); 76 brelse(bh);
77
78 return 0;
77} 79}
78 80
79/* 81/*
diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c
index cb6e83557112..f565f24019b5 100644
--- a/fs/fat/namei_vfat.c
+++ b/fs/fat/namei_vfat.c
@@ -499,17 +499,10 @@ xlate_to_uni(const unsigned char *name, int len, unsigned char *outname,
499 int charlen; 499 int charlen;
500 500
501 if (utf8) { 501 if (utf8) {
502 int name_len = strlen(name); 502 *outlen = utf8s_to_utf16s(name, len, (wchar_t *)outname);
503 503 if (*outlen < 0)
504 *outlen = utf8s_to_utf16s(name, PATH_MAX, (wchar_t *) outname); 504 return *outlen;
505 505 else if (*outlen > 255)
506 /*
507 * We stripped '.'s before and set len appropriately,
508 * but utf8s_to_utf16s doesn't care about len
509 */
510 *outlen -= (name_len - len);
511
512 if (*outlen > 255)
513 return -ENAMETOOLONG; 506 return -ENAMETOOLONG;
514 507
515 op = &outname[*outlen * sizeof(wchar_t)]; 508 op = &outname[*outlen * sizeof(wchar_t)];
diff --git a/fs/file.c b/fs/file.c
index f313314f996f..87e129030ab1 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -10,6 +10,7 @@
10#include <linux/fs.h> 10#include <linux/fs.h>
11#include <linux/mm.h> 11#include <linux/mm.h>
12#include <linux/time.h> 12#include <linux/time.h>
13#include <linux/sched.h>
13#include <linux/slab.h> 14#include <linux/slab.h>
14#include <linux/vmalloc.h> 15#include <linux/vmalloc.h>
15#include <linux/file.h> 16#include <linux/file.h>
diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c
index 5d70b3e6d49b..ca0f5eb62b20 100644
--- a/fs/jbd2/checkpoint.c
+++ b/fs/jbd2/checkpoint.c
@@ -643,6 +643,7 @@ out:
643 643
644int __jbd2_journal_remove_checkpoint(struct journal_head *jh) 644int __jbd2_journal_remove_checkpoint(struct journal_head *jh)
645{ 645{
646 struct transaction_chp_stats_s *stats;
646 transaction_t *transaction; 647 transaction_t *transaction;
647 journal_t *journal; 648 journal_t *journal;
648 int ret = 0; 649 int ret = 0;
@@ -679,6 +680,12 @@ int __jbd2_journal_remove_checkpoint(struct journal_head *jh)
679 680
680 /* OK, that was the last buffer for the transaction: we can now 681 /* OK, that was the last buffer for the transaction: we can now
681 safely remove this transaction from the log */ 682 safely remove this transaction from the log */
683 stats = &transaction->t_chp_stats;
684 if (stats->cs_chp_time)
685 stats->cs_chp_time = jbd2_time_diff(stats->cs_chp_time,
686 jiffies);
687 trace_jbd2_checkpoint_stats(journal->j_fs_dev->bd_dev,
688 transaction->t_tid, stats);
682 689
683 __jbd2_journal_drop_transaction(journal, transaction); 690 __jbd2_journal_drop_transaction(journal, transaction);
684 kfree(transaction); 691 kfree(transaction);
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
index 26d991ddc1e6..d4cfd6d2779e 100644
--- a/fs/jbd2/commit.c
+++ b/fs/jbd2/commit.c
@@ -410,10 +410,10 @@ void jbd2_journal_commit_transaction(journal_t *journal)
410 if (commit_transaction->t_synchronous_commit) 410 if (commit_transaction->t_synchronous_commit)
411 write_op = WRITE_SYNC_PLUG; 411 write_op = WRITE_SYNC_PLUG;
412 trace_jbd2_commit_locking(journal, commit_transaction); 412 trace_jbd2_commit_locking(journal, commit_transaction);
413 stats.u.run.rs_wait = commit_transaction->t_max_wait; 413 stats.run.rs_wait = commit_transaction->t_max_wait;
414 stats.u.run.rs_locked = jiffies; 414 stats.run.rs_locked = jiffies;
415 stats.u.run.rs_running = jbd2_time_diff(commit_transaction->t_start, 415 stats.run.rs_running = jbd2_time_diff(commit_transaction->t_start,
416 stats.u.run.rs_locked); 416 stats.run.rs_locked);
417 417
418 spin_lock(&commit_transaction->t_handle_lock); 418 spin_lock(&commit_transaction->t_handle_lock);
419 while (commit_transaction->t_updates) { 419 while (commit_transaction->t_updates) {
@@ -486,9 +486,9 @@ void jbd2_journal_commit_transaction(journal_t *journal)
486 jbd2_journal_switch_revoke_table(journal); 486 jbd2_journal_switch_revoke_table(journal);
487 487
488 trace_jbd2_commit_flushing(journal, commit_transaction); 488 trace_jbd2_commit_flushing(journal, commit_transaction);
489 stats.u.run.rs_flushing = jiffies; 489 stats.run.rs_flushing = jiffies;
490 stats.u.run.rs_locked = jbd2_time_diff(stats.u.run.rs_locked, 490 stats.run.rs_locked = jbd2_time_diff(stats.run.rs_locked,
491 stats.u.run.rs_flushing); 491 stats.run.rs_flushing);
492 492
493 commit_transaction->t_state = T_FLUSH; 493 commit_transaction->t_state = T_FLUSH;
494 journal->j_committing_transaction = commit_transaction; 494 journal->j_committing_transaction = commit_transaction;
@@ -523,11 +523,11 @@ void jbd2_journal_commit_transaction(journal_t *journal)
523 spin_unlock(&journal->j_state_lock); 523 spin_unlock(&journal->j_state_lock);
524 524
525 trace_jbd2_commit_logging(journal, commit_transaction); 525 trace_jbd2_commit_logging(journal, commit_transaction);
526 stats.u.run.rs_logging = jiffies; 526 stats.run.rs_logging = jiffies;
527 stats.u.run.rs_flushing = jbd2_time_diff(stats.u.run.rs_flushing, 527 stats.run.rs_flushing = jbd2_time_diff(stats.run.rs_flushing,
528 stats.u.run.rs_logging); 528 stats.run.rs_logging);
529 stats.u.run.rs_blocks = commit_transaction->t_outstanding_credits; 529 stats.run.rs_blocks = commit_transaction->t_outstanding_credits;
530 stats.u.run.rs_blocks_logged = 0; 530 stats.run.rs_blocks_logged = 0;
531 531
532 J_ASSERT(commit_transaction->t_nr_buffers <= 532 J_ASSERT(commit_transaction->t_nr_buffers <=
533 commit_transaction->t_outstanding_credits); 533 commit_transaction->t_outstanding_credits);
@@ -695,7 +695,7 @@ start_journal_io:
695 submit_bh(write_op, bh); 695 submit_bh(write_op, bh);
696 } 696 }
697 cond_resched(); 697 cond_resched();
698 stats.u.run.rs_blocks_logged += bufs; 698 stats.run.rs_blocks_logged += bufs;
699 699
700 /* Force a new descriptor to be generated next 700 /* Force a new descriptor to be generated next
701 time round the loop. */ 701 time round the loop. */
@@ -988,33 +988,30 @@ restart_loop:
988 J_ASSERT(commit_transaction->t_state == T_COMMIT); 988 J_ASSERT(commit_transaction->t_state == T_COMMIT);
989 989
990 commit_transaction->t_start = jiffies; 990 commit_transaction->t_start = jiffies;
991 stats.u.run.rs_logging = jbd2_time_diff(stats.u.run.rs_logging, 991 stats.run.rs_logging = jbd2_time_diff(stats.run.rs_logging,
992 commit_transaction->t_start); 992 commit_transaction->t_start);
993 993
994 /* 994 /*
995 * File the transaction for history 995 * File the transaction statistics
996 */ 996 */
997 stats.ts_type = JBD2_STATS_RUN;
998 stats.ts_tid = commit_transaction->t_tid; 997 stats.ts_tid = commit_transaction->t_tid;
999 stats.u.run.rs_handle_count = commit_transaction->t_handle_count; 998 stats.run.rs_handle_count = commit_transaction->t_handle_count;
1000 spin_lock(&journal->j_history_lock); 999 trace_jbd2_run_stats(journal->j_fs_dev->bd_dev,
1001 memcpy(journal->j_history + journal->j_history_cur, &stats, 1000 commit_transaction->t_tid, &stats.run);
1002 sizeof(stats));
1003 if (++journal->j_history_cur == journal->j_history_max)
1004 journal->j_history_cur = 0;
1005 1001
1006 /* 1002 /*
1007 * Calculate overall stats 1003 * Calculate overall stats
1008 */ 1004 */
1005 spin_lock(&journal->j_history_lock);
1009 journal->j_stats.ts_tid++; 1006 journal->j_stats.ts_tid++;
1010 journal->j_stats.u.run.rs_wait += stats.u.run.rs_wait; 1007 journal->j_stats.run.rs_wait += stats.run.rs_wait;
1011 journal->j_stats.u.run.rs_running += stats.u.run.rs_running; 1008 journal->j_stats.run.rs_running += stats.run.rs_running;
1012 journal->j_stats.u.run.rs_locked += stats.u.run.rs_locked; 1009 journal->j_stats.run.rs_locked += stats.run.rs_locked;
1013 journal->j_stats.u.run.rs_flushing += stats.u.run.rs_flushing; 1010 journal->j_stats.run.rs_flushing += stats.run.rs_flushing;
1014 journal->j_stats.u.run.rs_logging += stats.u.run.rs_logging; 1011 journal->j_stats.run.rs_logging += stats.run.rs_logging;
1015 journal->j_stats.u.run.rs_handle_count += stats.u.run.rs_handle_count; 1012 journal->j_stats.run.rs_handle_count += stats.run.rs_handle_count;
1016 journal->j_stats.u.run.rs_blocks += stats.u.run.rs_blocks; 1013 journal->j_stats.run.rs_blocks += stats.run.rs_blocks;
1017 journal->j_stats.u.run.rs_blocks_logged += stats.u.run.rs_blocks_logged; 1014 journal->j_stats.run.rs_blocks_logged += stats.run.rs_blocks_logged;
1018 spin_unlock(&journal->j_history_lock); 1015 spin_unlock(&journal->j_history_lock);
1019 1016
1020 commit_transaction->t_state = T_FINISHED; 1017 commit_transaction->t_state = T_FINISHED;
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index 53b86e16e5fe..b0ab5219becb 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -136,10 +136,6 @@ static int kjournald2(void *arg)
136 journal->j_task = current; 136 journal->j_task = current;
137 wake_up(&journal->j_wait_done_commit); 137 wake_up(&journal->j_wait_done_commit);
138 138
139 printk(KERN_INFO "kjournald2 starting: pid %d, dev %s, "
140 "commit interval %ld seconds\n", current->pid,
141 journal->j_devname, journal->j_commit_interval / HZ);
142
143 /* 139 /*
144 * And now, wait forever for commit wakeup events. 140 * And now, wait forever for commit wakeup events.
145 */ 141 */
@@ -223,7 +219,8 @@ static int jbd2_journal_start_thread(journal_t *journal)
223{ 219{
224 struct task_struct *t; 220 struct task_struct *t;
225 221
226 t = kthread_run(kjournald2, journal, "kjournald2"); 222 t = kthread_run(kjournald2, journal, "jbd2/%s",
223 journal->j_devname);
227 if (IS_ERR(t)) 224 if (IS_ERR(t))
228 return PTR_ERR(t); 225 return PTR_ERR(t);
229 226
@@ -679,153 +676,6 @@ struct jbd2_stats_proc_session {
679 int max; 676 int max;
680}; 677};
681 678
682static void *jbd2_history_skip_empty(struct jbd2_stats_proc_session *s,
683 struct transaction_stats_s *ts,
684 int first)
685{
686 if (ts == s->stats + s->max)
687 ts = s->stats;
688 if (!first && ts == s->stats + s->start)
689 return NULL;
690 while (ts->ts_type == 0) {
691 ts++;
692 if (ts == s->stats + s->max)
693 ts = s->stats;
694 if (ts == s->stats + s->start)
695 return NULL;
696 }
697 return ts;
698
699}
700
701static void *jbd2_seq_history_start(struct seq_file *seq, loff_t *pos)
702{
703 struct jbd2_stats_proc_session *s = seq->private;
704 struct transaction_stats_s *ts;
705 int l = *pos;
706
707 if (l == 0)
708 return SEQ_START_TOKEN;
709 ts = jbd2_history_skip_empty(s, s->stats + s->start, 1);
710 if (!ts)
711 return NULL;
712 l--;
713 while (l) {
714 ts = jbd2_history_skip_empty(s, ++ts, 0);
715 if (!ts)
716 break;
717 l--;
718 }
719 return ts;
720}
721
722static void *jbd2_seq_history_next(struct seq_file *seq, void *v, loff_t *pos)
723{
724 struct jbd2_stats_proc_session *s = seq->private;
725 struct transaction_stats_s *ts = v;
726
727 ++*pos;
728 if (v == SEQ_START_TOKEN)
729 return jbd2_history_skip_empty(s, s->stats + s->start, 1);
730 else
731 return jbd2_history_skip_empty(s, ++ts, 0);
732}
733
734static int jbd2_seq_history_show(struct seq_file *seq, void *v)
735{
736 struct transaction_stats_s *ts = v;
737 if (v == SEQ_START_TOKEN) {
738 seq_printf(seq, "%-4s %-5s %-5s %-5s %-5s %-5s %-5s %-6s %-5s "
739 "%-5s %-5s %-5s %-5s %-5s\n", "R/C", "tid",
740 "wait", "run", "lock", "flush", "log", "hndls",
741 "block", "inlog", "ctime", "write", "drop",
742 "close");
743 return 0;
744 }
745 if (ts->ts_type == JBD2_STATS_RUN)
746 seq_printf(seq, "%-4s %-5lu %-5u %-5u %-5u %-5u %-5u "
747 "%-6lu %-5lu %-5lu\n", "R", ts->ts_tid,
748 jiffies_to_msecs(ts->u.run.rs_wait),
749 jiffies_to_msecs(ts->u.run.rs_running),
750 jiffies_to_msecs(ts->u.run.rs_locked),
751 jiffies_to_msecs(ts->u.run.rs_flushing),
752 jiffies_to_msecs(ts->u.run.rs_logging),
753 ts->u.run.rs_handle_count,
754 ts->u.run.rs_blocks,
755 ts->u.run.rs_blocks_logged);
756 else if (ts->ts_type == JBD2_STATS_CHECKPOINT)
757 seq_printf(seq, "%-4s %-5lu %48s %-5u %-5lu %-5lu %-5lu\n",
758 "C", ts->ts_tid, " ",
759 jiffies_to_msecs(ts->u.chp.cs_chp_time),
760 ts->u.chp.cs_written, ts->u.chp.cs_dropped,
761 ts->u.chp.cs_forced_to_close);
762 else
763 J_ASSERT(0);
764 return 0;
765}
766
767static void jbd2_seq_history_stop(struct seq_file *seq, void *v)
768{
769}
770
771static const struct seq_operations jbd2_seq_history_ops = {
772 .start = jbd2_seq_history_start,
773 .next = jbd2_seq_history_next,
774 .stop = jbd2_seq_history_stop,
775 .show = jbd2_seq_history_show,
776};
777
778static int jbd2_seq_history_open(struct inode *inode, struct file *file)
779{
780 journal_t *journal = PDE(inode)->data;
781 struct jbd2_stats_proc_session *s;
782 int rc, size;
783
784 s = kmalloc(sizeof(*s), GFP_KERNEL);
785 if (s == NULL)
786 return -ENOMEM;
787 size = sizeof(struct transaction_stats_s) * journal->j_history_max;
788 s->stats = kmalloc(size, GFP_KERNEL);
789 if (s->stats == NULL) {
790 kfree(s);
791 return -ENOMEM;
792 }
793 spin_lock(&journal->j_history_lock);
794 memcpy(s->stats, journal->j_history, size);
795 s->max = journal->j_history_max;
796 s->start = journal->j_history_cur % s->max;
797 spin_unlock(&journal->j_history_lock);
798
799 rc = seq_open(file, &jbd2_seq_history_ops);
800 if (rc == 0) {
801 struct seq_file *m = file->private_data;
802 m->private = s;
803 } else {
804 kfree(s->stats);
805 kfree(s);
806 }
807 return rc;
808
809}
810
811static int jbd2_seq_history_release(struct inode *inode, struct file *file)
812{
813 struct seq_file *seq = file->private_data;
814 struct jbd2_stats_proc_session *s = seq->private;
815
816 kfree(s->stats);
817 kfree(s);
818 return seq_release(inode, file);
819}
820
821static struct file_operations jbd2_seq_history_fops = {
822 .owner = THIS_MODULE,
823 .open = jbd2_seq_history_open,
824 .read = seq_read,
825 .llseek = seq_lseek,
826 .release = jbd2_seq_history_release,
827};
828
829static void *jbd2_seq_info_start(struct seq_file *seq, loff_t *pos) 679static void *jbd2_seq_info_start(struct seq_file *seq, loff_t *pos)
830{ 680{
831 return *pos ? NULL : SEQ_START_TOKEN; 681 return *pos ? NULL : SEQ_START_TOKEN;
@@ -842,29 +692,29 @@ static int jbd2_seq_info_show(struct seq_file *seq, void *v)
842 692
843 if (v != SEQ_START_TOKEN) 693 if (v != SEQ_START_TOKEN)
844 return 0; 694 return 0;
845 seq_printf(seq, "%lu transaction, each upto %u blocks\n", 695 seq_printf(seq, "%lu transaction, each up to %u blocks\n",
846 s->stats->ts_tid, 696 s->stats->ts_tid,
847 s->journal->j_max_transaction_buffers); 697 s->journal->j_max_transaction_buffers);
848 if (s->stats->ts_tid == 0) 698 if (s->stats->ts_tid == 0)
849 return 0; 699 return 0;
850 seq_printf(seq, "average: \n %ums waiting for transaction\n", 700 seq_printf(seq, "average: \n %ums waiting for transaction\n",
851 jiffies_to_msecs(s->stats->u.run.rs_wait / s->stats->ts_tid)); 701 jiffies_to_msecs(s->stats->run.rs_wait / s->stats->ts_tid));
852 seq_printf(seq, " %ums running transaction\n", 702 seq_printf(seq, " %ums running transaction\n",
853 jiffies_to_msecs(s->stats->u.run.rs_running / s->stats->ts_tid)); 703 jiffies_to_msecs(s->stats->run.rs_running / s->stats->ts_tid));
854 seq_printf(seq, " %ums transaction was being locked\n", 704 seq_printf(seq, " %ums transaction was being locked\n",
855 jiffies_to_msecs(s->stats->u.run.rs_locked / s->stats->ts_tid)); 705 jiffies_to_msecs(s->stats->run.rs_locked / s->stats->ts_tid));
856 seq_printf(seq, " %ums flushing data (in ordered mode)\n", 706 seq_printf(seq, " %ums flushing data (in ordered mode)\n",
857 jiffies_to_msecs(s->stats->u.run.rs_flushing / s->stats->ts_tid)); 707 jiffies_to_msecs(s->stats->run.rs_flushing / s->stats->ts_tid));
858 seq_printf(seq, " %ums logging transaction\n", 708 seq_printf(seq, " %ums logging transaction\n",
859 jiffies_to_msecs(s->stats->u.run.rs_logging / s->stats->ts_tid)); 709 jiffies_to_msecs(s->stats->run.rs_logging / s->stats->ts_tid));
860 seq_printf(seq, " %lluus average transaction commit time\n", 710 seq_printf(seq, " %lluus average transaction commit time\n",
861 div_u64(s->journal->j_average_commit_time, 1000)); 711 div_u64(s->journal->j_average_commit_time, 1000));
862 seq_printf(seq, " %lu handles per transaction\n", 712 seq_printf(seq, " %lu handles per transaction\n",
863 s->stats->u.run.rs_handle_count / s->stats->ts_tid); 713 s->stats->run.rs_handle_count / s->stats->ts_tid);
864 seq_printf(seq, " %lu blocks per transaction\n", 714 seq_printf(seq, " %lu blocks per transaction\n",
865 s->stats->u.run.rs_blocks / s->stats->ts_tid); 715 s->stats->run.rs_blocks / s->stats->ts_tid);
866 seq_printf(seq, " %lu logged blocks per transaction\n", 716 seq_printf(seq, " %lu logged blocks per transaction\n",
867 s->stats->u.run.rs_blocks_logged / s->stats->ts_tid); 717 s->stats->run.rs_blocks_logged / s->stats->ts_tid);
868 return 0; 718 return 0;
869} 719}
870 720
@@ -920,7 +770,7 @@ static int jbd2_seq_info_release(struct inode *inode, struct file *file)
920 return seq_release(inode, file); 770 return seq_release(inode, file);
921} 771}
922 772
923static struct file_operations jbd2_seq_info_fops = { 773static const struct file_operations jbd2_seq_info_fops = {
924 .owner = THIS_MODULE, 774 .owner = THIS_MODULE,
925 .open = jbd2_seq_info_open, 775 .open = jbd2_seq_info_open,
926 .read = seq_read, 776 .read = seq_read,
@@ -934,8 +784,6 @@ static void jbd2_stats_proc_init(journal_t *journal)
934{ 784{
935 journal->j_proc_entry = proc_mkdir(journal->j_devname, proc_jbd2_stats); 785 journal->j_proc_entry = proc_mkdir(journal->j_devname, proc_jbd2_stats);
936 if (journal->j_proc_entry) { 786 if (journal->j_proc_entry) {
937 proc_create_data("history", S_IRUGO, journal->j_proc_entry,
938 &jbd2_seq_history_fops, journal);
939 proc_create_data("info", S_IRUGO, journal->j_proc_entry, 787 proc_create_data("info", S_IRUGO, journal->j_proc_entry,
940 &jbd2_seq_info_fops, journal); 788 &jbd2_seq_info_fops, journal);
941 } 789 }
@@ -944,27 +792,9 @@ static void jbd2_stats_proc_init(journal_t *journal)
944static void jbd2_stats_proc_exit(journal_t *journal) 792static void jbd2_stats_proc_exit(journal_t *journal)
945{ 793{
946 remove_proc_entry("info", journal->j_proc_entry); 794 remove_proc_entry("info", journal->j_proc_entry);
947 remove_proc_entry("history", journal->j_proc_entry);
948 remove_proc_entry(journal->j_devname, proc_jbd2_stats); 795 remove_proc_entry(journal->j_devname, proc_jbd2_stats);
949} 796}
950 797
951static void journal_init_stats(journal_t *journal)
952{
953 int size;
954
955 if (!proc_jbd2_stats)
956 return;
957
958 journal->j_history_max = 100;
959 size = sizeof(struct transaction_stats_s) * journal->j_history_max;
960 journal->j_history = kzalloc(size, GFP_KERNEL);
961 if (!journal->j_history) {
962 journal->j_history_max = 0;
963 return;
964 }
965 spin_lock_init(&journal->j_history_lock);
966}
967
968/* 798/*
969 * Management for journal control blocks: functions to create and 799 * Management for journal control blocks: functions to create and
970 * destroy journal_t structures, and to initialise and read existing 800 * destroy journal_t structures, and to initialise and read existing
@@ -1009,7 +839,7 @@ static journal_t * journal_init_common (void)
1009 goto fail; 839 goto fail;
1010 } 840 }
1011 841
1012 journal_init_stats(journal); 842 spin_lock_init(&journal->j_history_lock);
1013 843
1014 return journal; 844 return journal;
1015fail: 845fail:
@@ -1115,7 +945,7 @@ journal_t * jbd2_journal_init_inode (struct inode *inode)
1115 while ((p = strchr(p, '/'))) 945 while ((p = strchr(p, '/')))
1116 *p = '!'; 946 *p = '!';
1117 p = journal->j_devname + strlen(journal->j_devname); 947 p = journal->j_devname + strlen(journal->j_devname);
1118 sprintf(p, ":%lu", journal->j_inode->i_ino); 948 sprintf(p, "-%lu", journal->j_inode->i_ino);
1119 jbd_debug(1, 949 jbd_debug(1,
1120 "journal %p: inode %s/%ld, size %Ld, bits %d, blksize %ld\n", 950 "journal %p: inode %s/%ld, size %Ld, bits %d, blksize %ld\n",
1121 journal, inode->i_sb->s_id, inode->i_ino, 951 journal, inode->i_sb->s_id, inode->i_ino,
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 63976c0ccc25..99ea196f071f 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -1180,7 +1180,7 @@ static int nfs4_init_client(struct nfs_client *clp,
1180 1, flags & NFS_MOUNT_NORESVPORT); 1180 1, flags & NFS_MOUNT_NORESVPORT);
1181 if (error < 0) 1181 if (error < 0)
1182 goto error; 1182 goto error;
1183 memcpy(clp->cl_ipaddr, ip_addr, sizeof(clp->cl_ipaddr)); 1183 strlcpy(clp->cl_ipaddr, ip_addr, sizeof(clp->cl_ipaddr));
1184 1184
1185 error = nfs_idmap_new(clp); 1185 error = nfs_idmap_new(clp);
1186 if (error < 0) { 1186 if (error < 0) {
diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c
index 2636c26d56fa..fa3408f20112 100644
--- a/fs/nfs/nfs4namespace.c
+++ b/fs/nfs/nfs4namespace.c
@@ -121,7 +121,7 @@ static struct vfsmount *try_location(struct nfs_clone_mount *mountdata,
121 121
122 mnt_path = nfs4_pathname_string(&location->rootpath, page2, PAGE_SIZE); 122 mnt_path = nfs4_pathname_string(&location->rootpath, page2, PAGE_SIZE);
123 if (IS_ERR(mnt_path)) 123 if (IS_ERR(mnt_path))
124 return mnt; 124 return ERR_CAST(mnt_path);
125 mountdata->mnt_path = mnt_path; 125 mountdata->mnt_path = mnt_path;
126 maxbuflen = mnt_path - 1 - page2; 126 maxbuflen = mnt_path - 1 - page2;
127 127
@@ -132,15 +132,15 @@ static struct vfsmount *try_location(struct nfs_clone_mount *mountdata,
132 if (buf->len <= 0 || buf->len >= maxbuflen) 132 if (buf->len <= 0 || buf->len >= maxbuflen)
133 continue; 133 continue;
134 134
135 mountdata->addr = (struct sockaddr *)&addr;
136
137 if (memchr(buf->data, IPV6_SCOPE_DELIMITER, buf->len)) 135 if (memchr(buf->data, IPV6_SCOPE_DELIMITER, buf->len))
138 continue; 136 continue;
139 mountdata->addrlen = nfs_parse_server_name(buf->data, 137
140 buf->len, 138 mountdata->addrlen = nfs_parse_server_name(buf->data, buf->len,
141 mountdata->addr, mountdata->addrlen); 139 (struct sockaddr *)&addr, sizeof(addr));
142 if (mountdata->addrlen == 0) 140 if (mountdata->addrlen == 0)
143 continue; 141 continue;
142
143 mountdata->addr = (struct sockaddr *)&addr;
144 rpc_set_port(mountdata->addr, NFS_PORT); 144 rpc_set_port(mountdata->addr, NFS_PORT);
145 145
146 memcpy(page2, buf->data, buf->len); 146 memcpy(page2, buf->data, buf->len);
diff --git a/fs/nfs/nfs4renewd.c b/fs/nfs/nfs4renewd.c
index e27c6cef18f2..0156c01c212c 100644
--- a/fs/nfs/nfs4renewd.c
+++ b/fs/nfs/nfs4renewd.c
@@ -127,12 +127,6 @@ nfs4_schedule_state_renewal(struct nfs_client *clp)
127} 127}
128 128
129void 129void
130nfs4_renewd_prepare_shutdown(struct nfs_server *server)
131{
132 cancel_delayed_work(&server->nfs_client->cl_renewd);
133}
134
135void
136nfs4_kill_renewd(struct nfs_client *clp) 130nfs4_kill_renewd(struct nfs_client *clp)
137{ 131{
138 cancel_delayed_work_sync(&clp->cl_renewd); 132 cancel_delayed_work_sync(&clp->cl_renewd);
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 29786d3b9326..a2c18acb8568 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -728,22 +728,24 @@ static void nfs_umount_begin(struct super_block *sb)
728 unlock_kernel(); 728 unlock_kernel();
729} 729}
730 730
731static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(int flags) 731static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(unsigned int version)
732{ 732{
733 struct nfs_parsed_mount_data *data; 733 struct nfs_parsed_mount_data *data;
734 734
735 data = kzalloc(sizeof(*data), GFP_KERNEL); 735 data = kzalloc(sizeof(*data), GFP_KERNEL);
736 if (data) { 736 if (data) {
737 data->flags = flags;
738 data->rsize = NFS_MAX_FILE_IO_SIZE; 737 data->rsize = NFS_MAX_FILE_IO_SIZE;
739 data->wsize = NFS_MAX_FILE_IO_SIZE; 738 data->wsize = NFS_MAX_FILE_IO_SIZE;
740 data->acregmin = NFS_DEF_ACREGMIN; 739 data->acregmin = NFS_DEF_ACREGMIN;
741 data->acregmax = NFS_DEF_ACREGMAX; 740 data->acregmax = NFS_DEF_ACREGMAX;
742 data->acdirmin = NFS_DEF_ACDIRMIN; 741 data->acdirmin = NFS_DEF_ACDIRMIN;
743 data->acdirmax = NFS_DEF_ACDIRMAX; 742 data->acdirmax = NFS_DEF_ACDIRMAX;
743 data->mount_server.port = NFS_UNSPEC_PORT;
744 data->nfs_server.port = NFS_UNSPEC_PORT; 744 data->nfs_server.port = NFS_UNSPEC_PORT;
745 data->nfs_server.protocol = XPRT_TRANSPORT_TCP;
745 data->auth_flavors[0] = RPC_AUTH_UNIX; 746 data->auth_flavors[0] = RPC_AUTH_UNIX;
746 data->auth_flavor_len = 1; 747 data->auth_flavor_len = 1;
748 data->version = version;
747 data->minorversion = 0; 749 data->minorversion = 0;
748 } 750 }
749 return data; 751 return data;
@@ -776,15 +778,13 @@ static int nfs_verify_server_address(struct sockaddr *addr)
776 * Select between a default port value and a user-specified port value. 778 * Select between a default port value and a user-specified port value.
777 * If a zero value is set, then autobind will be used. 779 * If a zero value is set, then autobind will be used.
778 */ 780 */
779static void nfs_set_default_port(struct sockaddr *sap, const int parsed_port, 781static void nfs_set_port(struct sockaddr *sap, int *port,
780 const unsigned short default_port) 782 const unsigned short default_port)
781{ 783{
782 unsigned short port = default_port; 784 if (*port == NFS_UNSPEC_PORT)
785 *port = default_port;
783 786
784 if (parsed_port != NFS_UNSPEC_PORT) 787 rpc_set_port(sap, *port);
785 port = parsed_port;
786
787 rpc_set_port(sap, port);
788} 788}
789 789
790/* 790/*
@@ -1475,7 +1475,7 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args,
1475 args->mount_server.addrlen = args->nfs_server.addrlen; 1475 args->mount_server.addrlen = args->nfs_server.addrlen;
1476 } 1476 }
1477 request.salen = args->mount_server.addrlen; 1477 request.salen = args->mount_server.addrlen;
1478 nfs_set_default_port(request.sap, args->mount_server.port, 0); 1478 nfs_set_port(request.sap, &args->mount_server.port, 0);
1479 1479
1480 /* 1480 /*
1481 * Now ask the mount server to map our export path 1481 * Now ask the mount server to map our export path
@@ -1711,8 +1711,6 @@ static int nfs_validate_mount_data(void *options,
1711 1711
1712 if (!(data->flags & NFS_MOUNT_TCP)) 1712 if (!(data->flags & NFS_MOUNT_TCP))
1713 args->nfs_server.protocol = XPRT_TRANSPORT_UDP; 1713 args->nfs_server.protocol = XPRT_TRANSPORT_UDP;
1714 else
1715 args->nfs_server.protocol = XPRT_TRANSPORT_TCP;
1716 /* N.B. caller will free nfs_server.hostname in all cases */ 1714 /* N.B. caller will free nfs_server.hostname in all cases */
1717 args->nfs_server.hostname = kstrdup(data->hostname, GFP_KERNEL); 1715 args->nfs_server.hostname = kstrdup(data->hostname, GFP_KERNEL);
1718 args->namlen = data->namlen; 1716 args->namlen = data->namlen;
@@ -1767,7 +1765,7 @@ static int nfs_validate_mount_data(void *options,
1767 goto out_v4_not_compiled; 1765 goto out_v4_not_compiled;
1768#endif 1766#endif
1769 1767
1770 nfs_set_default_port(sap, args->nfs_server.port, 0); 1768 nfs_set_port(sap, &args->nfs_server.port, 0);
1771 1769
1772 nfs_set_mount_transport_protocol(args); 1770 nfs_set_mount_transport_protocol(args);
1773 1771
@@ -1848,9 +1846,10 @@ nfs_compare_remount_data(struct nfs_server *nfss,
1848 data->acdirmin != nfss->acdirmin / HZ || 1846 data->acdirmin != nfss->acdirmin / HZ ||
1849 data->acdirmax != nfss->acdirmax / HZ || 1847 data->acdirmax != nfss->acdirmax / HZ ||
1850 data->timeo != (10U * nfss->client->cl_timeout->to_initval / HZ) || 1848 data->timeo != (10U * nfss->client->cl_timeout->to_initval / HZ) ||
1849 data->nfs_server.port != nfss->port ||
1851 data->nfs_server.addrlen != nfss->nfs_client->cl_addrlen || 1850 data->nfs_server.addrlen != nfss->nfs_client->cl_addrlen ||
1852 memcmp(&data->nfs_server.address, &nfss->nfs_client->cl_addr, 1851 !rpc_cmp_addr((struct sockaddr *)&data->nfs_server.address,
1853 data->nfs_server.addrlen) != 0) 1852 (struct sockaddr *)&nfss->nfs_client->cl_addr))
1854 return -EINVAL; 1853 return -EINVAL;
1855 1854
1856 return 0; 1855 return 0;
@@ -1893,6 +1892,7 @@ nfs_remount(struct super_block *sb, int *flags, char *raw_data)
1893 data->acdirmin = nfss->acdirmin / HZ; 1892 data->acdirmin = nfss->acdirmin / HZ;
1894 data->acdirmax = nfss->acdirmax / HZ; 1893 data->acdirmax = nfss->acdirmax / HZ;
1895 data->timeo = 10U * nfss->client->cl_timeout->to_initval / HZ; 1894 data->timeo = 10U * nfss->client->cl_timeout->to_initval / HZ;
1895 data->nfs_server.port = nfss->port;
1896 data->nfs_server.addrlen = nfss->nfs_client->cl_addrlen; 1896 data->nfs_server.addrlen = nfss->nfs_client->cl_addrlen;
1897 memcpy(&data->nfs_server.address, &nfss->nfs_client->cl_addr, 1897 memcpy(&data->nfs_server.address, &nfss->nfs_client->cl_addr,
1898 data->nfs_server.addrlen); 1898 data->nfs_server.addrlen);
@@ -2106,7 +2106,7 @@ static int nfs_get_sb(struct file_system_type *fs_type,
2106 }; 2106 };
2107 int error = -ENOMEM; 2107 int error = -ENOMEM;
2108 2108
2109 data = nfs_alloc_parsed_mount_data(NFS_MOUNT_VER3 | NFS_MOUNT_TCP); 2109 data = nfs_alloc_parsed_mount_data(3);
2110 mntfh = kzalloc(sizeof(*mntfh), GFP_KERNEL); 2110 mntfh = kzalloc(sizeof(*mntfh), GFP_KERNEL);
2111 if (data == NULL || mntfh == NULL) 2111 if (data == NULL || mntfh == NULL)
2112 goto out_free_fh; 2112 goto out_free_fh;
@@ -2331,7 +2331,7 @@ static int nfs4_validate_text_mount_data(void *options,
2331{ 2331{
2332 struct sockaddr *sap = (struct sockaddr *)&args->nfs_server.address; 2332 struct sockaddr *sap = (struct sockaddr *)&args->nfs_server.address;
2333 2333
2334 nfs_set_default_port(sap, args->nfs_server.port, NFS_PORT); 2334 nfs_set_port(sap, &args->nfs_server.port, NFS_PORT);
2335 2335
2336 nfs_validate_transport_protocol(args); 2336 nfs_validate_transport_protocol(args);
2337 2337
@@ -2376,7 +2376,6 @@ static int nfs4_validate_mount_data(void *options,
2376 if (data == NULL) 2376 if (data == NULL)
2377 goto out_no_data; 2377 goto out_no_data;
2378 2378
2379 args->version = 4;
2380 switch (data->version) { 2379 switch (data->version) {
2381 case 1: 2380 case 1:
2382 if (data->host_addrlen > sizeof(args->nfs_server.address)) 2381 if (data->host_addrlen > sizeof(args->nfs_server.address))
@@ -2660,7 +2659,7 @@ static int nfs4_get_sb(struct file_system_type *fs_type,
2660 struct nfs_parsed_mount_data *data; 2659 struct nfs_parsed_mount_data *data;
2661 int error = -ENOMEM; 2660 int error = -ENOMEM;
2662 2661
2663 data = nfs_alloc_parsed_mount_data(0); 2662 data = nfs_alloc_parsed_mount_data(4);
2664 if (data == NULL) 2663 if (data == NULL)
2665 goto out_free_data; 2664 goto out_free_data;
2666 2665
@@ -2690,7 +2689,6 @@ static void nfs4_kill_super(struct super_block *sb)
2690 dprintk("--> %s\n", __func__); 2689 dprintk("--> %s\n", __func__);
2691 nfs_super_return_all_delegations(sb); 2690 nfs_super_return_all_delegations(sb);
2692 kill_anon_super(sb); 2691 kill_anon_super(sb);
2693 nfs4_renewd_prepare_shutdown(server);
2694 nfs_fscache_release_super_cookie(sb); 2692 nfs_fscache_release_super_cookie(sb);
2695 nfs_free_server(server); 2693 nfs_free_server(server);
2696 dprintk("<-- %s\n", __func__); 2694 dprintk("<-- %s\n", __func__);
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index 00388d2a3c99..5c01fc148ce8 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -176,7 +176,7 @@ static const struct file_operations exports_operations = {
176extern int nfsd_pool_stats_open(struct inode *inode, struct file *file); 176extern int nfsd_pool_stats_open(struct inode *inode, struct file *file);
177extern int nfsd_pool_stats_release(struct inode *inode, struct file *file); 177extern int nfsd_pool_stats_release(struct inode *inode, struct file *file);
178 178
179static struct file_operations pool_stats_operations = { 179static const struct file_operations pool_stats_operations = {
180 .open = nfsd_pool_stats_open, 180 .open = nfsd_pool_stats_open,
181 .read = seq_read, 181 .read = seq_read,
182 .llseek = seq_lseek, 182 .llseek = seq_lseek,
diff --git a/fs/nilfs2/btnode.c b/fs/nilfs2/btnode.c
index 6a2711f4c321..5941958f1e47 100644
--- a/fs/nilfs2/btnode.c
+++ b/fs/nilfs2/btnode.c
@@ -36,6 +36,7 @@
36 36
37void nilfs_btnode_cache_init_once(struct address_space *btnc) 37void nilfs_btnode_cache_init_once(struct address_space *btnc)
38{ 38{
39 memset(btnc, 0, sizeof(*btnc));
39 INIT_RADIX_TREE(&btnc->page_tree, GFP_ATOMIC); 40 INIT_RADIX_TREE(&btnc->page_tree, GFP_ATOMIC);
40 spin_lock_init(&btnc->tree_lock); 41 spin_lock_init(&btnc->tree_lock);
41 INIT_LIST_HEAD(&btnc->private_list); 42 INIT_LIST_HEAD(&btnc->private_list);
diff --git a/fs/nilfs2/dir.c b/fs/nilfs2/dir.c
index 1a4fa04cf071..e097099bfc8f 100644
--- a/fs/nilfs2/dir.c
+++ b/fs/nilfs2/dir.c
@@ -697,7 +697,7 @@ not_empty:
697 return 0; 697 return 0;
698} 698}
699 699
700struct file_operations nilfs_dir_operations = { 700const struct file_operations nilfs_dir_operations = {
701 .llseek = generic_file_llseek, 701 .llseek = generic_file_llseek,
702 .read = generic_read_dir, 702 .read = generic_read_dir,
703 .readdir = nilfs_readdir, 703 .readdir = nilfs_readdir,
diff --git a/fs/nilfs2/file.c b/fs/nilfs2/file.c
index 7d7b4983dee3..30292df443ce 100644
--- a/fs/nilfs2/file.c
+++ b/fs/nilfs2/file.c
@@ -134,7 +134,7 @@ static int nilfs_file_mmap(struct file *file, struct vm_area_struct *vma)
134 * We have mostly NULL's here: the current defaults are ok for 134 * We have mostly NULL's here: the current defaults are ok for
135 * the nilfs filesystem. 135 * the nilfs filesystem.
136 */ 136 */
137struct file_operations nilfs_file_operations = { 137const struct file_operations nilfs_file_operations = {
138 .llseek = generic_file_llseek, 138 .llseek = generic_file_llseek,
139 .read = do_sync_read, 139 .read = do_sync_read,
140 .write = do_sync_write, 140 .write = do_sync_write,
diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c
index 2d2c501deb54..5040220c3732 100644
--- a/fs/nilfs2/inode.c
+++ b/fs/nilfs2/inode.c
@@ -400,6 +400,7 @@ int nilfs_read_inode_common(struct inode *inode,
400 ii->i_dir_acl = S_ISREG(inode->i_mode) ? 400 ii->i_dir_acl = S_ISREG(inode->i_mode) ?
401 0 : le32_to_cpu(raw_inode->i_dir_acl); 401 0 : le32_to_cpu(raw_inode->i_dir_acl);
402#endif 402#endif
403 ii->i_dir_start_lookup = 0;
403 ii->i_cno = 0; 404 ii->i_cno = 0;
404 inode->i_generation = le32_to_cpu(raw_inode->i_generation); 405 inode->i_generation = le32_to_cpu(raw_inode->i_generation);
405 406
diff --git a/fs/nilfs2/mdt.c b/fs/nilfs2/mdt.c
index b18c4998f8d0..f6326112d647 100644
--- a/fs/nilfs2/mdt.c
+++ b/fs/nilfs2/mdt.c
@@ -433,7 +433,7 @@ static const struct address_space_operations def_mdt_aops = {
433}; 433};
434 434
435static const struct inode_operations def_mdt_iops; 435static const struct inode_operations def_mdt_iops;
436static struct file_operations def_mdt_fops; 436static const struct file_operations def_mdt_fops;
437 437
438/* 438/*
439 * NILFS2 uses pseudo inodes for meta data files such as DAT, cpfile, sufile, 439 * NILFS2 uses pseudo inodes for meta data files such as DAT, cpfile, sufile,
diff --git a/fs/nilfs2/nilfs.h b/fs/nilfs2/nilfs.h
index bad7368782d0..4da6f67e9a91 100644
--- a/fs/nilfs2/nilfs.h
+++ b/fs/nilfs2/nilfs.h
@@ -294,9 +294,9 @@ void nilfs_clear_gcdat_inode(struct the_nilfs *);
294/* 294/*
295 * Inodes and files operations 295 * Inodes and files operations
296 */ 296 */
297extern struct file_operations nilfs_dir_operations; 297extern const struct file_operations nilfs_dir_operations;
298extern const struct inode_operations nilfs_file_inode_operations; 298extern const struct inode_operations nilfs_file_inode_operations;
299extern struct file_operations nilfs_file_operations; 299extern const struct file_operations nilfs_file_operations;
300extern const struct address_space_operations nilfs_aops; 300extern const struct address_space_operations nilfs_aops;
301extern const struct inode_operations nilfs_dir_inode_operations; 301extern const struct inode_operations nilfs_dir_inode_operations;
302extern const struct inode_operations nilfs_special_inode_operations; 302extern const struct inode_operations nilfs_special_inode_operations;
diff --git a/fs/nls/nls_base.c b/fs/nls/nls_base.c
index 2224b4d07bf0..44a88a9fa2c8 100644
--- a/fs/nls/nls_base.c
+++ b/fs/nls/nls_base.c
@@ -124,10 +124,10 @@ int utf8s_to_utf16s(const u8 *s, int len, wchar_t *pwcs)
124 while (*s && len > 0) { 124 while (*s && len > 0) {
125 if (*s & 0x80) { 125 if (*s & 0x80) {
126 size = utf8_to_utf32(s, len, &u); 126 size = utf8_to_utf32(s, len, &u);
127 if (size < 0) { 127 if (size < 0)
128 /* Ignore character and move on */ 128 return -EINVAL;
129 size = 1; 129
130 } else if (u >= PLANE_SIZE) { 130 if (u >= PLANE_SIZE) {
131 u -= PLANE_SIZE; 131 u -= PLANE_SIZE;
132 *op++ = (wchar_t) (SURROGATE_PAIR | 132 *op++ = (wchar_t) (SURROGATE_PAIR |
133 ((u >> 10) & SURROGATE_BITS)); 133 ((u >> 10) & SURROGATE_BITS));
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c
index 09cc25d04611..c452d116b892 100644
--- a/fs/ocfs2/cluster/heartbeat.c
+++ b/fs/ocfs2/cluster/heartbeat.c
@@ -966,7 +966,7 @@ static ssize_t o2hb_debug_read(struct file *file, char __user *buf,
966} 966}
967#endif /* CONFIG_DEBUG_FS */ 967#endif /* CONFIG_DEBUG_FS */
968 968
969static struct file_operations o2hb_debug_fops = { 969static const struct file_operations o2hb_debug_fops = {
970 .open = o2hb_debug_open, 970 .open = o2hb_debug_open,
971 .release = o2hb_debug_release, 971 .release = o2hb_debug_release,
972 .read = o2hb_debug_read, 972 .read = o2hb_debug_read,
diff --git a/fs/ocfs2/cluster/netdebug.c b/fs/ocfs2/cluster/netdebug.c
index cfb2be708abe..da794bc07a6c 100644
--- a/fs/ocfs2/cluster/netdebug.c
+++ b/fs/ocfs2/cluster/netdebug.c
@@ -207,7 +207,7 @@ static int nst_fop_release(struct inode *inode, struct file *file)
207 return seq_release_private(inode, file); 207 return seq_release_private(inode, file);
208} 208}
209 209
210static struct file_operations nst_seq_fops = { 210static const struct file_operations nst_seq_fops = {
211 .open = nst_fop_open, 211 .open = nst_fop_open,
212 .read = seq_read, 212 .read = seq_read,
213 .llseek = seq_lseek, 213 .llseek = seq_lseek,
@@ -388,7 +388,7 @@ static int sc_fop_release(struct inode *inode, struct file *file)
388 return seq_release_private(inode, file); 388 return seq_release_private(inode, file);
389} 389}
390 390
391static struct file_operations sc_seq_fops = { 391static const struct file_operations sc_seq_fops = {
392 .open = sc_fop_open, 392 .open = sc_fop_open,
393 .read = seq_read, 393 .read = seq_read,
394 .llseek = seq_lseek, 394 .llseek = seq_lseek,
diff --git a/fs/ocfs2/dlm/dlmdebug.c b/fs/ocfs2/dlm/dlmdebug.c
index ca46002ec10e..42b0bad7a612 100644
--- a/fs/ocfs2/dlm/dlmdebug.c
+++ b/fs/ocfs2/dlm/dlmdebug.c
@@ -478,7 +478,7 @@ bail:
478 return -ENOMEM; 478 return -ENOMEM;
479} 479}
480 480
481static struct file_operations debug_purgelist_fops = { 481static const struct file_operations debug_purgelist_fops = {
482 .open = debug_purgelist_open, 482 .open = debug_purgelist_open,
483 .release = debug_buffer_release, 483 .release = debug_buffer_release,
484 .read = debug_buffer_read, 484 .read = debug_buffer_read,
@@ -538,7 +538,7 @@ bail:
538 return -ENOMEM; 538 return -ENOMEM;
539} 539}
540 540
541static struct file_operations debug_mle_fops = { 541static const struct file_operations debug_mle_fops = {
542 .open = debug_mle_open, 542 .open = debug_mle_open,
543 .release = debug_buffer_release, 543 .release = debug_buffer_release,
544 .read = debug_buffer_read, 544 .read = debug_buffer_read,
@@ -741,7 +741,7 @@ static int debug_lockres_release(struct inode *inode, struct file *file)
741 return seq_release_private(inode, file); 741 return seq_release_private(inode, file);
742} 742}
743 743
744static struct file_operations debug_lockres_fops = { 744static const struct file_operations debug_lockres_fops = {
745 .open = debug_lockres_open, 745 .open = debug_lockres_open,
746 .release = debug_lockres_release, 746 .release = debug_lockres_release,
747 .read = seq_read, 747 .read = seq_read,
@@ -925,7 +925,7 @@ bail:
925 return -ENOMEM; 925 return -ENOMEM;
926} 926}
927 927
928static struct file_operations debug_state_fops = { 928static const struct file_operations debug_state_fops = {
929 .open = debug_state_open, 929 .open = debug_state_open,
930 .release = debug_buffer_release, 930 .release = debug_buffer_release,
931 .read = debug_buffer_read, 931 .read = debug_buffer_read,
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index 4cc3c890a2cd..c0e48aeebb1c 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -373,7 +373,7 @@ static ssize_t ocfs2_debug_read(struct file *file, char __user *buf,
373} 373}
374#endif /* CONFIG_DEBUG_FS */ 374#endif /* CONFIG_DEBUG_FS */
375 375
376static struct file_operations ocfs2_osb_debug_fops = { 376static const struct file_operations ocfs2_osb_debug_fops = {
377 .open = ocfs2_osb_debug_open, 377 .open = ocfs2_osb_debug_open,
378 .release = ocfs2_debug_release, 378 .release = ocfs2_debug_release,
379 .read = ocfs2_debug_read, 379 .read = ocfs2_debug_read,
diff --git a/fs/omfs/dir.c b/fs/omfs/dir.c
index 3680bae335b5..b42d62419034 100644
--- a/fs/omfs/dir.c
+++ b/fs/omfs/dir.c
@@ -498,7 +498,7 @@ const struct inode_operations omfs_dir_inops = {
498 .rmdir = omfs_rmdir, 498 .rmdir = omfs_rmdir,
499}; 499};
500 500
501struct file_operations omfs_dir_operations = { 501const struct file_operations omfs_dir_operations = {
502 .read = generic_read_dir, 502 .read = generic_read_dir,
503 .readdir = omfs_readdir, 503 .readdir = omfs_readdir,
504 .llseek = generic_file_llseek, 504 .llseek = generic_file_llseek,
diff --git a/fs/omfs/file.c b/fs/omfs/file.c
index 4845fbb18e6e..399487c09364 100644
--- a/fs/omfs/file.c
+++ b/fs/omfs/file.c
@@ -322,7 +322,7 @@ static sector_t omfs_bmap(struct address_space *mapping, sector_t block)
322 return generic_block_bmap(mapping, block, omfs_get_block); 322 return generic_block_bmap(mapping, block, omfs_get_block);
323} 323}
324 324
325struct file_operations omfs_file_operations = { 325const struct file_operations omfs_file_operations = {
326 .llseek = generic_file_llseek, 326 .llseek = generic_file_llseek,
327 .read = do_sync_read, 327 .read = do_sync_read,
328 .write = do_sync_write, 328 .write = do_sync_write,
diff --git a/fs/omfs/omfs.h b/fs/omfs/omfs.h
index df71039945ac..ebe2fdbe535e 100644
--- a/fs/omfs/omfs.h
+++ b/fs/omfs/omfs.h
@@ -44,14 +44,14 @@ extern int omfs_allocate_range(struct super_block *sb, int min_request,
44extern int omfs_clear_range(struct super_block *sb, u64 block, int count); 44extern int omfs_clear_range(struct super_block *sb, u64 block, int count);
45 45
46/* dir.c */ 46/* dir.c */
47extern struct file_operations omfs_dir_operations; 47extern const struct file_operations omfs_dir_operations;
48extern const struct inode_operations omfs_dir_inops; 48extern const struct inode_operations omfs_dir_inops;
49extern int omfs_make_empty(struct inode *inode, struct super_block *sb); 49extern int omfs_make_empty(struct inode *inode, struct super_block *sb);
50extern int omfs_is_bad(struct omfs_sb_info *sbi, struct omfs_header *header, 50extern int omfs_is_bad(struct omfs_sb_info *sbi, struct omfs_header *header,
51 u64 fsblock); 51 u64 fsblock);
52 52
53/* file.c */ 53/* file.c */
54extern struct file_operations omfs_file_operations; 54extern const struct file_operations omfs_file_operations;
55extern const struct inode_operations omfs_file_inops; 55extern const struct inode_operations omfs_file_inops;
56extern const struct address_space_operations omfs_aops; 56extern const struct address_space_operations omfs_aops;
57extern void omfs_make_empty_table(struct buffer_head *bh, int offset); 57extern void omfs_make_empty_table(struct buffer_head *bh, int offset);
diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c
index 56013371f9f3..a44a7897fd4d 100644
--- a/fs/proc/kcore.c
+++ b/fs/proc/kcore.c
@@ -23,7 +23,6 @@
23#include <asm/io.h> 23#include <asm/io.h>
24#include <linux/list.h> 24#include <linux/list.h>
25#include <linux/ioport.h> 25#include <linux/ioport.h>
26#include <linux/mm.h>
27#include <linux/memory.h> 26#include <linux/memory.h>
28#include <asm/sections.h> 27#include <asm/sections.h>
29 28
diff --git a/fs/proc/page.c b/fs/proc/page.c
index 2281c2cbfe2b..5033ce0d254b 100644
--- a/fs/proc/page.c
+++ b/fs/proc/page.c
@@ -94,6 +94,7 @@ static const struct file_operations proc_kpagecount_operations = {
94#define KPF_COMPOUND_TAIL 16 94#define KPF_COMPOUND_TAIL 16
95#define KPF_HUGE 17 95#define KPF_HUGE 17
96#define KPF_UNEVICTABLE 18 96#define KPF_UNEVICTABLE 18
97#define KPF_HWPOISON 19
97#define KPF_NOPAGE 20 98#define KPF_NOPAGE 20
98 99
99#define KPF_KSM 21 100#define KPF_KSM 21
@@ -180,6 +181,10 @@ static u64 get_uflags(struct page *page)
180 u |= kpf_copy_bit(k, KPF_UNEVICTABLE, PG_unevictable); 181 u |= kpf_copy_bit(k, KPF_UNEVICTABLE, PG_unevictable);
181 u |= kpf_copy_bit(k, KPF_MLOCKED, PG_mlocked); 182 u |= kpf_copy_bit(k, KPF_MLOCKED, PG_mlocked);
182 183
184#ifdef CONFIG_MEMORY_FAILURE
185 u |= kpf_copy_bit(k, KPF_HWPOISON, PG_hwpoison);
186#endif
187
183#ifdef CONFIG_IA64_UNCACHED_ALLOCATOR 188#ifdef CONFIG_IA64_UNCACHED_ALLOCATOR
184 u |= kpf_copy_bit(k, KPF_UNCACHED, PG_uncached); 189 u |= kpf_copy_bit(k, KPF_UNCACHED, PG_uncached);
185#endif 190#endif
diff --git a/fs/romfs/storage.c b/fs/romfs/storage.c
index b3208adf8e71..71e2b4d50a0a 100644
--- a/fs/romfs/storage.c
+++ b/fs/romfs/storage.c
@@ -253,11 +253,11 @@ ssize_t romfs_dev_strnlen(struct super_block *sb,
253 253
254#ifdef CONFIG_ROMFS_ON_MTD 254#ifdef CONFIG_ROMFS_ON_MTD
255 if (sb->s_mtd) 255 if (sb->s_mtd)
256 return romfs_mtd_strnlen(sb, pos, limit); 256 return romfs_mtd_strnlen(sb, pos, maxlen);
257#endif 257#endif
258#ifdef CONFIG_ROMFS_ON_BLOCK 258#ifdef CONFIG_ROMFS_ON_BLOCK
259 if (sb->s_bdev) 259 if (sb->s_bdev)
260 return romfs_blk_strnlen(sb, pos, limit); 260 return romfs_blk_strnlen(sb, pos, maxlen);
261#endif 261#endif
262 return -EIO; 262 return -EIO;
263} 263}
diff --git a/fs/select.c b/fs/select.c
index a201fc370223..fd38ce2e32e3 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -15,6 +15,7 @@
15 */ 15 */
16 16
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/sched.h>
18#include <linux/syscalls.h> 19#include <linux/syscalls.h>
19#include <linux/module.h> 20#include <linux/module.h>
20#include <linux/slab.h> 21#include <linux/slab.h>
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index 0050fc40e8c9..5fad489ce5bc 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -894,7 +894,8 @@ int sysfs_move_dir(struct kobject *kobj, struct kobject *new_parent_kobj)
894 894
895 mutex_lock(&sysfs_rename_mutex); 895 mutex_lock(&sysfs_rename_mutex);
896 BUG_ON(!sd->s_parent); 896 BUG_ON(!sd->s_parent);
897 new_parent_sd = new_parent_kobj->sd ? new_parent_kobj->sd : &sysfs_root; 897 new_parent_sd = (new_parent_kobj && new_parent_kobj->sd) ?
898 new_parent_kobj->sd : &sysfs_root;
898 899
899 error = 0; 900 error = 0;
900 if (sd->s_parent == new_parent_sd) 901 if (sd->s_parent == new_parent_sd)
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index 561a9c050cef..f5ea4680f15f 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -268,7 +268,7 @@ static int sysfs_get_open_dirent(struct sysfs_dirent *sd,
268 struct sysfs_open_dirent *od, *new_od = NULL; 268 struct sysfs_open_dirent *od, *new_od = NULL;
269 269
270 retry: 270 retry:
271 spin_lock(&sysfs_open_dirent_lock); 271 spin_lock_irq(&sysfs_open_dirent_lock);
272 272
273 if (!sd->s_attr.open && new_od) { 273 if (!sd->s_attr.open && new_od) {
274 sd->s_attr.open = new_od; 274 sd->s_attr.open = new_od;
@@ -281,7 +281,7 @@ static int sysfs_get_open_dirent(struct sysfs_dirent *sd,
281 list_add_tail(&buffer->list, &od->buffers); 281 list_add_tail(&buffer->list, &od->buffers);
282 } 282 }
283 283
284 spin_unlock(&sysfs_open_dirent_lock); 284 spin_unlock_irq(&sysfs_open_dirent_lock);
285 285
286 if (od) { 286 if (od) {
287 kfree(new_od); 287 kfree(new_od);
@@ -315,8 +315,9 @@ static void sysfs_put_open_dirent(struct sysfs_dirent *sd,
315 struct sysfs_buffer *buffer) 315 struct sysfs_buffer *buffer)
316{ 316{
317 struct sysfs_open_dirent *od = sd->s_attr.open; 317 struct sysfs_open_dirent *od = sd->s_attr.open;
318 unsigned long flags;
318 319
319 spin_lock(&sysfs_open_dirent_lock); 320 spin_lock_irqsave(&sysfs_open_dirent_lock, flags);
320 321
321 list_del(&buffer->list); 322 list_del(&buffer->list);
322 if (atomic_dec_and_test(&od->refcnt)) 323 if (atomic_dec_and_test(&od->refcnt))
@@ -324,7 +325,7 @@ static void sysfs_put_open_dirent(struct sysfs_dirent *sd,
324 else 325 else
325 od = NULL; 326 od = NULL;
326 327
327 spin_unlock(&sysfs_open_dirent_lock); 328 spin_unlock_irqrestore(&sysfs_open_dirent_lock, flags);
328 329
329 kfree(od); 330 kfree(od);
330} 331}
@@ -456,8 +457,9 @@ static unsigned int sysfs_poll(struct file *filp, poll_table *wait)
456void sysfs_notify_dirent(struct sysfs_dirent *sd) 457void sysfs_notify_dirent(struct sysfs_dirent *sd)
457{ 458{
458 struct sysfs_open_dirent *od; 459 struct sysfs_open_dirent *od;
460 unsigned long flags;
459 461
460 spin_lock(&sysfs_open_dirent_lock); 462 spin_lock_irqsave(&sysfs_open_dirent_lock, flags);
461 463
462 od = sd->s_attr.open; 464 od = sd->s_attr.open;
463 if (od) { 465 if (od) {
@@ -465,7 +467,7 @@ void sysfs_notify_dirent(struct sysfs_dirent *sd)
465 wake_up_interruptible(&od->poll); 467 wake_up_interruptible(&od->poll);
466 } 468 }
467 469
468 spin_unlock(&sysfs_open_dirent_lock); 470 spin_unlock_irqrestore(&sysfs_open_dirent_lock, flags);
469} 471}
470EXPORT_SYMBOL_GPL(sysfs_notify_dirent); 472EXPORT_SYMBOL_GPL(sysfs_notify_dirent);
471 473
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index 381854461b28..c2e30eea74dc 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -186,19 +186,37 @@ xfs_destroy_ioend(
186} 186}
187 187
188/* 188/*
189 * If the end of the current ioend is beyond the current EOF,
190 * return the new EOF value, otherwise zero.
191 */
192STATIC xfs_fsize_t
193xfs_ioend_new_eof(
194 xfs_ioend_t *ioend)
195{
196 xfs_inode_t *ip = XFS_I(ioend->io_inode);
197 xfs_fsize_t isize;
198 xfs_fsize_t bsize;
199
200 bsize = ioend->io_offset + ioend->io_size;
201 isize = MAX(ip->i_size, ip->i_new_size);
202 isize = MIN(isize, bsize);
203 return isize > ip->i_d.di_size ? isize : 0;
204}
205
206/*
189 * Update on-disk file size now that data has been written to disk. 207 * Update on-disk file size now that data has been written to disk.
190 * The current in-memory file size is i_size. If a write is beyond 208 * The current in-memory file size is i_size. If a write is beyond
191 * eof i_new_size will be the intended file size until i_size is 209 * eof i_new_size will be the intended file size until i_size is
192 * updated. If this write does not extend all the way to the valid 210 * updated. If this write does not extend all the way to the valid
193 * file size then restrict this update to the end of the write. 211 * file size then restrict this update to the end of the write.
194 */ 212 */
213
195STATIC void 214STATIC void
196xfs_setfilesize( 215xfs_setfilesize(
197 xfs_ioend_t *ioend) 216 xfs_ioend_t *ioend)
198{ 217{
199 xfs_inode_t *ip = XFS_I(ioend->io_inode); 218 xfs_inode_t *ip = XFS_I(ioend->io_inode);
200 xfs_fsize_t isize; 219 xfs_fsize_t isize;
201 xfs_fsize_t bsize;
202 220
203 ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFREG); 221 ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFREG);
204 ASSERT(ioend->io_type != IOMAP_READ); 222 ASSERT(ioend->io_type != IOMAP_READ);
@@ -206,16 +224,10 @@ xfs_setfilesize(
206 if (unlikely(ioend->io_error)) 224 if (unlikely(ioend->io_error))
207 return; 225 return;
208 226
209 bsize = ioend->io_offset + ioend->io_size;
210
211 xfs_ilock(ip, XFS_ILOCK_EXCL); 227 xfs_ilock(ip, XFS_ILOCK_EXCL);
212 228 isize = xfs_ioend_new_eof(ioend);
213 isize = MAX(ip->i_size, ip->i_new_size); 229 if (isize) {
214 isize = MIN(isize, bsize);
215
216 if (ip->i_d.di_size < isize) {
217 ip->i_d.di_size = isize; 230 ip->i_d.di_size = isize;
218 ip->i_update_core = 1;
219 xfs_mark_inode_dirty_sync(ip); 231 xfs_mark_inode_dirty_sync(ip);
220 } 232 }
221 233
@@ -404,10 +416,16 @@ xfs_submit_ioend_bio(
404 struct bio *bio) 416 struct bio *bio)
405{ 417{
406 atomic_inc(&ioend->io_remaining); 418 atomic_inc(&ioend->io_remaining);
407
408 bio->bi_private = ioend; 419 bio->bi_private = ioend;
409 bio->bi_end_io = xfs_end_bio; 420 bio->bi_end_io = xfs_end_bio;
410 421
422 /*
423 * If the I/O is beyond EOF we mark the inode dirty immediately
424 * but don't update the inode size until I/O completion.
425 */
426 if (xfs_ioend_new_eof(ioend))
427 xfs_mark_inode_dirty_sync(XFS_I(ioend->io_inode));
428
411 submit_bio(WRITE, bio); 429 submit_bio(WRITE, bio);
412 ASSERT(!bio_flagged(bio, BIO_EOPNOTSUPP)); 430 ASSERT(!bio_flagged(bio, BIO_EOPNOTSUPP));
413 bio_put(bio); 431 bio_put(bio);
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c
index 629370974e57..eff61e2732af 100644
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -176,14 +176,7 @@ xfs_file_fsync(
176 struct dentry *dentry, 176 struct dentry *dentry,
177 int datasync) 177 int datasync)
178{ 178{
179 struct inode *inode = dentry->d_inode; 179 struct xfs_inode *ip = XFS_I(dentry->d_inode);
180 struct xfs_inode *ip = XFS_I(inode);
181 int error;
182
183 /* capture size updates in I/O completion before writing the inode. */
184 error = filemap_fdatawait(inode->i_mapping);
185 if (error)
186 return error;
187 180
188 xfs_iflags_clear(ip, XFS_ITRUNCATED); 181 xfs_iflags_clear(ip, XFS_ITRUNCATED);
189 return -xfs_fsync(ip); 182 return -xfs_fsync(ip);
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
index da0159d99f82..cd42ef78f6b5 100644
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/linux-2.6/xfs_iops.c
@@ -57,19 +57,22 @@
57#include <linux/fiemap.h> 57#include <linux/fiemap.h>
58 58
59/* 59/*
60 * Bring the atime in the XFS inode uptodate. 60 * Bring the timestamps in the XFS inode uptodate.
61 * Used before logging the inode to disk or when the Linux inode goes away. 61 *
62 * Used before writing the inode to disk.
62 */ 63 */
63void 64void
64xfs_synchronize_atime( 65xfs_synchronize_times(
65 xfs_inode_t *ip) 66 xfs_inode_t *ip)
66{ 67{
67 struct inode *inode = VFS_I(ip); 68 struct inode *inode = VFS_I(ip);
68 69
69 if (!(inode->i_state & I_CLEAR)) { 70 ip->i_d.di_atime.t_sec = (__int32_t)inode->i_atime.tv_sec;
70 ip->i_d.di_atime.t_sec = (__int32_t)inode->i_atime.tv_sec; 71 ip->i_d.di_atime.t_nsec = (__int32_t)inode->i_atime.tv_nsec;
71 ip->i_d.di_atime.t_nsec = (__int32_t)inode->i_atime.tv_nsec; 72 ip->i_d.di_ctime.t_sec = (__int32_t)inode->i_ctime.tv_sec;
72 } 73 ip->i_d.di_ctime.t_nsec = (__int32_t)inode->i_ctime.tv_nsec;
74 ip->i_d.di_mtime.t_sec = (__int32_t)inode->i_mtime.tv_sec;
75 ip->i_d.di_mtime.t_nsec = (__int32_t)inode->i_mtime.tv_nsec;
73} 76}
74 77
75/* 78/*
@@ -106,32 +109,20 @@ xfs_ichgtime(
106 if ((flags & XFS_ICHGTIME_MOD) && 109 if ((flags & XFS_ICHGTIME_MOD) &&
107 !timespec_equal(&inode->i_mtime, &tv)) { 110 !timespec_equal(&inode->i_mtime, &tv)) {
108 inode->i_mtime = tv; 111 inode->i_mtime = tv;
109 ip->i_d.di_mtime.t_sec = (__int32_t)tv.tv_sec;
110 ip->i_d.di_mtime.t_nsec = (__int32_t)tv.tv_nsec;
111 sync_it = 1; 112 sync_it = 1;
112 } 113 }
113 if ((flags & XFS_ICHGTIME_CHG) && 114 if ((flags & XFS_ICHGTIME_CHG) &&
114 !timespec_equal(&inode->i_ctime, &tv)) { 115 !timespec_equal(&inode->i_ctime, &tv)) {
115 inode->i_ctime = tv; 116 inode->i_ctime = tv;
116 ip->i_d.di_ctime.t_sec = (__int32_t)tv.tv_sec;
117 ip->i_d.di_ctime.t_nsec = (__int32_t)tv.tv_nsec;
118 sync_it = 1; 117 sync_it = 1;
119 } 118 }
120 119
121 /* 120 /*
122 * We update the i_update_core field _after_ changing 121 * Update complete - now make sure everyone knows that the inode
123 * the timestamps in order to coordinate properly with 122 * is dirty.
124 * xfs_iflush() so that we don't lose timestamp updates.
125 * This keeps us from having to hold the inode lock
126 * while doing this. We use the SYNCHRONIZE macro to
127 * ensure that the compiler does not reorder the update
128 * of i_update_core above the timestamp updates above.
129 */ 123 */
130 if (sync_it) { 124 if (sync_it)
131 SYNCHRONIZE();
132 ip->i_update_core = 1;
133 xfs_mark_inode_dirty_sync(ip); 125 xfs_mark_inode_dirty_sync(ip);
134 }
135} 126}
136 127
137/* 128/*
@@ -506,10 +497,8 @@ xfs_vn_getattr(
506 stat->gid = ip->i_d.di_gid; 497 stat->gid = ip->i_d.di_gid;
507 stat->ino = ip->i_ino; 498 stat->ino = ip->i_ino;
508 stat->atime = inode->i_atime; 499 stat->atime = inode->i_atime;
509 stat->mtime.tv_sec = ip->i_d.di_mtime.t_sec; 500 stat->mtime = inode->i_mtime;
510 stat->mtime.tv_nsec = ip->i_d.di_mtime.t_nsec; 501 stat->ctime = inode->i_ctime;
511 stat->ctime.tv_sec = ip->i_d.di_ctime.t_sec;
512 stat->ctime.tv_nsec = ip->i_d.di_ctime.t_nsec;
513 stat->blocks = 502 stat->blocks =
514 XFS_FSB_TO_BB(mp, ip->i_d.di_nblocks + ip->i_delayed_blks); 503 XFS_FSB_TO_BB(mp, ip->i_d.di_nblocks + ip->i_delayed_blks);
515 504
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c
index 49e4a6aea73c..072050f8d346 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.c
+++ b/fs/xfs/linux-2.6/xfs_lrw.c
@@ -667,7 +667,7 @@ start:
667 xip->i_new_size = new_size; 667 xip->i_new_size = new_size;
668 668
669 if (likely(!(ioflags & IO_INVIS))) 669 if (likely(!(ioflags & IO_INVIS)))
670 xfs_ichgtime(xip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); 670 file_update_time(file);
671 671
672 /* 672 /*
673 * If the offset is beyond the size of the file, we have a couple 673 * If the offset is beyond the size of the file, we have a couple
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index bdd41c8c342f..18a4b8e11df2 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -977,6 +977,28 @@ xfs_fs_inode_init_once(
977} 977}
978 978
979/* 979/*
980 * Dirty the XFS inode when mark_inode_dirty_sync() is called so that
981 * we catch unlogged VFS level updates to the inode. Care must be taken
982 * here - the transaction code calls mark_inode_dirty_sync() to mark the
983 * VFS inode dirty in a transaction and clears the i_update_core field;
984 * it must clear the field after calling mark_inode_dirty_sync() to
985 * correctly indicate that the dirty state has been propagated into the
986 * inode log item.
987 *
988 * We need the barrier() to maintain correct ordering between unlogged
989 * updates and the transaction commit code that clears the i_update_core
990 * field. This requires all updates to be completed before marking the
991 * inode dirty.
992 */
993STATIC void
994xfs_fs_dirty_inode(
995 struct inode *inode)
996{
997 barrier();
998 XFS_I(inode)->i_update_core = 1;
999}
1000
1001/*
980 * Attempt to flush the inode, this will actually fail 1002 * Attempt to flush the inode, this will actually fail
981 * if the inode is pinned, but we dirty the inode again 1003 * if the inode is pinned, but we dirty the inode again
982 * at the point when it is unpinned after a log write, 1004 * at the point when it is unpinned after a log write,
@@ -1126,7 +1148,7 @@ xfs_fs_put_super(
1126} 1148}
1127 1149
1128STATIC int 1150STATIC int
1129xfs_fs_sync_super( 1151xfs_fs_sync_fs(
1130 struct super_block *sb, 1152 struct super_block *sb,
1131 int wait) 1153 int wait)
1132{ 1154{
@@ -1134,23 +1156,23 @@ xfs_fs_sync_super(
1134 int error; 1156 int error;
1135 1157
1136 /* 1158 /*
1137 * Treat a sync operation like a freeze. This is to work 1159 * Not much we can do for the first async pass. Writing out the
1138 * around a race in sync_inodes() which works in two phases 1160 * superblock would be counter-productive as we are going to redirty
1139 * - an asynchronous flush, which can write out an inode 1161 * when writing out other data and metadata (and writing out a single
1140 * without waiting for file size updates to complete, and a 1162 * block is quite fast anyway).
1141 * synchronous flush, which wont do anything because the 1163 *
1142 * async flush removed the inode's dirty flag. Also 1164 * Try to asynchronously kick off quota syncing at least.
1143 * sync_inodes() will not see any files that just have
1144 * outstanding transactions to be flushed because we don't
1145 * dirty the Linux inode until after the transaction I/O
1146 * completes.
1147 */ 1165 */
1148 if (wait || unlikely(sb->s_frozen == SB_FREEZE_WRITE)) 1166 if (!wait) {
1149 error = xfs_quiesce_data(mp); 1167 xfs_qm_sync(mp, SYNC_TRYLOCK);
1150 else 1168 return 0;
1151 error = xfs_sync_fsdata(mp, 0); 1169 }
1170
1171 error = xfs_quiesce_data(mp);
1172 if (error)
1173 return -error;
1152 1174
1153 if (unlikely(laptop_mode)) { 1175 if (laptop_mode) {
1154 int prev_sync_seq = mp->m_sync_seq; 1176 int prev_sync_seq = mp->m_sync_seq;
1155 1177
1156 /* 1178 /*
@@ -1169,7 +1191,7 @@ xfs_fs_sync_super(
1169 mp->m_sync_seq != prev_sync_seq); 1191 mp->m_sync_seq != prev_sync_seq);
1170 } 1192 }
1171 1193
1172 return -error; 1194 return 0;
1173} 1195}
1174 1196
1175STATIC int 1197STATIC int
@@ -1539,10 +1561,11 @@ xfs_fs_get_sb(
1539static const struct super_operations xfs_super_operations = { 1561static const struct super_operations xfs_super_operations = {
1540 .alloc_inode = xfs_fs_alloc_inode, 1562 .alloc_inode = xfs_fs_alloc_inode,
1541 .destroy_inode = xfs_fs_destroy_inode, 1563 .destroy_inode = xfs_fs_destroy_inode,
1564 .dirty_inode = xfs_fs_dirty_inode,
1542 .write_inode = xfs_fs_write_inode, 1565 .write_inode = xfs_fs_write_inode,
1543 .clear_inode = xfs_fs_clear_inode, 1566 .clear_inode = xfs_fs_clear_inode,
1544 .put_super = xfs_fs_put_super, 1567 .put_super = xfs_fs_put_super,
1545 .sync_fs = xfs_fs_sync_super, 1568 .sync_fs = xfs_fs_sync_fs,
1546 .freeze_fs = xfs_fs_freeze, 1569 .freeze_fs = xfs_fs_freeze,
1547 .statfs = xfs_fs_statfs, 1570 .statfs = xfs_fs_statfs,
1548 .remount_fs = xfs_fs_remount, 1571 .remount_fs = xfs_fs_remount,
diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c
index 320be6aea492..961df0a22c78 100644
--- a/fs/xfs/linux-2.6/xfs_sync.c
+++ b/fs/xfs/linux-2.6/xfs_sync.c
@@ -309,11 +309,15 @@ xfs_sync_attr(
309STATIC int 309STATIC int
310xfs_commit_dummy_trans( 310xfs_commit_dummy_trans(
311 struct xfs_mount *mp, 311 struct xfs_mount *mp,
312 uint log_flags) 312 uint flags)
313{ 313{
314 struct xfs_inode *ip = mp->m_rootip; 314 struct xfs_inode *ip = mp->m_rootip;
315 struct xfs_trans *tp; 315 struct xfs_trans *tp;
316 int error; 316 int error;
317 int log_flags = XFS_LOG_FORCE;
318
319 if (flags & SYNC_WAIT)
320 log_flags |= XFS_LOG_SYNC;
317 321
318 /* 322 /*
319 * Put a dummy transaction in the log to tell recovery 323 * Put a dummy transaction in the log to tell recovery
@@ -331,13 +335,12 @@ xfs_commit_dummy_trans(
331 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); 335 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
332 xfs_trans_ihold(tp, ip); 336 xfs_trans_ihold(tp, ip);
333 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 337 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
334 /* XXX(hch): ignoring the error here.. */
335 error = xfs_trans_commit(tp, 0); 338 error = xfs_trans_commit(tp, 0);
336
337 xfs_iunlock(ip, XFS_ILOCK_EXCL); 339 xfs_iunlock(ip, XFS_ILOCK_EXCL);
338 340
341 /* the log force ensures this transaction is pushed to disk */
339 xfs_log_force(mp, 0, log_flags); 342 xfs_log_force(mp, 0, log_flags);
340 return 0; 343 return error;
341} 344}
342 345
343int 346int
@@ -385,7 +388,20 @@ xfs_sync_fsdata(
385 else 388 else
386 XFS_BUF_ASYNC(bp); 389 XFS_BUF_ASYNC(bp);
387 390
388 return xfs_bwrite(mp, bp); 391 error = xfs_bwrite(mp, bp);
392 if (error)
393 return error;
394
395 /*
396 * If this is a data integrity sync make sure all pending buffers
397 * are flushed out for the log coverage check below.
398 */
399 if (flags & SYNC_WAIT)
400 xfs_flush_buftarg(mp->m_ddev_targp, 1);
401
402 if (xfs_log_need_covered(mp))
403 error = xfs_commit_dummy_trans(mp, flags);
404 return error;
389 405
390 out_brelse: 406 out_brelse:
391 xfs_buf_relse(bp); 407 xfs_buf_relse(bp);
@@ -419,14 +435,16 @@ xfs_quiesce_data(
419 /* push non-blocking */ 435 /* push non-blocking */
420 xfs_sync_data(mp, 0); 436 xfs_sync_data(mp, 0);
421 xfs_qm_sync(mp, SYNC_TRYLOCK); 437 xfs_qm_sync(mp, SYNC_TRYLOCK);
422 xfs_filestream_flush(mp);
423 438
424 /* push and block */ 439 /* push and block till complete */
425 xfs_sync_data(mp, SYNC_WAIT); 440 xfs_sync_data(mp, SYNC_WAIT);
426 xfs_qm_sync(mp, SYNC_WAIT); 441 xfs_qm_sync(mp, SYNC_WAIT);
427 442
443 /* drop inode references pinned by filestreams */
444 xfs_filestream_flush(mp);
445
428 /* write superblock and hoover up shutdown errors */ 446 /* write superblock and hoover up shutdown errors */
429 error = xfs_sync_fsdata(mp, 0); 447 error = xfs_sync_fsdata(mp, SYNC_WAIT);
430 448
431 /* flush data-only devices */ 449 /* flush data-only devices */
432 if (mp->m_rtdev_targp) 450 if (mp->m_rtdev_targp)
@@ -570,8 +588,6 @@ xfs_sync_worker(
570 /* dgc: errors ignored here */ 588 /* dgc: errors ignored here */
571 error = xfs_qm_sync(mp, SYNC_TRYLOCK); 589 error = xfs_qm_sync(mp, SYNC_TRYLOCK);
572 error = xfs_sync_fsdata(mp, SYNC_TRYLOCK); 590 error = xfs_sync_fsdata(mp, SYNC_TRYLOCK);
573 if (xfs_log_need_covered(mp))
574 error = xfs_commit_dummy_trans(mp, XFS_LOG_FORCE);
575 } 591 }
576 mp->m_sync_seq++; 592 mp->m_sync_seq++;
577 wake_up(&mp->m_wait_single_sync_task); 593 wake_up(&mp->m_wait_single_sync_task);
diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c
index 7465f9ee125f..ab89a7e94a0f 100644
--- a/fs/xfs/xfs_dfrag.c
+++ b/fs/xfs/xfs_dfrag.c
@@ -206,10 +206,10 @@ xfs_swap_extents(
206 * process that the file was not changed out from 206 * process that the file was not changed out from
207 * under it. 207 * under it.
208 */ 208 */
209 if ((sbp->bs_ctime.tv_sec != ip->i_d.di_ctime.t_sec) || 209 if ((sbp->bs_ctime.tv_sec != VFS_I(ip)->i_ctime.tv_sec) ||
210 (sbp->bs_ctime.tv_nsec != ip->i_d.di_ctime.t_nsec) || 210 (sbp->bs_ctime.tv_nsec != VFS_I(ip)->i_ctime.tv_nsec) ||
211 (sbp->bs_mtime.tv_sec != ip->i_d.di_mtime.t_sec) || 211 (sbp->bs_mtime.tv_sec != VFS_I(ip)->i_mtime.tv_sec) ||
212 (sbp->bs_mtime.tv_nsec != ip->i_d.di_mtime.t_nsec)) { 212 (sbp->bs_mtime.tv_nsec != VFS_I(ip)->i_mtime.tv_nsec)) {
213 error = XFS_ERROR(EBUSY); 213 error = XFS_ERROR(EBUSY);
214 goto out_unlock; 214 goto out_unlock;
215 } 215 }
diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c
index fa913e459442..41ad537c49e9 100644
--- a/fs/xfs/xfs_dir2_leaf.c
+++ b/fs/xfs/xfs_dir2_leaf.c
@@ -854,6 +854,7 @@ xfs_dir2_leaf_getdents(
854 */ 854 */
855 ra_want = howmany(bufsize + mp->m_dirblksize, 855 ra_want = howmany(bufsize + mp->m_dirblksize,
856 mp->m_sb.sb_blocksize) - 1; 856 mp->m_sb.sb_blocksize) - 1;
857 ASSERT(ra_want >= 0);
857 858
858 /* 859 /*
859 * If we don't have as many as we want, and we haven't 860 * If we don't have as many as we want, and we haven't
@@ -1088,7 +1089,8 @@ xfs_dir2_leaf_getdents(
1088 */ 1089 */
1089 ptr += length; 1090 ptr += length;
1090 curoff += length; 1091 curoff += length;
1091 bufsize -= length; 1092 /* bufsize may have just been a guess; don't go negative */
1093 bufsize = bufsize > length ? bufsize - length : 0;
1092 } 1094 }
1093 1095
1094 /* 1096 /*
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index c1dc7ef5a1d8..b92a4fa2a0a1 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -3068,9 +3068,9 @@ xfs_iflush_int(
3068 SYNCHRONIZE(); 3068 SYNCHRONIZE();
3069 3069
3070 /* 3070 /*
3071 * Make sure to get the latest atime from the Linux inode. 3071 * Make sure to get the latest timestamps from the Linux inode.
3072 */ 3072 */
3073 xfs_synchronize_atime(ip); 3073 xfs_synchronize_times(ip);
3074 3074
3075 if (XFS_TEST_ERROR(be16_to_cpu(dip->di_magic) != XFS_DINODE_MAGIC, 3075 if (XFS_TEST_ERROR(be16_to_cpu(dip->di_magic) != XFS_DINODE_MAGIC,
3076 mp, XFS_ERRTAG_IFLUSH_1, XFS_RANDOM_IFLUSH_1)) { 3076 mp, XFS_ERRTAG_IFLUSH_1, XFS_RANDOM_IFLUSH_1)) {
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index 0b38b9a869ec..41555de1d1db 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -504,7 +504,7 @@ void xfs_ichgtime(xfs_inode_t *, int);
504void xfs_lock_inodes(xfs_inode_t **, int, uint); 504void xfs_lock_inodes(xfs_inode_t **, int, uint);
505void xfs_lock_two_inodes(xfs_inode_t *, xfs_inode_t *, uint); 505void xfs_lock_two_inodes(xfs_inode_t *, xfs_inode_t *, uint);
506 506
507void xfs_synchronize_atime(xfs_inode_t *); 507void xfs_synchronize_times(xfs_inode_t *);
508void xfs_mark_inode_dirty_sync(xfs_inode_t *); 508void xfs_mark_inode_dirty_sync(xfs_inode_t *);
509 509
510#if defined(XFS_INODE_TRACE) 510#if defined(XFS_INODE_TRACE)
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c
index 47d5b663c37e..9794b876d6ff 100644
--- a/fs/xfs/xfs_inode_item.c
+++ b/fs/xfs/xfs_inode_item.c
@@ -232,6 +232,15 @@ xfs_inode_item_format(
232 nvecs = 1; 232 nvecs = 1;
233 233
234 /* 234 /*
235 * Make sure the linux inode is dirty. We do this before
236 * clearing i_update_core as the VFS will call back into
237 * XFS here and set i_update_core, so we need to dirty the
238 * inode first so that the ordering of i_update_core and
239 * unlogged modifications still works as described below.
240 */
241 xfs_mark_inode_dirty_sync(ip);
242
243 /*
235 * Clear i_update_core if the timestamps (or any other 244 * Clear i_update_core if the timestamps (or any other
236 * non-transactional modification) need flushing/logging 245 * non-transactional modification) need flushing/logging
237 * and we're about to log them with the rest of the core. 246 * and we're about to log them with the rest of the core.
@@ -263,14 +272,9 @@ xfs_inode_item_format(
263 } 272 }
264 273
265 /* 274 /*
266 * Make sure to get the latest atime from the Linux inode. 275 * Make sure to get the latest timestamps from the Linux inode.
267 */ 276 */
268 xfs_synchronize_atime(ip); 277 xfs_synchronize_times(ip);
269
270 /*
271 * make sure the linux inode is dirty
272 */
273 xfs_mark_inode_dirty_sync(ip);
274 278
275 vecp->i_addr = (xfs_caddr_t)&ip->i_d; 279 vecp->i_addr = (xfs_caddr_t)&ip->i_d;
276 vecp->i_len = sizeof(struct xfs_icdinode); 280 vecp->i_len = sizeof(struct xfs_icdinode);
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c
index b68f9107e26c..62efab2f3839 100644
--- a/fs/xfs/xfs_itable.c
+++ b/fs/xfs/xfs_itable.c
@@ -59,6 +59,7 @@ xfs_bulkstat_one_iget(
59{ 59{
60 xfs_icdinode_t *dic; /* dinode core info pointer */ 60 xfs_icdinode_t *dic; /* dinode core info pointer */
61 xfs_inode_t *ip; /* incore inode pointer */ 61 xfs_inode_t *ip; /* incore inode pointer */
62 struct inode *inode;
62 int error; 63 int error;
63 64
64 error = xfs_iget(mp, NULL, ino, 65 error = xfs_iget(mp, NULL, ino,
@@ -72,6 +73,7 @@ xfs_bulkstat_one_iget(
72 ASSERT(ip->i_imap.im_blkno != 0); 73 ASSERT(ip->i_imap.im_blkno != 0);
73 74
74 dic = &ip->i_d; 75 dic = &ip->i_d;
76 inode = VFS_I(ip);
75 77
76 /* xfs_iget returns the following without needing 78 /* xfs_iget returns the following without needing
77 * further change. 79 * further change.
@@ -83,16 +85,19 @@ xfs_bulkstat_one_iget(
83 buf->bs_uid = dic->di_uid; 85 buf->bs_uid = dic->di_uid;
84 buf->bs_gid = dic->di_gid; 86 buf->bs_gid = dic->di_gid;
85 buf->bs_size = dic->di_size; 87 buf->bs_size = dic->di_size;
88
86 /* 89 /*
87 * We are reading the atime from the Linux inode because the 90 * We need to read the timestamps from the Linux inode because
88 * dinode might not be uptodate. 91 * the VFS keeps writing directly into the inode structure instead
92 * of telling us about the updates.
89 */ 93 */
90 buf->bs_atime.tv_sec = VFS_I(ip)->i_atime.tv_sec; 94 buf->bs_atime.tv_sec = inode->i_atime.tv_sec;
91 buf->bs_atime.tv_nsec = VFS_I(ip)->i_atime.tv_nsec; 95 buf->bs_atime.tv_nsec = inode->i_atime.tv_nsec;
92 buf->bs_mtime.tv_sec = dic->di_mtime.t_sec; 96 buf->bs_mtime.tv_sec = inode->i_mtime.tv_sec;
93 buf->bs_mtime.tv_nsec = dic->di_mtime.t_nsec; 97 buf->bs_mtime.tv_nsec = inode->i_mtime.tv_nsec;
94 buf->bs_ctime.tv_sec = dic->di_ctime.t_sec; 98 buf->bs_ctime.tv_sec = inode->i_ctime.tv_sec;
95 buf->bs_ctime.tv_nsec = dic->di_ctime.t_nsec; 99 buf->bs_ctime.tv_nsec = inode->i_ctime.tv_nsec;
100
96 buf->bs_xflags = xfs_ip2xflags(ip); 101 buf->bs_xflags = xfs_ip2xflags(ip);
97 buf->bs_extsize = dic->di_extsize << mp->m_sb.sb_blocklog; 102 buf->bs_extsize = dic->di_extsize << mp->m_sb.sb_blocklog;
98 buf->bs_extents = dic->di_nextents; 103 buf->bs_extents = dic->di_nextents;
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index a434f287962d..b572f7e840e0 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -2476,12 +2476,6 @@ xfs_reclaim(
2476 ASSERT(XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0); 2476 ASSERT(XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0);
2477 2477
2478 /* 2478 /*
2479 * Make sure the atime in the XFS inode is correct before freeing the
2480 * Linux inode.
2481 */
2482 xfs_synchronize_atime(ip);
2483
2484 /*
2485 * If we have nothing to flush with this inode then complete the 2479 * If we have nothing to flush with this inode then complete the
2486 * teardown now, otherwise break the link between the xfs inode and the 2480 * teardown now, otherwise break the link between the xfs inode and the
2487 * linux inode and clean up the xfs inode later. This avoids flushing 2481 * linux inode and clean up the xfs inode later. This avoids flushing
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
index 9cca3785cab8..66d6106a2067 100644
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -1,6 +1,7 @@
1#ifndef _ASM_GENERIC_GPIO_H 1#ifndef _ASM_GENERIC_GPIO_H
2#define _ASM_GENERIC_GPIO_H 2#define _ASM_GENERIC_GPIO_H
3 3
4#include <linux/kernel.h>
4#include <linux/types.h> 5#include <linux/types.h>
5#include <linux/errno.h> 6#include <linux/errno.h>
6 7
diff --git a/include/asm-generic/hardirq.h b/include/asm-generic/hardirq.h
index 23bb4dad4962..62f59080e5cc 100644
--- a/include/asm-generic/hardirq.h
+++ b/include/asm-generic/hardirq.h
@@ -6,7 +6,7 @@
6#include <linux/irq.h> 6#include <linux/irq.h>
7 7
8typedef struct { 8typedef struct {
9 unsigned long __softirq_pending; 9 unsigned int __softirq_pending;
10} ____cacheline_aligned irq_cpustat_t; 10} ____cacheline_aligned irq_cpustat_t;
11 11
12#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ 12#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h
index ef47dfd8e5e9..b29e20168b5f 100644
--- a/include/drm/drm_crtc_helper.h
+++ b/include/drm/drm_crtc_helper.h
@@ -61,6 +61,9 @@ struct drm_crtc_helper_funcs {
61 /* Move the crtc on the current fb to the given position *optional* */ 61 /* Move the crtc on the current fb to the given position *optional* */
62 int (*mode_set_base)(struct drm_crtc *crtc, int x, int y, 62 int (*mode_set_base)(struct drm_crtc *crtc, int x, int y,
63 struct drm_framebuffer *old_fb); 63 struct drm_framebuffer *old_fb);
64
65 /* reload the current crtc LUT */
66 void (*load_lut)(struct drm_crtc *crtc);
64}; 67};
65 68
66struct drm_encoder_helper_funcs { 69struct drm_encoder_helper_funcs {
diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h
index 4aa5740ce59f..58c892a2cbfa 100644
--- a/include/drm/drm_fb_helper.h
+++ b/include/drm/drm_fb_helper.h
@@ -39,6 +39,8 @@ struct drm_fb_helper_crtc {
39struct drm_fb_helper_funcs { 39struct drm_fb_helper_funcs {
40 void (*gamma_set)(struct drm_crtc *crtc, u16 red, u16 green, 40 void (*gamma_set)(struct drm_crtc *crtc, u16 red, u16 green,
41 u16 blue, int regno); 41 u16 blue, int regno);
42 void (*gamma_get)(struct drm_crtc *crtc, u16 *red, u16 *green,
43 u16 *blue, int regno);
42}; 44};
43 45
44/* mode specified on the command line */ 46/* mode specified on the command line */
@@ -71,6 +73,7 @@ struct drm_fb_helper {
71}; 73};
72 74
73int drm_fb_helper_single_fb_probe(struct drm_device *dev, 75int drm_fb_helper_single_fb_probe(struct drm_device *dev,
76 int preferred_bpp,
74 int (*fb_create)(struct drm_device *dev, 77 int (*fb_create)(struct drm_device *dev,
75 uint32_t fb_width, 78 uint32_t fb_width,
76 uint32_t fb_height, 79 uint32_t fb_height,
@@ -98,9 +101,11 @@ int drm_fb_helper_setcolreg(unsigned regno,
98void drm_fb_helper_restore(void); 101void drm_fb_helper_restore(void);
99void drm_fb_helper_fill_var(struct fb_info *info, struct drm_framebuffer *fb, 102void drm_fb_helper_fill_var(struct fb_info *info, struct drm_framebuffer *fb,
100 uint32_t fb_width, uint32_t fb_height); 103 uint32_t fb_width, uint32_t fb_height);
101void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch); 104void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch,
105 uint32_t depth);
102 106
103int drm_fb_helper_add_connector(struct drm_connector *connector); 107int drm_fb_helper_add_connector(struct drm_connector *connector);
104int drm_fb_helper_parse_command_line(struct drm_device *dev); 108int drm_fb_helper_parse_command_line(struct drm_device *dev);
109int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info);
105 110
106#endif 111#endif
diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h
index 3f6e545609be..e6f3b120f51a 100644
--- a/include/drm/drm_pciids.h
+++ b/include/drm/drm_pciids.h
@@ -80,7 +80,7 @@
80 {0x1002, 0x5158, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200}, \ 80 {0x1002, 0x5158, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200}, \
81 {0x1002, 0x5159, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ 81 {0x1002, 0x5159, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \
82 {0x1002, 0x515A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ 82 {0x1002, 0x515A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \
83 {0x1002, 0x515E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ 83 {0x1002, 0x515E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100|RADEON_SINGLE_CRTC}, \
84 {0x1002, 0x5460, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ 84 {0x1002, 0x5460, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \
85 {0x1002, 0x5462, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ 85 {0x1002, 0x5462, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \
86 {0x1002, 0x5464, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ 86 {0x1002, 0x5464, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \
@@ -113,7 +113,7 @@
113 {0x1002, 0x5962, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ 113 {0x1002, 0x5962, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
114 {0x1002, 0x5964, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ 114 {0x1002, 0x5964, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
115 {0x1002, 0x5965, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ 115 {0x1002, 0x5965, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
116 {0x1002, 0x5969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ 116 {0x1002, 0x5969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100|RADEON_SINGLE_CRTC}, \
117 {0x1002, 0x5a41, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_IGPGART}, \ 117 {0x1002, 0x5a41, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_IGPGART}, \
118 {0x1002, 0x5a42, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \ 118 {0x1002, 0x5a42, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
119 {0x1002, 0x5a61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_IGPGART}, \ 119 {0x1002, 0x5a61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_IGPGART}, \
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index cff4a101f266..3f384d4b163a 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -126,6 +126,7 @@ header-y += nfs_mount.h
126header-y += nl80211.h 126header-y += nl80211.h
127header-y += param.h 127header-y += param.h
128header-y += pci_regs.h 128header-y += pci_regs.h
129header-y += perf_event.h
129header-y += pfkeyv2.h 130header-y += pfkeyv2.h
130header-y += pg.h 131header-y += pg.h
131header-y += phantom.h 132header-y += phantom.h
diff --git a/include/linux/ata.h b/include/linux/ata.h
index 6299a259ed19..4fb357312b3b 100644
--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -334,9 +334,12 @@ enum {
334 SETFEATURES_SATA_DISABLE = 0x90, /* Disable use of SATA feature */ 334 SETFEATURES_SATA_DISABLE = 0x90, /* Disable use of SATA feature */
335 335
336 /* SETFEATURE Sector counts for SATA features */ 336 /* SETFEATURE Sector counts for SATA features */
337 SATA_AN = 0x05, /* Asynchronous Notification */ 337 SATA_FPDMA_OFFSET = 0x01, /* FPDMA non-zero buffer offsets */
338 SATA_DIPM = 0x03, /* Device Initiated Power Management */ 338 SATA_FPDMA_AA = 0x02, /* FPDMA Setup FIS Auto-Activate */
339 SATA_FPDMA_AA = 0x02, /* DMA Setup FIS Auto-Activate */ 339 SATA_DIPM = 0x03, /* Device Initiated Power Management */
340 SATA_FPDMA_IN_ORDER = 0x04, /* FPDMA in-order data delivery */
341 SATA_AN = 0x05, /* Asynchronous Notification */
342 SATA_SSP = 0x06, /* Software Settings Preservation */
340 343
341 /* feature values for SET_MAX */ 344 /* feature values for SET_MAX */
342 ATA_SET_MAX_ADDR = 0x00, 345 ATA_SET_MAX_ADDR = 0x00,
diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h
index 086e5c362d3a..817b23705c91 100644
--- a/include/linux/atmdev.h
+++ b/include/linux/atmdev.h
@@ -397,7 +397,7 @@ struct atmdev_ops { /* only send is required */
397 int (*getsockopt)(struct atm_vcc *vcc,int level,int optname, 397 int (*getsockopt)(struct atm_vcc *vcc,int level,int optname,
398 void __user *optval,int optlen); 398 void __user *optval,int optlen);
399 int (*setsockopt)(struct atm_vcc *vcc,int level,int optname, 399 int (*setsockopt)(struct atm_vcc *vcc,int level,int optname,
400 void __user *optval,int optlen); 400 void __user *optval,unsigned int optlen);
401 int (*send)(struct atm_vcc *vcc,struct sk_buff *skb); 401 int (*send)(struct atm_vcc *vcc,struct sk_buff *skb);
402 int (*send_oam)(struct atm_vcc *vcc,void *cell,int flags); 402 int (*send_oam)(struct atm_vcc *vcc,void *cell,int flags);
403 void (*phy_put)(struct atm_dev *dev,unsigned char value, 403 void (*phy_put)(struct atm_dev *dev,unsigned char value,
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index e23a86cae5ac..221cecd86bd3 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -82,7 +82,6 @@ enum rq_cmd_type_bits {
82enum { 82enum {
83 REQ_LB_OP_EJECT = 0x40, /* eject request */ 83 REQ_LB_OP_EJECT = 0x40, /* eject request */
84 REQ_LB_OP_FLUSH = 0x41, /* flush request */ 84 REQ_LB_OP_FLUSH = 0x41, /* flush request */
85 REQ_LB_OP_DISCARD = 0x42, /* discard sectors */
86}; 85};
87 86
88/* 87/*
@@ -261,7 +260,6 @@ typedef void (request_fn_proc) (struct request_queue *q);
261typedef int (make_request_fn) (struct request_queue *q, struct bio *bio); 260typedef int (make_request_fn) (struct request_queue *q, struct bio *bio);
262typedef int (prep_rq_fn) (struct request_queue *, struct request *); 261typedef int (prep_rq_fn) (struct request_queue *, struct request *);
263typedef void (unplug_fn) (struct request_queue *); 262typedef void (unplug_fn) (struct request_queue *);
264typedef int (prepare_discard_fn) (struct request_queue *, struct request *);
265 263
266struct bio_vec; 264struct bio_vec;
267struct bvec_merge_data { 265struct bvec_merge_data {
@@ -313,6 +311,7 @@ struct queue_limits {
313 unsigned int alignment_offset; 311 unsigned int alignment_offset;
314 unsigned int io_min; 312 unsigned int io_min;
315 unsigned int io_opt; 313 unsigned int io_opt;
314 unsigned int max_discard_sectors;
316 315
317 unsigned short logical_block_size; 316 unsigned short logical_block_size;
318 unsigned short max_hw_segments; 317 unsigned short max_hw_segments;
@@ -340,7 +339,6 @@ struct request_queue
340 make_request_fn *make_request_fn; 339 make_request_fn *make_request_fn;
341 prep_rq_fn *prep_rq_fn; 340 prep_rq_fn *prep_rq_fn;
342 unplug_fn *unplug_fn; 341 unplug_fn *unplug_fn;
343 prepare_discard_fn *prepare_discard_fn;
344 merge_bvec_fn *merge_bvec_fn; 342 merge_bvec_fn *merge_bvec_fn;
345 prepare_flush_fn *prepare_flush_fn; 343 prepare_flush_fn *prepare_flush_fn;
346 softirq_done_fn *softirq_done_fn; 344 softirq_done_fn *softirq_done_fn;
@@ -460,6 +458,7 @@ struct request_queue
460#define QUEUE_FLAG_VIRT QUEUE_FLAG_NONROT /* paravirt device */ 458#define QUEUE_FLAG_VIRT QUEUE_FLAG_NONROT /* paravirt device */
461#define QUEUE_FLAG_IO_STAT 15 /* do IO stats */ 459#define QUEUE_FLAG_IO_STAT 15 /* do IO stats */
462#define QUEUE_FLAG_CQ 16 /* hardware does queuing */ 460#define QUEUE_FLAG_CQ 16 /* hardware does queuing */
461#define QUEUE_FLAG_DISCARD 17 /* supports DISCARD */
463 462
464#define QUEUE_FLAG_DEFAULT ((1 << QUEUE_FLAG_IO_STAT) | \ 463#define QUEUE_FLAG_DEFAULT ((1 << QUEUE_FLAG_IO_STAT) | \
465 (1 << QUEUE_FLAG_CLUSTER) | \ 464 (1 << QUEUE_FLAG_CLUSTER) | \
@@ -591,6 +590,7 @@ enum {
591#define blk_queue_flushing(q) ((q)->ordseq) 590#define blk_queue_flushing(q) ((q)->ordseq)
592#define blk_queue_stackable(q) \ 591#define blk_queue_stackable(q) \
593 test_bit(QUEUE_FLAG_STACKABLE, &(q)->queue_flags) 592 test_bit(QUEUE_FLAG_STACKABLE, &(q)->queue_flags)
593#define blk_queue_discard(q) test_bit(QUEUE_FLAG_DISCARD, &(q)->queue_flags)
594 594
595#define blk_fs_request(rq) ((rq)->cmd_type == REQ_TYPE_FS) 595#define blk_fs_request(rq) ((rq)->cmd_type == REQ_TYPE_FS)
596#define blk_pc_request(rq) ((rq)->cmd_type == REQ_TYPE_BLOCK_PC) 596#define blk_pc_request(rq) ((rq)->cmd_type == REQ_TYPE_BLOCK_PC)
@@ -929,6 +929,8 @@ extern void blk_queue_max_hw_sectors(struct request_queue *, unsigned int);
929extern void blk_queue_max_phys_segments(struct request_queue *, unsigned short); 929extern void blk_queue_max_phys_segments(struct request_queue *, unsigned short);
930extern void blk_queue_max_hw_segments(struct request_queue *, unsigned short); 930extern void blk_queue_max_hw_segments(struct request_queue *, unsigned short);
931extern void blk_queue_max_segment_size(struct request_queue *, unsigned int); 931extern void blk_queue_max_segment_size(struct request_queue *, unsigned int);
932extern void blk_queue_max_discard_sectors(struct request_queue *q,
933 unsigned int max_discard_sectors);
932extern void blk_queue_logical_block_size(struct request_queue *, unsigned short); 934extern void blk_queue_logical_block_size(struct request_queue *, unsigned short);
933extern void blk_queue_physical_block_size(struct request_queue *, unsigned short); 935extern void blk_queue_physical_block_size(struct request_queue *, unsigned short);
934extern void blk_queue_alignment_offset(struct request_queue *q, 936extern void blk_queue_alignment_offset(struct request_queue *q,
@@ -955,7 +957,6 @@ extern void blk_queue_merge_bvec(struct request_queue *, merge_bvec_fn *);
955extern void blk_queue_dma_alignment(struct request_queue *, int); 957extern void blk_queue_dma_alignment(struct request_queue *, int);
956extern void blk_queue_update_dma_alignment(struct request_queue *, int); 958extern void blk_queue_update_dma_alignment(struct request_queue *, int);
957extern void blk_queue_softirq_done(struct request_queue *, softirq_done_fn *); 959extern void blk_queue_softirq_done(struct request_queue *, softirq_done_fn *);
958extern void blk_queue_set_discard(struct request_queue *, prepare_discard_fn *);
959extern void blk_queue_rq_timed_out(struct request_queue *, rq_timed_out_fn *); 960extern void blk_queue_rq_timed_out(struct request_queue *, rq_timed_out_fn *);
960extern void blk_queue_rq_timeout(struct request_queue *, unsigned int); 961extern void blk_queue_rq_timeout(struct request_queue *, unsigned int);
961extern struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev); 962extern struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev);
@@ -1080,25 +1081,37 @@ static inline unsigned int queue_physical_block_size(struct request_queue *q)
1080 return q->limits.physical_block_size; 1081 return q->limits.physical_block_size;
1081} 1082}
1082 1083
1084static inline int bdev_physical_block_size(struct block_device *bdev)
1085{
1086 return queue_physical_block_size(bdev_get_queue(bdev));
1087}
1088
1083static inline unsigned int queue_io_min(struct request_queue *q) 1089static inline unsigned int queue_io_min(struct request_queue *q)
1084{ 1090{
1085 return q->limits.io_min; 1091 return q->limits.io_min;
1086} 1092}
1087 1093
1094static inline int bdev_io_min(struct block_device *bdev)
1095{
1096 return queue_io_min(bdev_get_queue(bdev));
1097}
1098
1088static inline unsigned int queue_io_opt(struct request_queue *q) 1099static inline unsigned int queue_io_opt(struct request_queue *q)
1089{ 1100{
1090 return q->limits.io_opt; 1101 return q->limits.io_opt;
1091} 1102}
1092 1103
1104static inline int bdev_io_opt(struct block_device *bdev)
1105{
1106 return queue_io_opt(bdev_get_queue(bdev));
1107}
1108
1093static inline int queue_alignment_offset(struct request_queue *q) 1109static inline int queue_alignment_offset(struct request_queue *q)
1094{ 1110{
1095 if (q && q->limits.misaligned) 1111 if (q->limits.misaligned)
1096 return -1; 1112 return -1;
1097 1113
1098 if (q && q->limits.alignment_offset) 1114 return q->limits.alignment_offset;
1099 return q->limits.alignment_offset;
1100
1101 return 0;
1102} 1115}
1103 1116
1104static inline int queue_sector_alignment_offset(struct request_queue *q, 1117static inline int queue_sector_alignment_offset(struct request_queue *q,
@@ -1108,6 +1121,19 @@ static inline int queue_sector_alignment_offset(struct request_queue *q,
1108 & (q->limits.io_min - 1); 1121 & (q->limits.io_min - 1);
1109} 1122}
1110 1123
1124static inline int bdev_alignment_offset(struct block_device *bdev)
1125{
1126 struct request_queue *q = bdev_get_queue(bdev);
1127
1128 if (q->limits.misaligned)
1129 return -1;
1130
1131 if (bdev != bdev->bd_contains)
1132 return bdev->bd_part->alignment_offset;
1133
1134 return q->limits.alignment_offset;
1135}
1136
1111static inline int queue_dma_alignment(struct request_queue *q) 1137static inline int queue_dma_alignment(struct request_queue *q)
1112{ 1138{
1113 return q ? q->dma_alignment : 511; 1139 return q ? q->dma_alignment : 511;
diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h
index 7e4350ece0f8..3b73b9992b26 100644
--- a/include/linux/blktrace_api.h
+++ b/include/linux/blktrace_api.h
@@ -198,6 +198,7 @@ extern int blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
198 char __user *arg); 198 char __user *arg);
199extern int blk_trace_startstop(struct request_queue *q, int start); 199extern int blk_trace_startstop(struct request_queue *q, int start);
200extern int blk_trace_remove(struct request_queue *q); 200extern int blk_trace_remove(struct request_queue *q);
201extern void blk_trace_remove_sysfs(struct device *dev);
201extern int blk_trace_init_sysfs(struct device *dev); 202extern int blk_trace_init_sysfs(struct device *dev);
202 203
203extern struct attribute_group blk_trace_attr_group; 204extern struct attribute_group blk_trace_attr_group;
@@ -211,6 +212,7 @@ extern struct attribute_group blk_trace_attr_group;
211# define blk_trace_startstop(q, start) (-ENOTTY) 212# define blk_trace_startstop(q, start) (-ENOTTY)
212# define blk_trace_remove(q) (-ENOTTY) 213# define blk_trace_remove(q) (-ENOTTY)
213# define blk_add_trace_msg(q, fmt, ...) do { } while (0) 214# define blk_add_trace_msg(q, fmt, ...) do { } while (0)
215# define blk_trace_remove_sysfs(dev) do { } while (0)
214static inline int blk_trace_init_sysfs(struct device *dev) 216static inline int blk_trace_init_sysfs(struct device *dev)
215{ 217{
216 return 0; 218 return 0;
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index b62bb9294d0c..0008dee66514 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -37,7 +37,7 @@ extern void cgroup_exit(struct task_struct *p, int run_callbacks);
37extern int cgroupstats_build(struct cgroupstats *stats, 37extern int cgroupstats_build(struct cgroupstats *stats,
38 struct dentry *dentry); 38 struct dentry *dentry);
39 39
40extern struct file_operations proc_cgroup_operations; 40extern const struct file_operations proc_cgroup_operations;
41 41
42/* Define the enumeration of all cgroup subsystems */ 42/* Define the enumeration of all cgroup subsystems */
43#define SUBSYS(_x) _x ## _subsys_id, 43#define SUBSYS(_x) _x ## _subsys_id,
diff --git a/include/linux/connector.h b/include/linux/connector.h
index 47ebf416f512..3a14615fd35c 100644
--- a/include/linux/connector.h
+++ b/include/linux/connector.h
@@ -132,11 +132,8 @@ struct cn_callback_id {
132}; 132};
133 133
134struct cn_callback_data { 134struct cn_callback_data {
135 void (*destruct_data) (void *); 135 struct sk_buff *skb;
136 void *ddata; 136 void (*callback) (struct cn_msg *, struct netlink_skb_parms *);
137
138 void *callback_priv;
139 void (*callback) (struct cn_msg *);
140 137
141 void *free; 138 void *free;
142}; 139};
@@ -167,11 +164,11 @@ struct cn_dev {
167 struct cn_queue_dev *cbdev; 164 struct cn_queue_dev *cbdev;
168}; 165};
169 166
170int cn_add_callback(struct cb_id *, char *, void (*callback) (struct cn_msg *)); 167int cn_add_callback(struct cb_id *, char *, void (*callback) (struct cn_msg *, struct netlink_skb_parms *));
171void cn_del_callback(struct cb_id *); 168void cn_del_callback(struct cb_id *);
172int cn_netlink_send(struct cn_msg *, u32, gfp_t); 169int cn_netlink_send(struct cn_msg *, u32, gfp_t);
173 170
174int cn_queue_add_callback(struct cn_queue_dev *dev, char *name, struct cb_id *id, void (*callback)(struct cn_msg *)); 171int cn_queue_add_callback(struct cn_queue_dev *dev, char *name, struct cb_id *id, void (*callback)(struct cn_msg *, struct netlink_skb_parms *));
175void cn_queue_del_callback(struct cn_queue_dev *dev, struct cb_id *id); 172void cn_queue_del_callback(struct cn_queue_dev *dev, struct cb_id *id);
176 173
177int queue_cn_work(struct cn_callback_entry *cbq, struct work_struct *work); 174int queue_cn_work(struct cn_callback_entry *cbq, struct work_struct *work);
diff --git a/include/linux/elf.h b/include/linux/elf.h
index 45a937be6d38..90a4ed0ea0e5 100644
--- a/include/linux/elf.h
+++ b/include/linux/elf.h
@@ -361,6 +361,7 @@ typedef struct elf64_shdr {
361#define NT_PPC_VSX 0x102 /* PowerPC VSX registers */ 361#define NT_PPC_VSX 0x102 /* PowerPC VSX registers */
362#define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */ 362#define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */
363#define NT_386_IOPERM 0x201 /* x86 io permission bitmap (1=deny) */ 363#define NT_386_IOPERM 0x201 /* x86 io permission bitmap (1=deny) */
364#define NT_PRXSTATUS 0x300 /* s390 upper register halves */
364 365
365 366
366/* Note header in a PT_NOTE section */ 367/* Note header in a PT_NOTE section */
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 2adaa2529f18..2620a8c63571 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -300,6 +300,10 @@ struct inodes_stat_t {
300#define BLKTRACESTOP _IO(0x12,117) 300#define BLKTRACESTOP _IO(0x12,117)
301#define BLKTRACETEARDOWN _IO(0x12,118) 301#define BLKTRACETEARDOWN _IO(0x12,118)
302#define BLKDISCARD _IO(0x12,119) 302#define BLKDISCARD _IO(0x12,119)
303#define BLKIOMIN _IO(0x12,120)
304#define BLKIOOPT _IO(0x12,121)
305#define BLKALIGNOFF _IO(0x12,122)
306#define BLKPBSZGET _IO(0x12,123)
303 307
304#define BMAP_IOCTL 1 /* obsolete - kept for compatibility */ 308#define BMAP_IOCTL 1 /* obsolete - kept for compatibility */
305#define FIBMAP _IO(0x00,1) /* bmap access */ 309#define FIBMAP _IO(0x00,1) /* bmap access */
@@ -2446,7 +2450,7 @@ static int __fops ## _open(struct inode *inode, struct file *file) \
2446 __simple_attr_check_format(__fmt, 0ull); \ 2450 __simple_attr_check_format(__fmt, 0ull); \
2447 return simple_attr_open(inode, file, __get, __set, __fmt); \ 2451 return simple_attr_open(inode, file, __get, __set, __fmt); \
2448} \ 2452} \
2449static struct file_operations __fops = { \ 2453static const struct file_operations __fops = { \
2450 .owner = THIS_MODULE, \ 2454 .owner = THIS_MODULE, \
2451 .open = __fops ## _open, \ 2455 .open = __fops ## _open, \
2452 .release = simple_attr_release, \ 2456 .release = simple_attr_release, \
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
index cd3d2abaf30a..0b4f97d24d7f 100644
--- a/include/linux/ftrace.h
+++ b/include/linux/ftrace.h
@@ -241,7 +241,7 @@ extern void ftrace_enable_daemon(void);
241# define ftrace_set_filter(buf, len, reset) do { } while (0) 241# define ftrace_set_filter(buf, len, reset) do { } while (0)
242# define ftrace_disable_daemon() do { } while (0) 242# define ftrace_disable_daemon() do { } while (0)
243# define ftrace_enable_daemon() do { } while (0) 243# define ftrace_enable_daemon() do { } while (0)
244static inline void ftrace_release(void *start, unsigned long size) { } 244static inline void ftrace_release_mod(struct module *mod) {}
245static inline int register_ftrace_command(struct ftrace_func_command *cmd) 245static inline int register_ftrace_command(struct ftrace_func_command *cmd)
246{ 246{
247 return -EINVAL; 247 return -EINVAL;
diff --git a/include/linux/futex.h b/include/linux/futex.h
index 8ec17997d94f..1e5a26d79232 100644
--- a/include/linux/futex.h
+++ b/include/linux/futex.h
@@ -33,8 +33,8 @@
33#define FUTEX_LOCK_PI_PRIVATE (FUTEX_LOCK_PI | FUTEX_PRIVATE_FLAG) 33#define FUTEX_LOCK_PI_PRIVATE (FUTEX_LOCK_PI | FUTEX_PRIVATE_FLAG)
34#define FUTEX_UNLOCK_PI_PRIVATE (FUTEX_UNLOCK_PI | FUTEX_PRIVATE_FLAG) 34#define FUTEX_UNLOCK_PI_PRIVATE (FUTEX_UNLOCK_PI | FUTEX_PRIVATE_FLAG)
35#define FUTEX_TRYLOCK_PI_PRIVATE (FUTEX_TRYLOCK_PI | FUTEX_PRIVATE_FLAG) 35#define FUTEX_TRYLOCK_PI_PRIVATE (FUTEX_TRYLOCK_PI | FUTEX_PRIVATE_FLAG)
36#define FUTEX_WAIT_BITSET_PRIVATE (FUTEX_WAIT_BITS | FUTEX_PRIVATE_FLAG) 36#define FUTEX_WAIT_BITSET_PRIVATE (FUTEX_WAIT_BITSET | FUTEX_PRIVATE_FLAG)
37#define FUTEX_WAKE_BITSET_PRIVATE (FUTEX_WAKE_BITS | FUTEX_PRIVATE_FLAG) 37#define FUTEX_WAKE_BITSET_PRIVATE (FUTEX_WAKE_BITSET | FUTEX_PRIVATE_FLAG)
38#define FUTEX_WAIT_REQUEUE_PI_PRIVATE (FUTEX_WAIT_REQUEUE_PI | \ 38#define FUTEX_WAIT_REQUEUE_PI_PRIVATE (FUTEX_WAIT_REQUEUE_PI | \
39 FUTEX_PRIVATE_FLAG) 39 FUTEX_PRIVATE_FLAG)
40#define FUTEX_CMP_REQUEUE_PI_PRIVATE (FUTEX_CMP_REQUEUE_PI | \ 40#define FUTEX_CMP_REQUEUE_PI_PRIVATE (FUTEX_CMP_REQUEUE_PI | \
diff --git a/include/linux/i2c/twl4030.h b/include/linux/i2c/twl4030.h
index 2d02dfd7076c..508824ee35e6 100644
--- a/include/linux/i2c/twl4030.h
+++ b/include/linux/i2c/twl4030.h
@@ -349,11 +349,11 @@ struct twl4030_madc_platform_data {
349 int irq_line; 349 int irq_line;
350}; 350};
351 351
352/* Boards have uniqe mappings of {col, row} --> keycode. 352/* Boards have uniqe mappings of {row, col} --> keycode.
353 * Column and row are 4 bits, but range only from 0..7. 353 * Column and row are 8 bits each, but range only from 0..7.
354 * a PERSISTENT_KEY is "always on" and never reported. 354 * a PERSISTENT_KEY is "always on" and never reported.
355 */ 355 */
356#define PERSISTENT_KEY(c, r) KEY((c), (r), KEY_RESERVED) 356#define PERSISTENT_KEY(r, c) KEY((r), (c), KEY_RESERVED)
357 357
358struct twl4030_keypad_data { 358struct twl4030_keypad_data {
359 const struct matrix_keymap_data *keymap_data; 359 const struct matrix_keymap_data *keymap_data;
diff --git a/include/linux/init.h b/include/linux/init.h
index 400adbb45414..ff8bde520d03 100644
--- a/include/linux/init.h
+++ b/include/linux/init.h
@@ -271,6 +271,7 @@ void __init parse_early_options(char *cmdline);
271#else /* MODULE */ 271#else /* MODULE */
272 272
273/* Don't use these in modules, but some people do... */ 273/* Don't use these in modules, but some people do... */
274#define early_initcall(fn) module_init(fn)
274#define core_initcall(fn) module_init(fn) 275#define core_initcall(fn) module_init(fn)
275#define postcore_initcall(fn) module_init(fn) 276#define postcore_initcall(fn) module_init(fn)
276#define arch_initcall(fn) module_init(fn) 277#define arch_initcall(fn) module_init(fn)
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index b78cf8194957..7ca72b74eec7 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -10,7 +10,6 @@
10#include <linux/irqreturn.h> 10#include <linux/irqreturn.h>
11#include <linux/irqnr.h> 11#include <linux/irqnr.h>
12#include <linux/hardirq.h> 12#include <linux/hardirq.h>
13#include <linux/sched.h>
14#include <linux/irqflags.h> 13#include <linux/irqflags.h>
15#include <linux/smp.h> 14#include <linux/smp.h>
16#include <linux/percpu.h> 15#include <linux/percpu.h>
@@ -610,6 +609,7 @@ extern void debug_poll_all_shared_irqs(void);
610static inline void debug_poll_all_shared_irqs(void) { } 609static inline void debug_poll_all_shared_irqs(void) { }
611#endif 610#endif
612 611
612struct seq_file;
613int show_interrupts(struct seq_file *p, void *v); 613int show_interrupts(struct seq_file *p, void *v);
614 614
615struct irq_desc; 615struct irq_desc;
diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h
index 52695d3dfd0b..f1011f7f3d41 100644
--- a/include/linux/jbd2.h
+++ b/include/linux/jbd2.h
@@ -464,9 +464,9 @@ struct handle_s
464 */ 464 */
465struct transaction_chp_stats_s { 465struct transaction_chp_stats_s {
466 unsigned long cs_chp_time; 466 unsigned long cs_chp_time;
467 unsigned long cs_forced_to_close; 467 __u32 cs_forced_to_close;
468 unsigned long cs_written; 468 __u32 cs_written;
469 unsigned long cs_dropped; 469 __u32 cs_dropped;
470}; 470};
471 471
472/* The transaction_t type is the guts of the journaling mechanism. It 472/* The transaction_t type is the guts of the journaling mechanism. It
@@ -668,23 +668,16 @@ struct transaction_run_stats_s {
668 unsigned long rs_flushing; 668 unsigned long rs_flushing;
669 unsigned long rs_logging; 669 unsigned long rs_logging;
670 670
671 unsigned long rs_handle_count; 671 __u32 rs_handle_count;
672 unsigned long rs_blocks; 672 __u32 rs_blocks;
673 unsigned long rs_blocks_logged; 673 __u32 rs_blocks_logged;
674}; 674};
675 675
676struct transaction_stats_s { 676struct transaction_stats_s {
677 int ts_type;
678 unsigned long ts_tid; 677 unsigned long ts_tid;
679 union { 678 struct transaction_run_stats_s run;
680 struct transaction_run_stats_s run;
681 struct transaction_chp_stats_s chp;
682 } u;
683}; 679};
684 680
685#define JBD2_STATS_RUN 1
686#define JBD2_STATS_CHECKPOINT 2
687
688static inline unsigned long 681static inline unsigned long
689jbd2_time_diff(unsigned long start, unsigned long end) 682jbd2_time_diff(unsigned long start, unsigned long end)
690{ 683{
@@ -988,12 +981,6 @@ struct journal_s
988 /* 981 /*
989 * Journal statistics 982 * Journal statistics
990 */ 983 */
991 struct transaction_stats_s *j_history;
992 int j_history_max;
993 int j_history_cur;
994 /*
995 * Protect the transactions statistics history
996 */
997 spinlock_t j_history_lock; 984 spinlock_t j_history_lock;
998 struct proc_dir_entry *j_proc_entry; 985 struct proc_dir_entry *j_proc_entry;
999 struct transaction_stats_s j_stats; 986 struct transaction_stats_s j_stats;
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index d3cd23f30039..f4e3184fa054 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -659,6 +659,12 @@ extern int do_sysinfo(struct sysinfo *info);
659 659
660#endif /* __KERNEL__ */ 660#endif /* __KERNEL__ */
661 661
662#ifndef __EXPORTED_HEADERS__
663#ifndef __KERNEL__
664#warning Attempt to use kernel headers from user space, see http://kernelnewbies.org/KernelHeaders
665#endif /* __KERNEL__ */
666#endif /* __EXPORTED_HEADERS__ */
667
662#define SI_LOAD_SHIFT 16 668#define SI_LOAD_SHIFT 16
663struct sysinfo { 669struct sysinfo {
664 long uptime; /* Seconds since boot */ 670 long uptime; /* Seconds since boot */
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 76319bf03e37..87698640c091 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -418,6 +418,17 @@ enum {
418 ATA_TIMING_ACTIVE | ATA_TIMING_RECOVER | 418 ATA_TIMING_ACTIVE | ATA_TIMING_RECOVER |
419 ATA_TIMING_DMACK_HOLD | ATA_TIMING_CYCLE | 419 ATA_TIMING_DMACK_HOLD | ATA_TIMING_CYCLE |
420 ATA_TIMING_UDMA, 420 ATA_TIMING_UDMA,
421
422 /* ACPI constants */
423 ATA_ACPI_FILTER_SETXFER = 1 << 0,
424 ATA_ACPI_FILTER_LOCK = 1 << 1,
425 ATA_ACPI_FILTER_DIPM = 1 << 2,
426 ATA_ACPI_FILTER_FPDMA_OFFSET = 1 << 3, /* FPDMA non-zero offset */
427 ATA_ACPI_FILTER_FPDMA_AA = 1 << 4, /* FPDMA auto activate */
428
429 ATA_ACPI_FILTER_DEFAULT = ATA_ACPI_FILTER_SETXFER |
430 ATA_ACPI_FILTER_LOCK |
431 ATA_ACPI_FILTER_DIPM,
421}; 432};
422 433
423enum ata_xfer_mask { 434enum ata_xfer_mask {
@@ -587,6 +598,7 @@ struct ata_device {
587#ifdef CONFIG_ATA_ACPI 598#ifdef CONFIG_ATA_ACPI
588 acpi_handle acpi_handle; 599 acpi_handle acpi_handle;
589 union acpi_object *gtf_cache; 600 union acpi_object *gtf_cache;
601 unsigned int gtf_filter;
590#endif 602#endif
591 /* n_sector is CLEAR_BEGIN, read comment above CLEAR_BEGIN */ 603 /* n_sector is CLEAR_BEGIN, read comment above CLEAR_BEGIN */
592 u64 n_sectors; /* size of device, if ATA */ 604 u64 n_sectors; /* size of device, if ATA */
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 81bb42358595..eaf36364b7d4 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -11,6 +11,7 @@
11#define LINUX_MMC_HOST_H 11#define LINUX_MMC_HOST_H
12 12
13#include <linux/leds.h> 13#include <linux/leds.h>
14#include <linux/sched.h>
14 15
15#include <linux/mmc/core.h> 16#include <linux/mmc/core.h>
16 17
diff --git a/include/linux/mroute.h b/include/linux/mroute.h
index 0d45b4e8d367..08bc776d05e2 100644
--- a/include/linux/mroute.h
+++ b/include/linux/mroute.h
@@ -145,14 +145,14 @@ static inline int ip_mroute_opt(int opt)
145#endif 145#endif
146 146
147#ifdef CONFIG_IP_MROUTE 147#ifdef CONFIG_IP_MROUTE
148extern int ip_mroute_setsockopt(struct sock *, int, char __user *, int); 148extern int ip_mroute_setsockopt(struct sock *, int, char __user *, unsigned int);
149extern int ip_mroute_getsockopt(struct sock *, int, char __user *, int __user *); 149extern int ip_mroute_getsockopt(struct sock *, int, char __user *, int __user *);
150extern int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg); 150extern int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg);
151extern int ip_mr_init(void); 151extern int ip_mr_init(void);
152#else 152#else
153static inline 153static inline
154int ip_mroute_setsockopt(struct sock *sock, 154int ip_mroute_setsockopt(struct sock *sock,
155 int optname, char __user *optval, int optlen) 155 int optname, char __user *optval, unsigned int optlen)
156{ 156{
157 return -ENOPROTOOPT; 157 return -ENOPROTOOPT;
158} 158}
diff --git a/include/linux/mroute6.h b/include/linux/mroute6.h
index 43dc97e32183..b191865a6ca3 100644
--- a/include/linux/mroute6.h
+++ b/include/linux/mroute6.h
@@ -134,7 +134,7 @@ static inline int ip6_mroute_opt(int opt)
134struct sock; 134struct sock;
135 135
136#ifdef CONFIG_IPV6_MROUTE 136#ifdef CONFIG_IPV6_MROUTE
137extern int ip6_mroute_setsockopt(struct sock *, int, char __user *, int); 137extern int ip6_mroute_setsockopt(struct sock *, int, char __user *, unsigned int);
138extern int ip6_mroute_getsockopt(struct sock *, int, char __user *, int __user *); 138extern int ip6_mroute_getsockopt(struct sock *, int, char __user *, int __user *);
139extern int ip6_mr_input(struct sk_buff *skb); 139extern int ip6_mr_input(struct sk_buff *skb);
140extern int ip6mr_ioctl(struct sock *sk, int cmd, void __user *arg); 140extern int ip6mr_ioctl(struct sock *sk, int cmd, void __user *arg);
@@ -143,7 +143,7 @@ extern void ip6_mr_cleanup(void);
143#else 143#else
144static inline 144static inline
145int ip6_mroute_setsockopt(struct sock *sock, 145int ip6_mroute_setsockopt(struct sock *sock,
146 int optname, char __user *optval, int optlen) 146 int optname, char __user *optval, unsigned int optlen)
147{ 147{
148 return -ENOPROTOOPT; 148 return -ENOPROTOOPT;
149} 149}
diff --git a/include/linux/net.h b/include/linux/net.h
index 9040a10584f7..529a0931711d 100644
--- a/include/linux/net.h
+++ b/include/linux/net.h
@@ -178,11 +178,11 @@ struct proto_ops {
178 int (*listen) (struct socket *sock, int len); 178 int (*listen) (struct socket *sock, int len);
179 int (*shutdown) (struct socket *sock, int flags); 179 int (*shutdown) (struct socket *sock, int flags);
180 int (*setsockopt)(struct socket *sock, int level, 180 int (*setsockopt)(struct socket *sock, int level,
181 int optname, char __user *optval, int optlen); 181 int optname, char __user *optval, unsigned int optlen);
182 int (*getsockopt)(struct socket *sock, int level, 182 int (*getsockopt)(struct socket *sock, int level,
183 int optname, char __user *optval, int __user *optlen); 183 int optname, char __user *optval, int __user *optlen);
184 int (*compat_setsockopt)(struct socket *sock, int level, 184 int (*compat_setsockopt)(struct socket *sock, int level,
185 int optname, char __user *optval, int optlen); 185 int optname, char __user *optval, unsigned int optlen);
186 int (*compat_getsockopt)(struct socket *sock, int level, 186 int (*compat_getsockopt)(struct socket *sock, int level,
187 int optname, char __user *optval, int __user *optlen); 187 int optname, char __user *optval, int __user *optlen);
188 int (*sendmsg) (struct kiocb *iocb, struct socket *sock, 188 int (*sendmsg) (struct kiocb *iocb, struct socket *sock,
@@ -256,7 +256,7 @@ extern int kernel_getpeername(struct socket *sock, struct sockaddr *addr,
256extern int kernel_getsockopt(struct socket *sock, int level, int optname, 256extern int kernel_getsockopt(struct socket *sock, int level, int optname,
257 char *optval, int *optlen); 257 char *optval, int *optlen);
258extern int kernel_setsockopt(struct socket *sock, int level, int optname, 258extern int kernel_setsockopt(struct socket *sock, int level, int optname,
259 char *optval, int optlen); 259 char *optval, unsigned int optlen);
260extern int kernel_sendpage(struct socket *sock, struct page *page, int offset, 260extern int kernel_sendpage(struct socket *sock, struct page *page, int offset,
261 size_t size, int flags); 261 size_t size, int flags);
262extern int kernel_sock_ioctl(struct socket *sock, int cmd, unsigned long arg); 262extern int kernel_sock_ioctl(struct socket *sock, int cmd, unsigned long arg);
@@ -313,7 +313,7 @@ SOCKCALL_WRAP(name, compat_ioctl, (struct socket *sock, unsigned int cmd, \
313SOCKCALL_WRAP(name, listen, (struct socket *sock, int len), (sock, len)) \ 313SOCKCALL_WRAP(name, listen, (struct socket *sock, int len), (sock, len)) \
314SOCKCALL_WRAP(name, shutdown, (struct socket *sock, int flags), (sock, flags)) \ 314SOCKCALL_WRAP(name, shutdown, (struct socket *sock, int flags), (sock, flags)) \
315SOCKCALL_WRAP(name, setsockopt, (struct socket *sock, int level, int optname, \ 315SOCKCALL_WRAP(name, setsockopt, (struct socket *sock, int level, int optname, \
316 char __user *optval, int optlen), (sock, level, optname, optval, optlen)) \ 316 char __user *optval, unsigned int optlen), (sock, level, optname, optval, optlen)) \
317SOCKCALL_WRAP(name, getsockopt, (struct socket *sock, int level, int optname, \ 317SOCKCALL_WRAP(name, getsockopt, (struct socket *sock, int level, int optname, \
318 char __user *optval, int __user *optlen), (sock, level, optname, optval, optlen)) \ 318 char __user *optval, int __user *optlen), (sock, level, optname, optval, optlen)) \
319SOCKCALL_WRAP(name, sendmsg, (struct kiocb *iocb, struct socket *sock, struct msghdr *m, size_t len), \ 319SOCKCALL_WRAP(name, sendmsg, (struct kiocb *iocb, struct socket *sock, struct msghdr *m, size_t len), \
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 94958c109761..812a5f3c2abe 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -557,7 +557,7 @@ struct netdev_queue {
557 * Callback uses when the transmitter has not made any progress 557 * Callback uses when the transmitter has not made any progress
558 * for dev->watchdog ticks. 558 * for dev->watchdog ticks.
559 * 559 *
560 * struct net_device_stats* (*get_stats)(struct net_device *dev); 560 * struct net_device_stats* (*ndo_get_stats)(struct net_device *dev);
561 * Called when a user wants to get the network device usage 561 * Called when a user wants to get the network device usage
562 * statistics. If not defined, the counters in dev->stats will 562 * statistics. If not defined, the counters in dev->stats will
563 * be used. 563 * be used.
diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index 48cfe51bfddc..6132b5e6d9d3 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -221,12 +221,12 @@ __ret;})
221 221
222/* Call setsockopt() */ 222/* Call setsockopt() */
223int nf_setsockopt(struct sock *sk, u_int8_t pf, int optval, char __user *opt, 223int nf_setsockopt(struct sock *sk, u_int8_t pf, int optval, char __user *opt,
224 int len); 224 unsigned int len);
225int nf_getsockopt(struct sock *sk, u_int8_t pf, int optval, char __user *opt, 225int nf_getsockopt(struct sock *sk, u_int8_t pf, int optval, char __user *opt,
226 int *len); 226 int *len);
227 227
228int compat_nf_setsockopt(struct sock *sk, u_int8_t pf, int optval, 228int compat_nf_setsockopt(struct sock *sk, u_int8_t pf, int optval,
229 char __user *opt, int len); 229 char __user *opt, unsigned int len);
230int compat_nf_getsockopt(struct sock *sk, u_int8_t pf, int optval, 230int compat_nf_getsockopt(struct sock *sk, u_int8_t pf, int optval,
231 char __user *opt, int *len); 231 char __user *opt, int *len);
232 232
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index da1fda8623e0..f490e7a7307a 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -776,6 +776,7 @@
776#define PCI_DEVICE_ID_TI_X515 0x8036 776#define PCI_DEVICE_ID_TI_X515 0x8036
777#define PCI_DEVICE_ID_TI_XX12 0x8039 777#define PCI_DEVICE_ID_TI_XX12 0x8039
778#define PCI_DEVICE_ID_TI_XX12_FM 0x803b 778#define PCI_DEVICE_ID_TI_XX12_FM 0x803b
779#define PCI_DEVICE_ID_TI_XIO2000A 0x8231
779#define PCI_DEVICE_ID_TI_1130 0xac12 780#define PCI_DEVICE_ID_TI_1130 0xac12
780#define PCI_DEVICE_ID_TI_1031 0xac13 781#define PCI_DEVICE_ID_TI_1031 0xac13
781#define PCI_DEVICE_ID_TI_1131 0xac15 782#define PCI_DEVICE_ID_TI_1131 0xac15
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 3a9d36d1e92a..2e6d95f97419 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -442,6 +442,7 @@ enum perf_callchain_context {
442#include <linux/hrtimer.h> 442#include <linux/hrtimer.h>
443#include <linux/fs.h> 443#include <linux/fs.h>
444#include <linux/pid_namespace.h> 444#include <linux/pid_namespace.h>
445#include <linux/workqueue.h>
445#include <asm/atomic.h> 446#include <asm/atomic.h>
446 447
447#define PERF_MAX_STACK_DEPTH 255 448#define PERF_MAX_STACK_DEPTH 255
@@ -513,6 +514,10 @@ struct file;
513 514
514struct perf_mmap_data { 515struct perf_mmap_data {
515 struct rcu_head rcu_head; 516 struct rcu_head rcu_head;
517#ifdef CONFIG_PERF_USE_VMALLOC
518 struct work_struct work;
519#endif
520 int data_order;
516 int nr_pages; /* nr of data pages */ 521 int nr_pages; /* nr of data pages */
517 int writable; /* are we writable */ 522 int writable; /* are we writable */
518 int nr_locked; /* nr pages mlocked */ 523 int nr_locked; /* nr pages mlocked */
diff --git a/include/linux/poll.h b/include/linux/poll.h
index fa287f25138d..6673743946f7 100644
--- a/include/linux/poll.h
+++ b/include/linux/poll.h
@@ -6,10 +6,10 @@
6#ifdef __KERNEL__ 6#ifdef __KERNEL__
7 7
8#include <linux/compiler.h> 8#include <linux/compiler.h>
9#include <linux/ktime.h>
9#include <linux/wait.h> 10#include <linux/wait.h>
10#include <linux/string.h> 11#include <linux/string.h>
11#include <linux/fs.h> 12#include <linux/fs.h>
12#include <linux/sched.h>
13#include <asm/uaccess.h> 13#include <asm/uaccess.h>
14 14
15/* ~832 bytes of stack space used max in sys_select/sys_poll before allocating 15/* ~832 bytes of stack space used max in sys_select/sys_poll before allocating
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index 6fe0363724e9..3ebd0b7bcb08 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -77,7 +77,7 @@ extern int rcu_scheduler_active;
77#error "Unknown RCU implementation specified to kernel configuration" 77#error "Unknown RCU implementation specified to kernel configuration"
78#endif 78#endif
79 79
80#define RCU_HEAD_INIT { .next = NULL, .func = NULL } 80#define RCU_HEAD_INIT { .next = NULL, .func = NULL }
81#define RCU_HEAD(head) struct rcu_head head = RCU_HEAD_INIT 81#define RCU_HEAD(head) struct rcu_head head = RCU_HEAD_INIT
82#define INIT_RCU_HEAD(ptr) do { \ 82#define INIT_RCU_HEAD(ptr) do { \
83 (ptr)->next = NULL; (ptr)->func = NULL; \ 83 (ptr)->next = NULL; (ptr)->func = NULL; \
@@ -129,12 +129,6 @@ static inline void rcu_read_lock(void)
129 rcu_read_acquire(); 129 rcu_read_acquire();
130} 130}
131 131
132/**
133 * rcu_read_unlock - marks the end of an RCU read-side critical section.
134 *
135 * See rcu_read_lock() for more information.
136 */
137
138/* 132/*
139 * So where is rcu_write_lock()? It does not exist, as there is no 133 * So where is rcu_write_lock()? It does not exist, as there is no
140 * way for writers to lock out RCU readers. This is a feature, not 134 * way for writers to lock out RCU readers. This is a feature, not
@@ -144,6 +138,12 @@ static inline void rcu_read_lock(void)
144 * used as well. RCU does not care how the writers keep out of each 138 * used as well. RCU does not care how the writers keep out of each
145 * others' way, as long as they do so. 139 * others' way, as long as they do so.
146 */ 140 */
141
142/**
143 * rcu_read_unlock - marks the end of an RCU read-side critical section.
144 *
145 * See rcu_read_lock() for more information.
146 */
147static inline void rcu_read_unlock(void) 147static inline void rcu_read_unlock(void)
148{ 148{
149 rcu_read_release(); 149 rcu_read_release();
@@ -196,6 +196,8 @@ static inline void rcu_read_lock_sched(void)
196 __acquire(RCU_SCHED); 196 __acquire(RCU_SCHED);
197 rcu_read_acquire(); 197 rcu_read_acquire();
198} 198}
199
200/* Used by lockdep and tracing: cannot be traced, cannot call lockdep. */
199static inline notrace void rcu_read_lock_sched_notrace(void) 201static inline notrace void rcu_read_lock_sched_notrace(void)
200{ 202{
201 preempt_disable_notrace(); 203 preempt_disable_notrace();
@@ -213,6 +215,8 @@ static inline void rcu_read_unlock_sched(void)
213 __release(RCU_SCHED); 215 __release(RCU_SCHED);
214 preempt_enable(); 216 preempt_enable();
215} 217}
218
219/* Used by lockdep and tracing: cannot be traced, cannot call lockdep. */
216static inline notrace void rcu_read_unlock_sched_notrace(void) 220static inline notrace void rcu_read_unlock_sched_notrace(void)
217{ 221{
218 __release(RCU_SCHED); 222 __release(RCU_SCHED);
diff --git a/include/linux/rcutree.h b/include/linux/rcutree.h
index 37682770e9d2..46e9ab3ee6e1 100644
--- a/include/linux/rcutree.h
+++ b/include/linux/rcutree.h
@@ -30,10 +30,14 @@
30#ifndef __LINUX_RCUTREE_H 30#ifndef __LINUX_RCUTREE_H
31#define __LINUX_RCUTREE_H 31#define __LINUX_RCUTREE_H
32 32
33struct notifier_block;
34
33extern void rcu_sched_qs(int cpu); 35extern void rcu_sched_qs(int cpu);
34extern void rcu_bh_qs(int cpu); 36extern void rcu_bh_qs(int cpu);
35 37extern int rcu_cpu_notify(struct notifier_block *self,
38 unsigned long action, void *hcpu);
36extern int rcu_needs_cpu(int cpu); 39extern int rcu_needs_cpu(int cpu);
40extern int rcu_expedited_torture_stats(char *page);
37 41
38#ifdef CONFIG_TREE_PREEMPT_RCU 42#ifdef CONFIG_TREE_PREEMPT_RCU
39 43
@@ -85,16 +89,11 @@ static inline void synchronize_rcu_bh_expedited(void)
85 89
86extern void __rcu_init(void); 90extern void __rcu_init(void);
87extern void rcu_check_callbacks(int cpu, int user); 91extern void rcu_check_callbacks(int cpu, int user);
88extern void rcu_restart_cpu(int cpu);
89 92
90extern long rcu_batches_completed(void); 93extern long rcu_batches_completed(void);
91extern long rcu_batches_completed_bh(void); 94extern long rcu_batches_completed_bh(void);
92extern long rcu_batches_completed_sched(void); 95extern long rcu_batches_completed_sched(void);
93 96
94static inline void rcu_init_sched(void)
95{
96}
97
98#ifdef CONFIG_NO_HZ 97#ifdef CONFIG_NO_HZ
99void rcu_enter_nohz(void); 98void rcu_enter_nohz(void);
100void rcu_exit_nohz(void); 99void rcu_exit_nohz(void);
@@ -107,7 +106,7 @@ static inline void rcu_exit_nohz(void)
107} 106}
108#endif /* CONFIG_NO_HZ */ 107#endif /* CONFIG_NO_HZ */
109 108
110/* A context switch is a grace period for rcutree. */ 109/* A context switch is a grace period for RCU-sched and RCU-bh. */
111static inline int rcu_blocking_is_gp(void) 110static inline int rcu_blocking_is_gp(void)
112{ 111{
113 return num_online_cpus() == 1; 112 return num_online_cpus() == 1;
diff --git a/include/linux/res_counter.h b/include/linux/res_counter.h
index 731af71cddc9..fcb9884df618 100644
--- a/include/linux/res_counter.h
+++ b/include/linux/res_counter.h
@@ -114,8 +114,7 @@ void res_counter_init(struct res_counter *counter, struct res_counter *parent);
114int __must_check res_counter_charge_locked(struct res_counter *counter, 114int __must_check res_counter_charge_locked(struct res_counter *counter,
115 unsigned long val); 115 unsigned long val);
116int __must_check res_counter_charge(struct res_counter *counter, 116int __must_check res_counter_charge(struct res_counter *counter,
117 unsigned long val, struct res_counter **limit_fail_at, 117 unsigned long val, struct res_counter **limit_fail_at);
118 struct res_counter **soft_limit_at);
119 118
120/* 119/*
121 * uncharge - tell that some portion of the resource is released 120 * uncharge - tell that some portion of the resource is released
@@ -128,8 +127,7 @@ int __must_check res_counter_charge(struct res_counter *counter,
128 */ 127 */
129 128
130void res_counter_uncharge_locked(struct res_counter *counter, unsigned long val); 129void res_counter_uncharge_locked(struct res_counter *counter, unsigned long val);
131void res_counter_uncharge(struct res_counter *counter, unsigned long val, 130void res_counter_uncharge(struct res_counter *counter, unsigned long val);
132 bool *was_soft_limit_excess);
133 131
134static inline bool res_counter_limit_check_locked(struct res_counter *cnt) 132static inline bool res_counter_limit_check_locked(struct res_counter *cnt)
135{ 133{
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index fe661afe0713..db532ce288be 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -176,6 +176,9 @@
176/* Qualcomm MSM SoCs */ 176/* Qualcomm MSM SoCs */
177#define PORT_MSM 88 177#define PORT_MSM 88
178 178
179/* BCM63xx family SoCs */
180#define PORT_BCM63XX 89
181
179#ifdef __KERNEL__ 182#ifdef __KERNEL__
180 183
181#include <linux/compiler.h> 184#include <linux/compiler.h>
diff --git a/include/linux/socket.h b/include/linux/socket.h
index 3b461dffe244..3273a0c5043b 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -16,7 +16,7 @@ struct __kernel_sockaddr_storage {
16 /* _SS_MAXSIZE value minus size of ss_family */ 16 /* _SS_MAXSIZE value minus size of ss_family */
17} __attribute__ ((aligned(_K_SS_ALIGNSIZE))); /* force desired alignment */ 17} __attribute__ ((aligned(_K_SS_ALIGNSIZE))); /* force desired alignment */
18 18
19#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) 19#ifdef __KERNEL__
20 20
21#include <asm/socket.h> /* arch-dependent defines */ 21#include <asm/socket.h> /* arch-dependent defines */
22#include <linux/sockios.h> /* the SIOCxxx I/O controls */ 22#include <linux/sockios.h> /* the SIOCxxx I/O controls */
@@ -101,21 +101,6 @@ struct cmsghdr {
101 ((char *)(cmsg) - (char *)(mhdr)->msg_control))) 101 ((char *)(cmsg) - (char *)(mhdr)->msg_control)))
102 102
103/* 103/*
104 * This mess will go away with glibc
105 */
106
107#ifdef __KERNEL__
108#define __KINLINE static inline
109#elif defined(__GNUC__)
110#define __KINLINE static __inline__
111#elif defined(__cplusplus)
112#define __KINLINE static inline
113#else
114#define __KINLINE static
115#endif
116
117
118/*
119 * Get the next cmsg header 104 * Get the next cmsg header
120 * 105 *
121 * PLEASE, do not touch this function. If you think, that it is 106 * PLEASE, do not touch this function. If you think, that it is
@@ -128,7 +113,7 @@ struct cmsghdr {
128 * ancillary object DATA. --ANK (980731) 113 * ancillary object DATA. --ANK (980731)
129 */ 114 */
130 115
131__KINLINE struct cmsghdr * __cmsg_nxthdr(void *__ctl, __kernel_size_t __size, 116static inline struct cmsghdr * __cmsg_nxthdr(void *__ctl, __kernel_size_t __size,
132 struct cmsghdr *__cmsg) 117 struct cmsghdr *__cmsg)
133{ 118{
134 struct cmsghdr * __ptr; 119 struct cmsghdr * __ptr;
@@ -140,7 +125,7 @@ __KINLINE struct cmsghdr * __cmsg_nxthdr(void *__ctl, __kernel_size_t __size,
140 return __ptr; 125 return __ptr;
141} 126}
142 127
143__KINLINE struct cmsghdr * cmsg_nxthdr (struct msghdr *__msg, struct cmsghdr *__cmsg) 128static inline struct cmsghdr * cmsg_nxthdr (struct msghdr *__msg, struct cmsghdr *__cmsg)
144{ 129{
145 return __cmsg_nxthdr(__msg->msg_control, __msg->msg_controllen, __cmsg); 130 return __cmsg_nxthdr(__msg->msg_control, __msg->msg_controllen, __cmsg);
146} 131}
diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h
index c17eb64d7213..ce911ebf91e8 100644
--- a/include/linux/usb/serial.h
+++ b/include/linux/usb/serial.h
@@ -150,6 +150,7 @@ struct usb_serial {
150 struct usb_interface *interface; 150 struct usb_interface *interface;
151 unsigned char disconnected:1; 151 unsigned char disconnected:1;
152 unsigned char suspending:1; 152 unsigned char suspending:1;
153 unsigned char attached:1;
153 unsigned char minor; 154 unsigned char minor;
154 unsigned char num_ports; 155 unsigned char num_ports;
155 unsigned char num_port_pointers; 156 unsigned char num_port_pointers;
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h
index 7ef0c7b94f31..cf24c20de9e4 100644
--- a/include/linux/workqueue.h
+++ b/include/linux/workqueue.h
@@ -207,6 +207,7 @@ extern int queue_delayed_work_on(int cpu, struct workqueue_struct *wq,
207 207
208extern void flush_workqueue(struct workqueue_struct *wq); 208extern void flush_workqueue(struct workqueue_struct *wq);
209extern void flush_scheduled_work(void); 209extern void flush_scheduled_work(void);
210extern void flush_delayed_work(struct delayed_work *work);
210 211
211extern int schedule_work(struct work_struct *work); 212extern int schedule_work(struct work_struct *work);
212extern int schedule_work_on(int cpu, struct work_struct *work); 213extern int schedule_work_on(int cpu, struct work_struct *work);
diff --git a/include/net/compat.h b/include/net/compat.h
index 5bbf8bf9efea..7c3002832d05 100644
--- a/include/net/compat.h
+++ b/include/net/compat.h
@@ -40,8 +40,8 @@ extern int put_cmsg_compat(struct msghdr*, int, int, int, void *);
40 40
41extern int cmsghdr_from_user_compat_to_kern(struct msghdr *, struct sock *, unsigned char *, int); 41extern int cmsghdr_from_user_compat_to_kern(struct msghdr *, struct sock *, unsigned char *, int);
42 42
43extern int compat_mc_setsockopt(struct sock *, int, int, char __user *, int, 43extern int compat_mc_setsockopt(struct sock *, int, int, char __user *, unsigned int,
44 int (*)(struct sock *, int, int, char __user *, int)); 44 int (*)(struct sock *, int, int, char __user *, unsigned int));
45extern int compat_mc_getsockopt(struct sock *, int, int, char __user *, 45extern int compat_mc_getsockopt(struct sock *, int, int, char __user *,
46 int __user *, int (*)(struct sock *, int, int, char __user *, 46 int __user *, int (*)(struct sock *, int, int, char __user *,
47 int __user *)); 47 int __user *));
diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h
index 03cffd9f64e3..696d6e4ce68a 100644
--- a/include/net/inet_connection_sock.h
+++ b/include/net/inet_connection_sock.h
@@ -48,13 +48,13 @@ struct inet_connection_sock_af_ops {
48 u16 net_header_len; 48 u16 net_header_len;
49 u16 sockaddr_len; 49 u16 sockaddr_len;
50 int (*setsockopt)(struct sock *sk, int level, int optname, 50 int (*setsockopt)(struct sock *sk, int level, int optname,
51 char __user *optval, int optlen); 51 char __user *optval, unsigned int optlen);
52 int (*getsockopt)(struct sock *sk, int level, int optname, 52 int (*getsockopt)(struct sock *sk, int level, int optname,
53 char __user *optval, int __user *optlen); 53 char __user *optval, int __user *optlen);
54#ifdef CONFIG_COMPAT 54#ifdef CONFIG_COMPAT
55 int (*compat_setsockopt)(struct sock *sk, 55 int (*compat_setsockopt)(struct sock *sk,
56 int level, int optname, 56 int level, int optname,
57 char __user *optval, int optlen); 57 char __user *optval, unsigned int optlen);
58 int (*compat_getsockopt)(struct sock *sk, 58 int (*compat_getsockopt)(struct sock *sk,
59 int level, int optname, 59 int level, int optname,
60 char __user *optval, int __user *optlen); 60 char __user *optval, int __user *optlen);
@@ -332,5 +332,5 @@ extern void inet_csk_addr2sockaddr(struct sock *sk, struct sockaddr *uaddr);
332extern int inet_csk_compat_getsockopt(struct sock *sk, int level, int optname, 332extern int inet_csk_compat_getsockopt(struct sock *sk, int level, int optname,
333 char __user *optval, int __user *optlen); 333 char __user *optval, int __user *optlen);
334extern int inet_csk_compat_setsockopt(struct sock *sk, int level, int optname, 334extern int inet_csk_compat_setsockopt(struct sock *sk, int level, int optname,
335 char __user *optval, int optlen); 335 char __user *optval, unsigned int optlen);
336#endif /* _INET_CONNECTION_SOCK_H */ 336#endif /* _INET_CONNECTION_SOCK_H */
diff --git a/include/net/ip.h b/include/net/ip.h
index 5b26a0bd178e..2f47e5482b55 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -381,10 +381,10 @@ extern int ip_options_rcv_srr(struct sk_buff *skb);
381extern void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb); 381extern void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb);
382extern int ip_cmsg_send(struct net *net, 382extern int ip_cmsg_send(struct net *net,
383 struct msghdr *msg, struct ipcm_cookie *ipc); 383 struct msghdr *msg, struct ipcm_cookie *ipc);
384extern int ip_setsockopt(struct sock *sk, int level, int optname, char __user *optval, int optlen); 384extern int ip_setsockopt(struct sock *sk, int level, int optname, char __user *optval, unsigned int optlen);
385extern int ip_getsockopt(struct sock *sk, int level, int optname, char __user *optval, int __user *optlen); 385extern int ip_getsockopt(struct sock *sk, int level, int optname, char __user *optval, int __user *optlen);
386extern int compat_ip_setsockopt(struct sock *sk, int level, 386extern int compat_ip_setsockopt(struct sock *sk, int level,
387 int optname, char __user *optval, int optlen); 387 int optname, char __user *optval, unsigned int optlen);
388extern int compat_ip_getsockopt(struct sock *sk, int level, 388extern int compat_ip_getsockopt(struct sock *sk, int level,
389 int optname, char __user *optval, int __user *optlen); 389 int optname, char __user *optval, int __user *optlen);
390extern int ip_ra_control(struct sock *sk, unsigned char on, void (*destructor)(struct sock *)); 390extern int ip_ra_control(struct sock *sk, unsigned char on, void (*destructor)(struct sock *));
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index ad9a51130254..8c31d8a0c1fe 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -550,7 +550,7 @@ extern int ipv6_find_tlv(struct sk_buff *skb, int offset, int type);
550extern int ipv6_setsockopt(struct sock *sk, int level, 550extern int ipv6_setsockopt(struct sock *sk, int level,
551 int optname, 551 int optname,
552 char __user *optval, 552 char __user *optval,
553 int optlen); 553 unsigned int optlen);
554extern int ipv6_getsockopt(struct sock *sk, int level, 554extern int ipv6_getsockopt(struct sock *sk, int level,
555 int optname, 555 int optname,
556 char __user *optval, 556 char __user *optval,
@@ -559,7 +559,7 @@ extern int compat_ipv6_setsockopt(struct sock *sk,
559 int level, 559 int level,
560 int optname, 560 int optname,
561 char __user *optval, 561 char __user *optval,
562 int optlen); 562 unsigned int optlen);
563extern int compat_ipv6_getsockopt(struct sock *sk, 563extern int compat_ipv6_getsockopt(struct sock *sk,
564 int level, 564 int level,
565 int optname, 565 int optname,
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 466859b285e1..c75b960c8ac8 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -1669,6 +1669,8 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw);
1669 * to this function and ieee80211_rx_irqsafe() may not be mixed for a 1669 * to this function and ieee80211_rx_irqsafe() may not be mixed for a
1670 * single hardware. 1670 * single hardware.
1671 * 1671 *
1672 * Note that right now, this function must be called with softirqs disabled.
1673 *
1672 * @hw: the hardware this frame came in on 1674 * @hw: the hardware this frame came in on
1673 * @skb: the buffer to receive, owned by mac80211 after this call 1675 * @skb: the buffer to receive, owned by mac80211 after this call
1674 */ 1676 */
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 42d00ced5eb8..6e5f0e0c7967 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -544,7 +544,7 @@ struct sctp_af {
544 int level, 544 int level,
545 int optname, 545 int optname,
546 char __user *optval, 546 char __user *optval,
547 int optlen); 547 unsigned int optlen);
548 int (*getsockopt) (struct sock *sk, 548 int (*getsockopt) (struct sock *sk,
549 int level, 549 int level,
550 int optname, 550 int optname,
@@ -554,7 +554,7 @@ struct sctp_af {
554 int level, 554 int level,
555 int optname, 555 int optname,
556 char __user *optval, 556 char __user *optval,
557 int optlen); 557 unsigned int optlen);
558 int (*compat_getsockopt) (struct sock *sk, 558 int (*compat_getsockopt) (struct sock *sk,
559 int level, 559 int level,
560 int optname, 560 int optname,
diff --git a/include/net/sock.h b/include/net/sock.h
index 950409dcec3d..9f96394f694e 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -226,12 +226,12 @@ struct sock {
226#define sk_prot __sk_common.skc_prot 226#define sk_prot __sk_common.skc_prot
227#define sk_net __sk_common.skc_net 227#define sk_net __sk_common.skc_net
228 kmemcheck_bitfield_begin(flags); 228 kmemcheck_bitfield_begin(flags);
229 unsigned char sk_shutdown : 2, 229 unsigned int sk_shutdown : 2,
230 sk_no_check : 2, 230 sk_no_check : 2,
231 sk_userlocks : 4; 231 sk_userlocks : 4,
232 sk_protocol : 8,
233 sk_type : 16;
232 kmemcheck_bitfield_end(flags); 234 kmemcheck_bitfield_end(flags);
233 unsigned char sk_protocol;
234 unsigned short sk_type;
235 int sk_rcvbuf; 235 int sk_rcvbuf;
236 socket_lock_t sk_lock; 236 socket_lock_t sk_lock;
237 /* 237 /*
@@ -624,7 +624,7 @@ struct proto {
624 void (*shutdown)(struct sock *sk, int how); 624 void (*shutdown)(struct sock *sk, int how);
625 int (*setsockopt)(struct sock *sk, int level, 625 int (*setsockopt)(struct sock *sk, int level,
626 int optname, char __user *optval, 626 int optname, char __user *optval,
627 int optlen); 627 unsigned int optlen);
628 int (*getsockopt)(struct sock *sk, int level, 628 int (*getsockopt)(struct sock *sk, int level,
629 int optname, char __user *optval, 629 int optname, char __user *optval,
630 int __user *option); 630 int __user *option);
@@ -632,7 +632,7 @@ struct proto {
632 int (*compat_setsockopt)(struct sock *sk, 632 int (*compat_setsockopt)(struct sock *sk,
633 int level, 633 int level,
634 int optname, char __user *optval, 634 int optname, char __user *optval,
635 int optlen); 635 unsigned int optlen);
636 int (*compat_getsockopt)(struct sock *sk, 636 int (*compat_getsockopt)(struct sock *sk,
637 int level, 637 int level,
638 int optname, char __user *optval, 638 int optname, char __user *optval,
@@ -951,7 +951,7 @@ extern void sock_rfree(struct sk_buff *skb);
951 951
952extern int sock_setsockopt(struct socket *sock, int level, 952extern int sock_setsockopt(struct socket *sock, int level,
953 int op, char __user *optval, 953 int op, char __user *optval,
954 int optlen); 954 unsigned int optlen);
955 955
956extern int sock_getsockopt(struct socket *sock, int level, 956extern int sock_getsockopt(struct socket *sock, int level,
957 int op, char __user *optval, 957 int op, char __user *optval,
@@ -993,7 +993,7 @@ extern int sock_no_shutdown(struct socket *, int);
993extern int sock_no_getsockopt(struct socket *, int , int, 993extern int sock_no_getsockopt(struct socket *, int , int,
994 char __user *, int __user *); 994 char __user *, int __user *);
995extern int sock_no_setsockopt(struct socket *, int, int, 995extern int sock_no_setsockopt(struct socket *, int, int,
996 char __user *, int); 996 char __user *, unsigned int);
997extern int sock_no_sendmsg(struct kiocb *, struct socket *, 997extern int sock_no_sendmsg(struct kiocb *, struct socket *,
998 struct msghdr *, size_t); 998 struct msghdr *, size_t);
999extern int sock_no_recvmsg(struct kiocb *, struct socket *, 999extern int sock_no_recvmsg(struct kiocb *, struct socket *,
@@ -1015,11 +1015,11 @@ extern int sock_common_getsockopt(struct socket *sock, int level, int optname,
1015extern int sock_common_recvmsg(struct kiocb *iocb, struct socket *sock, 1015extern int sock_common_recvmsg(struct kiocb *iocb, struct socket *sock,
1016 struct msghdr *msg, size_t size, int flags); 1016 struct msghdr *msg, size_t size, int flags);
1017extern int sock_common_setsockopt(struct socket *sock, int level, int optname, 1017extern int sock_common_setsockopt(struct socket *sock, int level, int optname,
1018 char __user *optval, int optlen); 1018 char __user *optval, unsigned int optlen);
1019extern int compat_sock_common_getsockopt(struct socket *sock, int level, 1019extern int compat_sock_common_getsockopt(struct socket *sock, int level,
1020 int optname, char __user *optval, int __user *optlen); 1020 int optname, char __user *optval, int __user *optlen);
1021extern int compat_sock_common_setsockopt(struct socket *sock, int level, 1021extern int compat_sock_common_setsockopt(struct socket *sock, int level,
1022 int optname, char __user *optval, int optlen); 1022 int optname, char __user *optval, unsigned int optlen);
1023 1023
1024extern void sk_common_release(struct sock *sk); 1024extern void sk_common_release(struct sock *sk);
1025 1025
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 56b76027b85e..03a49c703377 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -394,13 +394,13 @@ extern int tcp_getsockopt(struct sock *sk, int level,
394 int __user *optlen); 394 int __user *optlen);
395extern int tcp_setsockopt(struct sock *sk, int level, 395extern int tcp_setsockopt(struct sock *sk, int level,
396 int optname, char __user *optval, 396 int optname, char __user *optval,
397 int optlen); 397 unsigned int optlen);
398extern int compat_tcp_getsockopt(struct sock *sk, 398extern int compat_tcp_getsockopt(struct sock *sk,
399 int level, int optname, 399 int level, int optname,
400 char __user *optval, int __user *optlen); 400 char __user *optval, int __user *optlen);
401extern int compat_tcp_setsockopt(struct sock *sk, 401extern int compat_tcp_setsockopt(struct sock *sk,
402 int level, int optname, 402 int level, int optname,
403 char __user *optval, int optlen); 403 char __user *optval, unsigned int optlen);
404extern void tcp_set_keepalive(struct sock *sk, int val); 404extern void tcp_set_keepalive(struct sock *sk, int val);
405extern int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, 405extern int tcp_recvmsg(struct kiocb *iocb, struct sock *sk,
406 struct msghdr *msg, 406 struct msghdr *msg,
diff --git a/include/net/udp.h b/include/net/udp.h
index 5fb029f817a3..f98abd2ce709 100644
--- a/include/net/udp.h
+++ b/include/net/udp.h
@@ -144,7 +144,7 @@ extern unsigned int udp_poll(struct file *file, struct socket *sock,
144extern int udp_lib_getsockopt(struct sock *sk, int level, int optname, 144extern int udp_lib_getsockopt(struct sock *sk, int level, int optname,
145 char __user *optval, int __user *optlen); 145 char __user *optval, int __user *optlen);
146extern int udp_lib_setsockopt(struct sock *sk, int level, int optname, 146extern int udp_lib_setsockopt(struct sock *sk, int level, int optname,
147 char __user *optval, int optlen, 147 char __user *optval, unsigned int optlen,
148 int (*push_pending_frames)(struct sock *)); 148 int (*push_pending_frames)(struct sock *));
149 149
150extern struct sock *udp4_lib_lookup(struct net *net, __be32 saddr, __be16 sport, 150extern struct sock *udp4_lib_lookup(struct net *net, __be32 saddr, __be16 sport,
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
index 887e57e3e223..a72edd4eceec 100644
--- a/include/scsi/libiscsi.h
+++ b/include/scsi/libiscsi.h
@@ -303,6 +303,7 @@ struct iscsi_session {
303 int cmds_max; /* size of cmds array */ 303 int cmds_max; /* size of cmds array */
304 struct iscsi_task **cmds; /* Original Cmds arr */ 304 struct iscsi_task **cmds; /* Original Cmds arr */
305 struct iscsi_pool cmdpool; /* PDU's pool */ 305 struct iscsi_pool cmdpool; /* PDU's pool */
306 void *dd_data; /* LLD private data */
306}; 307};
307 308
308enum { 309enum {
@@ -363,7 +364,7 @@ extern int iscsi_target_alloc(struct scsi_target *starget);
363 */ 364 */
364extern struct iscsi_cls_session * 365extern struct iscsi_cls_session *
365iscsi_session_setup(struct iscsi_transport *, struct Scsi_Host *shost, 366iscsi_session_setup(struct iscsi_transport *, struct Scsi_Host *shost,
366 uint16_t, int, uint32_t, unsigned int); 367 uint16_t, int, int, uint32_t, unsigned int);
367extern void iscsi_session_teardown(struct iscsi_cls_session *); 368extern void iscsi_session_teardown(struct iscsi_cls_session *);
368extern void iscsi_session_recovery_timedout(struct iscsi_cls_session *); 369extern void iscsi_session_recovery_timedout(struct iscsi_cls_session *);
369extern int iscsi_set_param(struct iscsi_cls_conn *cls_conn, 370extern int iscsi_set_param(struct iscsi_cls_conn *cls_conn,
diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h
index 084478e14d24..34c46ab5c31b 100644
--- a/include/scsi/scsi.h
+++ b/include/scsi/scsi.h
@@ -129,6 +129,9 @@ struct scsi_cmnd;
129#define MI_REPORT_TARGET_PGS 0x0a 129#define MI_REPORT_TARGET_PGS 0x0a
130/* values for maintenance out */ 130/* values for maintenance out */
131#define MO_SET_TARGET_PGS 0x0a 131#define MO_SET_TARGET_PGS 0x0a
132/* values for variable length command */
133#define READ_32 0x09
134#define WRITE_32 0x0b
132 135
133/* Values for T10/04-262r7 */ 136/* Values for T10/04-262r7 */
134#define ATA_16 0x85 /* 16-byte pass-thru */ 137#define ATA_16 0x85 /* 16-byte pass-thru */
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
index 3878d1dc7f59..a5e885a111df 100644
--- a/include/scsi/scsi_cmnd.h
+++ b/include/scsi/scsi_cmnd.h
@@ -229,10 +229,6 @@ enum scsi_prot_operations {
229 /* OS-HBA: Protected, HBA-Target: Protected */ 229 /* OS-HBA: Protected, HBA-Target: Protected */
230 SCSI_PROT_READ_PASS, 230 SCSI_PROT_READ_PASS,
231 SCSI_PROT_WRITE_PASS, 231 SCSI_PROT_WRITE_PASS,
232
233 /* OS-HBA: Protected, HBA-Target: Protected, checksum conversion */
234 SCSI_PROT_READ_CONVERT,
235 SCSI_PROT_WRITE_CONVERT,
236}; 232};
237 233
238static inline void scsi_set_prot_op(struct scsi_cmnd *scmd, unsigned char op) 234static inline void scsi_set_prot_op(struct scsi_cmnd *scmd, unsigned char op)
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
index b62a097b3ecb..6e728b176904 100644
--- a/include/scsi/scsi_host.h
+++ b/include/scsi/scsi_host.h
@@ -798,9 +798,15 @@ static inline unsigned int scsi_host_get_prot(struct Scsi_Host *shost)
798static inline unsigned int scsi_host_dif_capable(struct Scsi_Host *shost, unsigned int target_type) 798static inline unsigned int scsi_host_dif_capable(struct Scsi_Host *shost, unsigned int target_type)
799{ 799{
800 switch (target_type) { 800 switch (target_type) {
801 case 1: return shost->prot_capabilities & SHOST_DIF_TYPE1_PROTECTION; 801 case 1:
802 case 2: return shost->prot_capabilities & SHOST_DIF_TYPE2_PROTECTION; 802 if (shost->prot_capabilities & SHOST_DIF_TYPE1_PROTECTION)
803 case 3: return shost->prot_capabilities & SHOST_DIF_TYPE3_PROTECTION; 803 return target_type;
804 case 2:
805 if (shost->prot_capabilities & SHOST_DIF_TYPE2_PROTECTION)
806 return target_type;
807 case 3:
808 if (shost->prot_capabilities & SHOST_DIF_TYPE3_PROTECTION)
809 return target_type;
804 } 810 }
805 811
806 return 0; 812 return 0;
@@ -808,13 +814,14 @@ static inline unsigned int scsi_host_dif_capable(struct Scsi_Host *shost, unsign
808 814
809static inline unsigned int scsi_host_dix_capable(struct Scsi_Host *shost, unsigned int target_type) 815static inline unsigned int scsi_host_dix_capable(struct Scsi_Host *shost, unsigned int target_type)
810{ 816{
817#if defined(CONFIG_BLK_DEV_INTEGRITY)
811 switch (target_type) { 818 switch (target_type) {
812 case 0: return shost->prot_capabilities & SHOST_DIX_TYPE0_PROTECTION; 819 case 0: return shost->prot_capabilities & SHOST_DIX_TYPE0_PROTECTION;
813 case 1: return shost->prot_capabilities & SHOST_DIX_TYPE1_PROTECTION; 820 case 1: return shost->prot_capabilities & SHOST_DIX_TYPE1_PROTECTION;
814 case 2: return shost->prot_capabilities & SHOST_DIX_TYPE2_PROTECTION; 821 case 2: return shost->prot_capabilities & SHOST_DIX_TYPE2_PROTECTION;
815 case 3: return shost->prot_capabilities & SHOST_DIX_TYPE3_PROTECTION; 822 case 3: return shost->prot_capabilities & SHOST_DIX_TYPE3_PROTECTION;
816 } 823 }
817 824#endif
818 return 0; 825 return 0;
819} 826}
820 827
diff --git a/include/trace/events/block.h b/include/trace/events/block.h
index d86af94691c2..00405b5f624a 100644
--- a/include/trace/events/block.h
+++ b/include/trace/events/block.h
@@ -488,6 +488,39 @@ TRACE_EVENT(block_remap,
488 (unsigned long long)__entry->old_sector) 488 (unsigned long long)__entry->old_sector)
489); 489);
490 490
491TRACE_EVENT(block_rq_remap,
492
493 TP_PROTO(struct request_queue *q, struct request *rq, dev_t dev,
494 sector_t from),
495
496 TP_ARGS(q, rq, dev, from),
497
498 TP_STRUCT__entry(
499 __field( dev_t, dev )
500 __field( sector_t, sector )
501 __field( unsigned int, nr_sector )
502 __field( dev_t, old_dev )
503 __field( sector_t, old_sector )
504 __array( char, rwbs, 6 )
505 ),
506
507 TP_fast_assign(
508 __entry->dev = disk_devt(rq->rq_disk);
509 __entry->sector = blk_rq_pos(rq);
510 __entry->nr_sector = blk_rq_sectors(rq);
511 __entry->old_dev = dev;
512 __entry->old_sector = from;
513 blk_fill_rwbs_rq(__entry->rwbs, rq);
514 ),
515
516 TP_printk("%d,%d %s %llu + %u <- (%d,%d) %llu",
517 MAJOR(__entry->dev), MINOR(__entry->dev), __entry->rwbs,
518 (unsigned long long)__entry->sector,
519 __entry->nr_sector,
520 MAJOR(__entry->old_dev), MINOR(__entry->old_dev),
521 (unsigned long long)__entry->old_sector)
522);
523
491#endif /* _TRACE_BLOCK_H */ 524#endif /* _TRACE_BLOCK_H */
492 525
493/* This part must be outside protection */ 526/* This part must be outside protection */
diff --git a/include/trace/events/ext4.h b/include/trace/events/ext4.h
index c1bd8f1e8b94..d09550bf3f95 100644
--- a/include/trace/events/ext4.h
+++ b/include/trace/events/ext4.h
@@ -11,6 +11,7 @@ struct ext4_allocation_context;
11struct ext4_allocation_request; 11struct ext4_allocation_request;
12struct ext4_prealloc_space; 12struct ext4_prealloc_space;
13struct ext4_inode_info; 13struct ext4_inode_info;
14struct mpage_da_data;
14 15
15#define EXT4_I(inode) (container_of(inode, struct ext4_inode_info, vfs_inode)) 16#define EXT4_I(inode) (container_of(inode, struct ext4_inode_info, vfs_inode))
16 17
@@ -236,6 +237,7 @@ TRACE_EVENT(ext4_da_writepages,
236 __field( char, for_kupdate ) 237 __field( char, for_kupdate )
237 __field( char, for_reclaim ) 238 __field( char, for_reclaim )
238 __field( char, range_cyclic ) 239 __field( char, range_cyclic )
240 __field( pgoff_t, writeback_index )
239 ), 241 ),
240 242
241 TP_fast_assign( 243 TP_fast_assign(
@@ -249,15 +251,17 @@ TRACE_EVENT(ext4_da_writepages,
249 __entry->for_kupdate = wbc->for_kupdate; 251 __entry->for_kupdate = wbc->for_kupdate;
250 __entry->for_reclaim = wbc->for_reclaim; 252 __entry->for_reclaim = wbc->for_reclaim;
251 __entry->range_cyclic = wbc->range_cyclic; 253 __entry->range_cyclic = wbc->range_cyclic;
254 __entry->writeback_index = inode->i_mapping->writeback_index;
252 ), 255 ),
253 256
254 TP_printk("dev %s ino %lu nr_to_write %ld pages_skipped %ld range_start %llu range_end %llu nonblocking %d for_kupdate %d for_reclaim %d range_cyclic %d", 257 TP_printk("dev %s ino %lu nr_to_write %ld pages_skipped %ld range_start %llu range_end %llu nonblocking %d for_kupdate %d for_reclaim %d range_cyclic %d writeback_index %lu",
255 jbd2_dev_to_name(__entry->dev), 258 jbd2_dev_to_name(__entry->dev),
256 (unsigned long) __entry->ino, __entry->nr_to_write, 259 (unsigned long) __entry->ino, __entry->nr_to_write,
257 __entry->pages_skipped, __entry->range_start, 260 __entry->pages_skipped, __entry->range_start,
258 __entry->range_end, __entry->nonblocking, 261 __entry->range_end, __entry->nonblocking,
259 __entry->for_kupdate, __entry->for_reclaim, 262 __entry->for_kupdate, __entry->for_reclaim,
260 __entry->range_cyclic) 263 __entry->range_cyclic,
264 (unsigned long) __entry->writeback_index)
261); 265);
262 266
263TRACE_EVENT(ext4_da_write_pages, 267TRACE_EVENT(ext4_da_write_pages,
@@ -309,6 +313,7 @@ TRACE_EVENT(ext4_da_writepages_result,
309 __field( char, encountered_congestion ) 313 __field( char, encountered_congestion )
310 __field( char, more_io ) 314 __field( char, more_io )
311 __field( char, no_nrwrite_index_update ) 315 __field( char, no_nrwrite_index_update )
316 __field( pgoff_t, writeback_index )
312 ), 317 ),
313 318
314 TP_fast_assign( 319 TP_fast_assign(
@@ -320,14 +325,16 @@ TRACE_EVENT(ext4_da_writepages_result,
320 __entry->encountered_congestion = wbc->encountered_congestion; 325 __entry->encountered_congestion = wbc->encountered_congestion;
321 __entry->more_io = wbc->more_io; 326 __entry->more_io = wbc->more_io;
322 __entry->no_nrwrite_index_update = wbc->no_nrwrite_index_update; 327 __entry->no_nrwrite_index_update = wbc->no_nrwrite_index_update;
328 __entry->writeback_index = inode->i_mapping->writeback_index;
323 ), 329 ),
324 330
325 TP_printk("dev %s ino %lu ret %d pages_written %d pages_skipped %ld congestion %d more_io %d no_nrwrite_index_update %d", 331 TP_printk("dev %s ino %lu ret %d pages_written %d pages_skipped %ld congestion %d more_io %d no_nrwrite_index_update %d writeback_index %lu",
326 jbd2_dev_to_name(__entry->dev), 332 jbd2_dev_to_name(__entry->dev),
327 (unsigned long) __entry->ino, __entry->ret, 333 (unsigned long) __entry->ino, __entry->ret,
328 __entry->pages_written, __entry->pages_skipped, 334 __entry->pages_written, __entry->pages_skipped,
329 __entry->encountered_congestion, __entry->more_io, 335 __entry->encountered_congestion, __entry->more_io,
330 __entry->no_nrwrite_index_update) 336 __entry->no_nrwrite_index_update,
337 (unsigned long) __entry->writeback_index)
331); 338);
332 339
333TRACE_EVENT(ext4_da_write_begin, 340TRACE_EVENT(ext4_da_write_begin,
@@ -737,6 +744,169 @@ TRACE_EVENT(ext4_alloc_da_blocks,
737 __entry->data_blocks, __entry->meta_blocks) 744 __entry->data_blocks, __entry->meta_blocks)
738); 745);
739 746
747TRACE_EVENT(ext4_mballoc_alloc,
748 TP_PROTO(struct ext4_allocation_context *ac),
749
750 TP_ARGS(ac),
751
752 TP_STRUCT__entry(
753 __field( dev_t, dev )
754 __field( ino_t, ino )
755 __field( __u16, found )
756 __field( __u16, groups )
757 __field( __u16, buddy )
758 __field( __u16, flags )
759 __field( __u16, tail )
760 __field( __u8, cr )
761 __field( __u32, orig_logical )
762 __field( int, orig_start )
763 __field( __u32, orig_group )
764 __field( int, orig_len )
765 __field( __u32, goal_logical )
766 __field( int, goal_start )
767 __field( __u32, goal_group )
768 __field( int, goal_len )
769 __field( __u32, result_logical )
770 __field( int, result_start )
771 __field( __u32, result_group )
772 __field( int, result_len )
773 ),
774
775 TP_fast_assign(
776 __entry->dev = ac->ac_inode->i_sb->s_dev;
777 __entry->ino = ac->ac_inode->i_ino;
778 __entry->found = ac->ac_found;
779 __entry->flags = ac->ac_flags;
780 __entry->groups = ac->ac_groups_scanned;
781 __entry->buddy = ac->ac_buddy;
782 __entry->tail = ac->ac_tail;
783 __entry->cr = ac->ac_criteria;
784 __entry->orig_logical = ac->ac_o_ex.fe_logical;
785 __entry->orig_start = ac->ac_o_ex.fe_start;
786 __entry->orig_group = ac->ac_o_ex.fe_group;
787 __entry->orig_len = ac->ac_o_ex.fe_len;
788 __entry->goal_logical = ac->ac_g_ex.fe_logical;
789 __entry->goal_start = ac->ac_g_ex.fe_start;
790 __entry->goal_group = ac->ac_g_ex.fe_group;
791 __entry->goal_len = ac->ac_g_ex.fe_len;
792 __entry->result_logical = ac->ac_f_ex.fe_logical;
793 __entry->result_start = ac->ac_f_ex.fe_start;
794 __entry->result_group = ac->ac_f_ex.fe_group;
795 __entry->result_len = ac->ac_f_ex.fe_len;
796 ),
797
798 TP_printk("dev %s inode %lu orig %u/%d/%u@%u goal %u/%d/%u@%u "
799 "result %u/%d/%u@%u blks %u grps %u cr %u flags 0x%04x "
800 "tail %u broken %u",
801 jbd2_dev_to_name(__entry->dev), (unsigned long) __entry->ino,
802 __entry->orig_group, __entry->orig_start,
803 __entry->orig_len, __entry->orig_logical,
804 __entry->goal_group, __entry->goal_start,
805 __entry->goal_len, __entry->goal_logical,
806 __entry->result_group, __entry->result_start,
807 __entry->result_len, __entry->result_logical,
808 __entry->found, __entry->groups, __entry->cr,
809 __entry->flags, __entry->tail,
810 __entry->buddy ? 1 << __entry->buddy : 0)
811);
812
813TRACE_EVENT(ext4_mballoc_prealloc,
814 TP_PROTO(struct ext4_allocation_context *ac),
815
816 TP_ARGS(ac),
817
818 TP_STRUCT__entry(
819 __field( dev_t, dev )
820 __field( ino_t, ino )
821 __field( __u32, orig_logical )
822 __field( int, orig_start )
823 __field( __u32, orig_group )
824 __field( int, orig_len )
825 __field( __u32, result_logical )
826 __field( int, result_start )
827 __field( __u32, result_group )
828 __field( int, result_len )
829 ),
830
831 TP_fast_assign(
832 __entry->dev = ac->ac_inode->i_sb->s_dev;
833 __entry->ino = ac->ac_inode->i_ino;
834 __entry->orig_logical = ac->ac_o_ex.fe_logical;
835 __entry->orig_start = ac->ac_o_ex.fe_start;
836 __entry->orig_group = ac->ac_o_ex.fe_group;
837 __entry->orig_len = ac->ac_o_ex.fe_len;
838 __entry->result_logical = ac->ac_b_ex.fe_logical;
839 __entry->result_start = ac->ac_b_ex.fe_start;
840 __entry->result_group = ac->ac_b_ex.fe_group;
841 __entry->result_len = ac->ac_b_ex.fe_len;
842 ),
843
844 TP_printk("dev %s inode %lu orig %u/%d/%u@%u result %u/%d/%u@%u",
845 jbd2_dev_to_name(__entry->dev), (unsigned long) __entry->ino,
846 __entry->orig_group, __entry->orig_start,
847 __entry->orig_len, __entry->orig_logical,
848 __entry->result_group, __entry->result_start,
849 __entry->result_len, __entry->result_logical)
850);
851
852TRACE_EVENT(ext4_mballoc_discard,
853 TP_PROTO(struct ext4_allocation_context *ac),
854
855 TP_ARGS(ac),
856
857 TP_STRUCT__entry(
858 __field( dev_t, dev )
859 __field( ino_t, ino )
860 __field( __u32, result_logical )
861 __field( int, result_start )
862 __field( __u32, result_group )
863 __field( int, result_len )
864 ),
865
866 TP_fast_assign(
867 __entry->dev = ac->ac_inode->i_sb->s_dev;
868 __entry->ino = ac->ac_inode->i_ino;
869 __entry->result_logical = ac->ac_b_ex.fe_logical;
870 __entry->result_start = ac->ac_b_ex.fe_start;
871 __entry->result_group = ac->ac_b_ex.fe_group;
872 __entry->result_len = ac->ac_b_ex.fe_len;
873 ),
874
875 TP_printk("dev %s inode %lu extent %u/%d/%u@%u ",
876 jbd2_dev_to_name(__entry->dev), (unsigned long) __entry->ino,
877 __entry->result_group, __entry->result_start,
878 __entry->result_len, __entry->result_logical)
879);
880
881TRACE_EVENT(ext4_mballoc_free,
882 TP_PROTO(struct ext4_allocation_context *ac),
883
884 TP_ARGS(ac),
885
886 TP_STRUCT__entry(
887 __field( dev_t, dev )
888 __field( ino_t, ino )
889 __field( __u32, result_logical )
890 __field( int, result_start )
891 __field( __u32, result_group )
892 __field( int, result_len )
893 ),
894
895 TP_fast_assign(
896 __entry->dev = ac->ac_inode->i_sb->s_dev;
897 __entry->ino = ac->ac_inode->i_ino;
898 __entry->result_logical = ac->ac_b_ex.fe_logical;
899 __entry->result_start = ac->ac_b_ex.fe_start;
900 __entry->result_group = ac->ac_b_ex.fe_group;
901 __entry->result_len = ac->ac_b_ex.fe_len;
902 ),
903
904 TP_printk("dev %s inode %lu extent %u/%d/%u@%u ",
905 jbd2_dev_to_name(__entry->dev), (unsigned long) __entry->ino,
906 __entry->result_group, __entry->result_start,
907 __entry->result_len, __entry->result_logical)
908);
909
740#endif /* _TRACE_EXT4_H */ 910#endif /* _TRACE_EXT4_H */
741 911
742/* This part must be outside protection */ 912/* This part must be outside protection */
diff --git a/include/trace/events/jbd2.h b/include/trace/events/jbd2.h
index b851f0b4701c..3c60b75adb9e 100644
--- a/include/trace/events/jbd2.h
+++ b/include/trace/events/jbd2.h
@@ -7,6 +7,9 @@
7#include <linux/jbd2.h> 7#include <linux/jbd2.h>
8#include <linux/tracepoint.h> 8#include <linux/tracepoint.h>
9 9
10struct transaction_chp_stats_s;
11struct transaction_run_stats_s;
12
10TRACE_EVENT(jbd2_checkpoint, 13TRACE_EVENT(jbd2_checkpoint,
11 14
12 TP_PROTO(journal_t *journal, int result), 15 TP_PROTO(journal_t *journal, int result),
@@ -162,6 +165,81 @@ TRACE_EVENT(jbd2_submit_inode_data,
162 jbd2_dev_to_name(__entry->dev), (unsigned long) __entry->ino) 165 jbd2_dev_to_name(__entry->dev), (unsigned long) __entry->ino)
163); 166);
164 167
168TRACE_EVENT(jbd2_run_stats,
169 TP_PROTO(dev_t dev, unsigned long tid,
170 struct transaction_run_stats_s *stats),
171
172 TP_ARGS(dev, tid, stats),
173
174 TP_STRUCT__entry(
175 __field( dev_t, dev )
176 __field( unsigned long, tid )
177 __field( unsigned long, wait )
178 __field( unsigned long, running )
179 __field( unsigned long, locked )
180 __field( unsigned long, flushing )
181 __field( unsigned long, logging )
182 __field( __u32, handle_count )
183 __field( __u32, blocks )
184 __field( __u32, blocks_logged )
185 ),
186
187 TP_fast_assign(
188 __entry->dev = dev;
189 __entry->tid = tid;
190 __entry->wait = stats->rs_wait;
191 __entry->running = stats->rs_running;
192 __entry->locked = stats->rs_locked;
193 __entry->flushing = stats->rs_flushing;
194 __entry->logging = stats->rs_logging;
195 __entry->handle_count = stats->rs_handle_count;
196 __entry->blocks = stats->rs_blocks;
197 __entry->blocks_logged = stats->rs_blocks_logged;
198 ),
199
200 TP_printk("dev %s tid %lu wait %u running %u locked %u flushing %u "
201 "logging %u handle_count %u blocks %u blocks_logged %u",
202 jbd2_dev_to_name(__entry->dev), __entry->tid,
203 jiffies_to_msecs(__entry->wait),
204 jiffies_to_msecs(__entry->running),
205 jiffies_to_msecs(__entry->locked),
206 jiffies_to_msecs(__entry->flushing),
207 jiffies_to_msecs(__entry->logging),
208 __entry->handle_count, __entry->blocks,
209 __entry->blocks_logged)
210);
211
212TRACE_EVENT(jbd2_checkpoint_stats,
213 TP_PROTO(dev_t dev, unsigned long tid,
214 struct transaction_chp_stats_s *stats),
215
216 TP_ARGS(dev, tid, stats),
217
218 TP_STRUCT__entry(
219 __field( dev_t, dev )
220 __field( unsigned long, tid )
221 __field( unsigned long, chp_time )
222 __field( __u32, forced_to_close )
223 __field( __u32, written )
224 __field( __u32, dropped )
225 ),
226
227 TP_fast_assign(
228 __entry->dev = dev;
229 __entry->tid = tid;
230 __entry->chp_time = stats->cs_chp_time;
231 __entry->forced_to_close= stats->cs_forced_to_close;
232 __entry->written = stats->cs_written;
233 __entry->dropped = stats->cs_dropped;
234 ),
235
236 TP_printk("dev %s tid %lu chp_time %u forced_to_close %u "
237 "written %u dropped %u",
238 jbd2_dev_to_name(__entry->dev), __entry->tid,
239 jiffies_to_msecs(__entry->chp_time),
240 __entry->forced_to_close, __entry->written, __entry->dropped)
241);
242
165#endif /* _TRACE_JBD2_H */ 243#endif /* _TRACE_JBD2_H */
166 244
167/* This part must be outside protection */ 245/* This part must be outside protection */
diff --git a/init/Kconfig b/init/Kconfig
index c7bac39d6c61..09c5c6431f42 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -921,6 +921,11 @@ config HAVE_PERF_EVENTS
921 help 921 help
922 See tools/perf/design.txt for details. 922 See tools/perf/design.txt for details.
923 923
924config PERF_USE_VMALLOC
925 bool
926 help
927 See tools/perf/design.txt for details
928
924menu "Kernel Performance Events And Counters" 929menu "Kernel Performance Events And Counters"
925 930
926config PERF_EVENTS 931config PERF_EVENTS
@@ -976,6 +981,19 @@ config PERF_COUNTERS
976 981
977 Say N if unsure. 982 Say N if unsure.
978 983
984config DEBUG_PERF_USE_VMALLOC
985 default n
986 bool "Debug: use vmalloc to back perf mmap() buffers"
987 depends on PERF_EVENTS && DEBUG_KERNEL
988 select PERF_USE_VMALLOC
989 help
990 Use vmalloc memory to back perf mmap() buffers.
991
992 Mostly useful for debugging the vmalloc code on platforms
993 that don't require it.
994
995 Say N if unsure.
996
979endmenu 997endmenu
980 998
981config VM_EVENT_COUNTERS 999config VM_EVENT_COUNTERS
diff --git a/init/main.c b/init/main.c
index 7449819a4805..5988debfc505 100644
--- a/init/main.c
+++ b/init/main.c
@@ -778,7 +778,6 @@ static void __init do_initcalls(void)
778 */ 778 */
779static void __init do_basic_setup(void) 779static void __init do_basic_setup(void)
780{ 780{
781 rcu_init_sched(); /* needed by module_init stage. */
782 init_workqueues(); 781 init_workqueues();
783 cpuset_init_smp(); 782 cpuset_init_smp();
784 usermodehelper_init(); 783 usermodehelper_init();
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 7ccba4bc5e3b..ca83b73fba19 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -703,7 +703,7 @@ static int cgroup_mkdir(struct inode *dir, struct dentry *dentry, int mode);
703static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry); 703static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry);
704static int cgroup_populate_dir(struct cgroup *cgrp); 704static int cgroup_populate_dir(struct cgroup *cgrp);
705static const struct inode_operations cgroup_dir_inode_operations; 705static const struct inode_operations cgroup_dir_inode_operations;
706static struct file_operations proc_cgroupstats_operations; 706static const struct file_operations proc_cgroupstats_operations;
707 707
708static struct backing_dev_info cgroup_backing_dev_info = { 708static struct backing_dev_info cgroup_backing_dev_info = {
709 .name = "cgroup", 709 .name = "cgroup",
@@ -1863,7 +1863,7 @@ static int cgroup_seqfile_release(struct inode *inode, struct file *file)
1863 return single_release(inode, file); 1863 return single_release(inode, file);
1864} 1864}
1865 1865
1866static struct file_operations cgroup_seqfile_operations = { 1866static const struct file_operations cgroup_seqfile_operations = {
1867 .read = seq_read, 1867 .read = seq_read,
1868 .write = cgroup_file_write, 1868 .write = cgroup_file_write,
1869 .llseek = seq_lseek, 1869 .llseek = seq_lseek,
@@ -1922,7 +1922,7 @@ static int cgroup_rename(struct inode *old_dir, struct dentry *old_dentry,
1922 return simple_rename(old_dir, old_dentry, new_dir, new_dentry); 1922 return simple_rename(old_dir, old_dentry, new_dir, new_dentry);
1923} 1923}
1924 1924
1925static struct file_operations cgroup_file_operations = { 1925static const struct file_operations cgroup_file_operations = {
1926 .read = cgroup_file_read, 1926 .read = cgroup_file_read,
1927 .write = cgroup_file_write, 1927 .write = cgroup_file_write,
1928 .llseek = generic_file_llseek, 1928 .llseek = generic_file_llseek,
@@ -3369,7 +3369,7 @@ static int cgroup_open(struct inode *inode, struct file *file)
3369 return single_open(file, proc_cgroup_show, pid); 3369 return single_open(file, proc_cgroup_show, pid);
3370} 3370}
3371 3371
3372struct file_operations proc_cgroup_operations = { 3372const struct file_operations proc_cgroup_operations = {
3373 .open = cgroup_open, 3373 .open = cgroup_open,
3374 .read = seq_read, 3374 .read = seq_read,
3375 .llseek = seq_lseek, 3375 .llseek = seq_lseek,
@@ -3398,7 +3398,7 @@ static int cgroupstats_open(struct inode *inode, struct file *file)
3398 return single_open(file, proc_cgroupstats_show, NULL); 3398 return single_open(file, proc_cgroupstats_show, NULL);
3399} 3399}
3400 3400
3401static struct file_operations proc_cgroupstats_operations = { 3401static const struct file_operations proc_cgroupstats_operations = {
3402 .open = cgroupstats_open, 3402 .open = cgroupstats_open,
3403 .read = seq_read, 3403 .read = seq_read,
3404 .llseek = seq_lseek, 3404 .llseek = seq_lseek,
@@ -3708,8 +3708,10 @@ static void check_for_release(struct cgroup *cgrp)
3708void __css_put(struct cgroup_subsys_state *css) 3708void __css_put(struct cgroup_subsys_state *css)
3709{ 3709{
3710 struct cgroup *cgrp = css->cgroup; 3710 struct cgroup *cgrp = css->cgroup;
3711 int val;
3711 rcu_read_lock(); 3712 rcu_read_lock();
3712 if (atomic_dec_return(&css->refcnt) == 1) { 3713 val = atomic_dec_return(&css->refcnt);
3714 if (val == 1) {
3713 if (notify_on_release(cgrp)) { 3715 if (notify_on_release(cgrp)) {
3714 set_bit(CGRP_RELEASABLE, &cgrp->flags); 3716 set_bit(CGRP_RELEASABLE, &cgrp->flags);
3715 check_for_release(cgrp); 3717 check_for_release(cgrp);
@@ -3717,6 +3719,7 @@ void __css_put(struct cgroup_subsys_state *css)
3717 cgroup_wakeup_rmdir_waiter(cgrp); 3719 cgroup_wakeup_rmdir_waiter(cgrp);
3718 } 3720 }
3719 rcu_read_unlock(); 3721 rcu_read_unlock();
3722 WARN_ON_ONCE(val < 1);
3720} 3723}
3721 3724
3722/* 3725/*
diff --git a/kernel/exit.c b/kernel/exit.c
index 5859f598c951..e61891f80123 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -991,8 +991,6 @@ NORET_TYPE void do_exit(long code)
991 tsk->mempolicy = NULL; 991 tsk->mempolicy = NULL;
992#endif 992#endif
993#ifdef CONFIG_FUTEX 993#ifdef CONFIG_FUTEX
994 if (unlikely(!list_empty(&tsk->pi_state_list)))
995 exit_pi_state_list(tsk);
996 if (unlikely(current->pi_state_cache)) 994 if (unlikely(current->pi_state_cache))
997 kfree(current->pi_state_cache); 995 kfree(current->pi_state_cache);
998#endif 996#endif
diff --git a/kernel/fork.c b/kernel/fork.c
index 266c6af6ef1b..4c20fff8c13a 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -570,12 +570,18 @@ void mm_release(struct task_struct *tsk, struct mm_struct *mm)
570 570
571 /* Get rid of any futexes when releasing the mm */ 571 /* Get rid of any futexes when releasing the mm */
572#ifdef CONFIG_FUTEX 572#ifdef CONFIG_FUTEX
573 if (unlikely(tsk->robust_list)) 573 if (unlikely(tsk->robust_list)) {
574 exit_robust_list(tsk); 574 exit_robust_list(tsk);
575 tsk->robust_list = NULL;
576 }
575#ifdef CONFIG_COMPAT 577#ifdef CONFIG_COMPAT
576 if (unlikely(tsk->compat_robust_list)) 578 if (unlikely(tsk->compat_robust_list)) {
577 compat_exit_robust_list(tsk); 579 compat_exit_robust_list(tsk);
580 tsk->compat_robust_list = NULL;
581 }
578#endif 582#endif
583 if (unlikely(!list_empty(&tsk->pi_state_list)))
584 exit_pi_state_list(tsk);
579#endif 585#endif
580 586
581 /* Get rid of any cached register state */ 587 /* Get rid of any cached register state */
diff --git a/kernel/futex.c b/kernel/futex.c
index b911adceb2c4..4949d336d88d 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -916,8 +916,8 @@ retry:
916 hb1 = hash_futex(&key1); 916 hb1 = hash_futex(&key1);
917 hb2 = hash_futex(&key2); 917 hb2 = hash_futex(&key2);
918 918
919 double_lock_hb(hb1, hb2);
920retry_private: 919retry_private:
920 double_lock_hb(hb1, hb2);
921 op_ret = futex_atomic_op_inuser(op, uaddr2); 921 op_ret = futex_atomic_op_inuser(op, uaddr2);
922 if (unlikely(op_ret < 0)) { 922 if (unlikely(op_ret < 0)) {
923 923
@@ -2117,7 +2117,6 @@ int handle_early_requeue_pi_wakeup(struct futex_hash_bucket *hb,
2117 * Unqueue the futex_q and determine which it was. 2117 * Unqueue the futex_q and determine which it was.
2118 */ 2118 */
2119 plist_del(&q->list, &q->list.plist); 2119 plist_del(&q->list, &q->list.plist);
2120 drop_futex_key_refs(&q->key);
2121 2120
2122 if (timeout && !timeout->task) 2121 if (timeout && !timeout->task)
2123 ret = -ETIMEDOUT; 2122 ret = -ETIMEDOUT;
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index 6d7020490f94..3e1c36e7998f 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -726,8 +726,6 @@ static int hrtimer_switch_to_hres(void)
726 /* "Retrigger" the interrupt to get things going */ 726 /* "Retrigger" the interrupt to get things going */
727 retrigger_next_event(NULL); 727 retrigger_next_event(NULL);
728 local_irq_restore(flags); 728 local_irq_restore(flags);
729 printk(KERN_DEBUG "Switched to high resolution mode on CPU %d\n",
730 smp_processor_id());
731 return 1; 729 return 1;
732} 730}
733 731
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
index a81cf80554db..17c71bb565c6 100644
--- a/kernel/irq/handle.c
+++ b/kernel/irq/handle.c
@@ -11,6 +11,7 @@
11 */ 11 */
12 12
13#include <linux/irq.h> 13#include <linux/irq.h>
14#include <linux/sched.h>
14#include <linux/slab.h> 15#include <linux/slab.h>
15#include <linux/module.h> 16#include <linux/module.h>
16#include <linux/random.h> 17#include <linux/random.h>
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index cfadc1291d0b..5240d75f4c60 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -1333,7 +1333,7 @@ static int __kprobes kprobes_open(struct inode *inode, struct file *filp)
1333 return seq_open(filp, &kprobes_seq_ops); 1333 return seq_open(filp, &kprobes_seq_ops);
1334} 1334}
1335 1335
1336static struct file_operations debugfs_kprobes_operations = { 1336static const struct file_operations debugfs_kprobes_operations = {
1337 .open = kprobes_open, 1337 .open = kprobes_open,
1338 .read = seq_read, 1338 .read = seq_read,
1339 .llseek = seq_lseek, 1339 .llseek = seq_lseek,
@@ -1515,7 +1515,7 @@ static ssize_t write_enabled_file_bool(struct file *file,
1515 return count; 1515 return count;
1516} 1516}
1517 1517
1518static struct file_operations fops_kp = { 1518static const struct file_operations fops_kp = {
1519 .read = read_enabled_file_bool, 1519 .read = read_enabled_file_bool,
1520 .write = write_enabled_file_bool, 1520 .write = write_enabled_file_bool,
1521}; 1521};
diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index 3815ac1d58b2..9af56723c096 100644
--- a/kernel/lockdep.c
+++ b/kernel/lockdep.c
@@ -142,6 +142,11 @@ static inline struct lock_class *hlock_class(struct held_lock *hlock)
142#ifdef CONFIG_LOCK_STAT 142#ifdef CONFIG_LOCK_STAT
143static DEFINE_PER_CPU(struct lock_class_stats[MAX_LOCKDEP_KEYS], lock_stats); 143static DEFINE_PER_CPU(struct lock_class_stats[MAX_LOCKDEP_KEYS], lock_stats);
144 144
145static inline u64 lockstat_clock(void)
146{
147 return cpu_clock(smp_processor_id());
148}
149
145static int lock_point(unsigned long points[], unsigned long ip) 150static int lock_point(unsigned long points[], unsigned long ip)
146{ 151{
147 int i; 152 int i;
@@ -158,7 +163,7 @@ static int lock_point(unsigned long points[], unsigned long ip)
158 return i; 163 return i;
159} 164}
160 165
161static void lock_time_inc(struct lock_time *lt, s64 time) 166static void lock_time_inc(struct lock_time *lt, u64 time)
162{ 167{
163 if (time > lt->max) 168 if (time > lt->max)
164 lt->max = time; 169 lt->max = time;
@@ -234,12 +239,12 @@ static void put_lock_stats(struct lock_class_stats *stats)
234static void lock_release_holdtime(struct held_lock *hlock) 239static void lock_release_holdtime(struct held_lock *hlock)
235{ 240{
236 struct lock_class_stats *stats; 241 struct lock_class_stats *stats;
237 s64 holdtime; 242 u64 holdtime;
238 243
239 if (!lock_stat) 244 if (!lock_stat)
240 return; 245 return;
241 246
242 holdtime = sched_clock() - hlock->holdtime_stamp; 247 holdtime = lockstat_clock() - hlock->holdtime_stamp;
243 248
244 stats = get_lock_stats(hlock_class(hlock)); 249 stats = get_lock_stats(hlock_class(hlock));
245 if (hlock->read) 250 if (hlock->read)
@@ -2792,7 +2797,7 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass,
2792 hlock->references = references; 2797 hlock->references = references;
2793#ifdef CONFIG_LOCK_STAT 2798#ifdef CONFIG_LOCK_STAT
2794 hlock->waittime_stamp = 0; 2799 hlock->waittime_stamp = 0;
2795 hlock->holdtime_stamp = sched_clock(); 2800 hlock->holdtime_stamp = lockstat_clock();
2796#endif 2801#endif
2797 2802
2798 if (check == 2 && !mark_irqflags(curr, hlock)) 2803 if (check == 2 && !mark_irqflags(curr, hlock))
@@ -3322,7 +3327,7 @@ found_it:
3322 if (hlock->instance != lock) 3327 if (hlock->instance != lock)
3323 return; 3328 return;
3324 3329
3325 hlock->waittime_stamp = sched_clock(); 3330 hlock->waittime_stamp = lockstat_clock();
3326 3331
3327 contention_point = lock_point(hlock_class(hlock)->contention_point, ip); 3332 contention_point = lock_point(hlock_class(hlock)->contention_point, ip);
3328 contending_point = lock_point(hlock_class(hlock)->contending_point, 3333 contending_point = lock_point(hlock_class(hlock)->contending_point,
@@ -3345,8 +3350,7 @@ __lock_acquired(struct lockdep_map *lock, unsigned long ip)
3345 struct held_lock *hlock, *prev_hlock; 3350 struct held_lock *hlock, *prev_hlock;
3346 struct lock_class_stats *stats; 3351 struct lock_class_stats *stats;
3347 unsigned int depth; 3352 unsigned int depth;
3348 u64 now; 3353 u64 now, waittime = 0;
3349 s64 waittime = 0;
3350 int i, cpu; 3354 int i, cpu;
3351 3355
3352 depth = curr->lockdep_depth; 3356 depth = curr->lockdep_depth;
@@ -3374,7 +3378,7 @@ found_it:
3374 3378
3375 cpu = smp_processor_id(); 3379 cpu = smp_processor_id();
3376 if (hlock->waittime_stamp) { 3380 if (hlock->waittime_stamp) {
3377 now = sched_clock(); 3381 now = lockstat_clock();
3378 waittime = now - hlock->waittime_stamp; 3382 waittime = now - hlock->waittime_stamp;
3379 hlock->holdtime_stamp = now; 3383 hlock->holdtime_stamp = now;
3380 } 3384 }
diff --git a/kernel/module.c b/kernel/module.c
index fe748a86d452..8b7d8805819d 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -1992,12 +1992,14 @@ static inline unsigned long layout_symtab(struct module *mod,
1992 Elf_Shdr *sechdrs, 1992 Elf_Shdr *sechdrs,
1993 unsigned int symindex, 1993 unsigned int symindex,
1994 unsigned int strindex, 1994 unsigned int strindex,
1995 const Elf_Hdr *hdr, 1995 const Elf_Ehdr *hdr,
1996 const char *secstrings, 1996 const char *secstrings,
1997 unsigned long *pstroffs, 1997 unsigned long *pstroffs,
1998 unsigned long *strmap) 1998 unsigned long *strmap)
1999{ 1999{
2000 return 0;
2000} 2001}
2002
2001static inline void add_kallsyms(struct module *mod, 2003static inline void add_kallsyms(struct module *mod,
2002 Elf_Shdr *sechdrs, 2004 Elf_Shdr *sechdrs,
2003 unsigned int shnum, 2005 unsigned int shnum,
@@ -2081,9 +2083,8 @@ static noinline struct module *load_module(void __user *umod,
2081 struct module *mod; 2083 struct module *mod;
2082 long err = 0; 2084 long err = 0;
2083 void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */ 2085 void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */
2084#ifdef CONFIG_KALLSYMS
2085 unsigned long symoffs, stroffs, *strmap; 2086 unsigned long symoffs, stroffs, *strmap;
2086#endif 2087
2087 mm_segment_t old_fs; 2088 mm_segment_t old_fs;
2088 2089
2089 DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n", 2090 DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
diff --git a/kernel/mutex-debug.c b/kernel/mutex-debug.c
index 50d022e5a560..ec815a960b5d 100644
--- a/kernel/mutex-debug.c
+++ b/kernel/mutex-debug.c
@@ -16,6 +16,7 @@
16#include <linux/delay.h> 16#include <linux/delay.h>
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/poison.h> 18#include <linux/poison.h>
19#include <linux/sched.h>
19#include <linux/spinlock.h> 20#include <linux/spinlock.h>
20#include <linux/kallsyms.h> 21#include <linux/kallsyms.h>
21#include <linux/interrupt.h> 22#include <linux/interrupt.h>
diff --git a/kernel/panic.c b/kernel/panic.c
index bcdef26e3332..96b45d0b4ba5 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -90,6 +90,8 @@ NORET_TYPE void panic(const char * fmt, ...)
90 90
91 atomic_notifier_call_chain(&panic_notifier_list, 0, buf); 91 atomic_notifier_call_chain(&panic_notifier_list, 0, buf);
92 92
93 bust_spinlocks(0);
94
93 if (!panic_blink) 95 if (!panic_blink)
94 panic_blink = no_blink; 96 panic_blink = no_blink;
95 97
@@ -136,7 +138,6 @@ NORET_TYPE void panic(const char * fmt, ...)
136 mdelay(1); 138 mdelay(1);
137 i++; 139 i++;
138 } 140 }
139 bust_spinlocks(0);
140} 141}
141 142
142EXPORT_SYMBOL(panic); 143EXPORT_SYMBOL(panic);
diff --git a/kernel/perf_event.c b/kernel/perf_event.c
index 0f86feb6db0c..9d0b5c665883 100644
--- a/kernel/perf_event.c
+++ b/kernel/perf_event.c
@@ -20,6 +20,7 @@
20#include <linux/percpu.h> 20#include <linux/percpu.h>
21#include <linux/ptrace.h> 21#include <linux/ptrace.h>
22#include <linux/vmstat.h> 22#include <linux/vmstat.h>
23#include <linux/vmalloc.h>
23#include <linux/hardirq.h> 24#include <linux/hardirq.h>
24#include <linux/rculist.h> 25#include <linux/rculist.h>
25#include <linux/uaccess.h> 26#include <linux/uaccess.h>
@@ -1030,14 +1031,10 @@ void __perf_event_sched_out(struct perf_event_context *ctx,
1030 update_context_time(ctx); 1031 update_context_time(ctx);
1031 1032
1032 perf_disable(); 1033 perf_disable();
1033 if (ctx->nr_active) { 1034 if (ctx->nr_active)
1034 list_for_each_entry(event, &ctx->group_list, group_entry) { 1035 list_for_each_entry(event, &ctx->group_list, group_entry)
1035 if (event != event->group_leader) 1036 group_sched_out(event, cpuctx, ctx);
1036 event_sched_out(event, cpuctx, ctx); 1037
1037 else
1038 group_sched_out(event, cpuctx, ctx);
1039 }
1040 }
1041 perf_enable(); 1038 perf_enable();
1042 out: 1039 out:
1043 spin_unlock(&ctx->lock); 1040 spin_unlock(&ctx->lock);
@@ -1258,12 +1255,8 @@ __perf_event_sched_in(struct perf_event_context *ctx,
1258 if (event->cpu != -1 && event->cpu != cpu) 1255 if (event->cpu != -1 && event->cpu != cpu)
1259 continue; 1256 continue;
1260 1257
1261 if (event != event->group_leader) 1258 if (group_can_go_on(event, cpuctx, 1))
1262 event_sched_in(event, cpuctx, ctx, cpu); 1259 group_sched_in(event, cpuctx, ctx, cpu);
1263 else {
1264 if (group_can_go_on(event, cpuctx, 1))
1265 group_sched_in(event, cpuctx, ctx, cpu);
1266 }
1267 1260
1268 /* 1261 /*
1269 * If this pinned group hasn't been scheduled, 1262 * If this pinned group hasn't been scheduled,
@@ -1291,15 +1284,9 @@ __perf_event_sched_in(struct perf_event_context *ctx,
1291 if (event->cpu != -1 && event->cpu != cpu) 1284 if (event->cpu != -1 && event->cpu != cpu)
1292 continue; 1285 continue;
1293 1286
1294 if (event != event->group_leader) { 1287 if (group_can_go_on(event, cpuctx, can_add_hw))
1295 if (event_sched_in(event, cpuctx, ctx, cpu)) 1288 if (group_sched_in(event, cpuctx, ctx, cpu))
1296 can_add_hw = 0; 1289 can_add_hw = 0;
1297 } else {
1298 if (group_can_go_on(event, cpuctx, can_add_hw)) {
1299 if (group_sched_in(event, cpuctx, ctx, cpu))
1300 can_add_hw = 0;
1301 }
1302 }
1303 } 1290 }
1304 perf_enable(); 1291 perf_enable();
1305 out: 1292 out:
@@ -2105,49 +2092,31 @@ unlock:
2105 rcu_read_unlock(); 2092 rcu_read_unlock();
2106} 2093}
2107 2094
2108static int perf_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf) 2095static unsigned long perf_data_size(struct perf_mmap_data *data)
2109{ 2096{
2110 struct perf_event *event = vma->vm_file->private_data; 2097 return data->nr_pages << (PAGE_SHIFT + data->data_order);
2111 struct perf_mmap_data *data; 2098}
2112 int ret = VM_FAULT_SIGBUS;
2113
2114 if (vmf->flags & FAULT_FLAG_MKWRITE) {
2115 if (vmf->pgoff == 0)
2116 ret = 0;
2117 return ret;
2118 }
2119
2120 rcu_read_lock();
2121 data = rcu_dereference(event->data);
2122 if (!data)
2123 goto unlock;
2124
2125 if (vmf->pgoff == 0) {
2126 vmf->page = virt_to_page(data->user_page);
2127 } else {
2128 int nr = vmf->pgoff - 1;
2129
2130 if ((unsigned)nr > data->nr_pages)
2131 goto unlock;
2132 2099
2133 if (vmf->flags & FAULT_FLAG_WRITE) 2100#ifndef CONFIG_PERF_USE_VMALLOC
2134 goto unlock;
2135 2101
2136 vmf->page = virt_to_page(data->data_pages[nr]); 2102/*
2137 } 2103 * Back perf_mmap() with regular GFP_KERNEL-0 pages.
2104 */
2138 2105
2139 get_page(vmf->page); 2106static struct page *
2140 vmf->page->mapping = vma->vm_file->f_mapping; 2107perf_mmap_to_page(struct perf_mmap_data *data, unsigned long pgoff)
2141 vmf->page->index = vmf->pgoff; 2108{
2109 if (pgoff > data->nr_pages)
2110 return NULL;
2142 2111
2143 ret = 0; 2112 if (pgoff == 0)
2144unlock: 2113 return virt_to_page(data->user_page);
2145 rcu_read_unlock();
2146 2114
2147 return ret; 2115 return virt_to_page(data->data_pages[pgoff - 1]);
2148} 2116}
2149 2117
2150static int perf_mmap_data_alloc(struct perf_event *event, int nr_pages) 2118static struct perf_mmap_data *
2119perf_mmap_data_alloc(struct perf_event *event, int nr_pages)
2151{ 2120{
2152 struct perf_mmap_data *data; 2121 struct perf_mmap_data *data;
2153 unsigned long size; 2122 unsigned long size;
@@ -2172,19 +2141,10 @@ static int perf_mmap_data_alloc(struct perf_event *event, int nr_pages)
2172 goto fail_data_pages; 2141 goto fail_data_pages;
2173 } 2142 }
2174 2143
2144 data->data_order = 0;
2175 data->nr_pages = nr_pages; 2145 data->nr_pages = nr_pages;
2176 atomic_set(&data->lock, -1);
2177
2178 if (event->attr.watermark) {
2179 data->watermark = min_t(long, PAGE_SIZE * nr_pages,
2180 event->attr.wakeup_watermark);
2181 }
2182 if (!data->watermark)
2183 data->watermark = max(PAGE_SIZE, PAGE_SIZE * nr_pages / 4);
2184 2146
2185 rcu_assign_pointer(event->data, data); 2147 return data;
2186
2187 return 0;
2188 2148
2189fail_data_pages: 2149fail_data_pages:
2190 for (i--; i >= 0; i--) 2150 for (i--; i >= 0; i--)
@@ -2196,7 +2156,7 @@ fail_user_page:
2196 kfree(data); 2156 kfree(data);
2197 2157
2198fail: 2158fail:
2199 return -ENOMEM; 2159 return NULL;
2200} 2160}
2201 2161
2202static void perf_mmap_free_page(unsigned long addr) 2162static void perf_mmap_free_page(unsigned long addr)
@@ -2207,28 +2167,169 @@ static void perf_mmap_free_page(unsigned long addr)
2207 __free_page(page); 2167 __free_page(page);
2208} 2168}
2209 2169
2210static void __perf_mmap_data_free(struct rcu_head *rcu_head) 2170static void perf_mmap_data_free(struct perf_mmap_data *data)
2211{ 2171{
2212 struct perf_mmap_data *data;
2213 int i; 2172 int i;
2214 2173
2215 data = container_of(rcu_head, struct perf_mmap_data, rcu_head);
2216
2217 perf_mmap_free_page((unsigned long)data->user_page); 2174 perf_mmap_free_page((unsigned long)data->user_page);
2218 for (i = 0; i < data->nr_pages; i++) 2175 for (i = 0; i < data->nr_pages; i++)
2219 perf_mmap_free_page((unsigned long)data->data_pages[i]); 2176 perf_mmap_free_page((unsigned long)data->data_pages[i]);
2177}
2178
2179#else
2180
2181/*
2182 * Back perf_mmap() with vmalloc memory.
2183 *
2184 * Required for architectures that have d-cache aliasing issues.
2185 */
2186
2187static struct page *
2188perf_mmap_to_page(struct perf_mmap_data *data, unsigned long pgoff)
2189{
2190 if (pgoff > (1UL << data->data_order))
2191 return NULL;
2192
2193 return vmalloc_to_page((void *)data->user_page + pgoff * PAGE_SIZE);
2194}
2195
2196static void perf_mmap_unmark_page(void *addr)
2197{
2198 struct page *page = vmalloc_to_page(addr);
2199
2200 page->mapping = NULL;
2201}
2202
2203static void perf_mmap_data_free_work(struct work_struct *work)
2204{
2205 struct perf_mmap_data *data;
2206 void *base;
2207 int i, nr;
2208
2209 data = container_of(work, struct perf_mmap_data, work);
2210 nr = 1 << data->data_order;
2211
2212 base = data->user_page;
2213 for (i = 0; i < nr + 1; i++)
2214 perf_mmap_unmark_page(base + (i * PAGE_SIZE));
2215
2216 vfree(base);
2217}
2220 2218
2219static void perf_mmap_data_free(struct perf_mmap_data *data)
2220{
2221 schedule_work(&data->work);
2222}
2223
2224static struct perf_mmap_data *
2225perf_mmap_data_alloc(struct perf_event *event, int nr_pages)
2226{
2227 struct perf_mmap_data *data;
2228 unsigned long size;
2229 void *all_buf;
2230
2231 WARN_ON(atomic_read(&event->mmap_count));
2232
2233 size = sizeof(struct perf_mmap_data);
2234 size += sizeof(void *);
2235
2236 data = kzalloc(size, GFP_KERNEL);
2237 if (!data)
2238 goto fail;
2239
2240 INIT_WORK(&data->work, perf_mmap_data_free_work);
2241
2242 all_buf = vmalloc_user((nr_pages + 1) * PAGE_SIZE);
2243 if (!all_buf)
2244 goto fail_all_buf;
2245
2246 data->user_page = all_buf;
2247 data->data_pages[0] = all_buf + PAGE_SIZE;
2248 data->data_order = ilog2(nr_pages);
2249 data->nr_pages = 1;
2250
2251 return data;
2252
2253fail_all_buf:
2254 kfree(data);
2255
2256fail:
2257 return NULL;
2258}
2259
2260#endif
2261
2262static int perf_mmap_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
2263{
2264 struct perf_event *event = vma->vm_file->private_data;
2265 struct perf_mmap_data *data;
2266 int ret = VM_FAULT_SIGBUS;
2267
2268 if (vmf->flags & FAULT_FLAG_MKWRITE) {
2269 if (vmf->pgoff == 0)
2270 ret = 0;
2271 return ret;
2272 }
2273
2274 rcu_read_lock();
2275 data = rcu_dereference(event->data);
2276 if (!data)
2277 goto unlock;
2278
2279 if (vmf->pgoff && (vmf->flags & FAULT_FLAG_WRITE))
2280 goto unlock;
2281
2282 vmf->page = perf_mmap_to_page(data, vmf->pgoff);
2283 if (!vmf->page)
2284 goto unlock;
2285
2286 get_page(vmf->page);
2287 vmf->page->mapping = vma->vm_file->f_mapping;
2288 vmf->page->index = vmf->pgoff;
2289
2290 ret = 0;
2291unlock:
2292 rcu_read_unlock();
2293
2294 return ret;
2295}
2296
2297static void
2298perf_mmap_data_init(struct perf_event *event, struct perf_mmap_data *data)
2299{
2300 long max_size = perf_data_size(data);
2301
2302 atomic_set(&data->lock, -1);
2303
2304 if (event->attr.watermark) {
2305 data->watermark = min_t(long, max_size,
2306 event->attr.wakeup_watermark);
2307 }
2308
2309 if (!data->watermark)
2310 data->watermark = max_t(long, PAGE_SIZE, max_size / 2);
2311
2312
2313 rcu_assign_pointer(event->data, data);
2314}
2315
2316static void perf_mmap_data_free_rcu(struct rcu_head *rcu_head)
2317{
2318 struct perf_mmap_data *data;
2319
2320 data = container_of(rcu_head, struct perf_mmap_data, rcu_head);
2321 perf_mmap_data_free(data);
2221 kfree(data); 2322 kfree(data);
2222} 2323}
2223 2324
2224static void perf_mmap_data_free(struct perf_event *event) 2325static void perf_mmap_data_release(struct perf_event *event)
2225{ 2326{
2226 struct perf_mmap_data *data = event->data; 2327 struct perf_mmap_data *data = event->data;
2227 2328
2228 WARN_ON(atomic_read(&event->mmap_count)); 2329 WARN_ON(atomic_read(&event->mmap_count));
2229 2330
2230 rcu_assign_pointer(event->data, NULL); 2331 rcu_assign_pointer(event->data, NULL);
2231 call_rcu(&data->rcu_head, __perf_mmap_data_free); 2332 call_rcu(&data->rcu_head, perf_mmap_data_free_rcu);
2232} 2333}
2233 2334
2234static void perf_mmap_open(struct vm_area_struct *vma) 2335static void perf_mmap_open(struct vm_area_struct *vma)
@@ -2244,11 +2345,12 @@ static void perf_mmap_close(struct vm_area_struct *vma)
2244 2345
2245 WARN_ON_ONCE(event->ctx->parent_ctx); 2346 WARN_ON_ONCE(event->ctx->parent_ctx);
2246 if (atomic_dec_and_mutex_lock(&event->mmap_count, &event->mmap_mutex)) { 2347 if (atomic_dec_and_mutex_lock(&event->mmap_count, &event->mmap_mutex)) {
2348 unsigned long size = perf_data_size(event->data);
2247 struct user_struct *user = current_user(); 2349 struct user_struct *user = current_user();
2248 2350
2249 atomic_long_sub(event->data->nr_pages + 1, &user->locked_vm); 2351 atomic_long_sub((size >> PAGE_SHIFT) + 1, &user->locked_vm);
2250 vma->vm_mm->locked_vm -= event->data->nr_locked; 2352 vma->vm_mm->locked_vm -= event->data->nr_locked;
2251 perf_mmap_data_free(event); 2353 perf_mmap_data_release(event);
2252 mutex_unlock(&event->mmap_mutex); 2354 mutex_unlock(&event->mmap_mutex);
2253 } 2355 }
2254} 2356}
@@ -2266,6 +2368,7 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma)
2266 unsigned long user_locked, user_lock_limit; 2368 unsigned long user_locked, user_lock_limit;
2267 struct user_struct *user = current_user(); 2369 struct user_struct *user = current_user();
2268 unsigned long locked, lock_limit; 2370 unsigned long locked, lock_limit;
2371 struct perf_mmap_data *data;
2269 unsigned long vma_size; 2372 unsigned long vma_size;
2270 unsigned long nr_pages; 2373 unsigned long nr_pages;
2271 long user_extra, extra; 2374 long user_extra, extra;
@@ -2328,10 +2431,15 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma)
2328 } 2431 }
2329 2432
2330 WARN_ON(event->data); 2433 WARN_ON(event->data);
2331 ret = perf_mmap_data_alloc(event, nr_pages); 2434
2332 if (ret) 2435 data = perf_mmap_data_alloc(event, nr_pages);
2436 ret = -ENOMEM;
2437 if (!data)
2333 goto unlock; 2438 goto unlock;
2334 2439
2440 ret = 0;
2441 perf_mmap_data_init(event, data);
2442
2335 atomic_set(&event->mmap_count, 1); 2443 atomic_set(&event->mmap_count, 1);
2336 atomic_long_add(user_extra, &user->locked_vm); 2444 atomic_long_add(user_extra, &user->locked_vm);
2337 vma->vm_mm->locked_vm += extra; 2445 vma->vm_mm->locked_vm += extra;
@@ -2519,7 +2627,7 @@ static bool perf_output_space(struct perf_mmap_data *data, unsigned long tail,
2519 if (!data->writable) 2627 if (!data->writable)
2520 return true; 2628 return true;
2521 2629
2522 mask = (data->nr_pages << PAGE_SHIFT) - 1; 2630 mask = perf_data_size(data) - 1;
2523 2631
2524 offset = (offset - tail) & mask; 2632 offset = (offset - tail) & mask;
2525 head = (head - tail) & mask; 2633 head = (head - tail) & mask;
@@ -2624,7 +2732,7 @@ void perf_output_copy(struct perf_output_handle *handle,
2624 const void *buf, unsigned int len) 2732 const void *buf, unsigned int len)
2625{ 2733{
2626 unsigned int pages_mask; 2734 unsigned int pages_mask;
2627 unsigned int offset; 2735 unsigned long offset;
2628 unsigned int size; 2736 unsigned int size;
2629 void **pages; 2737 void **pages;
2630 2738
@@ -2633,12 +2741,14 @@ void perf_output_copy(struct perf_output_handle *handle,
2633 pages = handle->data->data_pages; 2741 pages = handle->data->data_pages;
2634 2742
2635 do { 2743 do {
2636 unsigned int page_offset; 2744 unsigned long page_offset;
2745 unsigned long page_size;
2637 int nr; 2746 int nr;
2638 2747
2639 nr = (offset >> PAGE_SHIFT) & pages_mask; 2748 nr = (offset >> PAGE_SHIFT) & pages_mask;
2640 page_offset = offset & (PAGE_SIZE - 1); 2749 page_size = 1UL << (handle->data->data_order + PAGE_SHIFT);
2641 size = min_t(unsigned int, PAGE_SIZE - page_offset, len); 2750 page_offset = offset & (page_size - 1);
2751 size = min_t(unsigned int, page_size - page_offset, len);
2642 2752
2643 memcpy(pages[nr] + page_offset, buf, size); 2753 memcpy(pages[nr] + page_offset, buf, size);
2644 2754
@@ -4781,9 +4891,7 @@ int perf_event_init_task(struct task_struct *child)
4781 * We dont have to disable NMIs - we are only looking at 4891 * We dont have to disable NMIs - we are only looking at
4782 * the list, not manipulating it: 4892 * the list, not manipulating it:
4783 */ 4893 */
4784 list_for_each_entry_rcu(event, &parent_ctx->event_list, event_entry) { 4894 list_for_each_entry(event, &parent_ctx->group_list, group_entry) {
4785 if (event != event->group_leader)
4786 continue;
4787 4895
4788 if (!event->attr.inherit) { 4896 if (!event->attr.inherit) {
4789 inherited_all = 0; 4897 inherited_all = 0;
diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c
index 37ac45483082..400183346ad2 100644
--- a/kernel/rcupdate.c
+++ b/kernel/rcupdate.c
@@ -46,22 +46,15 @@
46#include <linux/module.h> 46#include <linux/module.h>
47#include <linux/kernel_stat.h> 47#include <linux/kernel_stat.h>
48 48
49enum rcu_barrier { 49#ifdef CONFIG_DEBUG_LOCK_ALLOC
50 RCU_BARRIER_STD, 50static struct lock_class_key rcu_lock_key;
51 RCU_BARRIER_BH, 51struct lockdep_map rcu_lock_map =
52 RCU_BARRIER_SCHED, 52 STATIC_LOCKDEP_MAP_INIT("rcu_read_lock", &rcu_lock_key);
53}; 53EXPORT_SYMBOL_GPL(rcu_lock_map);
54#endif
54 55
55static DEFINE_PER_CPU(struct rcu_head, rcu_barrier_head) = {NULL};
56static atomic_t rcu_barrier_cpu_count;
57static DEFINE_MUTEX(rcu_barrier_mutex);
58static struct completion rcu_barrier_completion;
59int rcu_scheduler_active __read_mostly; 56int rcu_scheduler_active __read_mostly;
60 57
61static atomic_t rcu_migrate_type_count = ATOMIC_INIT(0);
62static struct rcu_head rcu_migrate_head[3];
63static DECLARE_WAIT_QUEUE_HEAD(rcu_migrate_wq);
64
65/* 58/*
66 * Awaken the corresponding synchronize_rcu() instance now that a 59 * Awaken the corresponding synchronize_rcu() instance now that a
67 * grace period has elapsed. 60 * grace period has elapsed.
@@ -164,129 +157,10 @@ void synchronize_rcu_bh(void)
164} 157}
165EXPORT_SYMBOL_GPL(synchronize_rcu_bh); 158EXPORT_SYMBOL_GPL(synchronize_rcu_bh);
166 159
167static void rcu_barrier_callback(struct rcu_head *notused)
168{
169 if (atomic_dec_and_test(&rcu_barrier_cpu_count))
170 complete(&rcu_barrier_completion);
171}
172
173/*
174 * Called with preemption disabled, and from cross-cpu IRQ context.
175 */
176static void rcu_barrier_func(void *type)
177{
178 int cpu = smp_processor_id();
179 struct rcu_head *head = &per_cpu(rcu_barrier_head, cpu);
180
181 atomic_inc(&rcu_barrier_cpu_count);
182 switch ((enum rcu_barrier)type) {
183 case RCU_BARRIER_STD:
184 call_rcu(head, rcu_barrier_callback);
185 break;
186 case RCU_BARRIER_BH:
187 call_rcu_bh(head, rcu_barrier_callback);
188 break;
189 case RCU_BARRIER_SCHED:
190 call_rcu_sched(head, rcu_barrier_callback);
191 break;
192 }
193}
194
195static inline void wait_migrated_callbacks(void)
196{
197 wait_event(rcu_migrate_wq, !atomic_read(&rcu_migrate_type_count));
198 smp_mb(); /* In case we didn't sleep. */
199}
200
201/*
202 * Orchestrate the specified type of RCU barrier, waiting for all
203 * RCU callbacks of the specified type to complete.
204 */
205static void _rcu_barrier(enum rcu_barrier type)
206{
207 BUG_ON(in_interrupt());
208 /* Take cpucontrol mutex to protect against CPU hotplug */
209 mutex_lock(&rcu_barrier_mutex);
210 init_completion(&rcu_barrier_completion);
211 /*
212 * Initialize rcu_barrier_cpu_count to 1, then invoke
213 * rcu_barrier_func() on each CPU, so that each CPU also has
214 * incremented rcu_barrier_cpu_count. Only then is it safe to
215 * decrement rcu_barrier_cpu_count -- otherwise the first CPU
216 * might complete its grace period before all of the other CPUs
217 * did their increment, causing this function to return too
218 * early.
219 */
220 atomic_set(&rcu_barrier_cpu_count, 1);
221 on_each_cpu(rcu_barrier_func, (void *)type, 1);
222 if (atomic_dec_and_test(&rcu_barrier_cpu_count))
223 complete(&rcu_barrier_completion);
224 wait_for_completion(&rcu_barrier_completion);
225 mutex_unlock(&rcu_barrier_mutex);
226 wait_migrated_callbacks();
227}
228
229/**
230 * rcu_barrier - Wait until all in-flight call_rcu() callbacks complete.
231 */
232void rcu_barrier(void)
233{
234 _rcu_barrier(RCU_BARRIER_STD);
235}
236EXPORT_SYMBOL_GPL(rcu_barrier);
237
238/**
239 * rcu_barrier_bh - Wait until all in-flight call_rcu_bh() callbacks complete.
240 */
241void rcu_barrier_bh(void)
242{
243 _rcu_barrier(RCU_BARRIER_BH);
244}
245EXPORT_SYMBOL_GPL(rcu_barrier_bh);
246
247/**
248 * rcu_barrier_sched - Wait for in-flight call_rcu_sched() callbacks.
249 */
250void rcu_barrier_sched(void)
251{
252 _rcu_barrier(RCU_BARRIER_SCHED);
253}
254EXPORT_SYMBOL_GPL(rcu_barrier_sched);
255
256static void rcu_migrate_callback(struct rcu_head *notused)
257{
258 if (atomic_dec_and_test(&rcu_migrate_type_count))
259 wake_up(&rcu_migrate_wq);
260}
261
262extern int rcu_cpu_notify(struct notifier_block *self,
263 unsigned long action, void *hcpu);
264
265static int __cpuinit rcu_barrier_cpu_hotplug(struct notifier_block *self, 160static int __cpuinit rcu_barrier_cpu_hotplug(struct notifier_block *self,
266 unsigned long action, void *hcpu) 161 unsigned long action, void *hcpu)
267{ 162{
268 rcu_cpu_notify(self, action, hcpu); 163 return rcu_cpu_notify(self, action, hcpu);
269 if (action == CPU_DYING) {
270 /*
271 * preempt_disable() in on_each_cpu() prevents stop_machine(),
272 * so when "on_each_cpu(rcu_barrier_func, (void *)type, 1);"
273 * returns, all online cpus have queued rcu_barrier_func(),
274 * and the dead cpu(if it exist) queues rcu_migrate_callback()s.
275 *
276 * These callbacks ensure _rcu_barrier() waits for all
277 * RCU callbacks of the specified type to complete.
278 */
279 atomic_set(&rcu_migrate_type_count, 3);
280 call_rcu_bh(rcu_migrate_head, rcu_migrate_callback);
281 call_rcu_sched(rcu_migrate_head + 1, rcu_migrate_callback);
282 call_rcu(rcu_migrate_head + 2, rcu_migrate_callback);
283 } else if (action == CPU_DOWN_PREPARE) {
284 /* Don't need to wait until next removal operation. */
285 /* rcu_migrate_head is protected by cpu_add_remove_lock */
286 wait_migrated_callbacks();
287 }
288
289 return NOTIFY_OK;
290} 164}
291 165
292void __init rcu_init(void) 166void __init rcu_init(void)
diff --git a/kernel/rcutorture.c b/kernel/rcutorture.c
index 233768f21f97..697c0a0229d4 100644
--- a/kernel/rcutorture.c
+++ b/kernel/rcutorture.c
@@ -606,8 +606,6 @@ static struct rcu_torture_ops sched_ops_sync = {
606 .name = "sched_sync" 606 .name = "sched_sync"
607}; 607};
608 608
609extern int rcu_expedited_torture_stats(char *page);
610
611static struct rcu_torture_ops sched_expedited_ops = { 609static struct rcu_torture_ops sched_expedited_ops = {
612 .init = rcu_sync_torture_init, 610 .init = rcu_sync_torture_init,
613 .cleanup = NULL, 611 .cleanup = NULL,
@@ -650,7 +648,7 @@ rcu_torture_writer(void *arg)
650 old_rp = rcu_torture_current; 648 old_rp = rcu_torture_current;
651 rp->rtort_mbtest = 1; 649 rp->rtort_mbtest = 1;
652 rcu_assign_pointer(rcu_torture_current, rp); 650 rcu_assign_pointer(rcu_torture_current, rp);
653 smp_wmb(); 651 smp_wmb(); /* Mods to old_rp must follow rcu_assign_pointer() */
654 if (old_rp) { 652 if (old_rp) {
655 i = old_rp->rtort_pipe_count; 653 i = old_rp->rtort_pipe_count;
656 if (i > RCU_TORTURE_PIPE_LEN) 654 if (i > RCU_TORTURE_PIPE_LEN)
diff --git a/kernel/rcutree.c b/kernel/rcutree.c
index 52b06f6e158c..705f02ac7433 100644
--- a/kernel/rcutree.c
+++ b/kernel/rcutree.c
@@ -49,13 +49,6 @@
49 49
50#include "rcutree.h" 50#include "rcutree.h"
51 51
52#ifdef CONFIG_DEBUG_LOCK_ALLOC
53static struct lock_class_key rcu_lock_key;
54struct lockdep_map rcu_lock_map =
55 STATIC_LOCKDEP_MAP_INIT("rcu_read_lock", &rcu_lock_key);
56EXPORT_SYMBOL_GPL(rcu_lock_map);
57#endif
58
59/* Data structures. */ 52/* Data structures. */
60 53
61#define RCU_STATE_INITIALIZER(name) { \ 54#define RCU_STATE_INITIALIZER(name) { \
@@ -70,6 +63,9 @@ EXPORT_SYMBOL_GPL(rcu_lock_map);
70 .gpnum = -300, \ 63 .gpnum = -300, \
71 .completed = -300, \ 64 .completed = -300, \
72 .onofflock = __SPIN_LOCK_UNLOCKED(&name.onofflock), \ 65 .onofflock = __SPIN_LOCK_UNLOCKED(&name.onofflock), \
66 .orphan_cbs_list = NULL, \
67 .orphan_cbs_tail = &name.orphan_cbs_list, \
68 .orphan_qlen = 0, \
73 .fqslock = __SPIN_LOCK_UNLOCKED(&name.fqslock), \ 69 .fqslock = __SPIN_LOCK_UNLOCKED(&name.fqslock), \
74 .n_force_qs = 0, \ 70 .n_force_qs = 0, \
75 .n_force_qs_ngp = 0, \ 71 .n_force_qs_ngp = 0, \
@@ -81,24 +77,16 @@ DEFINE_PER_CPU(struct rcu_data, rcu_sched_data);
81struct rcu_state rcu_bh_state = RCU_STATE_INITIALIZER(rcu_bh_state); 77struct rcu_state rcu_bh_state = RCU_STATE_INITIALIZER(rcu_bh_state);
82DEFINE_PER_CPU(struct rcu_data, rcu_bh_data); 78DEFINE_PER_CPU(struct rcu_data, rcu_bh_data);
83 79
84extern long rcu_batches_completed_sched(void);
85static struct rcu_node *rcu_get_root(struct rcu_state *rsp);
86static void cpu_quiet_msk(unsigned long mask, struct rcu_state *rsp,
87 struct rcu_node *rnp, unsigned long flags);
88static void cpu_quiet_msk_finish(struct rcu_state *rsp, unsigned long flags);
89#ifdef CONFIG_HOTPLUG_CPU
90static void __rcu_offline_cpu(int cpu, struct rcu_state *rsp);
91#endif /* #ifdef CONFIG_HOTPLUG_CPU */
92static void __rcu_process_callbacks(struct rcu_state *rsp,
93 struct rcu_data *rdp);
94static void __call_rcu(struct rcu_head *head,
95 void (*func)(struct rcu_head *rcu),
96 struct rcu_state *rsp);
97static int __rcu_pending(struct rcu_state *rsp, struct rcu_data *rdp);
98static void __cpuinit rcu_init_percpu_data(int cpu, struct rcu_state *rsp,
99 int preemptable);
100 80
101#include "rcutree_plugin.h" 81/*
82 * Return true if an RCU grace period is in progress. The ACCESS_ONCE()s
83 * permit this function to be invoked without holding the root rcu_node
84 * structure's ->lock, but of course results can be subject to change.
85 */
86static int rcu_gp_in_progress(struct rcu_state *rsp)
87{
88 return ACCESS_ONCE(rsp->completed) != ACCESS_ONCE(rsp->gpnum);
89}
102 90
103/* 91/*
104 * Note a quiescent state. Because we do not need to know 92 * Note a quiescent state. Because we do not need to know
@@ -137,6 +125,10 @@ static int blimit = 10; /* Maximum callbacks per softirq. */
137static int qhimark = 10000; /* If this many pending, ignore blimit. */ 125static int qhimark = 10000; /* If this many pending, ignore blimit. */
138static int qlowmark = 100; /* Once only this many pending, use blimit. */ 126static int qlowmark = 100; /* Once only this many pending, use blimit. */
139 127
128module_param(blimit, int, 0);
129module_param(qhimark, int, 0);
130module_param(qlowmark, int, 0);
131
140static void force_quiescent_state(struct rcu_state *rsp, int relaxed); 132static void force_quiescent_state(struct rcu_state *rsp, int relaxed);
141static int rcu_pending(int cpu); 133static int rcu_pending(int cpu);
142 134
@@ -173,9 +165,7 @@ cpu_has_callbacks_ready_to_invoke(struct rcu_data *rdp)
173static int 165static int
174cpu_needs_another_gp(struct rcu_state *rsp, struct rcu_data *rdp) 166cpu_needs_another_gp(struct rcu_state *rsp, struct rcu_data *rdp)
175{ 167{
176 /* ACCESS_ONCE() because we are accessing outside of lock. */ 168 return *rdp->nxttail[RCU_DONE_TAIL] && !rcu_gp_in_progress(rsp);
177 return *rdp->nxttail[RCU_DONE_TAIL] &&
178 ACCESS_ONCE(rsp->completed) == ACCESS_ONCE(rsp->gpnum);
179} 169}
180 170
181/* 171/*
@@ -369,7 +359,7 @@ static long dyntick_recall_completed(struct rcu_state *rsp)
369/* 359/*
370 * Snapshot the specified CPU's dynticks counter so that we can later 360 * Snapshot the specified CPU's dynticks counter so that we can later
371 * credit them with an implicit quiescent state. Return 1 if this CPU 361 * credit them with an implicit quiescent state. Return 1 if this CPU
372 * is already in a quiescent state courtesy of dynticks idle mode. 362 * is in dynticks idle mode, which is an extended quiescent state.
373 */ 363 */
374static int dyntick_save_progress_counter(struct rcu_data *rdp) 364static int dyntick_save_progress_counter(struct rcu_data *rdp)
375{ 365{
@@ -475,30 +465,34 @@ static void print_other_cpu_stall(struct rcu_state *rsp)
475 long delta; 465 long delta;
476 unsigned long flags; 466 unsigned long flags;
477 struct rcu_node *rnp = rcu_get_root(rsp); 467 struct rcu_node *rnp = rcu_get_root(rsp);
478 struct rcu_node *rnp_cur = rsp->level[NUM_RCU_LVLS - 1];
479 struct rcu_node *rnp_end = &rsp->node[NUM_RCU_NODES];
480 468
481 /* Only let one CPU complain about others per time interval. */ 469 /* Only let one CPU complain about others per time interval. */
482 470
483 spin_lock_irqsave(&rnp->lock, flags); 471 spin_lock_irqsave(&rnp->lock, flags);
484 delta = jiffies - rsp->jiffies_stall; 472 delta = jiffies - rsp->jiffies_stall;
485 if (delta < RCU_STALL_RAT_DELAY || rsp->gpnum == rsp->completed) { 473 if (delta < RCU_STALL_RAT_DELAY || !rcu_gp_in_progress(rsp)) {
486 spin_unlock_irqrestore(&rnp->lock, flags); 474 spin_unlock_irqrestore(&rnp->lock, flags);
487 return; 475 return;
488 } 476 }
489 rsp->jiffies_stall = jiffies + RCU_SECONDS_TILL_STALL_RECHECK; 477 rsp->jiffies_stall = jiffies + RCU_SECONDS_TILL_STALL_RECHECK;
478
479 /*
480 * Now rat on any tasks that got kicked up to the root rcu_node
481 * due to CPU offlining.
482 */
483 rcu_print_task_stall(rnp);
490 spin_unlock_irqrestore(&rnp->lock, flags); 484 spin_unlock_irqrestore(&rnp->lock, flags);
491 485
492 /* OK, time to rat on our buddy... */ 486 /* OK, time to rat on our buddy... */
493 487
494 printk(KERN_ERR "INFO: RCU detected CPU stalls:"); 488 printk(KERN_ERR "INFO: RCU detected CPU stalls:");
495 for (; rnp_cur < rnp_end; rnp_cur++) { 489 rcu_for_each_leaf_node(rsp, rnp) {
496 rcu_print_task_stall(rnp); 490 rcu_print_task_stall(rnp);
497 if (rnp_cur->qsmask == 0) 491 if (rnp->qsmask == 0)
498 continue; 492 continue;
499 for (cpu = 0; cpu <= rnp_cur->grphi - rnp_cur->grplo; cpu++) 493 for (cpu = 0; cpu <= rnp->grphi - rnp->grplo; cpu++)
500 if (rnp_cur->qsmask & (1UL << cpu)) 494 if (rnp->qsmask & (1UL << cpu))
501 printk(" %d", rnp_cur->grplo + cpu); 495 printk(" %d", rnp->grplo + cpu);
502 } 496 }
503 printk(" (detected by %d, t=%ld jiffies)\n", 497 printk(" (detected by %d, t=%ld jiffies)\n",
504 smp_processor_id(), (long)(jiffies - rsp->gp_start)); 498 smp_processor_id(), (long)(jiffies - rsp->gp_start));
@@ -537,8 +531,7 @@ static void check_cpu_stall(struct rcu_state *rsp, struct rcu_data *rdp)
537 /* We haven't checked in, so go dump stack. */ 531 /* We haven't checked in, so go dump stack. */
538 print_cpu_stall(rsp); 532 print_cpu_stall(rsp);
539 533
540 } else if (rsp->gpnum != rsp->completed && 534 } else if (rcu_gp_in_progress(rsp) && delta >= RCU_STALL_RAT_DELAY) {
541 delta >= RCU_STALL_RAT_DELAY) {
542 535
543 /* They had two time units to dump stack, so complain. */ 536 /* They had two time units to dump stack, so complain. */
544 print_other_cpu_stall(rsp); 537 print_other_cpu_stall(rsp);
@@ -617,9 +610,15 @@ rcu_start_gp(struct rcu_state *rsp, unsigned long flags)
617 note_new_gpnum(rsp, rdp); 610 note_new_gpnum(rsp, rdp);
618 611
619 /* 612 /*
620 * Because we are first, we know that all our callbacks will 613 * Because this CPU just now started the new grace period, we know
621 * be covered by this upcoming grace period, even the ones 614 * that all of its callbacks will be covered by this upcoming grace
622 * that were registered arbitrarily recently. 615 * period, even the ones that were registered arbitrarily recently.
616 * Therefore, advance all outstanding callbacks to RCU_WAIT_TAIL.
617 *
618 * Other CPUs cannot be sure exactly when the grace period started.
619 * Therefore, their recently registered callbacks must pass through
620 * an additional RCU_NEXT_READY stage, so that they will be handled
621 * by the next RCU grace period.
623 */ 622 */
624 rdp->nxttail[RCU_NEXT_READY_TAIL] = rdp->nxttail[RCU_NEXT_TAIL]; 623 rdp->nxttail[RCU_NEXT_READY_TAIL] = rdp->nxttail[RCU_NEXT_TAIL];
625 rdp->nxttail[RCU_WAIT_TAIL] = rdp->nxttail[RCU_NEXT_TAIL]; 624 rdp->nxttail[RCU_WAIT_TAIL] = rdp->nxttail[RCU_NEXT_TAIL];
@@ -657,7 +656,7 @@ rcu_start_gp(struct rcu_state *rsp, unsigned long flags)
657 * one corresponding to this CPU, due to the fact that we have 656 * one corresponding to this CPU, due to the fact that we have
658 * irqs disabled. 657 * irqs disabled.
659 */ 658 */
660 for (rnp = &rsp->node[0]; rnp < &rsp->node[NUM_RCU_NODES]; rnp++) { 659 rcu_for_each_node_breadth_first(rsp, rnp) {
661 spin_lock(&rnp->lock); /* irqs already disabled. */ 660 spin_lock(&rnp->lock); /* irqs already disabled. */
662 rcu_preempt_check_blocked_tasks(rnp); 661 rcu_preempt_check_blocked_tasks(rnp);
663 rnp->qsmask = rnp->qsmaskinit; 662 rnp->qsmask = rnp->qsmaskinit;
@@ -703,9 +702,9 @@ rcu_process_gp_end(struct rcu_state *rsp, struct rcu_data *rdp)
703 * hold rnp->lock, as required by rcu_start_gp(), which will release it. 702 * hold rnp->lock, as required by rcu_start_gp(), which will release it.
704 */ 703 */
705static void cpu_quiet_msk_finish(struct rcu_state *rsp, unsigned long flags) 704static void cpu_quiet_msk_finish(struct rcu_state *rsp, unsigned long flags)
706 __releases(rnp->lock) 705 __releases(rcu_get_root(rsp)->lock)
707{ 706{
708 WARN_ON_ONCE(rsp->completed == rsp->gpnum); 707 WARN_ON_ONCE(!rcu_gp_in_progress(rsp));
709 rsp->completed = rsp->gpnum; 708 rsp->completed = rsp->gpnum;
710 rcu_process_gp_end(rsp, rsp->rda[smp_processor_id()]); 709 rcu_process_gp_end(rsp, rsp->rda[smp_processor_id()]);
711 rcu_start_gp(rsp, flags); /* releases root node's rnp->lock. */ 710 rcu_start_gp(rsp, flags); /* releases root node's rnp->lock. */
@@ -842,17 +841,63 @@ rcu_check_quiescent_state(struct rcu_state *rsp, struct rcu_data *rdp)
842#ifdef CONFIG_HOTPLUG_CPU 841#ifdef CONFIG_HOTPLUG_CPU
843 842
844/* 843/*
844 * Move a dying CPU's RCU callbacks to the ->orphan_cbs_list for the
845 * specified flavor of RCU. The callbacks will be adopted by the next
846 * _rcu_barrier() invocation or by the CPU_DEAD notifier, whichever
847 * comes first. Because this is invoked from the CPU_DYING notifier,
848 * irqs are already disabled.
849 */
850static void rcu_send_cbs_to_orphanage(struct rcu_state *rsp)
851{
852 int i;
853 struct rcu_data *rdp = rsp->rda[smp_processor_id()];
854
855 if (rdp->nxtlist == NULL)
856 return; /* irqs disabled, so comparison is stable. */
857 spin_lock(&rsp->onofflock); /* irqs already disabled. */
858 *rsp->orphan_cbs_tail = rdp->nxtlist;
859 rsp->orphan_cbs_tail = rdp->nxttail[RCU_NEXT_TAIL];
860 rdp->nxtlist = NULL;
861 for (i = 0; i < RCU_NEXT_SIZE; i++)
862 rdp->nxttail[i] = &rdp->nxtlist;
863 rsp->orphan_qlen += rdp->qlen;
864 rdp->qlen = 0;
865 spin_unlock(&rsp->onofflock); /* irqs remain disabled. */
866}
867
868/*
869 * Adopt previously orphaned RCU callbacks.
870 */
871static void rcu_adopt_orphan_cbs(struct rcu_state *rsp)
872{
873 unsigned long flags;
874 struct rcu_data *rdp;
875
876 spin_lock_irqsave(&rsp->onofflock, flags);
877 rdp = rsp->rda[smp_processor_id()];
878 if (rsp->orphan_cbs_list == NULL) {
879 spin_unlock_irqrestore(&rsp->onofflock, flags);
880 return;
881 }
882 *rdp->nxttail[RCU_NEXT_TAIL] = rsp->orphan_cbs_list;
883 rdp->nxttail[RCU_NEXT_TAIL] = rsp->orphan_cbs_tail;
884 rdp->qlen += rsp->orphan_qlen;
885 rsp->orphan_cbs_list = NULL;
886 rsp->orphan_cbs_tail = &rsp->orphan_cbs_list;
887 rsp->orphan_qlen = 0;
888 spin_unlock_irqrestore(&rsp->onofflock, flags);
889}
890
891/*
845 * Remove the outgoing CPU from the bitmasks in the rcu_node hierarchy 892 * Remove the outgoing CPU from the bitmasks in the rcu_node hierarchy
846 * and move all callbacks from the outgoing CPU to the current one. 893 * and move all callbacks from the outgoing CPU to the current one.
847 */ 894 */
848static void __rcu_offline_cpu(int cpu, struct rcu_state *rsp) 895static void __rcu_offline_cpu(int cpu, struct rcu_state *rsp)
849{ 896{
850 int i;
851 unsigned long flags; 897 unsigned long flags;
852 long lastcomp; 898 long lastcomp;
853 unsigned long mask; 899 unsigned long mask;
854 struct rcu_data *rdp = rsp->rda[cpu]; 900 struct rcu_data *rdp = rsp->rda[cpu];
855 struct rcu_data *rdp_me;
856 struct rcu_node *rnp; 901 struct rcu_node *rnp;
857 902
858 /* Exclude any attempts to start a new grace period. */ 903 /* Exclude any attempts to start a new grace period. */
@@ -875,32 +920,9 @@ static void __rcu_offline_cpu(int cpu, struct rcu_state *rsp)
875 } while (rnp != NULL); 920 } while (rnp != NULL);
876 lastcomp = rsp->completed; 921 lastcomp = rsp->completed;
877 922
878 spin_unlock(&rsp->onofflock); /* irqs remain disabled. */ 923 spin_unlock_irqrestore(&rsp->onofflock, flags);
879 924
880 /* 925 rcu_adopt_orphan_cbs(rsp);
881 * Move callbacks from the outgoing CPU to the running CPU.
882 * Note that the outgoing CPU is now quiscent, so it is now
883 * (uncharacteristically) safe to access its rcu_data structure.
884 * Note also that we must carefully retain the order of the
885 * outgoing CPU's callbacks in order for rcu_barrier() to work
886 * correctly. Finally, note that we start all the callbacks
887 * afresh, even those that have passed through a grace period
888 * and are therefore ready to invoke. The theory is that hotplug
889 * events are rare, and that if they are frequent enough to
890 * indefinitely delay callbacks, you have far worse things to
891 * be worrying about.
892 */
893 rdp_me = rsp->rda[smp_processor_id()];
894 if (rdp->nxtlist != NULL) {
895 *rdp_me->nxttail[RCU_NEXT_TAIL] = rdp->nxtlist;
896 rdp_me->nxttail[RCU_NEXT_TAIL] = rdp->nxttail[RCU_NEXT_TAIL];
897 rdp->nxtlist = NULL;
898 for (i = 0; i < RCU_NEXT_SIZE; i++)
899 rdp->nxttail[i] = &rdp->nxtlist;
900 rdp_me->qlen += rdp->qlen;
901 rdp->qlen = 0;
902 }
903 local_irq_restore(flags);
904} 926}
905 927
906/* 928/*
@@ -918,6 +940,14 @@ static void rcu_offline_cpu(int cpu)
918 940
919#else /* #ifdef CONFIG_HOTPLUG_CPU */ 941#else /* #ifdef CONFIG_HOTPLUG_CPU */
920 942
943static void rcu_send_cbs_to_orphanage(struct rcu_state *rsp)
944{
945}
946
947static void rcu_adopt_orphan_cbs(struct rcu_state *rsp)
948{
949}
950
921static void rcu_offline_cpu(int cpu) 951static void rcu_offline_cpu(int cpu)
922{ 952{
923} 953}
@@ -1050,33 +1080,32 @@ static int rcu_process_dyntick(struct rcu_state *rsp, long lastcomp,
1050 int cpu; 1080 int cpu;
1051 unsigned long flags; 1081 unsigned long flags;
1052 unsigned long mask; 1082 unsigned long mask;
1053 struct rcu_node *rnp_cur = rsp->level[NUM_RCU_LVLS - 1]; 1083 struct rcu_node *rnp;
1054 struct rcu_node *rnp_end = &rsp->node[NUM_RCU_NODES];
1055 1084
1056 for (; rnp_cur < rnp_end; rnp_cur++) { 1085 rcu_for_each_leaf_node(rsp, rnp) {
1057 mask = 0; 1086 mask = 0;
1058 spin_lock_irqsave(&rnp_cur->lock, flags); 1087 spin_lock_irqsave(&rnp->lock, flags);
1059 if (rsp->completed != lastcomp) { 1088 if (rsp->completed != lastcomp) {
1060 spin_unlock_irqrestore(&rnp_cur->lock, flags); 1089 spin_unlock_irqrestore(&rnp->lock, flags);
1061 return 1; 1090 return 1;
1062 } 1091 }
1063 if (rnp_cur->qsmask == 0) { 1092 if (rnp->qsmask == 0) {
1064 spin_unlock_irqrestore(&rnp_cur->lock, flags); 1093 spin_unlock_irqrestore(&rnp->lock, flags);
1065 continue; 1094 continue;
1066 } 1095 }
1067 cpu = rnp_cur->grplo; 1096 cpu = rnp->grplo;
1068 bit = 1; 1097 bit = 1;
1069 for (; cpu <= rnp_cur->grphi; cpu++, bit <<= 1) { 1098 for (; cpu <= rnp->grphi; cpu++, bit <<= 1) {
1070 if ((rnp_cur->qsmask & bit) != 0 && f(rsp->rda[cpu])) 1099 if ((rnp->qsmask & bit) != 0 && f(rsp->rda[cpu]))
1071 mask |= bit; 1100 mask |= bit;
1072 } 1101 }
1073 if (mask != 0 && rsp->completed == lastcomp) { 1102 if (mask != 0 && rsp->completed == lastcomp) {
1074 1103
1075 /* cpu_quiet_msk() releases rnp_cur->lock. */ 1104 /* cpu_quiet_msk() releases rnp->lock. */
1076 cpu_quiet_msk(mask, rsp, rnp_cur, flags); 1105 cpu_quiet_msk(mask, rsp, rnp, flags);
1077 continue; 1106 continue;
1078 } 1107 }
1079 spin_unlock_irqrestore(&rnp_cur->lock, flags); 1108 spin_unlock_irqrestore(&rnp->lock, flags);
1080 } 1109 }
1081 return 0; 1110 return 0;
1082} 1111}
@@ -1092,7 +1121,7 @@ static void force_quiescent_state(struct rcu_state *rsp, int relaxed)
1092 struct rcu_node *rnp = rcu_get_root(rsp); 1121 struct rcu_node *rnp = rcu_get_root(rsp);
1093 u8 signaled; 1122 u8 signaled;
1094 1123
1095 if (ACCESS_ONCE(rsp->completed) == ACCESS_ONCE(rsp->gpnum)) 1124 if (!rcu_gp_in_progress(rsp))
1096 return; /* No grace period in progress, nothing to force. */ 1125 return; /* No grace period in progress, nothing to force. */
1097 if (!spin_trylock_irqsave(&rsp->fqslock, flags)) { 1126 if (!spin_trylock_irqsave(&rsp->fqslock, flags)) {
1098 rsp->n_force_qs_lh++; /* Inexact, can lose counts. Tough! */ 1127 rsp->n_force_qs_lh++; /* Inexact, can lose counts. Tough! */
@@ -1251,7 +1280,7 @@ __call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu),
1251 rdp->nxttail[RCU_NEXT_TAIL] = &head->next; 1280 rdp->nxttail[RCU_NEXT_TAIL] = &head->next;
1252 1281
1253 /* Start a new grace period if one not already started. */ 1282 /* Start a new grace period if one not already started. */
1254 if (ACCESS_ONCE(rsp->completed) == ACCESS_ONCE(rsp->gpnum)) { 1283 if (!rcu_gp_in_progress(rsp)) {
1255 unsigned long nestflag; 1284 unsigned long nestflag;
1256 struct rcu_node *rnp_root = rcu_get_root(rsp); 1285 struct rcu_node *rnp_root = rcu_get_root(rsp);
1257 1286
@@ -1331,7 +1360,7 @@ static int __rcu_pending(struct rcu_state *rsp, struct rcu_data *rdp)
1331 } 1360 }
1332 1361
1333 /* Has an RCU GP gone long enough to send resched IPIs &c? */ 1362 /* Has an RCU GP gone long enough to send resched IPIs &c? */
1334 if (ACCESS_ONCE(rsp->completed) != ACCESS_ONCE(rsp->gpnum) && 1363 if (rcu_gp_in_progress(rsp) &&
1335 ((long)(ACCESS_ONCE(rsp->jiffies_force_qs) - jiffies) < 0)) { 1364 ((long)(ACCESS_ONCE(rsp->jiffies_force_qs) - jiffies) < 0)) {
1336 rdp->n_rp_need_fqs++; 1365 rdp->n_rp_need_fqs++;
1337 return 1; 1366 return 1;
@@ -1368,6 +1397,82 @@ int rcu_needs_cpu(int cpu)
1368 rcu_preempt_needs_cpu(cpu); 1397 rcu_preempt_needs_cpu(cpu);
1369} 1398}
1370 1399
1400static DEFINE_PER_CPU(struct rcu_head, rcu_barrier_head) = {NULL};
1401static atomic_t rcu_barrier_cpu_count;
1402static DEFINE_MUTEX(rcu_barrier_mutex);
1403static struct completion rcu_barrier_completion;
1404
1405static void rcu_barrier_callback(struct rcu_head *notused)
1406{
1407 if (atomic_dec_and_test(&rcu_barrier_cpu_count))
1408 complete(&rcu_barrier_completion);
1409}
1410
1411/*
1412 * Called with preemption disabled, and from cross-cpu IRQ context.
1413 */
1414static void rcu_barrier_func(void *type)
1415{
1416 int cpu = smp_processor_id();
1417 struct rcu_head *head = &per_cpu(rcu_barrier_head, cpu);
1418 void (*call_rcu_func)(struct rcu_head *head,
1419 void (*func)(struct rcu_head *head));
1420
1421 atomic_inc(&rcu_barrier_cpu_count);
1422 call_rcu_func = type;
1423 call_rcu_func(head, rcu_barrier_callback);
1424}
1425
1426/*
1427 * Orchestrate the specified type of RCU barrier, waiting for all
1428 * RCU callbacks of the specified type to complete.
1429 */
1430static void _rcu_barrier(struct rcu_state *rsp,
1431 void (*call_rcu_func)(struct rcu_head *head,
1432 void (*func)(struct rcu_head *head)))
1433{
1434 BUG_ON(in_interrupt());
1435 /* Take mutex to serialize concurrent rcu_barrier() requests. */
1436 mutex_lock(&rcu_barrier_mutex);
1437 init_completion(&rcu_barrier_completion);
1438 /*
1439 * Initialize rcu_barrier_cpu_count to 1, then invoke
1440 * rcu_barrier_func() on each CPU, so that each CPU also has
1441 * incremented rcu_barrier_cpu_count. Only then is it safe to
1442 * decrement rcu_barrier_cpu_count -- otherwise the first CPU
1443 * might complete its grace period before all of the other CPUs
1444 * did their increment, causing this function to return too
1445 * early.
1446 */
1447 atomic_set(&rcu_barrier_cpu_count, 1);
1448 preempt_disable(); /* stop CPU_DYING from filling orphan_cbs_list */
1449 rcu_adopt_orphan_cbs(rsp);
1450 on_each_cpu(rcu_barrier_func, (void *)call_rcu_func, 1);
1451 preempt_enable(); /* CPU_DYING can again fill orphan_cbs_list */
1452 if (atomic_dec_and_test(&rcu_barrier_cpu_count))
1453 complete(&rcu_barrier_completion);
1454 wait_for_completion(&rcu_barrier_completion);
1455 mutex_unlock(&rcu_barrier_mutex);
1456}
1457
1458/**
1459 * rcu_barrier_bh - Wait until all in-flight call_rcu_bh() callbacks complete.
1460 */
1461void rcu_barrier_bh(void)
1462{
1463 _rcu_barrier(&rcu_bh_state, call_rcu_bh);
1464}
1465EXPORT_SYMBOL_GPL(rcu_barrier_bh);
1466
1467/**
1468 * rcu_barrier_sched - Wait for in-flight call_rcu_sched() callbacks.
1469 */
1470void rcu_barrier_sched(void)
1471{
1472 _rcu_barrier(&rcu_sched_state, call_rcu_sched);
1473}
1474EXPORT_SYMBOL_GPL(rcu_barrier_sched);
1475
1371/* 1476/*
1372 * Do boot-time initialization of a CPU's per-CPU RCU data. 1477 * Do boot-time initialization of a CPU's per-CPU RCU data.
1373 */ 1478 */
@@ -1464,6 +1569,22 @@ int __cpuinit rcu_cpu_notify(struct notifier_block *self,
1464 case CPU_UP_PREPARE_FROZEN: 1569 case CPU_UP_PREPARE_FROZEN:
1465 rcu_online_cpu(cpu); 1570 rcu_online_cpu(cpu);
1466 break; 1571 break;
1572 case CPU_DYING:
1573 case CPU_DYING_FROZEN:
1574 /*
1575 * preempt_disable() in _rcu_barrier() prevents stop_machine(),
1576 * so when "on_each_cpu(rcu_barrier_func, (void *)type, 1);"
1577 * returns, all online cpus have queued rcu_barrier_func().
1578 * The dying CPU clears its cpu_online_mask bit and
1579 * moves all of its RCU callbacks to ->orphan_cbs_list
1580 * in the context of stop_machine(), so subsequent calls
1581 * to _rcu_barrier() will adopt these callbacks and only
1582 * then queue rcu_barrier_func() on all remaining CPUs.
1583 */
1584 rcu_send_cbs_to_orphanage(&rcu_bh_state);
1585 rcu_send_cbs_to_orphanage(&rcu_sched_state);
1586 rcu_preempt_send_cbs_to_orphanage();
1587 break;
1467 case CPU_DEAD: 1588 case CPU_DEAD:
1468 case CPU_DEAD_FROZEN: 1589 case CPU_DEAD_FROZEN:
1469 case CPU_UP_CANCELED: 1590 case CPU_UP_CANCELED:
@@ -1526,7 +1647,8 @@ static void __init rcu_init_one(struct rcu_state *rsp)
1526 cpustride *= rsp->levelspread[i]; 1647 cpustride *= rsp->levelspread[i];
1527 rnp = rsp->level[i]; 1648 rnp = rsp->level[i];
1528 for (j = 0; j < rsp->levelcnt[i]; j++, rnp++) { 1649 for (j = 0; j < rsp->levelcnt[i]; j++, rnp++) {
1529 spin_lock_init(&rnp->lock); 1650 if (rnp != rcu_get_root(rsp))
1651 spin_lock_init(&rnp->lock);
1530 rnp->gpnum = 0; 1652 rnp->gpnum = 0;
1531 rnp->qsmask = 0; 1653 rnp->qsmask = 0;
1532 rnp->qsmaskinit = 0; 1654 rnp->qsmaskinit = 0;
@@ -1549,6 +1671,7 @@ static void __init rcu_init_one(struct rcu_state *rsp)
1549 INIT_LIST_HEAD(&rnp->blocked_tasks[1]); 1671 INIT_LIST_HEAD(&rnp->blocked_tasks[1]);
1550 } 1672 }
1551 } 1673 }
1674 spin_lock_init(&rcu_get_root(rsp)->lock);
1552} 1675}
1553 1676
1554/* 1677/*
@@ -1558,6 +1681,10 @@ static void __init rcu_init_one(struct rcu_state *rsp)
1558 */ 1681 */
1559#define RCU_INIT_FLAVOR(rsp, rcu_data) \ 1682#define RCU_INIT_FLAVOR(rsp, rcu_data) \
1560do { \ 1683do { \
1684 int i; \
1685 int j; \
1686 struct rcu_node *rnp; \
1687 \
1561 rcu_init_one(rsp); \ 1688 rcu_init_one(rsp); \
1562 rnp = (rsp)->level[NUM_RCU_LVLS - 1]; \ 1689 rnp = (rsp)->level[NUM_RCU_LVLS - 1]; \
1563 j = 0; \ 1690 j = 0; \
@@ -1570,31 +1697,8 @@ do { \
1570 } \ 1697 } \
1571} while (0) 1698} while (0)
1572 1699
1573#ifdef CONFIG_TREE_PREEMPT_RCU
1574
1575void __init __rcu_init_preempt(void)
1576{
1577 int i; /* All used by RCU_INIT_FLAVOR(). */
1578 int j;
1579 struct rcu_node *rnp;
1580
1581 RCU_INIT_FLAVOR(&rcu_preempt_state, rcu_preempt_data);
1582}
1583
1584#else /* #ifdef CONFIG_TREE_PREEMPT_RCU */
1585
1586void __init __rcu_init_preempt(void)
1587{
1588}
1589
1590#endif /* #else #ifdef CONFIG_TREE_PREEMPT_RCU */
1591
1592void __init __rcu_init(void) 1700void __init __rcu_init(void)
1593{ 1701{
1594 int i; /* All used by RCU_INIT_FLAVOR(). */
1595 int j;
1596 struct rcu_node *rnp;
1597
1598 rcu_bootup_announce(); 1702 rcu_bootup_announce();
1599#ifdef CONFIG_RCU_CPU_STALL_DETECTOR 1703#ifdef CONFIG_RCU_CPU_STALL_DETECTOR
1600 printk(KERN_INFO "RCU-based detection of stalled CPUs is enabled.\n"); 1704 printk(KERN_INFO "RCU-based detection of stalled CPUs is enabled.\n");
@@ -1605,6 +1709,4 @@ void __init __rcu_init(void)
1605 open_softirq(RCU_SOFTIRQ, rcu_process_callbacks); 1709 open_softirq(RCU_SOFTIRQ, rcu_process_callbacks);
1606} 1710}
1607 1711
1608module_param(blimit, int, 0); 1712#include "rcutree_plugin.h"
1609module_param(qhimark, int, 0);
1610module_param(qlowmark, int, 0);
diff --git a/kernel/rcutree.h b/kernel/rcutree.h
index 8e8287a983c2..b40ac5706040 100644
--- a/kernel/rcutree.h
+++ b/kernel/rcutree.h
@@ -48,14 +48,14 @@
48#elif NR_CPUS <= RCU_FANOUT_SQ 48#elif NR_CPUS <= RCU_FANOUT_SQ
49# define NUM_RCU_LVLS 2 49# define NUM_RCU_LVLS 2
50# define NUM_RCU_LVL_0 1 50# define NUM_RCU_LVL_0 1
51# define NUM_RCU_LVL_1 (((NR_CPUS) + RCU_FANOUT - 1) / RCU_FANOUT) 51# define NUM_RCU_LVL_1 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT)
52# define NUM_RCU_LVL_2 (NR_CPUS) 52# define NUM_RCU_LVL_2 (NR_CPUS)
53# define NUM_RCU_LVL_3 0 53# define NUM_RCU_LVL_3 0
54#elif NR_CPUS <= RCU_FANOUT_CUBE 54#elif NR_CPUS <= RCU_FANOUT_CUBE
55# define NUM_RCU_LVLS 3 55# define NUM_RCU_LVLS 3
56# define NUM_RCU_LVL_0 1 56# define NUM_RCU_LVL_0 1
57# define NUM_RCU_LVL_1 (((NR_CPUS) + RCU_FANOUT_SQ - 1) / RCU_FANOUT_SQ) 57# define NUM_RCU_LVL_1 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_SQ)
58# define NUM_RCU_LVL_2 (((NR_CPUS) + (RCU_FANOUT) - 1) / (RCU_FANOUT)) 58# define NUM_RCU_LVL_2 DIV_ROUND_UP(NR_CPUS, RCU_FANOUT)
59# define NUM_RCU_LVL_3 NR_CPUS 59# define NUM_RCU_LVL_3 NR_CPUS
60#else 60#else
61# error "CONFIG_RCU_FANOUT insufficient for NR_CPUS" 61# error "CONFIG_RCU_FANOUT insufficient for NR_CPUS"
@@ -79,15 +79,21 @@ struct rcu_dynticks {
79 * Definition for node within the RCU grace-period-detection hierarchy. 79 * Definition for node within the RCU grace-period-detection hierarchy.
80 */ 80 */
81struct rcu_node { 81struct rcu_node {
82 spinlock_t lock; 82 spinlock_t lock; /* Root rcu_node's lock protects some */
83 /* rcu_state fields as well as following. */
83 long gpnum; /* Current grace period for this node. */ 84 long gpnum; /* Current grace period for this node. */
84 /* This will either be equal to or one */ 85 /* This will either be equal to or one */
85 /* behind the root rcu_node's gpnum. */ 86 /* behind the root rcu_node's gpnum. */
86 unsigned long qsmask; /* CPUs or groups that need to switch in */ 87 unsigned long qsmask; /* CPUs or groups that need to switch in */
87 /* order for current grace period to proceed.*/ 88 /* order for current grace period to proceed.*/
89 /* In leaf rcu_node, each bit corresponds to */
90 /* an rcu_data structure, otherwise, each */
91 /* bit corresponds to a child rcu_node */
92 /* structure. */
88 unsigned long qsmaskinit; 93 unsigned long qsmaskinit;
89 /* Per-GP initialization for qsmask. */ 94 /* Per-GP initialization for qsmask. */
90 unsigned long grpmask; /* Mask to apply to parent qsmask. */ 95 unsigned long grpmask; /* Mask to apply to parent qsmask. */
96 /* Only one bit will be set in this mask. */
91 int grplo; /* lowest-numbered CPU or group here. */ 97 int grplo; /* lowest-numbered CPU or group here. */
92 int grphi; /* highest-numbered CPU or group here. */ 98 int grphi; /* highest-numbered CPU or group here. */
93 u8 grpnum; /* CPU/group number for next level up. */ 99 u8 grpnum; /* CPU/group number for next level up. */
@@ -95,8 +101,23 @@ struct rcu_node {
95 struct rcu_node *parent; 101 struct rcu_node *parent;
96 struct list_head blocked_tasks[2]; 102 struct list_head blocked_tasks[2];
97 /* Tasks blocked in RCU read-side critsect. */ 103 /* Tasks blocked in RCU read-side critsect. */
104 /* Grace period number (->gpnum) x blocked */
105 /* by tasks on the (x & 0x1) element of the */
106 /* blocked_tasks[] array. */
98} ____cacheline_internodealigned_in_smp; 107} ____cacheline_internodealigned_in_smp;
99 108
109/*
110 * Do a full breadth-first scan of the rcu_node structures for the
111 * specified rcu_state structure.
112 */
113#define rcu_for_each_node_breadth_first(rsp, rnp) \
114 for ((rnp) = &(rsp)->node[0]; \
115 (rnp) < &(rsp)->node[NUM_RCU_NODES]; (rnp)++)
116
117#define rcu_for_each_leaf_node(rsp, rnp) \
118 for ((rnp) = (rsp)->level[NUM_RCU_LVLS - 1]; \
119 (rnp) < &(rsp)->node[NUM_RCU_NODES]; (rnp)++)
120
100/* Index values for nxttail array in struct rcu_data. */ 121/* Index values for nxttail array in struct rcu_data. */
101#define RCU_DONE_TAIL 0 /* Also RCU_WAIT head. */ 122#define RCU_DONE_TAIL 0 /* Also RCU_WAIT head. */
102#define RCU_WAIT_TAIL 1 /* Also RCU_NEXT_READY head. */ 123#define RCU_WAIT_TAIL 1 /* Also RCU_NEXT_READY head. */
@@ -126,19 +147,22 @@ struct rcu_data {
126 * Any of the partitions might be empty, in which case the 147 * Any of the partitions might be empty, in which case the
127 * pointer to that partition will be equal to the pointer for 148 * pointer to that partition will be equal to the pointer for
128 * the following partition. When the list is empty, all of 149 * the following partition. When the list is empty, all of
129 * the nxttail elements point to nxtlist, which is NULL. 150 * the nxttail elements point to the ->nxtlist pointer itself,
151 * which in that case is NULL.
130 * 152 *
131 * [*nxttail[RCU_NEXT_READY_TAIL], NULL = *nxttail[RCU_NEXT_TAIL]):
132 * Entries that might have arrived after current GP ended
133 * [*nxttail[RCU_WAIT_TAIL], *nxttail[RCU_NEXT_READY_TAIL]):
134 * Entries known to have arrived before current GP ended
135 * [*nxttail[RCU_DONE_TAIL], *nxttail[RCU_WAIT_TAIL]):
136 * Entries that batch # <= ->completed - 1: waiting for current GP
137 * [nxtlist, *nxttail[RCU_DONE_TAIL]): 153 * [nxtlist, *nxttail[RCU_DONE_TAIL]):
138 * Entries that batch # <= ->completed 154 * Entries that batch # <= ->completed
139 * The grace period for these entries has completed, and 155 * The grace period for these entries has completed, and
140 * the other grace-period-completed entries may be moved 156 * the other grace-period-completed entries may be moved
141 * here temporarily in rcu_process_callbacks(). 157 * here temporarily in rcu_process_callbacks().
158 * [*nxttail[RCU_DONE_TAIL], *nxttail[RCU_WAIT_TAIL]):
159 * Entries that batch # <= ->completed - 1: waiting for current GP
160 * [*nxttail[RCU_WAIT_TAIL], *nxttail[RCU_NEXT_READY_TAIL]):
161 * Entries known to have arrived before current GP ended
162 * [*nxttail[RCU_NEXT_READY_TAIL], *nxttail[RCU_NEXT_TAIL]):
163 * Entries that might have arrived after current GP ended
164 * Note that the value of *nxttail[RCU_NEXT_TAIL] will
165 * always be NULL, as this is the end of the list.
142 */ 166 */
143 struct rcu_head *nxtlist; 167 struct rcu_head *nxtlist;
144 struct rcu_head **nxttail[RCU_NEXT_SIZE]; 168 struct rcu_head **nxttail[RCU_NEXT_SIZE];
@@ -216,8 +240,19 @@ struct rcu_state {
216 /* Force QS state. */ 240 /* Force QS state. */
217 long gpnum; /* Current gp number. */ 241 long gpnum; /* Current gp number. */
218 long completed; /* # of last completed gp. */ 242 long completed; /* # of last completed gp. */
243
244 /* End of fields guarded by root rcu_node's lock. */
245
219 spinlock_t onofflock; /* exclude on/offline and */ 246 spinlock_t onofflock; /* exclude on/offline and */
220 /* starting new GP. */ 247 /* starting new GP. Also */
248 /* protects the following */
249 /* orphan_cbs fields. */
250 struct rcu_head *orphan_cbs_list; /* list of rcu_head structs */
251 /* orphaned by all CPUs in */
252 /* a given leaf rcu_node */
253 /* going offline. */
254 struct rcu_head **orphan_cbs_tail; /* And tail pointer. */
255 long orphan_qlen; /* Number of orphaned cbs. */
221 spinlock_t fqslock; /* Only one task forcing */ 256 spinlock_t fqslock; /* Only one task forcing */
222 /* quiescent states. */ 257 /* quiescent states. */
223 unsigned long jiffies_force_qs; /* Time at which to invoke */ 258 unsigned long jiffies_force_qs; /* Time at which to invoke */
@@ -255,5 +290,30 @@ extern struct rcu_state rcu_preempt_state;
255DECLARE_PER_CPU(struct rcu_data, rcu_preempt_data); 290DECLARE_PER_CPU(struct rcu_data, rcu_preempt_data);
256#endif /* #ifdef CONFIG_TREE_PREEMPT_RCU */ 291#endif /* #ifdef CONFIG_TREE_PREEMPT_RCU */
257 292
258#endif /* #ifdef RCU_TREE_NONCORE */ 293#else /* #ifdef RCU_TREE_NONCORE */
294
295/* Forward declarations for rcutree_plugin.h */
296static inline void rcu_bootup_announce(void);
297long rcu_batches_completed(void);
298static void rcu_preempt_note_context_switch(int cpu);
299static int rcu_preempted_readers(struct rcu_node *rnp);
300#ifdef CONFIG_RCU_CPU_STALL_DETECTOR
301static void rcu_print_task_stall(struct rcu_node *rnp);
302#endif /* #ifdef CONFIG_RCU_CPU_STALL_DETECTOR */
303static void rcu_preempt_check_blocked_tasks(struct rcu_node *rnp);
304#ifdef CONFIG_HOTPLUG_CPU
305static void rcu_preempt_offline_tasks(struct rcu_state *rsp,
306 struct rcu_node *rnp,
307 struct rcu_data *rdp);
308static void rcu_preempt_offline_cpu(int cpu);
309#endif /* #ifdef CONFIG_HOTPLUG_CPU */
310static void rcu_preempt_check_callbacks(int cpu);
311static void rcu_preempt_process_callbacks(void);
312void call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu));
313static int rcu_preempt_pending(int cpu);
314static int rcu_preempt_needs_cpu(int cpu);
315static void __cpuinit rcu_preempt_init_percpu_data(int cpu);
316static void rcu_preempt_send_cbs_to_orphanage(void);
317static void __init __rcu_init_preempt(void);
259 318
319#endif /* #else #ifdef RCU_TREE_NONCORE */
diff --git a/kernel/rcutree_plugin.h b/kernel/rcutree_plugin.h
index 1cee04f627eb..c0cb783aa16a 100644
--- a/kernel/rcutree_plugin.h
+++ b/kernel/rcutree_plugin.h
@@ -150,6 +150,16 @@ void __rcu_read_lock(void)
150} 150}
151EXPORT_SYMBOL_GPL(__rcu_read_lock); 151EXPORT_SYMBOL_GPL(__rcu_read_lock);
152 152
153/*
154 * Check for preempted RCU readers blocking the current grace period
155 * for the specified rcu_node structure. If the caller needs a reliable
156 * answer, it must hold the rcu_node's ->lock.
157 */
158static int rcu_preempted_readers(struct rcu_node *rnp)
159{
160 return !list_empty(&rnp->blocked_tasks[rnp->gpnum & 0x1]);
161}
162
153static void rcu_read_unlock_special(struct task_struct *t) 163static void rcu_read_unlock_special(struct task_struct *t)
154{ 164{
155 int empty; 165 int empty;
@@ -196,7 +206,7 @@ static void rcu_read_unlock_special(struct task_struct *t)
196 break; 206 break;
197 spin_unlock(&rnp->lock); /* irqs remain disabled. */ 207 spin_unlock(&rnp->lock); /* irqs remain disabled. */
198 } 208 }
199 empty = list_empty(&rnp->blocked_tasks[rnp->gpnum & 0x1]); 209 empty = !rcu_preempted_readers(rnp);
200 list_del_init(&t->rcu_node_entry); 210 list_del_init(&t->rcu_node_entry);
201 t->rcu_blocked_node = NULL; 211 t->rcu_blocked_node = NULL;
202 212
@@ -207,7 +217,7 @@ static void rcu_read_unlock_special(struct task_struct *t)
207 * drop rnp->lock and restore irq. 217 * drop rnp->lock and restore irq.
208 */ 218 */
209 if (!empty && rnp->qsmask == 0 && 219 if (!empty && rnp->qsmask == 0 &&
210 list_empty(&rnp->blocked_tasks[rnp->gpnum & 0x1])) { 220 !rcu_preempted_readers(rnp)) {
211 struct rcu_node *rnp_p; 221 struct rcu_node *rnp_p;
212 222
213 if (rnp->parent == NULL) { 223 if (rnp->parent == NULL) {
@@ -257,12 +267,12 @@ static void rcu_print_task_stall(struct rcu_node *rnp)
257{ 267{
258 unsigned long flags; 268 unsigned long flags;
259 struct list_head *lp; 269 struct list_head *lp;
260 int phase = rnp->gpnum & 0x1; 270 int phase;
261 struct task_struct *t; 271 struct task_struct *t;
262 272
263 if (!list_empty(&rnp->blocked_tasks[phase])) { 273 if (rcu_preempted_readers(rnp)) {
264 spin_lock_irqsave(&rnp->lock, flags); 274 spin_lock_irqsave(&rnp->lock, flags);
265 phase = rnp->gpnum & 0x1; /* re-read under lock. */ 275 phase = rnp->gpnum & 0x1;
266 lp = &rnp->blocked_tasks[phase]; 276 lp = &rnp->blocked_tasks[phase];
267 list_for_each_entry(t, lp, rcu_node_entry) 277 list_for_each_entry(t, lp, rcu_node_entry)
268 printk(" P%d", t->pid); 278 printk(" P%d", t->pid);
@@ -281,20 +291,10 @@ static void rcu_print_task_stall(struct rcu_node *rnp)
281 */ 291 */
282static void rcu_preempt_check_blocked_tasks(struct rcu_node *rnp) 292static void rcu_preempt_check_blocked_tasks(struct rcu_node *rnp)
283{ 293{
284 WARN_ON_ONCE(!list_empty(&rnp->blocked_tasks[rnp->gpnum & 0x1])); 294 WARN_ON_ONCE(rcu_preempted_readers(rnp));
285 WARN_ON_ONCE(rnp->qsmask); 295 WARN_ON_ONCE(rnp->qsmask);
286} 296}
287 297
288/*
289 * Check for preempted RCU readers for the specified rcu_node structure.
290 * If the caller needs a reliable answer, it must hold the rcu_node's
291 * >lock.
292 */
293static int rcu_preempted_readers(struct rcu_node *rnp)
294{
295 return !list_empty(&rnp->blocked_tasks[rnp->gpnum & 0x1]);
296}
297
298#ifdef CONFIG_HOTPLUG_CPU 298#ifdef CONFIG_HOTPLUG_CPU
299 299
300/* 300/*
@@ -410,6 +410,15 @@ static int rcu_preempt_needs_cpu(int cpu)
410 return !!per_cpu(rcu_preempt_data, cpu).nxtlist; 410 return !!per_cpu(rcu_preempt_data, cpu).nxtlist;
411} 411}
412 412
413/**
414 * rcu_barrier - Wait until all in-flight call_rcu() callbacks complete.
415 */
416void rcu_barrier(void)
417{
418 _rcu_barrier(&rcu_preempt_state, call_rcu);
419}
420EXPORT_SYMBOL_GPL(rcu_barrier);
421
413/* 422/*
414 * Initialize preemptable RCU's per-CPU data. 423 * Initialize preemptable RCU's per-CPU data.
415 */ 424 */
@@ -419,6 +428,22 @@ static void __cpuinit rcu_preempt_init_percpu_data(int cpu)
419} 428}
420 429
421/* 430/*
431 * Move preemptable RCU's callbacks to ->orphan_cbs_list.
432 */
433static void rcu_preempt_send_cbs_to_orphanage(void)
434{
435 rcu_send_cbs_to_orphanage(&rcu_preempt_state);
436}
437
438/*
439 * Initialize preemptable RCU's state structures.
440 */
441static void __init __rcu_init_preempt(void)
442{
443 RCU_INIT_FLAVOR(&rcu_preempt_state, rcu_preempt_data);
444}
445
446/*
422 * Check for a task exiting while in a preemptable-RCU read-side 447 * Check for a task exiting while in a preemptable-RCU read-side
423 * critical section, clean up if so. No need to issue warnings, 448 * critical section, clean up if so. No need to issue warnings,
424 * as debug_check_no_locks_held() already does this if lockdep 449 * as debug_check_no_locks_held() already does this if lockdep
@@ -461,6 +486,15 @@ static void rcu_preempt_note_context_switch(int cpu)
461{ 486{
462} 487}
463 488
489/*
490 * Because preemptable RCU does not exist, there are never any preempted
491 * RCU readers.
492 */
493static int rcu_preempted_readers(struct rcu_node *rnp)
494{
495 return 0;
496}
497
464#ifdef CONFIG_RCU_CPU_STALL_DETECTOR 498#ifdef CONFIG_RCU_CPU_STALL_DETECTOR
465 499
466/* 500/*
@@ -483,15 +517,6 @@ static void rcu_preempt_check_blocked_tasks(struct rcu_node *rnp)
483 WARN_ON_ONCE(rnp->qsmask); 517 WARN_ON_ONCE(rnp->qsmask);
484} 518}
485 519
486/*
487 * Because preemptable RCU does not exist, there are never any preempted
488 * RCU readers.
489 */
490static int rcu_preempted_readers(struct rcu_node *rnp)
491{
492 return 0;
493}
494
495#ifdef CONFIG_HOTPLUG_CPU 520#ifdef CONFIG_HOTPLUG_CPU
496 521
497/* 522/*
@@ -518,7 +543,7 @@ static void rcu_preempt_offline_cpu(int cpu)
518 * Because preemptable RCU does not exist, it never has any callbacks 543 * Because preemptable RCU does not exist, it never has any callbacks
519 * to check. 544 * to check.
520 */ 545 */
521void rcu_preempt_check_callbacks(int cpu) 546static void rcu_preempt_check_callbacks(int cpu)
522{ 547{
523} 548}
524 549
@@ -526,7 +551,7 @@ void rcu_preempt_check_callbacks(int cpu)
526 * Because preemptable RCU does not exist, it never has any callbacks 551 * Because preemptable RCU does not exist, it never has any callbacks
527 * to process. 552 * to process.
528 */ 553 */
529void rcu_preempt_process_callbacks(void) 554static void rcu_preempt_process_callbacks(void)
530{ 555{
531} 556}
532 557
@@ -556,6 +581,16 @@ static int rcu_preempt_needs_cpu(int cpu)
556} 581}
557 582
558/* 583/*
584 * Because preemptable RCU does not exist, rcu_barrier() is just
585 * another name for rcu_barrier_sched().
586 */
587void rcu_barrier(void)
588{
589 rcu_barrier_sched();
590}
591EXPORT_SYMBOL_GPL(rcu_barrier);
592
593/*
559 * Because preemptable RCU does not exist, there is no per-CPU 594 * Because preemptable RCU does not exist, there is no per-CPU
560 * data to initialize. 595 * data to initialize.
561 */ 596 */
@@ -563,4 +598,18 @@ static void __cpuinit rcu_preempt_init_percpu_data(int cpu)
563{ 598{
564} 599}
565 600
601/*
602 * Because there is no preemptable RCU, there are no callbacks to move.
603 */
604static void rcu_preempt_send_cbs_to_orphanage(void)
605{
606}
607
608/*
609 * Because preemptable RCU does not exist, it need not be initialized.
610 */
611static void __init __rcu_init_preempt(void)
612{
613}
614
566#endif /* #else #ifdef CONFIG_TREE_PREEMPT_RCU */ 615#endif /* #else #ifdef CONFIG_TREE_PREEMPT_RCU */
diff --git a/kernel/rcutree_trace.c b/kernel/rcutree_trace.c
index c89f5e9fd173..4b31c779e62e 100644
--- a/kernel/rcutree_trace.c
+++ b/kernel/rcutree_trace.c
@@ -93,7 +93,7 @@ static int rcudata_open(struct inode *inode, struct file *file)
93 return single_open(file, show_rcudata, NULL); 93 return single_open(file, show_rcudata, NULL);
94} 94}
95 95
96static struct file_operations rcudata_fops = { 96static const struct file_operations rcudata_fops = {
97 .owner = THIS_MODULE, 97 .owner = THIS_MODULE,
98 .open = rcudata_open, 98 .open = rcudata_open,
99 .read = seq_read, 99 .read = seq_read,
@@ -145,7 +145,7 @@ static int rcudata_csv_open(struct inode *inode, struct file *file)
145 return single_open(file, show_rcudata_csv, NULL); 145 return single_open(file, show_rcudata_csv, NULL);
146} 146}
147 147
148static struct file_operations rcudata_csv_fops = { 148static const struct file_operations rcudata_csv_fops = {
149 .owner = THIS_MODULE, 149 .owner = THIS_MODULE,
150 .open = rcudata_csv_open, 150 .open = rcudata_csv_open,
151 .read = seq_read, 151 .read = seq_read,
@@ -159,13 +159,13 @@ static void print_one_rcu_state(struct seq_file *m, struct rcu_state *rsp)
159 struct rcu_node *rnp; 159 struct rcu_node *rnp;
160 160
161 seq_printf(m, "c=%ld g=%ld s=%d jfq=%ld j=%x " 161 seq_printf(m, "c=%ld g=%ld s=%d jfq=%ld j=%x "
162 "nfqs=%lu/nfqsng=%lu(%lu) fqlh=%lu\n", 162 "nfqs=%lu/nfqsng=%lu(%lu) fqlh=%lu oqlen=%ld\n",
163 rsp->completed, rsp->gpnum, rsp->signaled, 163 rsp->completed, rsp->gpnum, rsp->signaled,
164 (long)(rsp->jiffies_force_qs - jiffies), 164 (long)(rsp->jiffies_force_qs - jiffies),
165 (int)(jiffies & 0xffff), 165 (int)(jiffies & 0xffff),
166 rsp->n_force_qs, rsp->n_force_qs_ngp, 166 rsp->n_force_qs, rsp->n_force_qs_ngp,
167 rsp->n_force_qs - rsp->n_force_qs_ngp, 167 rsp->n_force_qs - rsp->n_force_qs_ngp,
168 rsp->n_force_qs_lh); 168 rsp->n_force_qs_lh, rsp->orphan_qlen);
169 for (rnp = &rsp->node[0]; rnp - &rsp->node[0] < NUM_RCU_NODES; rnp++) { 169 for (rnp = &rsp->node[0]; rnp - &rsp->node[0] < NUM_RCU_NODES; rnp++) {
170 if (rnp->level != level) { 170 if (rnp->level != level) {
171 seq_puts(m, "\n"); 171 seq_puts(m, "\n");
@@ -196,7 +196,7 @@ static int rcuhier_open(struct inode *inode, struct file *file)
196 return single_open(file, show_rcuhier, NULL); 196 return single_open(file, show_rcuhier, NULL);
197} 197}
198 198
199static struct file_operations rcuhier_fops = { 199static const struct file_operations rcuhier_fops = {
200 .owner = THIS_MODULE, 200 .owner = THIS_MODULE,
201 .open = rcuhier_open, 201 .open = rcuhier_open,
202 .read = seq_read, 202 .read = seq_read,
@@ -222,7 +222,7 @@ static int rcugp_open(struct inode *inode, struct file *file)
222 return single_open(file, show_rcugp, NULL); 222 return single_open(file, show_rcugp, NULL);
223} 223}
224 224
225static struct file_operations rcugp_fops = { 225static const struct file_operations rcugp_fops = {
226 .owner = THIS_MODULE, 226 .owner = THIS_MODULE,
227 .open = rcugp_open, 227 .open = rcugp_open,
228 .read = seq_read, 228 .read = seq_read,
@@ -276,7 +276,7 @@ static int rcu_pending_open(struct inode *inode, struct file *file)
276 return single_open(file, show_rcu_pending, NULL); 276 return single_open(file, show_rcu_pending, NULL);
277} 277}
278 278
279static struct file_operations rcu_pending_fops = { 279static const struct file_operations rcu_pending_fops = {
280 .owner = THIS_MODULE, 280 .owner = THIS_MODULE,
281 .open = rcu_pending_open, 281 .open = rcu_pending_open,
282 .read = seq_read, 282 .read = seq_read,
diff --git a/kernel/res_counter.c b/kernel/res_counter.c
index 88faec23e833..bcdabf37c40b 100644
--- a/kernel/res_counter.c
+++ b/kernel/res_counter.c
@@ -37,27 +37,17 @@ int res_counter_charge_locked(struct res_counter *counter, unsigned long val)
37} 37}
38 38
39int res_counter_charge(struct res_counter *counter, unsigned long val, 39int res_counter_charge(struct res_counter *counter, unsigned long val,
40 struct res_counter **limit_fail_at, 40 struct res_counter **limit_fail_at)
41 struct res_counter **soft_limit_fail_at)
42{ 41{
43 int ret; 42 int ret;
44 unsigned long flags; 43 unsigned long flags;
45 struct res_counter *c, *u; 44 struct res_counter *c, *u;
46 45
47 *limit_fail_at = NULL; 46 *limit_fail_at = NULL;
48 if (soft_limit_fail_at)
49 *soft_limit_fail_at = NULL;
50 local_irq_save(flags); 47 local_irq_save(flags);
51 for (c = counter; c != NULL; c = c->parent) { 48 for (c = counter; c != NULL; c = c->parent) {
52 spin_lock(&c->lock); 49 spin_lock(&c->lock);
53 ret = res_counter_charge_locked(c, val); 50 ret = res_counter_charge_locked(c, val);
54 /*
55 * With soft limits, we return the highest ancestor
56 * that exceeds its soft limit
57 */
58 if (soft_limit_fail_at &&
59 !res_counter_soft_limit_check_locked(c))
60 *soft_limit_fail_at = c;
61 spin_unlock(&c->lock); 51 spin_unlock(&c->lock);
62 if (ret < 0) { 52 if (ret < 0) {
63 *limit_fail_at = c; 53 *limit_fail_at = c;
@@ -85,8 +75,7 @@ void res_counter_uncharge_locked(struct res_counter *counter, unsigned long val)
85 counter->usage -= val; 75 counter->usage -= val;
86} 76}
87 77
88void res_counter_uncharge(struct res_counter *counter, unsigned long val, 78void res_counter_uncharge(struct res_counter *counter, unsigned long val)
89 bool *was_soft_limit_excess)
90{ 79{
91 unsigned long flags; 80 unsigned long flags;
92 struct res_counter *c; 81 struct res_counter *c;
@@ -94,9 +83,6 @@ void res_counter_uncharge(struct res_counter *counter, unsigned long val,
94 local_irq_save(flags); 83 local_irq_save(flags);
95 for (c = counter; c != NULL; c = c->parent) { 84 for (c = counter; c != NULL; c = c->parent) {
96 spin_lock(&c->lock); 85 spin_lock(&c->lock);
97 if (was_soft_limit_excess)
98 *was_soft_limit_excess =
99 !res_counter_soft_limit_check_locked(c);
100 res_counter_uncharge_locked(c, val); 86 res_counter_uncharge_locked(c, val);
101 spin_unlock(&c->lock); 87 spin_unlock(&c->lock);
102 } 88 }
diff --git a/kernel/sched.c b/kernel/sched.c
index ee61f454a98b..e88689522e66 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -676,6 +676,7 @@ inline void update_rq_clock(struct rq *rq)
676 676
677/** 677/**
678 * runqueue_is_locked 678 * runqueue_is_locked
679 * @cpu: the processor in question.
679 * 680 *
680 * Returns true if the current cpu runqueue is locked. 681 * Returns true if the current cpu runqueue is locked.
681 * This interface allows printk to be called with the runqueue lock 682 * This interface allows printk to be called with the runqueue lock
@@ -780,7 +781,7 @@ static int sched_feat_open(struct inode *inode, struct file *filp)
780 return single_open(filp, sched_feat_show, NULL); 781 return single_open(filp, sched_feat_show, NULL);
781} 782}
782 783
783static struct file_operations sched_feat_fops = { 784static const struct file_operations sched_feat_fops = {
784 .open = sched_feat_open, 785 .open = sched_feat_open,
785 .write = sched_feat_write, 786 .write = sched_feat_write,
786 .read = seq_read, 787 .read = seq_read,
@@ -2311,7 +2312,7 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state,
2311{ 2312{
2312 int cpu, orig_cpu, this_cpu, success = 0; 2313 int cpu, orig_cpu, this_cpu, success = 0;
2313 unsigned long flags; 2314 unsigned long flags;
2314 struct rq *rq; 2315 struct rq *rq, *orig_rq;
2315 2316
2316 if (!sched_feat(SYNC_WAKEUPS)) 2317 if (!sched_feat(SYNC_WAKEUPS))
2317 wake_flags &= ~WF_SYNC; 2318 wake_flags &= ~WF_SYNC;
@@ -2319,7 +2320,7 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state,
2319 this_cpu = get_cpu(); 2320 this_cpu = get_cpu();
2320 2321
2321 smp_wmb(); 2322 smp_wmb();
2322 rq = task_rq_lock(p, &flags); 2323 rq = orig_rq = task_rq_lock(p, &flags);
2323 update_rq_clock(rq); 2324 update_rq_clock(rq);
2324 if (!(p->state & state)) 2325 if (!(p->state & state))
2325 goto out; 2326 goto out;
@@ -2350,6 +2351,10 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state,
2350 set_task_cpu(p, cpu); 2351 set_task_cpu(p, cpu);
2351 2352
2352 rq = task_rq_lock(p, &flags); 2353 rq = task_rq_lock(p, &flags);
2354
2355 if (rq != orig_rq)
2356 update_rq_clock(rq);
2357
2353 WARN_ON(p->state != TASK_WAKING); 2358 WARN_ON(p->state != TASK_WAKING);
2354 cpu = task_cpu(p); 2359 cpu = task_cpu(p);
2355 2360
@@ -2515,22 +2520,17 @@ void sched_fork(struct task_struct *p, int clone_flags)
2515 __sched_fork(p); 2520 __sched_fork(p);
2516 2521
2517 /* 2522 /*
2518 * Make sure we do not leak PI boosting priority to the child.
2519 */
2520 p->prio = current->normal_prio;
2521
2522 /*
2523 * Revert to default priority/policy on fork if requested. 2523 * Revert to default priority/policy on fork if requested.
2524 */ 2524 */
2525 if (unlikely(p->sched_reset_on_fork)) { 2525 if (unlikely(p->sched_reset_on_fork)) {
2526 if (p->policy == SCHED_FIFO || p->policy == SCHED_RR) 2526 if (p->policy == SCHED_FIFO || p->policy == SCHED_RR) {
2527 p->policy = SCHED_NORMAL; 2527 p->policy = SCHED_NORMAL;
2528 2528 p->normal_prio = p->static_prio;
2529 if (p->normal_prio < DEFAULT_PRIO) 2529 }
2530 p->prio = DEFAULT_PRIO;
2531 2530
2532 if (PRIO_TO_NICE(p->static_prio) < 0) { 2531 if (PRIO_TO_NICE(p->static_prio) < 0) {
2533 p->static_prio = NICE_TO_PRIO(0); 2532 p->static_prio = NICE_TO_PRIO(0);
2533 p->normal_prio = p->static_prio;
2534 set_load_weight(p); 2534 set_load_weight(p);
2535 } 2535 }
2536 2536
@@ -2541,6 +2541,11 @@ void sched_fork(struct task_struct *p, int clone_flags)
2541 p->sched_reset_on_fork = 0; 2541 p->sched_reset_on_fork = 0;
2542 } 2542 }
2543 2543
2544 /*
2545 * Make sure we do not leak PI boosting priority to the child.
2546 */
2547 p->prio = current->normal_prio;
2548
2544 if (!rt_prio(p->prio)) 2549 if (!rt_prio(p->prio))
2545 p->sched_class = &fair_sched_class; 2550 p->sched_class = &fair_sched_class;
2546 2551
@@ -2581,8 +2586,6 @@ void wake_up_new_task(struct task_struct *p, unsigned long clone_flags)
2581 BUG_ON(p->state != TASK_RUNNING); 2586 BUG_ON(p->state != TASK_RUNNING);
2582 update_rq_clock(rq); 2587 update_rq_clock(rq);
2583 2588
2584 p->prio = effective_prio(p);
2585
2586 if (!p->sched_class->task_new || !current->se.on_rq) { 2589 if (!p->sched_class->task_new || !current->se.on_rq) {
2587 activate_task(rq, p, 0); 2590 activate_task(rq, p, 0);
2588 } else { 2591 } else {
@@ -3658,6 +3661,7 @@ static void update_group_power(struct sched_domain *sd, int cpu)
3658 3661
3659/** 3662/**
3660 * update_sg_lb_stats - Update sched_group's statistics for load balancing. 3663 * update_sg_lb_stats - Update sched_group's statistics for load balancing.
3664 * @sd: The sched_domain whose statistics are to be updated.
3661 * @group: sched_group whose statistics are to be updated. 3665 * @group: sched_group whose statistics are to be updated.
3662 * @this_cpu: Cpu for which load balance is currently performed. 3666 * @this_cpu: Cpu for which load balance is currently performed.
3663 * @idle: Idle status of this_cpu 3667 * @idle: Idle status of this_cpu
@@ -6720,9 +6724,6 @@ EXPORT_SYMBOL(yield);
6720/* 6724/*
6721 * This task is about to go to sleep on IO. Increment rq->nr_iowait so 6725 * This task is about to go to sleep on IO. Increment rq->nr_iowait so
6722 * that process accounting knows that this is a task in IO wait state. 6726 * that process accounting knows that this is a task in IO wait state.
6723 *
6724 * But don't do that if it is a deliberate, throttling IO wait (this task
6725 * has set its backing_dev_info: the queue against which it should throttle)
6726 */ 6727 */
6727void __sched io_schedule(void) 6728void __sched io_schedule(void)
6728{ 6729{
diff --git a/kernel/sched_clock.c b/kernel/sched_clock.c
index ac2e1dc708bd..479ce5682d7c 100644
--- a/kernel/sched_clock.c
+++ b/kernel/sched_clock.c
@@ -127,7 +127,7 @@ again:
127 clock = wrap_max(clock, min_clock); 127 clock = wrap_max(clock, min_clock);
128 clock = wrap_min(clock, max_clock); 128 clock = wrap_min(clock, max_clock);
129 129
130 if (cmpxchg(&scd->clock, old_clock, clock) != old_clock) 130 if (cmpxchg64(&scd->clock, old_clock, clock) != old_clock)
131 goto again; 131 goto again;
132 132
133 return clock; 133 return clock;
@@ -163,7 +163,7 @@ again:
163 val = remote_clock; 163 val = remote_clock;
164 } 164 }
165 165
166 if (cmpxchg(ptr, old_val, val) != old_val) 166 if (cmpxchg64(ptr, old_val, val) != old_val)
167 goto again; 167 goto again;
168 168
169 return val; 169 return val;
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index e0f59a21c061..89aed5933ed4 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -231,6 +231,13 @@ void tick_nohz_stop_sched_tick(int inidle)
231 if (!inidle && !ts->inidle) 231 if (!inidle && !ts->inidle)
232 goto end; 232 goto end;
233 233
234 /*
235 * Set ts->inidle unconditionally. Even if the system did not
236 * switch to NOHZ mode the cpu frequency governers rely on the
237 * update of the idle time accounting in tick_nohz_start_idle().
238 */
239 ts->inidle = 1;
240
234 now = tick_nohz_start_idle(ts); 241 now = tick_nohz_start_idle(ts);
235 242
236 /* 243 /*
@@ -248,8 +255,6 @@ void tick_nohz_stop_sched_tick(int inidle)
248 if (unlikely(ts->nohz_mode == NOHZ_MODE_INACTIVE)) 255 if (unlikely(ts->nohz_mode == NOHZ_MODE_INACTIVE))
249 goto end; 256 goto end;
250 257
251 ts->inidle = 1;
252
253 if (need_resched()) 258 if (need_resched())
254 goto end; 259 goto end;
255 260
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index fb0f46fa1ecd..c3a4e2907eaa 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -13,6 +13,7 @@
13#include <linux/percpu.h> 13#include <linux/percpu.h>
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/mm.h> 15#include <linux/mm.h>
16#include <linux/sched.h>
16#include <linux/sysdev.h> 17#include <linux/sysdev.h>
17#include <linux/clocksource.h> 18#include <linux/clocksource.h>
18#include <linux/jiffies.h> 19#include <linux/jiffies.h>
diff --git a/kernel/time/timer_list.c b/kernel/time/timer_list.c
index fddd69d16e03..1b5b7aa2fdfd 100644
--- a/kernel/time/timer_list.c
+++ b/kernel/time/timer_list.c
@@ -275,7 +275,7 @@ static int timer_list_open(struct inode *inode, struct file *filp)
275 return single_open(filp, timer_list_show, NULL); 275 return single_open(filp, timer_list_show, NULL);
276} 276}
277 277
278static struct file_operations timer_list_fops = { 278static const struct file_operations timer_list_fops = {
279 .open = timer_list_open, 279 .open = timer_list_open,
280 .read = seq_read, 280 .read = seq_read,
281 .llseek = seq_lseek, 281 .llseek = seq_lseek,
diff --git a/kernel/time/timer_stats.c b/kernel/time/timer_stats.c
index 4cde8b9c716f..ee5681f8d7ec 100644
--- a/kernel/time/timer_stats.c
+++ b/kernel/time/timer_stats.c
@@ -395,7 +395,7 @@ static int tstats_open(struct inode *inode, struct file *filp)
395 return single_open(filp, tstats_show, NULL); 395 return single_open(filp, tstats_show, NULL);
396} 396}
397 397
398static struct file_operations tstats_fops = { 398static const struct file_operations tstats_fops = {
399 .open = tstats_open, 399 .open = tstats_open,
400 .read = seq_read, 400 .read = seq_read,
401 .write = tstats_write, 401 .write = tstats_write,
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c
index 3eb159c277c8..d9d6206e0b14 100644
--- a/kernel/trace/blktrace.c
+++ b/kernel/trace/blktrace.c
@@ -856,6 +856,37 @@ static void blk_add_trace_remap(struct request_queue *q, struct bio *bio,
856} 856}
857 857
858/** 858/**
859 * blk_add_trace_rq_remap - Add a trace for a request-remap operation
860 * @q: queue the io is for
861 * @rq: the source request
862 * @dev: target device
863 * @from: source sector
864 *
865 * Description:
866 * Device mapper remaps request to other devices.
867 * Add a trace for that action.
868 *
869 **/
870static void blk_add_trace_rq_remap(struct request_queue *q,
871 struct request *rq, dev_t dev,
872 sector_t from)
873{
874 struct blk_trace *bt = q->blk_trace;
875 struct blk_io_trace_remap r;
876
877 if (likely(!bt))
878 return;
879
880 r.device_from = cpu_to_be32(dev);
881 r.device_to = cpu_to_be32(disk_devt(rq->rq_disk));
882 r.sector_from = cpu_to_be64(from);
883
884 __blk_add_trace(bt, blk_rq_pos(rq), blk_rq_bytes(rq),
885 rq_data_dir(rq), BLK_TA_REMAP, !!rq->errors,
886 sizeof(r), &r);
887}
888
889/**
859 * blk_add_driver_data - Add binary message with driver-specific data 890 * blk_add_driver_data - Add binary message with driver-specific data
860 * @q: queue the io is for 891 * @q: queue the io is for
861 * @rq: io request 892 * @rq: io request
@@ -922,10 +953,13 @@ static void blk_register_tracepoints(void)
922 WARN_ON(ret); 953 WARN_ON(ret);
923 ret = register_trace_block_remap(blk_add_trace_remap); 954 ret = register_trace_block_remap(blk_add_trace_remap);
924 WARN_ON(ret); 955 WARN_ON(ret);
956 ret = register_trace_block_rq_remap(blk_add_trace_rq_remap);
957 WARN_ON(ret);
925} 958}
926 959
927static void blk_unregister_tracepoints(void) 960static void blk_unregister_tracepoints(void)
928{ 961{
962 unregister_trace_block_rq_remap(blk_add_trace_rq_remap);
929 unregister_trace_block_remap(blk_add_trace_remap); 963 unregister_trace_block_remap(blk_add_trace_remap);
930 unregister_trace_block_split(blk_add_trace_split); 964 unregister_trace_block_split(blk_add_trace_split);
931 unregister_trace_block_unplug_io(blk_add_trace_unplug_io); 965 unregister_trace_block_unplug_io(blk_add_trace_unplug_io);
@@ -1657,6 +1691,11 @@ int blk_trace_init_sysfs(struct device *dev)
1657 return sysfs_create_group(&dev->kobj, &blk_trace_attr_group); 1691 return sysfs_create_group(&dev->kobj, &blk_trace_attr_group);
1658} 1692}
1659 1693
1694void blk_trace_remove_sysfs(struct device *dev)
1695{
1696 sysfs_remove_group(&dev->kobj, &blk_trace_attr_group);
1697}
1698
1660#endif /* CONFIG_BLK_DEV_IO_TRACE */ 1699#endif /* CONFIG_BLK_DEV_IO_TRACE */
1661 1700
1662#ifdef CONFIG_EVENT_TRACING 1701#ifdef CONFIG_EVENT_TRACING
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 46592feab5a6..37ba67e33265 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -225,7 +225,11 @@ static void ftrace_update_pid_func(void)
225 if (ftrace_trace_function == ftrace_stub) 225 if (ftrace_trace_function == ftrace_stub)
226 return; 226 return;
227 227
228#ifdef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST
228 func = ftrace_trace_function; 229 func = ftrace_trace_function;
230#else
231 func = __ftrace_trace_function;
232#endif
229 233
230 if (ftrace_pid_trace) { 234 if (ftrace_pid_trace) {
231 set_ftrace_pid_function(func); 235 set_ftrace_pid_function(func);
@@ -1074,14 +1078,9 @@ static void ftrace_replace_code(int enable)
1074 failed = __ftrace_replace_code(rec, enable); 1078 failed = __ftrace_replace_code(rec, enable);
1075 if (failed) { 1079 if (failed) {
1076 rec->flags |= FTRACE_FL_FAILED; 1080 rec->flags |= FTRACE_FL_FAILED;
1077 if ((system_state == SYSTEM_BOOTING) || 1081 ftrace_bug(failed, rec->ip);
1078 !core_kernel_text(rec->ip)) { 1082 /* Stop processing */
1079 ftrace_free_rec(rec); 1083 return;
1080 } else {
1081 ftrace_bug(failed, rec->ip);
1082 /* Stop processing */
1083 return;
1084 }
1085 } 1084 }
1086 } while_for_each_ftrace_rec(); 1085 } while_for_each_ftrace_rec();
1087} 1086}
@@ -2658,19 +2657,17 @@ static int ftrace_convert_nops(struct module *mod,
2658} 2657}
2659 2658
2660#ifdef CONFIG_MODULES 2659#ifdef CONFIG_MODULES
2661void ftrace_release(void *start, void *end) 2660void ftrace_release_mod(struct module *mod)
2662{ 2661{
2663 struct dyn_ftrace *rec; 2662 struct dyn_ftrace *rec;
2664 struct ftrace_page *pg; 2663 struct ftrace_page *pg;
2665 unsigned long s = (unsigned long)start;
2666 unsigned long e = (unsigned long)end;
2667 2664
2668 if (ftrace_disabled || !start || start == end) 2665 if (ftrace_disabled)
2669 return; 2666 return;
2670 2667
2671 mutex_lock(&ftrace_lock); 2668 mutex_lock(&ftrace_lock);
2672 do_for_each_ftrace_rec(pg, rec) { 2669 do_for_each_ftrace_rec(pg, rec) {
2673 if ((rec->ip >= s) && (rec->ip < e)) { 2670 if (within_module_core(rec->ip, mod)) {
2674 /* 2671 /*
2675 * rec->ip is changed in ftrace_free_rec() 2672 * rec->ip is changed in ftrace_free_rec()
2676 * It should not between s and e if record was freed. 2673 * It should not between s and e if record was freed.
@@ -2702,9 +2699,7 @@ static int ftrace_module_notify(struct notifier_block *self,
2702 mod->num_ftrace_callsites); 2699 mod->num_ftrace_callsites);
2703 break; 2700 break;
2704 case MODULE_STATE_GOING: 2701 case MODULE_STATE_GOING:
2705 ftrace_release(mod->ftrace_callsites, 2702 ftrace_release_mod(mod);
2706 mod->ftrace_callsites +
2707 mod->num_ftrace_callsites);
2708 break; 2703 break;
2709 } 2704 }
2710 2705
diff --git a/kernel/trace/kmemtrace.c b/kernel/trace/kmemtrace.c
index 81b1645c8549..a91da69f153a 100644
--- a/kernel/trace/kmemtrace.c
+++ b/kernel/trace/kmemtrace.c
@@ -501,7 +501,7 @@ static int __init init_kmem_tracer(void)
501 return 1; 501 return 1;
502 } 502 }
503 503
504 if (!register_tracer(&kmem_tracer)) { 504 if (register_tracer(&kmem_tracer) != 0) {
505 pr_warning("Warning: could not register the kmem tracer\n"); 505 pr_warning("Warning: could not register the kmem tracer\n");
506 return 1; 506 return 1;
507 } 507 }
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 45068269ebb1..c820b0310a12 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -1393,7 +1393,7 @@ int trace_array_vprintk(struct trace_array *tr,
1393 1393
1394int trace_vprintk(unsigned long ip, const char *fmt, va_list args) 1394int trace_vprintk(unsigned long ip, const char *fmt, va_list args)
1395{ 1395{
1396 return trace_array_printk(&global_trace, ip, fmt, args); 1396 return trace_array_vprintk(&global_trace, ip, fmt, args);
1397} 1397}
1398EXPORT_SYMBOL_GPL(trace_vprintk); 1398EXPORT_SYMBOL_GPL(trace_vprintk);
1399 1399
diff --git a/kernel/trace/trace_branch.c b/kernel/trace/trace_branch.c
index 7a7a9fd249a9..4a194f08f88c 100644
--- a/kernel/trace/trace_branch.c
+++ b/kernel/trace/trace_branch.c
@@ -34,6 +34,7 @@ probe_likely_condition(struct ftrace_branch_data *f, int val, int expect)
34 struct trace_array *tr = branch_tracer; 34 struct trace_array *tr = branch_tracer;
35 struct ring_buffer_event *event; 35 struct ring_buffer_event *event;
36 struct trace_branch *entry; 36 struct trace_branch *entry;
37 struct ring_buffer *buffer;
37 unsigned long flags; 38 unsigned long flags;
38 int cpu, pc; 39 int cpu, pc;
39 const char *p; 40 const char *p;
@@ -54,7 +55,8 @@ probe_likely_condition(struct ftrace_branch_data *f, int val, int expect)
54 goto out; 55 goto out;
55 56
56 pc = preempt_count(); 57 pc = preempt_count();
57 event = trace_buffer_lock_reserve(tr, TRACE_BRANCH, 58 buffer = tr->buffer;
59 event = trace_buffer_lock_reserve(buffer, TRACE_BRANCH,
58 sizeof(*entry), flags, pc); 60 sizeof(*entry), flags, pc);
59 if (!event) 61 if (!event)
60 goto out; 62 goto out;
@@ -74,8 +76,8 @@ probe_likely_condition(struct ftrace_branch_data *f, int val, int expect)
74 entry->line = f->line; 76 entry->line = f->line;
75 entry->correct = val == expect; 77 entry->correct = val == expect;
76 78
77 if (!filter_check_discard(call, entry, tr->buffer, event)) 79 if (!filter_check_discard(call, entry, buffer, event))
78 ring_buffer_unlock_commit(tr->buffer, event); 80 ring_buffer_unlock_commit(buffer, event);
79 81
80 out: 82 out:
81 atomic_dec(&tr->data[cpu]->disabled); 83 atomic_dec(&tr->data[cpu]->disabled);
diff --git a/kernel/trace/trace_event_profile.c b/kernel/trace/trace_event_profile.c
index dd44b8768867..8d5c171cc998 100644
--- a/kernel/trace/trace_event_profile.c
+++ b/kernel/trace/trace_event_profile.c
@@ -31,7 +31,7 @@ static int ftrace_profile_enable_event(struct ftrace_event_call *event)
31 if (atomic_inc_return(&event->profile_count)) 31 if (atomic_inc_return(&event->profile_count))
32 return 0; 32 return 0;
33 33
34 if (!total_profile_count++) { 34 if (!total_profile_count) {
35 buf = (char *)alloc_percpu(profile_buf_t); 35 buf = (char *)alloc_percpu(profile_buf_t);
36 if (!buf) 36 if (!buf)
37 goto fail_buf; 37 goto fail_buf;
@@ -46,14 +46,19 @@ static int ftrace_profile_enable_event(struct ftrace_event_call *event)
46 } 46 }
47 47
48 ret = event->profile_enable(); 48 ret = event->profile_enable();
49 if (!ret) 49 if (!ret) {
50 total_profile_count++;
50 return 0; 51 return 0;
52 }
51 53
52 kfree(trace_profile_buf_nmi);
53fail_buf_nmi: 54fail_buf_nmi:
54 kfree(trace_profile_buf); 55 if (!total_profile_count) {
56 free_percpu(trace_profile_buf_nmi);
57 free_percpu(trace_profile_buf);
58 trace_profile_buf_nmi = NULL;
59 trace_profile_buf = NULL;
60 }
55fail_buf: 61fail_buf:
56 total_profile_count--;
57 atomic_dec(&event->profile_count); 62 atomic_dec(&event->profile_count);
58 63
59 return ret; 64 return ret;
diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c
index 23245785927f..98a6cc5c64ed 100644
--- a/kernel/trace/trace_events_filter.c
+++ b/kernel/trace/trace_events_filter.c
@@ -933,8 +933,9 @@ static void postfix_clear(struct filter_parse_state *ps)
933 933
934 while (!list_empty(&ps->postfix)) { 934 while (!list_empty(&ps->postfix)) {
935 elt = list_first_entry(&ps->postfix, struct postfix_elt, list); 935 elt = list_first_entry(&ps->postfix, struct postfix_elt, list);
936 kfree(elt->operand);
937 list_del(&elt->list); 936 list_del(&elt->list);
937 kfree(elt->operand);
938 kfree(elt);
938 } 939 }
939} 940}
940 941
diff --git a/kernel/trace/trace_hw_branches.c b/kernel/trace/trace_hw_branches.c
index 23b63859130e..69543a905cd5 100644
--- a/kernel/trace/trace_hw_branches.c
+++ b/kernel/trace/trace_hw_branches.c
@@ -165,6 +165,7 @@ void trace_hw_branch(u64 from, u64 to)
165 struct ftrace_event_call *call = &event_hw_branch; 165 struct ftrace_event_call *call = &event_hw_branch;
166 struct trace_array *tr = hw_branch_trace; 166 struct trace_array *tr = hw_branch_trace;
167 struct ring_buffer_event *event; 167 struct ring_buffer_event *event;
168 struct ring_buffer *buf;
168 struct hw_branch_entry *entry; 169 struct hw_branch_entry *entry;
169 unsigned long irq1; 170 unsigned long irq1;
170 int cpu; 171 int cpu;
@@ -180,7 +181,8 @@ void trace_hw_branch(u64 from, u64 to)
180 if (atomic_inc_return(&tr->data[cpu]->disabled) != 1) 181 if (atomic_inc_return(&tr->data[cpu]->disabled) != 1)
181 goto out; 182 goto out;
182 183
183 event = trace_buffer_lock_reserve(tr, TRACE_HW_BRANCHES, 184 buf = tr->buffer;
185 event = trace_buffer_lock_reserve(buf, TRACE_HW_BRANCHES,
184 sizeof(*entry), 0, 0); 186 sizeof(*entry), 0, 0);
185 if (!event) 187 if (!event)
186 goto out; 188 goto out;
@@ -189,8 +191,8 @@ void trace_hw_branch(u64 from, u64 to)
189 entry->ent.type = TRACE_HW_BRANCHES; 191 entry->ent.type = TRACE_HW_BRANCHES;
190 entry->from = from; 192 entry->from = from;
191 entry->to = to; 193 entry->to = to;
192 if (!filter_check_discard(call, entry, tr->buffer, event)) 194 if (!filter_check_discard(call, entry, buf, event))
193 trace_buffer_unlock_commit(tr, event, 0, 0); 195 trace_buffer_unlock_commit(buf, event, 0, 0);
194 196
195 out: 197 out:
196 atomic_dec(&tr->data[cpu]->disabled); 198 atomic_dec(&tr->data[cpu]->disabled);
diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c
index f572f44c6e1e..ed17565826b0 100644
--- a/kernel/trace/trace_output.c
+++ b/kernel/trace/trace_output.c
@@ -486,16 +486,18 @@ int trace_print_lat_fmt(struct trace_seq *s, struct trace_entry *entry)
486 hardirq ? 'h' : softirq ? 's' : '.')) 486 hardirq ? 'h' : softirq ? 's' : '.'))
487 return 0; 487 return 0;
488 488
489 if (entry->lock_depth < 0) 489 if (entry->preempt_count)
490 ret = trace_seq_putc(s, '.'); 490 ret = trace_seq_printf(s, "%x", entry->preempt_count);
491 else 491 else
492 ret = trace_seq_printf(s, "%d", entry->lock_depth); 492 ret = trace_seq_putc(s, '.');
493
493 if (!ret) 494 if (!ret)
494 return 0; 495 return 0;
495 496
496 if (entry->preempt_count) 497 if (entry->lock_depth < 0)
497 return trace_seq_printf(s, "%x", entry->preempt_count); 498 return trace_seq_putc(s, '.');
498 return trace_seq_putc(s, '.'); 499
500 return trace_seq_printf(s, "%d", entry->lock_depth);
499} 501}
500 502
501static int 503static int
@@ -883,7 +885,7 @@ static int trace_ctxwake_raw(struct trace_iterator *iter, char S)
883 trace_assign_type(field, iter->ent); 885 trace_assign_type(field, iter->ent);
884 886
885 if (!S) 887 if (!S)
886 task_state_char(field->prev_state); 888 S = task_state_char(field->prev_state);
887 T = task_state_char(field->next_state); 889 T = task_state_char(field->next_state);
888 if (!trace_seq_printf(&iter->seq, "%d %d %c %d %d %d %c\n", 890 if (!trace_seq_printf(&iter->seq, "%d %d %c %d %d %d %c\n",
889 field->prev_pid, 891 field->prev_pid,
@@ -918,7 +920,7 @@ static int trace_ctxwake_hex(struct trace_iterator *iter, char S)
918 trace_assign_type(field, iter->ent); 920 trace_assign_type(field, iter->ent);
919 921
920 if (!S) 922 if (!S)
921 task_state_char(field->prev_state); 923 S = task_state_char(field->prev_state);
922 T = task_state_char(field->next_state); 924 T = task_state_char(field->next_state);
923 925
924 SEQ_PUT_HEX_FIELD_RET(s, field->prev_pid); 926 SEQ_PUT_HEX_FIELD_RET(s, field->prev_pid);
diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c
index 9fbce6c9d2e1..527e17eae575 100644
--- a/kernel/trace/trace_syscalls.c
+++ b/kernel/trace/trace_syscalls.c
@@ -166,7 +166,7 @@ int syscall_exit_format(struct ftrace_event_call *call, struct trace_seq *s)
166 "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n" 166 "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n"
167 "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n", 167 "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n",
168 SYSCALL_FIELD(int, nr), 168 SYSCALL_FIELD(int, nr),
169 SYSCALL_FIELD(unsigned long, ret)); 169 SYSCALL_FIELD(long, ret));
170 if (!ret) 170 if (!ret)
171 return 0; 171 return 0;
172 172
@@ -212,7 +212,7 @@ int syscall_exit_define_fields(struct ftrace_event_call *call)
212 if (ret) 212 if (ret)
213 return ret; 213 return ret;
214 214
215 ret = trace_define_field(call, SYSCALL_FIELD(unsigned long, ret), 0, 215 ret = trace_define_field(call, SYSCALL_FIELD(long, ret), 0,
216 FILTER_OTHER); 216 FILTER_OTHER);
217 217
218 return ret; 218 return ret;
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index addfe2df93b1..47cdd7e76f2b 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -640,6 +640,24 @@ int schedule_delayed_work(struct delayed_work *dwork,
640EXPORT_SYMBOL(schedule_delayed_work); 640EXPORT_SYMBOL(schedule_delayed_work);
641 641
642/** 642/**
643 * flush_delayed_work - block until a dwork_struct's callback has terminated
644 * @dwork: the delayed work which is to be flushed
645 *
646 * Any timeout is cancelled, and any pending work is run immediately.
647 */
648void flush_delayed_work(struct delayed_work *dwork)
649{
650 if (del_timer_sync(&dwork->timer)) {
651 struct cpu_workqueue_struct *cwq;
652 cwq = wq_per_cpu(keventd_wq, get_cpu());
653 __queue_work(cwq, &dwork->work);
654 put_cpu();
655 }
656 flush_work(&dwork->work);
657}
658EXPORT_SYMBOL(flush_delayed_work);
659
660/**
643 * schedule_delayed_work_on - queue work in global workqueue on CPU after delay 661 * schedule_delayed_work_on - queue work in global workqueue on CPU after delay
644 * @cpu: cpu to use 662 * @cpu: cpu to use
645 * @dwork: job to be done 663 * @dwork: job to be done
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 891155817bc6..30df5865ecbe 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -346,8 +346,9 @@ config SLUB_STATS
346 346
347config DEBUG_KMEMLEAK 347config DEBUG_KMEMLEAK
348 bool "Kernel memory leak detector" 348 bool "Kernel memory leak detector"
349 depends on DEBUG_KERNEL && EXPERIMENTAL && (X86 || ARM || PPC) && \ 349 depends on DEBUG_KERNEL && EXPERIMENTAL && !MEMORY_HOTPLUG && \
350 !MEMORY_HOTPLUG 350 (X86 || ARM || PPC || S390)
351
351 select DEBUG_FS if SYSFS 352 select DEBUG_FS if SYSFS
352 select STACKTRACE if STACKTRACE_SUPPORT 353 select STACKTRACE if STACKTRACE_SUPPORT
353 select KALLSYMS 354 select KALLSYMS
@@ -370,7 +371,7 @@ config DEBUG_KMEMLEAK
370config DEBUG_KMEMLEAK_EARLY_LOG_SIZE 371config DEBUG_KMEMLEAK_EARLY_LOG_SIZE
371 int "Maximum kmemleak early log entries" 372 int "Maximum kmemleak early log entries"
372 depends on DEBUG_KMEMLEAK 373 depends on DEBUG_KMEMLEAK
373 range 200 2000 374 range 200 40000
374 default 400 375 default 400
375 help 376 help
376 Kmemleak must track all the memory allocations to avoid 377 Kmemleak must track all the memory allocations to avoid
diff --git a/lib/debugobjects.c b/lib/debugobjects.c
index 2755a3bd16a1..eae56fddfa3b 100644
--- a/lib/debugobjects.c
+++ b/lib/debugobjects.c
@@ -9,6 +9,7 @@
9 */ 9 */
10#include <linux/debugobjects.h> 10#include <linux/debugobjects.h>
11#include <linux/interrupt.h> 11#include <linux/interrupt.h>
12#include <linux/sched.h>
12#include <linux/seq_file.h> 13#include <linux/seq_file.h>
13#include <linux/debugfs.h> 14#include <linux/debugfs.h>
14#include <linux/hash.h> 15#include <linux/hash.h>
diff --git a/lib/fault-inject.c b/lib/fault-inject.c
index f97af55bdd96..7e65af70635e 100644
--- a/lib/fault-inject.c
+++ b/lib/fault-inject.c
@@ -1,6 +1,7 @@
1#include <linux/kernel.h> 1#include <linux/kernel.h>
2#include <linux/init.h> 2#include <linux/init.h>
3#include <linux/random.h> 3#include <linux/random.h>
4#include <linux/sched.h>
4#include <linux/stat.h> 5#include <linux/stat.h>
5#include <linux/types.h> 6#include <linux/types.h>
6#include <linux/fs.h> 7#include <linux/fs.h>
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index b91839e9e892..33bed5e67a21 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -1771,7 +1771,7 @@ int vsscanf(const char * buf, const char * fmt, va_list args)
1771 * advance both strings to next white space 1771 * advance both strings to next white space
1772 */ 1772 */
1773 if (*fmt == '*') { 1773 if (*fmt == '*') {
1774 while (!isspace(*fmt) && *fmt) 1774 while (!isspace(*fmt) && *fmt != '%' && *fmt)
1775 fmt++; 1775 fmt++;
1776 while (!isspace(*str) && *str) 1776 while (!isspace(*str) && *str)
1777 str++; 1777 str++;
diff --git a/mm/Kconfig b/mm/Kconfig
index edd300aca173..57963c6063d1 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -224,7 +224,9 @@ config KSM
224 the many instances by a single resident page with that content, so 224 the many instances by a single resident page with that content, so
225 saving memory until one or another app needs to modify the content. 225 saving memory until one or another app needs to modify the content.
226 Recommended for use with KVM, or with other duplicative applications. 226 Recommended for use with KVM, or with other duplicative applications.
227 See Documentation/vm/ksm.txt for more information. 227 See Documentation/vm/ksm.txt for more information: KSM is inactive
228 until a program has madvised that an area is MADV_MERGEABLE, and
229 root has set /sys/kernel/mm/ksm/run to 1 (if CONFIG_SYSFS is set).
228 230
229config DEFAULT_MMAP_MIN_ADDR 231config DEFAULT_MMAP_MIN_ADDR
230 int "Low address space to protect from user allocation" 232 int "Low address space to protect from user allocation"
diff --git a/mm/backing-dev.c b/mm/backing-dev.c
index 3d3accb1f800..5a37e2055717 100644
--- a/mm/backing-dev.c
+++ b/mm/backing-dev.c
@@ -92,7 +92,7 @@ static int bdi_debug_stats_show(struct seq_file *m, void *v)
92 "BdiDirtyThresh: %8lu kB\n" 92 "BdiDirtyThresh: %8lu kB\n"
93 "DirtyThresh: %8lu kB\n" 93 "DirtyThresh: %8lu kB\n"
94 "BackgroundThresh: %8lu kB\n" 94 "BackgroundThresh: %8lu kB\n"
95 "WriteBack threads:%8lu\n" 95 "WritebackThreads: %8lu\n"
96 "b_dirty: %8lu\n" 96 "b_dirty: %8lu\n"
97 "b_io: %8lu\n" 97 "b_io: %8lu\n"
98 "b_more_io: %8lu\n" 98 "b_more_io: %8lu\n"
diff --git a/mm/kmemleak.c b/mm/kmemleak.c
index 4ea4510e2996..8bf765c4f58d 100644
--- a/mm/kmemleak.c
+++ b/mm/kmemleak.c
@@ -833,12 +833,15 @@ static void early_alloc(struct early_log *log)
833 */ 833 */
834 rcu_read_lock(); 834 rcu_read_lock();
835 object = create_object((unsigned long)log->ptr, log->size, 835 object = create_object((unsigned long)log->ptr, log->size,
836 log->min_count, GFP_KERNEL); 836 log->min_count, GFP_ATOMIC);
837 if (!object)
838 goto out;
837 spin_lock_irqsave(&object->lock, flags); 839 spin_lock_irqsave(&object->lock, flags);
838 for (i = 0; i < log->trace_len; i++) 840 for (i = 0; i < log->trace_len; i++)
839 object->trace[i] = log->trace[i]; 841 object->trace[i] = log->trace[i];
840 object->trace_len = log->trace_len; 842 object->trace_len = log->trace_len;
841 spin_unlock_irqrestore(&object->lock, flags); 843 spin_unlock_irqrestore(&object->lock, flags);
844out:
842 rcu_read_unlock(); 845 rcu_read_unlock();
843} 846}
844 847
diff --git a/mm/ksm.c b/mm/ksm.c
index f7edac356f46..bef1af4f77e3 100644
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -184,11 +184,6 @@ static DEFINE_SPINLOCK(ksm_mmlist_lock);
184 sizeof(struct __struct), __alignof__(struct __struct),\ 184 sizeof(struct __struct), __alignof__(struct __struct),\
185 (__flags), NULL) 185 (__flags), NULL)
186 186
187static void __init ksm_init_max_kernel_pages(void)
188{
189 ksm_max_kernel_pages = nr_free_buffer_pages() / 4;
190}
191
192static int __init ksm_slab_init(void) 187static int __init ksm_slab_init(void)
193{ 188{
194 rmap_item_cache = KSM_KMEM_CACHE(rmap_item, 0); 189 rmap_item_cache = KSM_KMEM_CACHE(rmap_item, 0);
@@ -1673,7 +1668,7 @@ static int __init ksm_init(void)
1673 struct task_struct *ksm_thread; 1668 struct task_struct *ksm_thread;
1674 int err; 1669 int err;
1675 1670
1676 ksm_init_max_kernel_pages(); 1671 ksm_max_kernel_pages = totalram_pages / 4;
1677 1672
1678 err = ksm_slab_init(); 1673 err = ksm_slab_init();
1679 if (err) 1674 if (err)
@@ -1697,6 +1692,9 @@ static int __init ksm_init(void)
1697 kthread_stop(ksm_thread); 1692 kthread_stop(ksm_thread);
1698 goto out_free2; 1693 goto out_free2;
1699 } 1694 }
1695#else
1696 ksm_run = KSM_RUN_MERGE; /* no way for user to start it */
1697
1700#endif /* CONFIG_SYSFS */ 1698#endif /* CONFIG_SYSFS */
1701 1699
1702 return 0; 1700 return 0;
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index e2b98a6875c0..f99f5991d6bb 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -313,7 +313,8 @@ soft_limit_tree_from_page(struct page *page)
313static void 313static void
314__mem_cgroup_insert_exceeded(struct mem_cgroup *mem, 314__mem_cgroup_insert_exceeded(struct mem_cgroup *mem,
315 struct mem_cgroup_per_zone *mz, 315 struct mem_cgroup_per_zone *mz,
316 struct mem_cgroup_tree_per_zone *mctz) 316 struct mem_cgroup_tree_per_zone *mctz,
317 unsigned long long new_usage_in_excess)
317{ 318{
318 struct rb_node **p = &mctz->rb_root.rb_node; 319 struct rb_node **p = &mctz->rb_root.rb_node;
319 struct rb_node *parent = NULL; 320 struct rb_node *parent = NULL;
@@ -322,7 +323,9 @@ __mem_cgroup_insert_exceeded(struct mem_cgroup *mem,
322 if (mz->on_tree) 323 if (mz->on_tree)
323 return; 324 return;
324 325
325 mz->usage_in_excess = res_counter_soft_limit_excess(&mem->res); 326 mz->usage_in_excess = new_usage_in_excess;
327 if (!mz->usage_in_excess)
328 return;
326 while (*p) { 329 while (*p) {
327 parent = *p; 330 parent = *p;
328 mz_node = rb_entry(parent, struct mem_cgroup_per_zone, 331 mz_node = rb_entry(parent, struct mem_cgroup_per_zone,
@@ -353,16 +356,6 @@ __mem_cgroup_remove_exceeded(struct mem_cgroup *mem,
353} 356}
354 357
355static void 358static void
356mem_cgroup_insert_exceeded(struct mem_cgroup *mem,
357 struct mem_cgroup_per_zone *mz,
358 struct mem_cgroup_tree_per_zone *mctz)
359{
360 spin_lock(&mctz->lock);
361 __mem_cgroup_insert_exceeded(mem, mz, mctz);
362 spin_unlock(&mctz->lock);
363}
364
365static void
366mem_cgroup_remove_exceeded(struct mem_cgroup *mem, 359mem_cgroup_remove_exceeded(struct mem_cgroup *mem,
367 struct mem_cgroup_per_zone *mz, 360 struct mem_cgroup_per_zone *mz,
368 struct mem_cgroup_tree_per_zone *mctz) 361 struct mem_cgroup_tree_per_zone *mctz)
@@ -392,34 +385,36 @@ static bool mem_cgroup_soft_limit_check(struct mem_cgroup *mem)
392 385
393static void mem_cgroup_update_tree(struct mem_cgroup *mem, struct page *page) 386static void mem_cgroup_update_tree(struct mem_cgroup *mem, struct page *page)
394{ 387{
395 unsigned long long prev_usage_in_excess, new_usage_in_excess; 388 unsigned long long excess;
396 bool updated_tree = false;
397 struct mem_cgroup_per_zone *mz; 389 struct mem_cgroup_per_zone *mz;
398 struct mem_cgroup_tree_per_zone *mctz; 390 struct mem_cgroup_tree_per_zone *mctz;
399 391 int nid = page_to_nid(page);
400 mz = mem_cgroup_zoneinfo(mem, page_to_nid(page), page_zonenum(page)); 392 int zid = page_zonenum(page);
401 mctz = soft_limit_tree_from_page(page); 393 mctz = soft_limit_tree_from_page(page);
402 394
403 /* 395 /*
404 * We do updates in lazy mode, mem's are removed 396 * Necessary to update all ancestors when hierarchy is used.
405 * lazily from the per-zone, per-node rb tree 397 * because their event counter is not touched.
406 */ 398 */
407 prev_usage_in_excess = mz->usage_in_excess; 399 for (; mem; mem = parent_mem_cgroup(mem)) {
408 400 mz = mem_cgroup_zoneinfo(mem, nid, zid);
409 new_usage_in_excess = res_counter_soft_limit_excess(&mem->res); 401 excess = res_counter_soft_limit_excess(&mem->res);
410 if (prev_usage_in_excess) { 402 /*
411 mem_cgroup_remove_exceeded(mem, mz, mctz); 403 * We have to update the tree if mz is on RB-tree or
412 updated_tree = true; 404 * mem is over its softlimit.
413 } 405 */
414 if (!new_usage_in_excess) 406 if (excess || mz->on_tree) {
415 goto done; 407 spin_lock(&mctz->lock);
416 mem_cgroup_insert_exceeded(mem, mz, mctz); 408 /* if on-tree, remove it */
417 409 if (mz->on_tree)
418done: 410 __mem_cgroup_remove_exceeded(mem, mz, mctz);
419 if (updated_tree) { 411 /*
420 spin_lock(&mctz->lock); 412 * Insert again. mz->usage_in_excess will be updated.
421 mz->usage_in_excess = new_usage_in_excess; 413 * If excess is 0, no tree ops.
422 spin_unlock(&mctz->lock); 414 */
415 __mem_cgroup_insert_exceeded(mem, mz, mctz, excess);
416 spin_unlock(&mctz->lock);
417 }
423 } 418 }
424} 419}
425 420
@@ -447,9 +442,10 @@ static struct mem_cgroup_per_zone *
447__mem_cgroup_largest_soft_limit_node(struct mem_cgroup_tree_per_zone *mctz) 442__mem_cgroup_largest_soft_limit_node(struct mem_cgroup_tree_per_zone *mctz)
448{ 443{
449 struct rb_node *rightmost = NULL; 444 struct rb_node *rightmost = NULL;
450 struct mem_cgroup_per_zone *mz = NULL; 445 struct mem_cgroup_per_zone *mz;
451 446
452retry: 447retry:
448 mz = NULL;
453 rightmost = rb_last(&mctz->rb_root); 449 rightmost = rb_last(&mctz->rb_root);
454 if (!rightmost) 450 if (!rightmost)
455 goto done; /* Nothing to reclaim from */ 451 goto done; /* Nothing to reclaim from */
@@ -1270,9 +1266,9 @@ static int __mem_cgroup_try_charge(struct mm_struct *mm,
1270 gfp_t gfp_mask, struct mem_cgroup **memcg, 1266 gfp_t gfp_mask, struct mem_cgroup **memcg,
1271 bool oom, struct page *page) 1267 bool oom, struct page *page)
1272{ 1268{
1273 struct mem_cgroup *mem, *mem_over_limit, *mem_over_soft_limit; 1269 struct mem_cgroup *mem, *mem_over_limit;
1274 int nr_retries = MEM_CGROUP_RECLAIM_RETRIES; 1270 int nr_retries = MEM_CGROUP_RECLAIM_RETRIES;
1275 struct res_counter *fail_res, *soft_fail_res = NULL; 1271 struct res_counter *fail_res;
1276 1272
1277 if (unlikely(test_thread_flag(TIF_MEMDIE))) { 1273 if (unlikely(test_thread_flag(TIF_MEMDIE))) {
1278 /* Don't account this! */ 1274 /* Don't account this! */
@@ -1304,17 +1300,16 @@ static int __mem_cgroup_try_charge(struct mm_struct *mm,
1304 1300
1305 if (mem_cgroup_is_root(mem)) 1301 if (mem_cgroup_is_root(mem))
1306 goto done; 1302 goto done;
1307 ret = res_counter_charge(&mem->res, PAGE_SIZE, &fail_res, 1303 ret = res_counter_charge(&mem->res, PAGE_SIZE, &fail_res);
1308 &soft_fail_res);
1309 if (likely(!ret)) { 1304 if (likely(!ret)) {
1310 if (!do_swap_account) 1305 if (!do_swap_account)
1311 break; 1306 break;
1312 ret = res_counter_charge(&mem->memsw, PAGE_SIZE, 1307 ret = res_counter_charge(&mem->memsw, PAGE_SIZE,
1313 &fail_res, NULL); 1308 &fail_res);
1314 if (likely(!ret)) 1309 if (likely(!ret))
1315 break; 1310 break;
1316 /* mem+swap counter fails */ 1311 /* mem+swap counter fails */
1317 res_counter_uncharge(&mem->res, PAGE_SIZE, NULL); 1312 res_counter_uncharge(&mem->res, PAGE_SIZE);
1318 flags |= MEM_CGROUP_RECLAIM_NOSWAP; 1313 flags |= MEM_CGROUP_RECLAIM_NOSWAP;
1319 mem_over_limit = mem_cgroup_from_res_counter(fail_res, 1314 mem_over_limit = mem_cgroup_from_res_counter(fail_res,
1320 memsw); 1315 memsw);
@@ -1353,16 +1348,11 @@ static int __mem_cgroup_try_charge(struct mm_struct *mm,
1353 } 1348 }
1354 } 1349 }
1355 /* 1350 /*
1356 * Insert just the ancestor, we should trickle down to the correct 1351 * Insert ancestor (and ancestor's ancestors), to softlimit RB-tree.
1357 * cgroup for reclaim, since the other nodes will be below their 1352 * if they exceeds softlimit.
1358 * soft limit
1359 */ 1353 */
1360 if (soft_fail_res) { 1354 if (mem_cgroup_soft_limit_check(mem))
1361 mem_over_soft_limit = 1355 mem_cgroup_update_tree(mem, page);
1362 mem_cgroup_from_res_counter(soft_fail_res, res);
1363 if (mem_cgroup_soft_limit_check(mem_over_soft_limit))
1364 mem_cgroup_update_tree(mem_over_soft_limit, page);
1365 }
1366done: 1356done:
1367 return 0; 1357 return 0;
1368nomem: 1358nomem:
@@ -1437,10 +1427,9 @@ static void __mem_cgroup_commit_charge(struct mem_cgroup *mem,
1437 if (unlikely(PageCgroupUsed(pc))) { 1427 if (unlikely(PageCgroupUsed(pc))) {
1438 unlock_page_cgroup(pc); 1428 unlock_page_cgroup(pc);
1439 if (!mem_cgroup_is_root(mem)) { 1429 if (!mem_cgroup_is_root(mem)) {
1440 res_counter_uncharge(&mem->res, PAGE_SIZE, NULL); 1430 res_counter_uncharge(&mem->res, PAGE_SIZE);
1441 if (do_swap_account) 1431 if (do_swap_account)
1442 res_counter_uncharge(&mem->memsw, PAGE_SIZE, 1432 res_counter_uncharge(&mem->memsw, PAGE_SIZE);
1443 NULL);
1444 } 1433 }
1445 css_put(&mem->css); 1434 css_put(&mem->css);
1446 return; 1435 return;
@@ -1519,7 +1508,7 @@ static int mem_cgroup_move_account(struct page_cgroup *pc,
1519 goto out; 1508 goto out;
1520 1509
1521 if (!mem_cgroup_is_root(from)) 1510 if (!mem_cgroup_is_root(from))
1522 res_counter_uncharge(&from->res, PAGE_SIZE, NULL); 1511 res_counter_uncharge(&from->res, PAGE_SIZE);
1523 mem_cgroup_charge_statistics(from, pc, false); 1512 mem_cgroup_charge_statistics(from, pc, false);
1524 1513
1525 page = pc->page; 1514 page = pc->page;
@@ -1539,7 +1528,7 @@ static int mem_cgroup_move_account(struct page_cgroup *pc,
1539 } 1528 }
1540 1529
1541 if (do_swap_account && !mem_cgroup_is_root(from)) 1530 if (do_swap_account && !mem_cgroup_is_root(from))
1542 res_counter_uncharge(&from->memsw, PAGE_SIZE, NULL); 1531 res_counter_uncharge(&from->memsw, PAGE_SIZE);
1543 css_put(&from->css); 1532 css_put(&from->css);
1544 1533
1545 css_get(&to->css); 1534 css_get(&to->css);
@@ -1610,9 +1599,9 @@ uncharge:
1610 css_put(&parent->css); 1599 css_put(&parent->css);
1611 /* uncharge if move fails */ 1600 /* uncharge if move fails */
1612 if (!mem_cgroup_is_root(parent)) { 1601 if (!mem_cgroup_is_root(parent)) {
1613 res_counter_uncharge(&parent->res, PAGE_SIZE, NULL); 1602 res_counter_uncharge(&parent->res, PAGE_SIZE);
1614 if (do_swap_account) 1603 if (do_swap_account)
1615 res_counter_uncharge(&parent->memsw, PAGE_SIZE, NULL); 1604 res_counter_uncharge(&parent->memsw, PAGE_SIZE);
1616 } 1605 }
1617 return ret; 1606 return ret;
1618} 1607}
@@ -1803,8 +1792,7 @@ __mem_cgroup_commit_charge_swapin(struct page *page, struct mem_cgroup *ptr,
1803 * calling css_tryget 1792 * calling css_tryget
1804 */ 1793 */
1805 if (!mem_cgroup_is_root(memcg)) 1794 if (!mem_cgroup_is_root(memcg))
1806 res_counter_uncharge(&memcg->memsw, PAGE_SIZE, 1795 res_counter_uncharge(&memcg->memsw, PAGE_SIZE);
1807 NULL);
1808 mem_cgroup_swap_statistics(memcg, false); 1796 mem_cgroup_swap_statistics(memcg, false);
1809 mem_cgroup_put(memcg); 1797 mem_cgroup_put(memcg);
1810 } 1798 }
@@ -1831,9 +1819,9 @@ void mem_cgroup_cancel_charge_swapin(struct mem_cgroup *mem)
1831 if (!mem) 1819 if (!mem)
1832 return; 1820 return;
1833 if (!mem_cgroup_is_root(mem)) { 1821 if (!mem_cgroup_is_root(mem)) {
1834 res_counter_uncharge(&mem->res, PAGE_SIZE, NULL); 1822 res_counter_uncharge(&mem->res, PAGE_SIZE);
1835 if (do_swap_account) 1823 if (do_swap_account)
1836 res_counter_uncharge(&mem->memsw, PAGE_SIZE, NULL); 1824 res_counter_uncharge(&mem->memsw, PAGE_SIZE);
1837 } 1825 }
1838 css_put(&mem->css); 1826 css_put(&mem->css);
1839} 1827}
@@ -1848,7 +1836,6 @@ __mem_cgroup_uncharge_common(struct page *page, enum charge_type ctype)
1848 struct page_cgroup *pc; 1836 struct page_cgroup *pc;
1849 struct mem_cgroup *mem = NULL; 1837 struct mem_cgroup *mem = NULL;
1850 struct mem_cgroup_per_zone *mz; 1838 struct mem_cgroup_per_zone *mz;
1851 bool soft_limit_excess = false;
1852 1839
1853 if (mem_cgroup_disabled()) 1840 if (mem_cgroup_disabled())
1854 return NULL; 1841 return NULL;
@@ -1888,10 +1875,10 @@ __mem_cgroup_uncharge_common(struct page *page, enum charge_type ctype)
1888 } 1875 }
1889 1876
1890 if (!mem_cgroup_is_root(mem)) { 1877 if (!mem_cgroup_is_root(mem)) {
1891 res_counter_uncharge(&mem->res, PAGE_SIZE, &soft_limit_excess); 1878 res_counter_uncharge(&mem->res, PAGE_SIZE);
1892 if (do_swap_account && 1879 if (do_swap_account &&
1893 (ctype != MEM_CGROUP_CHARGE_TYPE_SWAPOUT)) 1880 (ctype != MEM_CGROUP_CHARGE_TYPE_SWAPOUT))
1894 res_counter_uncharge(&mem->memsw, PAGE_SIZE, NULL); 1881 res_counter_uncharge(&mem->memsw, PAGE_SIZE);
1895 } 1882 }
1896 if (ctype == MEM_CGROUP_CHARGE_TYPE_SWAPOUT) 1883 if (ctype == MEM_CGROUP_CHARGE_TYPE_SWAPOUT)
1897 mem_cgroup_swap_statistics(mem, true); 1884 mem_cgroup_swap_statistics(mem, true);
@@ -1908,7 +1895,7 @@ __mem_cgroup_uncharge_common(struct page *page, enum charge_type ctype)
1908 mz = page_cgroup_zoneinfo(pc); 1895 mz = page_cgroup_zoneinfo(pc);
1909 unlock_page_cgroup(pc); 1896 unlock_page_cgroup(pc);
1910 1897
1911 if (soft_limit_excess && mem_cgroup_soft_limit_check(mem)) 1898 if (mem_cgroup_soft_limit_check(mem))
1912 mem_cgroup_update_tree(mem, page); 1899 mem_cgroup_update_tree(mem, page);
1913 /* at swapout, this memcg will be accessed to record to swap */ 1900 /* at swapout, this memcg will be accessed to record to swap */
1914 if (ctype != MEM_CGROUP_CHARGE_TYPE_SWAPOUT) 1901 if (ctype != MEM_CGROUP_CHARGE_TYPE_SWAPOUT)
@@ -1986,7 +1973,7 @@ void mem_cgroup_uncharge_swap(swp_entry_t ent)
1986 * This memcg can be obsolete one. We avoid calling css_tryget 1973 * This memcg can be obsolete one. We avoid calling css_tryget
1987 */ 1974 */
1988 if (!mem_cgroup_is_root(memcg)) 1975 if (!mem_cgroup_is_root(memcg))
1989 res_counter_uncharge(&memcg->memsw, PAGE_SIZE, NULL); 1976 res_counter_uncharge(&memcg->memsw, PAGE_SIZE);
1990 mem_cgroup_swap_statistics(memcg, false); 1977 mem_cgroup_swap_statistics(memcg, false);
1991 mem_cgroup_put(memcg); 1978 mem_cgroup_put(memcg);
1992 } 1979 }
@@ -2233,6 +2220,7 @@ unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order,
2233 unsigned long reclaimed; 2220 unsigned long reclaimed;
2234 int loop = 0; 2221 int loop = 0;
2235 struct mem_cgroup_tree_per_zone *mctz; 2222 struct mem_cgroup_tree_per_zone *mctz;
2223 unsigned long long excess;
2236 2224
2237 if (order > 0) 2225 if (order > 0)
2238 return 0; 2226 return 0;
@@ -2284,9 +2272,8 @@ unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order,
2284 break; 2272 break;
2285 } while (1); 2273 } while (1);
2286 } 2274 }
2287 mz->usage_in_excess =
2288 res_counter_soft_limit_excess(&mz->mem->res);
2289 __mem_cgroup_remove_exceeded(mz->mem, mz, mctz); 2275 __mem_cgroup_remove_exceeded(mz->mem, mz, mctz);
2276 excess = res_counter_soft_limit_excess(&mz->mem->res);
2290 /* 2277 /*
2291 * One school of thought says that we should not add 2278 * One school of thought says that we should not add
2292 * back the node to the tree if reclaim returns 0. 2279 * back the node to the tree if reclaim returns 0.
@@ -2295,8 +2282,8 @@ unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order,
2295 * memory to reclaim from. Consider this as a longer 2282 * memory to reclaim from. Consider this as a longer
2296 * term TODO. 2283 * term TODO.
2297 */ 2284 */
2298 if (mz->usage_in_excess) 2285 /* If excess == 0, no tree ops */
2299 __mem_cgroup_insert_exceeded(mz->mem, mz, mctz); 2286 __mem_cgroup_insert_exceeded(mz->mem, mz, mctz, excess);
2300 spin_unlock(&mctz->lock); 2287 spin_unlock(&mctz->lock);
2301 css_put(&mz->mem->css); 2288 css_put(&mz->mem->css);
2302 loop++; 2289 loop++;
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index a3b14090b1fb..2c5d79236ead 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -566,7 +566,8 @@ static void balance_dirty_pages(struct address_space *mapping,
566 if (pages_written >= write_chunk) 566 if (pages_written >= write_chunk)
567 break; /* We've done our duty */ 567 break; /* We've done our duty */
568 568
569 schedule_timeout_interruptible(pause); 569 __set_current_state(TASK_INTERRUPTIBLE);
570 io_schedule_timeout(pause);
570 571
571 /* 572 /*
572 * Increase the delay for each loop, up to our previous 573 * Increase the delay for each loop, up to our previous
diff --git a/mm/percpu.c b/mm/percpu.c
index 4a048abad043..6af78c1ee704 100644
--- a/mm/percpu.c
+++ b/mm/percpu.c
@@ -1870,13 +1870,14 @@ int __init pcpu_embed_first_chunk(size_t reserved_size, ssize_t dyn_size,
1870 max_distance = 0; 1870 max_distance = 0;
1871 for (group = 0; group < ai->nr_groups; group++) { 1871 for (group = 0; group < ai->nr_groups; group++) {
1872 ai->groups[group].base_offset = areas[group] - base; 1872 ai->groups[group].base_offset = areas[group] - base;
1873 max_distance = max(max_distance, ai->groups[group].base_offset); 1873 max_distance = max_t(size_t, max_distance,
1874 ai->groups[group].base_offset);
1874 } 1875 }
1875 max_distance += ai->unit_size; 1876 max_distance += ai->unit_size;
1876 1877
1877 /* warn if maximum distance is further than 75% of vmalloc space */ 1878 /* warn if maximum distance is further than 75% of vmalloc space */
1878 if (max_distance > (VMALLOC_END - VMALLOC_START) * 3 / 4) { 1879 if (max_distance > (VMALLOC_END - VMALLOC_START) * 3 / 4) {
1879 pr_warning("PERCPU: max_distance=0x%lx too large for vmalloc " 1880 pr_warning("PERCPU: max_distance=0x%zx too large for vmalloc "
1880 "space 0x%lx\n", 1881 "space 0x%lx\n",
1881 max_distance, VMALLOC_END - VMALLOC_START); 1882 max_distance, VMALLOC_END - VMALLOC_START);
1882#ifdef CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK 1883#ifdef CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK
diff --git a/mm/rmap.c b/mm/rmap.c
index 28aafe2b5306..dd43373a483f 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -242,8 +242,8 @@ vma_address(struct page *page, struct vm_area_struct *vma)
242} 242}
243 243
244/* 244/*
245 * At what user virtual address is page expected in vma? checking that the 245 * At what user virtual address is page expected in vma?
246 * page matches the vma: currently only used on anon pages, by unuse_vma; 246 * checking that the page matches the vma.
247 */ 247 */
248unsigned long page_address_in_vma(struct page *page, struct vm_area_struct *vma) 248unsigned long page_address_in_vma(struct page *page, struct vm_area_struct *vma)
249{ 249{
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 4de7f02f820b..a1bc6b9af9a2 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -1974,12 +1974,14 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
1974 goto bad_swap; 1974 goto bad_swap;
1975 } 1975 }
1976 1976
1977 if (blk_queue_nonrot(bdev_get_queue(p->bdev))) { 1977 if (p->bdev) {
1978 p->flags |= SWP_SOLIDSTATE; 1978 if (blk_queue_nonrot(bdev_get_queue(p->bdev))) {
1979 p->cluster_next = 1 + (random32() % p->highest_bit); 1979 p->flags |= SWP_SOLIDSTATE;
1980 p->cluster_next = 1 + (random32() % p->highest_bit);
1981 }
1982 if (discard_swap(p) == 0)
1983 p->flags |= SWP_DISCARDABLE;
1980 } 1984 }
1981 if (discard_swap(p) == 0)
1982 p->flags |= SWP_DISCARDABLE;
1983 1985
1984 mutex_lock(&swapon_mutex); 1986 mutex_lock(&swapon_mutex);
1985 spin_lock(&swap_lock); 1987 spin_lock(&swap_lock);
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 69511e663234..0f551a4a44cd 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -12,6 +12,7 @@
12#include <linux/mm.h> 12#include <linux/mm.h>
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/highmem.h> 14#include <linux/highmem.h>
15#include <linux/sched.h>
15#include <linux/slab.h> 16#include <linux/slab.h>
16#include <linux/spinlock.h> 17#include <linux/spinlock.h>
17#include <linux/interrupt.h> 18#include <linux/interrupt.h>
@@ -25,10 +26,10 @@
25#include <linux/rcupdate.h> 26#include <linux/rcupdate.h>
26#include <linux/pfn.h> 27#include <linux/pfn.h>
27#include <linux/kmemleak.h> 28#include <linux/kmemleak.h>
28#include <linux/highmem.h>
29#include <asm/atomic.h> 29#include <asm/atomic.h>
30#include <asm/uaccess.h> 30#include <asm/uaccess.h>
31#include <asm/tlbflush.h> 31#include <asm/tlbflush.h>
32#include <asm/shmparam.h>
32 33
33 34
34/*** Page table manipulation functions ***/ 35/*** Page table manipulation functions ***/
@@ -1156,12 +1157,11 @@ static void insert_vmalloc_vm(struct vm_struct *vm, struct vmap_area *va,
1156} 1157}
1157 1158
1158static struct vm_struct *__get_vm_area_node(unsigned long size, 1159static struct vm_struct *__get_vm_area_node(unsigned long size,
1159 unsigned long flags, unsigned long start, unsigned long end, 1160 unsigned long align, unsigned long flags, unsigned long start,
1160 int node, gfp_t gfp_mask, void *caller) 1161 unsigned long end, int node, gfp_t gfp_mask, void *caller)
1161{ 1162{
1162 static struct vmap_area *va; 1163 static struct vmap_area *va;
1163 struct vm_struct *area; 1164 struct vm_struct *area;
1164 unsigned long align = 1;
1165 1165
1166 BUG_ON(in_interrupt()); 1166 BUG_ON(in_interrupt());
1167 if (flags & VM_IOREMAP) { 1167 if (flags & VM_IOREMAP) {
@@ -1201,7 +1201,7 @@ static struct vm_struct *__get_vm_area_node(unsigned long size,
1201struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags, 1201struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags,
1202 unsigned long start, unsigned long end) 1202 unsigned long start, unsigned long end)
1203{ 1203{
1204 return __get_vm_area_node(size, flags, start, end, -1, GFP_KERNEL, 1204 return __get_vm_area_node(size, 1, flags, start, end, -1, GFP_KERNEL,
1205 __builtin_return_address(0)); 1205 __builtin_return_address(0));
1206} 1206}
1207EXPORT_SYMBOL_GPL(__get_vm_area); 1207EXPORT_SYMBOL_GPL(__get_vm_area);
@@ -1210,7 +1210,7 @@ struct vm_struct *__get_vm_area_caller(unsigned long size, unsigned long flags,
1210 unsigned long start, unsigned long end, 1210 unsigned long start, unsigned long end,
1211 void *caller) 1211 void *caller)
1212{ 1212{
1213 return __get_vm_area_node(size, flags, start, end, -1, GFP_KERNEL, 1213 return __get_vm_area_node(size, 1, flags, start, end, -1, GFP_KERNEL,
1214 caller); 1214 caller);
1215} 1215}
1216 1216
@@ -1225,22 +1225,22 @@ struct vm_struct *__get_vm_area_caller(unsigned long size, unsigned long flags,
1225 */ 1225 */
1226struct vm_struct *get_vm_area(unsigned long size, unsigned long flags) 1226struct vm_struct *get_vm_area(unsigned long size, unsigned long flags)
1227{ 1227{
1228 return __get_vm_area_node(size, flags, VMALLOC_START, VMALLOC_END, 1228 return __get_vm_area_node(size, 1, flags, VMALLOC_START, VMALLOC_END,
1229 -1, GFP_KERNEL, __builtin_return_address(0)); 1229 -1, GFP_KERNEL, __builtin_return_address(0));
1230} 1230}
1231 1231
1232struct vm_struct *get_vm_area_caller(unsigned long size, unsigned long flags, 1232struct vm_struct *get_vm_area_caller(unsigned long size, unsigned long flags,
1233 void *caller) 1233 void *caller)
1234{ 1234{
1235 return __get_vm_area_node(size, flags, VMALLOC_START, VMALLOC_END, 1235 return __get_vm_area_node(size, 1, flags, VMALLOC_START, VMALLOC_END,
1236 -1, GFP_KERNEL, caller); 1236 -1, GFP_KERNEL, caller);
1237} 1237}
1238 1238
1239struct vm_struct *get_vm_area_node(unsigned long size, unsigned long flags, 1239struct vm_struct *get_vm_area_node(unsigned long size, unsigned long flags,
1240 int node, gfp_t gfp_mask) 1240 int node, gfp_t gfp_mask)
1241{ 1241{
1242 return __get_vm_area_node(size, flags, VMALLOC_START, VMALLOC_END, node, 1242 return __get_vm_area_node(size, 1, flags, VMALLOC_START, VMALLOC_END,
1243 gfp_mask, __builtin_return_address(0)); 1243 node, gfp_mask, __builtin_return_address(0));
1244} 1244}
1245 1245
1246static struct vm_struct *find_vm_area(const void *addr) 1246static struct vm_struct *find_vm_area(const void *addr)
@@ -1403,7 +1403,8 @@ void *vmap(struct page **pages, unsigned int count,
1403} 1403}
1404EXPORT_SYMBOL(vmap); 1404EXPORT_SYMBOL(vmap);
1405 1405
1406static void *__vmalloc_node(unsigned long size, gfp_t gfp_mask, pgprot_t prot, 1406static void *__vmalloc_node(unsigned long size, unsigned long align,
1407 gfp_t gfp_mask, pgprot_t prot,
1407 int node, void *caller); 1408 int node, void *caller);
1408static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask, 1409static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
1409 pgprot_t prot, int node, void *caller) 1410 pgprot_t prot, int node, void *caller)
@@ -1417,7 +1418,7 @@ static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
1417 area->nr_pages = nr_pages; 1418 area->nr_pages = nr_pages;
1418 /* Please note that the recursion is strictly bounded. */ 1419 /* Please note that the recursion is strictly bounded. */
1419 if (array_size > PAGE_SIZE) { 1420 if (array_size > PAGE_SIZE) {
1420 pages = __vmalloc_node(array_size, gfp_mask | __GFP_ZERO, 1421 pages = __vmalloc_node(array_size, 1, gfp_mask | __GFP_ZERO,
1421 PAGE_KERNEL, node, caller); 1422 PAGE_KERNEL, node, caller);
1422 area->flags |= VM_VPAGES; 1423 area->flags |= VM_VPAGES;
1423 } else { 1424 } else {
@@ -1476,6 +1477,7 @@ void *__vmalloc_area(struct vm_struct *area, gfp_t gfp_mask, pgprot_t prot)
1476/** 1477/**
1477 * __vmalloc_node - allocate virtually contiguous memory 1478 * __vmalloc_node - allocate virtually contiguous memory
1478 * @size: allocation size 1479 * @size: allocation size
1480 * @align: desired alignment
1479 * @gfp_mask: flags for the page level allocator 1481 * @gfp_mask: flags for the page level allocator
1480 * @prot: protection mask for the allocated pages 1482 * @prot: protection mask for the allocated pages
1481 * @node: node to use for allocation or -1 1483 * @node: node to use for allocation or -1
@@ -1485,8 +1487,9 @@ void *__vmalloc_area(struct vm_struct *area, gfp_t gfp_mask, pgprot_t prot)
1485 * allocator with @gfp_mask flags. Map them into contiguous 1487 * allocator with @gfp_mask flags. Map them into contiguous
1486 * kernel virtual space, using a pagetable protection of @prot. 1488 * kernel virtual space, using a pagetable protection of @prot.
1487 */ 1489 */
1488static void *__vmalloc_node(unsigned long size, gfp_t gfp_mask, pgprot_t prot, 1490static void *__vmalloc_node(unsigned long size, unsigned long align,
1489 int node, void *caller) 1491 gfp_t gfp_mask, pgprot_t prot,
1492 int node, void *caller)
1490{ 1493{
1491 struct vm_struct *area; 1494 struct vm_struct *area;
1492 void *addr; 1495 void *addr;
@@ -1496,8 +1499,8 @@ static void *__vmalloc_node(unsigned long size, gfp_t gfp_mask, pgprot_t prot,
1496 if (!size || (size >> PAGE_SHIFT) > totalram_pages) 1499 if (!size || (size >> PAGE_SHIFT) > totalram_pages)
1497 return NULL; 1500 return NULL;
1498 1501
1499 area = __get_vm_area_node(size, VM_ALLOC, VMALLOC_START, VMALLOC_END, 1502 area = __get_vm_area_node(size, align, VM_ALLOC, VMALLOC_START,
1500 node, gfp_mask, caller); 1503 VMALLOC_END, node, gfp_mask, caller);
1501 1504
1502 if (!area) 1505 if (!area)
1503 return NULL; 1506 return NULL;
@@ -1516,7 +1519,7 @@ static void *__vmalloc_node(unsigned long size, gfp_t gfp_mask, pgprot_t prot,
1516 1519
1517void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot) 1520void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot)
1518{ 1521{
1519 return __vmalloc_node(size, gfp_mask, prot, -1, 1522 return __vmalloc_node(size, 1, gfp_mask, prot, -1,
1520 __builtin_return_address(0)); 1523 __builtin_return_address(0));
1521} 1524}
1522EXPORT_SYMBOL(__vmalloc); 1525EXPORT_SYMBOL(__vmalloc);
@@ -1532,7 +1535,7 @@ EXPORT_SYMBOL(__vmalloc);
1532 */ 1535 */
1533void *vmalloc(unsigned long size) 1536void *vmalloc(unsigned long size)
1534{ 1537{
1535 return __vmalloc_node(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL, 1538 return __vmalloc_node(size, 1, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL,
1536 -1, __builtin_return_address(0)); 1539 -1, __builtin_return_address(0));
1537} 1540}
1538EXPORT_SYMBOL(vmalloc); 1541EXPORT_SYMBOL(vmalloc);
@@ -1549,7 +1552,8 @@ void *vmalloc_user(unsigned long size)
1549 struct vm_struct *area; 1552 struct vm_struct *area;
1550 void *ret; 1553 void *ret;
1551 1554
1552 ret = __vmalloc_node(size, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, 1555 ret = __vmalloc_node(size, SHMLBA,
1556 GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO,
1553 PAGE_KERNEL, -1, __builtin_return_address(0)); 1557 PAGE_KERNEL, -1, __builtin_return_address(0));
1554 if (ret) { 1558 if (ret) {
1555 area = find_vm_area(ret); 1559 area = find_vm_area(ret);
@@ -1572,7 +1576,7 @@ EXPORT_SYMBOL(vmalloc_user);
1572 */ 1576 */
1573void *vmalloc_node(unsigned long size, int node) 1577void *vmalloc_node(unsigned long size, int node)
1574{ 1578{
1575 return __vmalloc_node(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL, 1579 return __vmalloc_node(size, 1, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL,
1576 node, __builtin_return_address(0)); 1580 node, __builtin_return_address(0));
1577} 1581}
1578EXPORT_SYMBOL(vmalloc_node); 1582EXPORT_SYMBOL(vmalloc_node);
@@ -1595,7 +1599,7 @@ EXPORT_SYMBOL(vmalloc_node);
1595 1599
1596void *vmalloc_exec(unsigned long size) 1600void *vmalloc_exec(unsigned long size)
1597{ 1601{
1598 return __vmalloc_node(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL_EXEC, 1602 return __vmalloc_node(size, 1, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL_EXEC,
1599 -1, __builtin_return_address(0)); 1603 -1, __builtin_return_address(0));
1600} 1604}
1601 1605
@@ -1616,7 +1620,7 @@ void *vmalloc_exec(unsigned long size)
1616 */ 1620 */
1617void *vmalloc_32(unsigned long size) 1621void *vmalloc_32(unsigned long size)
1618{ 1622{
1619 return __vmalloc_node(size, GFP_VMALLOC32, PAGE_KERNEL, 1623 return __vmalloc_node(size, 1, GFP_VMALLOC32, PAGE_KERNEL,
1620 -1, __builtin_return_address(0)); 1624 -1, __builtin_return_address(0));
1621} 1625}
1622EXPORT_SYMBOL(vmalloc_32); 1626EXPORT_SYMBOL(vmalloc_32);
@@ -1633,7 +1637,7 @@ void *vmalloc_32_user(unsigned long size)
1633 struct vm_struct *area; 1637 struct vm_struct *area;
1634 void *ret; 1638 void *ret;
1635 1639
1636 ret = __vmalloc_node(size, GFP_VMALLOC32 | __GFP_ZERO, PAGE_KERNEL, 1640 ret = __vmalloc_node(size, 1, GFP_VMALLOC32 | __GFP_ZERO, PAGE_KERNEL,
1637 -1, __builtin_return_address(0)); 1641 -1, __builtin_return_address(0));
1638 if (ret) { 1642 if (ret) {
1639 area = find_vm_area(ret); 1643 area = find_vm_area(ret);
diff --git a/net/atm/common.c b/net/atm/common.c
index 8c4d843eb17f..950bd16d2383 100644
--- a/net/atm/common.c
+++ b/net/atm/common.c
@@ -679,7 +679,7 @@ static int check_qos(const struct atm_qos *qos)
679} 679}
680 680
681int vcc_setsockopt(struct socket *sock, int level, int optname, 681int vcc_setsockopt(struct socket *sock, int level, int optname,
682 char __user *optval, int optlen) 682 char __user *optval, unsigned int optlen)
683{ 683{
684 struct atm_vcc *vcc; 684 struct atm_vcc *vcc;
685 unsigned long value; 685 unsigned long value;
diff --git a/net/atm/common.h b/net/atm/common.h
index 92e2981f479f..f48a76b6cdf4 100644
--- a/net/atm/common.h
+++ b/net/atm/common.h
@@ -21,7 +21,7 @@ unsigned int vcc_poll(struct file *file, struct socket *sock, poll_table *wait);
21int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg); 21int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
22int vcc_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg); 22int vcc_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
23int vcc_setsockopt(struct socket *sock, int level, int optname, 23int vcc_setsockopt(struct socket *sock, int level, int optname,
24 char __user *optval, int optlen); 24 char __user *optval, unsigned int optlen);
25int vcc_getsockopt(struct socket *sock, int level, int optname, 25int vcc_getsockopt(struct socket *sock, int level, int optname,
26 char __user *optval, int __user *optlen); 26 char __user *optval, int __user *optlen);
27 27
diff --git a/net/atm/pvc.c b/net/atm/pvc.c
index e1d22d9430dd..d4c024504f99 100644
--- a/net/atm/pvc.c
+++ b/net/atm/pvc.c
@@ -59,7 +59,7 @@ static int pvc_connect(struct socket *sock,struct sockaddr *sockaddr,
59} 59}
60 60
61static int pvc_setsockopt(struct socket *sock, int level, int optname, 61static int pvc_setsockopt(struct socket *sock, int level, int optname,
62 char __user *optval, int optlen) 62 char __user *optval, unsigned int optlen)
63{ 63{
64 struct sock *sk = sock->sk; 64 struct sock *sk = sock->sk;
65 int error; 65 int error;
diff --git a/net/atm/svc.c b/net/atm/svc.c
index 7b831b526d0b..f90d143c4b25 100644
--- a/net/atm/svc.c
+++ b/net/atm/svc.c
@@ -446,7 +446,7 @@ int svc_change_qos(struct atm_vcc *vcc,struct atm_qos *qos)
446 446
447 447
448static int svc_setsockopt(struct socket *sock, int level, int optname, 448static int svc_setsockopt(struct socket *sock, int level, int optname,
449 char __user *optval, int optlen) 449 char __user *optval, unsigned int optlen)
450{ 450{
451 struct sock *sk = sock->sk; 451 struct sock *sk = sock->sk;
452 struct atm_vcc *vcc = ATM_SD(sock); 452 struct atm_vcc *vcc = ATM_SD(sock);
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index 4102de1022ee..f45460730371 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -534,7 +534,7 @@ ax25_cb *ax25_create_cb(void)
534 */ 534 */
535 535
536static int ax25_setsockopt(struct socket *sock, int level, int optname, 536static int ax25_setsockopt(struct socket *sock, int level, int optname,
537 char __user *optval, int optlen) 537 char __user *optval, unsigned int optlen)
538{ 538{
539 struct sock *sk = sock->sk; 539 struct sock *sk = sock->sk;
540 ax25_cb *ax25; 540 ax25_cb *ax25;
@@ -901,7 +901,6 @@ struct sock *ax25_make_new(struct sock *osk, struct ax25_dev *ax25_dev)
901 901
902 sock_init_data(NULL, sk); 902 sock_init_data(NULL, sk);
903 903
904 sk->sk_destruct = ax25_free_sock;
905 sk->sk_type = osk->sk_type; 904 sk->sk_type = osk->sk_type;
906 sk->sk_priority = osk->sk_priority; 905 sk->sk_priority = osk->sk_priority;
907 sk->sk_protocol = osk->sk_protocol; 906 sk->sk_protocol = osk->sk_protocol;
@@ -939,6 +938,7 @@ struct sock *ax25_make_new(struct sock *osk, struct ax25_dev *ax25_dev)
939 } 938 }
940 939
941 sk->sk_protinfo = ax25; 940 sk->sk_protinfo = ax25;
941 sk->sk_destruct = ax25_free_sock;
942 ax25->sk = sk; 942 ax25->sk = sk;
943 943
944 return sk; 944 return sk;
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 4f9621f759a0..75302a986067 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -466,7 +466,7 @@ drop:
466 goto done; 466 goto done;
467} 467}
468 468
469static int hci_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int len) 469static int hci_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int len)
470{ 470{
471 struct hci_ufilter uf = { .opcode = 0 }; 471 struct hci_ufilter uf = { .opcode = 0 };
472 struct sock *sk = sock->sk; 472 struct sock *sk = sock->sk;
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index b03012564647..555d9da1869b 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -1698,7 +1698,7 @@ static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct ms
1698 return bt_sock_recvmsg(iocb, sock, msg, len, flags); 1698 return bt_sock_recvmsg(iocb, sock, msg, len, flags);
1699} 1699}
1700 1700
1701static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, int optlen) 1701static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
1702{ 1702{
1703 struct sock *sk = sock->sk; 1703 struct sock *sk = sock->sk;
1704 struct l2cap_options opts; 1704 struct l2cap_options opts;
@@ -1755,7 +1755,7 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us
1755 return err; 1755 return err;
1756} 1756}
1757 1757
1758static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen) 1758static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
1759{ 1759{
1760 struct sock *sk = sock->sk; 1760 struct sock *sk = sock->sk;
1761 struct bt_security sec; 1761 struct bt_security sec;
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 0b85e8116859..8a20aaf1f231 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -730,7 +730,7 @@ out:
730 return copied ? : err; 730 return copied ? : err;
731} 731}
732 732
733static int rfcomm_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, int optlen) 733static int rfcomm_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
734{ 734{
735 struct sock *sk = sock->sk; 735 struct sock *sk = sock->sk;
736 int err = 0; 736 int err = 0;
@@ -766,7 +766,7 @@ static int rfcomm_sock_setsockopt_old(struct socket *sock, int optname, char __u
766 return err; 766 return err;
767} 767}
768 768
769static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen) 769static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
770{ 770{
771 struct sock *sk = sock->sk; 771 struct sock *sk = sock->sk;
772 struct bt_security sec; 772 struct bt_security sec;
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 13c27f17192c..77f4153bdb5e 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -644,7 +644,7 @@ static int sco_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
644 return err; 644 return err;
645} 645}
646 646
647static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen) 647static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
648{ 648{
649 struct sock *sk = sock->sk; 649 struct sock *sk = sock->sk;
650 int err = 0; 650 int err = 0;
diff --git a/net/can/raw.c b/net/can/raw.c
index db3152df7d2b..b5e897922d32 100644
--- a/net/can/raw.c
+++ b/net/can/raw.c
@@ -411,7 +411,7 @@ static int raw_getname(struct socket *sock, struct sockaddr *uaddr,
411} 411}
412 412
413static int raw_setsockopt(struct socket *sock, int level, int optname, 413static int raw_setsockopt(struct socket *sock, int level, int optname,
414 char __user *optval, int optlen) 414 char __user *optval, unsigned int optlen)
415{ 415{
416 struct sock *sk = sock->sk; 416 struct sock *sk = sock->sk;
417 struct raw_sock *ro = raw_sk(sk); 417 struct raw_sock *ro = raw_sk(sk);
diff --git a/net/compat.c b/net/compat.c
index 12728b17a226..a407c3addbae 100644
--- a/net/compat.c
+++ b/net/compat.c
@@ -331,7 +331,7 @@ struct compat_sock_fprog {
331}; 331};
332 332
333static int do_set_attach_filter(struct socket *sock, int level, int optname, 333static int do_set_attach_filter(struct socket *sock, int level, int optname,
334 char __user *optval, int optlen) 334 char __user *optval, unsigned int optlen)
335{ 335{
336 struct compat_sock_fprog __user *fprog32 = (struct compat_sock_fprog __user *)optval; 336 struct compat_sock_fprog __user *fprog32 = (struct compat_sock_fprog __user *)optval;
337 struct sock_fprog __user *kfprog = compat_alloc_user_space(sizeof(struct sock_fprog)); 337 struct sock_fprog __user *kfprog = compat_alloc_user_space(sizeof(struct sock_fprog));
@@ -351,7 +351,7 @@ static int do_set_attach_filter(struct socket *sock, int level, int optname,
351} 351}
352 352
353static int do_set_sock_timeout(struct socket *sock, int level, 353static int do_set_sock_timeout(struct socket *sock, int level,
354 int optname, char __user *optval, int optlen) 354 int optname, char __user *optval, unsigned int optlen)
355{ 355{
356 struct compat_timeval __user *up = (struct compat_timeval __user *) optval; 356 struct compat_timeval __user *up = (struct compat_timeval __user *) optval;
357 struct timeval ktime; 357 struct timeval ktime;
@@ -373,7 +373,7 @@ static int do_set_sock_timeout(struct socket *sock, int level,
373} 373}
374 374
375static int compat_sock_setsockopt(struct socket *sock, int level, int optname, 375static int compat_sock_setsockopt(struct socket *sock, int level, int optname,
376 char __user *optval, int optlen) 376 char __user *optval, unsigned int optlen)
377{ 377{
378 if (optname == SO_ATTACH_FILTER) 378 if (optname == SO_ATTACH_FILTER)
379 return do_set_attach_filter(sock, level, optname, 379 return do_set_attach_filter(sock, level, optname,
@@ -385,7 +385,7 @@ static int compat_sock_setsockopt(struct socket *sock, int level, int optname,
385} 385}
386 386
387asmlinkage long compat_sys_setsockopt(int fd, int level, int optname, 387asmlinkage long compat_sys_setsockopt(int fd, int level, int optname,
388 char __user *optval, int optlen) 388 char __user *optval, unsigned int optlen)
389{ 389{
390 int err; 390 int err;
391 struct socket *sock; 391 struct socket *sock;
@@ -558,8 +558,8 @@ struct compat_group_filter {
558 558
559 559
560int compat_mc_setsockopt(struct sock *sock, int level, int optname, 560int compat_mc_setsockopt(struct sock *sock, int level, int optname,
561 char __user *optval, int optlen, 561 char __user *optval, unsigned int optlen,
562 int (*setsockopt)(struct sock *,int,int,char __user *,int)) 562 int (*setsockopt)(struct sock *,int,int,char __user *,unsigned int))
563{ 563{
564 char __user *koptval = optval; 564 char __user *koptval = optval;
565 int koptlen = optlen; 565 int koptlen = optlen;
diff --git a/net/core/dev.c b/net/core/dev.c
index 560c8c9c03ab..b8f74cfb1bfd 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2288,6 +2288,9 @@ int netif_receive_skb(struct sk_buff *skb)
2288 int ret = NET_RX_DROP; 2288 int ret = NET_RX_DROP;
2289 __be16 type; 2289 __be16 type;
2290 2290
2291 if (!skb->tstamp.tv64)
2292 net_timestamp(skb);
2293
2291 if (skb->vlan_tci && vlan_hwaccel_do_receive(skb)) 2294 if (skb->vlan_tci && vlan_hwaccel_do_receive(skb))
2292 return NET_RX_SUCCESS; 2295 return NET_RX_SUCCESS;
2293 2296
@@ -2295,9 +2298,6 @@ int netif_receive_skb(struct sk_buff *skb)
2295 if (netpoll_receive_skb(skb)) 2298 if (netpoll_receive_skb(skb))
2296 return NET_RX_DROP; 2299 return NET_RX_DROP;
2297 2300
2298 if (!skb->tstamp.tv64)
2299 net_timestamp(skb);
2300
2301 if (!skb->iif) 2301 if (!skb->iif)
2302 skb->iif = skb->dev->ifindex; 2302 skb->iif = skb->dev->ifindex;
2303 2303
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index 821d30918cfc..427ded841224 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -366,13 +366,13 @@ static ssize_t wireless_show(struct device *d, char *buf,
366 const struct iw_statistics *iw; 366 const struct iw_statistics *iw;
367 ssize_t ret = -EINVAL; 367 ssize_t ret = -EINVAL;
368 368
369 read_lock(&dev_base_lock); 369 rtnl_lock();
370 if (dev_isalive(dev)) { 370 if (dev_isalive(dev)) {
371 iw = get_wireless_stats(dev); 371 iw = get_wireless_stats(dev);
372 if (iw) 372 if (iw)
373 ret = (*format)(iw, buf); 373 ret = (*format)(iw, buf);
374 } 374 }
375 read_unlock(&dev_base_lock); 375 rtnl_unlock();
376 376
377 return ret; 377 return ret;
378} 378}
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 4d11c28ca8ca..86acdba0a97d 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -964,7 +964,7 @@ static ssize_t pktgen_if_write(struct file *file,
964 if (value == 0x7FFFFFFF) 964 if (value == 0x7FFFFFFF)
965 pkt_dev->delay = ULLONG_MAX; 965 pkt_dev->delay = ULLONG_MAX;
966 else 966 else
967 pkt_dev->delay = (u64)value * NSEC_PER_USEC; 967 pkt_dev->delay = (u64)value;
968 968
969 sprintf(pg_result, "OK: delay=%llu", 969 sprintf(pg_result, "OK: delay=%llu",
970 (unsigned long long) pkt_dev->delay); 970 (unsigned long long) pkt_dev->delay);
@@ -2105,15 +2105,17 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)
2105static void spin(struct pktgen_dev *pkt_dev, ktime_t spin_until) 2105static void spin(struct pktgen_dev *pkt_dev, ktime_t spin_until)
2106{ 2106{
2107 ktime_t start_time, end_time; 2107 ktime_t start_time, end_time;
2108 s32 remaining; 2108 s64 remaining;
2109 struct hrtimer_sleeper t; 2109 struct hrtimer_sleeper t;
2110 2110
2111 hrtimer_init_on_stack(&t.timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); 2111 hrtimer_init_on_stack(&t.timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
2112 hrtimer_set_expires(&t.timer, spin_until); 2112 hrtimer_set_expires(&t.timer, spin_until);
2113 2113
2114 remaining = ktime_to_us(hrtimer_expires_remaining(&t.timer)); 2114 remaining = ktime_to_us(hrtimer_expires_remaining(&t.timer));
2115 if (remaining <= 0) 2115 if (remaining <= 0) {
2116 pkt_dev->next_tx = ktime_add_ns(spin_until, pkt_dev->delay);
2116 return; 2117 return;
2118 }
2117 2119
2118 start_time = ktime_now(); 2120 start_time = ktime_now();
2119 if (remaining < 100) 2121 if (remaining < 100)
@@ -2210,7 +2212,7 @@ static void set_cur_queue_map(struct pktgen_dev *pkt_dev)
2210 if (pkt_dev->flags & F_QUEUE_MAP_CPU) 2212 if (pkt_dev->flags & F_QUEUE_MAP_CPU)
2211 pkt_dev->cur_queue_map = smp_processor_id(); 2213 pkt_dev->cur_queue_map = smp_processor_id();
2212 2214
2213 else if (pkt_dev->queue_map_min < pkt_dev->queue_map_max) { 2215 else if (pkt_dev->queue_map_min <= pkt_dev->queue_map_max) {
2214 __u16 t; 2216 __u16 t;
2215 if (pkt_dev->flags & F_QUEUE_MAP_RND) { 2217 if (pkt_dev->flags & F_QUEUE_MAP_RND) {
2216 t = random32() % 2218 t = random32() %
diff --git a/net/core/sock.c b/net/core/sock.c
index 524712a7b154..7626b6aacd68 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -446,7 +446,7 @@ static inline void sock_valbool_flag(struct sock *sk, int bit, int valbool)
446 */ 446 */
447 447
448int sock_setsockopt(struct socket *sock, int level, int optname, 448int sock_setsockopt(struct socket *sock, int level, int optname,
449 char __user *optval, int optlen) 449 char __user *optval, unsigned int optlen)
450{ 450{
451 struct sock *sk = sock->sk; 451 struct sock *sk = sock->sk;
452 int val; 452 int val;
@@ -1228,17 +1228,22 @@ void __init sk_init(void)
1228void sock_wfree(struct sk_buff *skb) 1228void sock_wfree(struct sk_buff *skb)
1229{ 1229{
1230 struct sock *sk = skb->sk; 1230 struct sock *sk = skb->sk;
1231 int res; 1231 unsigned int len = skb->truesize;
1232 1232
1233 /* In case it might be waiting for more memory. */ 1233 if (!sock_flag(sk, SOCK_USE_WRITE_QUEUE)) {
1234 res = atomic_sub_return(skb->truesize, &sk->sk_wmem_alloc); 1234 /*
1235 if (!sock_flag(sk, SOCK_USE_WRITE_QUEUE)) 1235 * Keep a reference on sk_wmem_alloc, this will be released
1236 * after sk_write_space() call
1237 */
1238 atomic_sub(len - 1, &sk->sk_wmem_alloc);
1236 sk->sk_write_space(sk); 1239 sk->sk_write_space(sk);
1240 len = 1;
1241 }
1237 /* 1242 /*
1238 * if sk_wmem_alloc reached 0, we are last user and should 1243 * if sk_wmem_alloc reaches 0, we must finish what sk_free()
1239 * free this sock, as sk_free() call could not do it. 1244 * could not do because of in-flight packets
1240 */ 1245 */
1241 if (res == 0) 1246 if (atomic_sub_and_test(len, &sk->sk_wmem_alloc))
1242 __sk_free(sk); 1247 __sk_free(sk);
1243} 1248}
1244EXPORT_SYMBOL(sock_wfree); 1249EXPORT_SYMBOL(sock_wfree);
@@ -1697,7 +1702,7 @@ int sock_no_shutdown(struct socket *sock, int how)
1697EXPORT_SYMBOL(sock_no_shutdown); 1702EXPORT_SYMBOL(sock_no_shutdown);
1698 1703
1699int sock_no_setsockopt(struct socket *sock, int level, int optname, 1704int sock_no_setsockopt(struct socket *sock, int level, int optname,
1700 char __user *optval, int optlen) 1705 char __user *optval, unsigned int optlen)
1701{ 1706{
1702 return -EOPNOTSUPP; 1707 return -EOPNOTSUPP;
1703} 1708}
@@ -2018,7 +2023,7 @@ EXPORT_SYMBOL(sock_common_recvmsg);
2018 * Set socket options on an inet socket. 2023 * Set socket options on an inet socket.
2019 */ 2024 */
2020int sock_common_setsockopt(struct socket *sock, int level, int optname, 2025int sock_common_setsockopt(struct socket *sock, int level, int optname,
2021 char __user *optval, int optlen) 2026 char __user *optval, unsigned int optlen)
2022{ 2027{
2023 struct sock *sk = sock->sk; 2028 struct sock *sk = sock->sk;
2024 2029
@@ -2028,7 +2033,7 @@ EXPORT_SYMBOL(sock_common_setsockopt);
2028 2033
2029#ifdef CONFIG_COMPAT 2034#ifdef CONFIG_COMPAT
2030int compat_sock_common_setsockopt(struct socket *sock, int level, int optname, 2035int compat_sock_common_setsockopt(struct socket *sock, int level, int optname,
2031 char __user *optval, int optlen) 2036 char __user *optval, unsigned int optlen)
2032{ 2037{
2033 struct sock *sk = sock->sk; 2038 struct sock *sk = sock->sk;
2034 2039
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h
index d6bc47363b1c..5ef32c2f0d6a 100644
--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -290,14 +290,14 @@ extern int dccp_disconnect(struct sock *sk, int flags);
290extern int dccp_getsockopt(struct sock *sk, int level, int optname, 290extern int dccp_getsockopt(struct sock *sk, int level, int optname,
291 char __user *optval, int __user *optlen); 291 char __user *optval, int __user *optlen);
292extern int dccp_setsockopt(struct sock *sk, int level, int optname, 292extern int dccp_setsockopt(struct sock *sk, int level, int optname,
293 char __user *optval, int optlen); 293 char __user *optval, unsigned int optlen);
294#ifdef CONFIG_COMPAT 294#ifdef CONFIG_COMPAT
295extern int compat_dccp_getsockopt(struct sock *sk, 295extern int compat_dccp_getsockopt(struct sock *sk,
296 int level, int optname, 296 int level, int optname,
297 char __user *optval, int __user *optlen); 297 char __user *optval, int __user *optlen);
298extern int compat_dccp_setsockopt(struct sock *sk, 298extern int compat_dccp_setsockopt(struct sock *sk,
299 int level, int optname, 299 int level, int optname,
300 char __user *optval, int optlen); 300 char __user *optval, unsigned int optlen);
301#endif 301#endif
302extern int dccp_ioctl(struct sock *sk, int cmd, unsigned long arg); 302extern int dccp_ioctl(struct sock *sk, int cmd, unsigned long arg);
303extern int dccp_sendmsg(struct kiocb *iocb, struct sock *sk, 303extern int dccp_sendmsg(struct kiocb *iocb, struct sock *sk,
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
index bc4467082a00..a156319fd0ac 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -393,7 +393,7 @@ out:
393EXPORT_SYMBOL_GPL(dccp_ioctl); 393EXPORT_SYMBOL_GPL(dccp_ioctl);
394 394
395static int dccp_setsockopt_service(struct sock *sk, const __be32 service, 395static int dccp_setsockopt_service(struct sock *sk, const __be32 service,
396 char __user *optval, int optlen) 396 char __user *optval, unsigned int optlen)
397{ 397{
398 struct dccp_sock *dp = dccp_sk(sk); 398 struct dccp_sock *dp = dccp_sk(sk);
399 struct dccp_service_list *sl = NULL; 399 struct dccp_service_list *sl = NULL;
@@ -464,7 +464,7 @@ static int dccp_setsockopt_cscov(struct sock *sk, int cscov, bool rx)
464} 464}
465 465
466static int dccp_setsockopt_ccid(struct sock *sk, int type, 466static int dccp_setsockopt_ccid(struct sock *sk, int type,
467 char __user *optval, int optlen) 467 char __user *optval, unsigned int optlen)
468{ 468{
469 u8 *val; 469 u8 *val;
470 int rc = 0; 470 int rc = 0;
@@ -494,7 +494,7 @@ static int dccp_setsockopt_ccid(struct sock *sk, int type,
494} 494}
495 495
496static int do_dccp_setsockopt(struct sock *sk, int level, int optname, 496static int do_dccp_setsockopt(struct sock *sk, int level, int optname,
497 char __user *optval, int optlen) 497 char __user *optval, unsigned int optlen)
498{ 498{
499 struct dccp_sock *dp = dccp_sk(sk); 499 struct dccp_sock *dp = dccp_sk(sk);
500 int val, err = 0; 500 int val, err = 0;
@@ -546,7 +546,7 @@ static int do_dccp_setsockopt(struct sock *sk, int level, int optname,
546} 546}
547 547
548int dccp_setsockopt(struct sock *sk, int level, int optname, 548int dccp_setsockopt(struct sock *sk, int level, int optname,
549 char __user *optval, int optlen) 549 char __user *optval, unsigned int optlen)
550{ 550{
551 if (level != SOL_DCCP) 551 if (level != SOL_DCCP)
552 return inet_csk(sk)->icsk_af_ops->setsockopt(sk, level, 552 return inet_csk(sk)->icsk_af_ops->setsockopt(sk, level,
@@ -559,7 +559,7 @@ EXPORT_SYMBOL_GPL(dccp_setsockopt);
559 559
560#ifdef CONFIG_COMPAT 560#ifdef CONFIG_COMPAT
561int compat_dccp_setsockopt(struct sock *sk, int level, int optname, 561int compat_dccp_setsockopt(struct sock *sk, int level, int optname,
562 char __user *optval, int optlen) 562 char __user *optval, unsigned int optlen)
563{ 563{
564 if (level != SOL_DCCP) 564 if (level != SOL_DCCP)
565 return inet_csk_compat_setsockopt(sk, level, optname, 565 return inet_csk_compat_setsockopt(sk, level, optname,
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c
index 77d40289653c..7a58c87baf17 100644
--- a/net/decnet/af_decnet.c
+++ b/net/decnet/af_decnet.c
@@ -157,7 +157,7 @@ static struct hlist_head dn_sk_hash[DN_SK_HASH_SIZE];
157static struct hlist_head dn_wild_sk; 157static struct hlist_head dn_wild_sk;
158static atomic_t decnet_memory_allocated; 158static atomic_t decnet_memory_allocated;
159 159
160static int __dn_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen, int flags); 160static int __dn_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen, int flags);
161static int __dn_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen, int flags); 161static int __dn_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen, int flags);
162 162
163static struct hlist_head *dn_find_list(struct sock *sk) 163static struct hlist_head *dn_find_list(struct sock *sk)
@@ -1325,7 +1325,7 @@ out:
1325 return err; 1325 return err;
1326} 1326}
1327 1327
1328static int dn_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen) 1328static int dn_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
1329{ 1329{
1330 struct sock *sk = sock->sk; 1330 struct sock *sk = sock->sk;
1331 int err; 1331 int err;
@@ -1337,7 +1337,7 @@ static int dn_setsockopt(struct socket *sock, int level, int optname, char __use
1337 return err; 1337 return err;
1338} 1338}
1339 1339
1340static int __dn_setsockopt(struct socket *sock, int level,int optname, char __user *optval, int optlen, int flags) 1340static int __dn_setsockopt(struct socket *sock, int level,int optname, char __user *optval, unsigned int optlen, int flags)
1341{ 1341{
1342 struct sock *sk = sock->sk; 1342 struct sock *sk = sock->sk;
1343 struct dn_scp *scp = DN_SK(sk); 1343 struct dn_scp *scp = DN_SK(sk);
diff --git a/net/ieee802154/dgram.c b/net/ieee802154/dgram.c
index 51593a48f2dd..a413b1bf4465 100644
--- a/net/ieee802154/dgram.c
+++ b/net/ieee802154/dgram.c
@@ -414,7 +414,7 @@ static int dgram_getsockopt(struct sock *sk, int level, int optname,
414} 414}
415 415
416static int dgram_setsockopt(struct sock *sk, int level, int optname, 416static int dgram_setsockopt(struct sock *sk, int level, int optname,
417 char __user *optval, int optlen) 417 char __user *optval, unsigned int optlen)
418{ 418{
419 struct dgram_sock *ro = dgram_sk(sk); 419 struct dgram_sock *ro = dgram_sk(sk);
420 int val; 420 int val;
diff --git a/net/ieee802154/raw.c b/net/ieee802154/raw.c
index 13198859982e..30e74eee07d6 100644
--- a/net/ieee802154/raw.c
+++ b/net/ieee802154/raw.c
@@ -244,7 +244,7 @@ static int raw_getsockopt(struct sock *sk, int level, int optname,
244} 244}
245 245
246static int raw_setsockopt(struct sock *sk, int level, int optname, 246static int raw_setsockopt(struct sock *sk, int level, int optname,
247 char __user *optval, int optlen) 247 char __user *optval, unsigned int optlen)
248{ 248{
249 return -EOPNOTSUPP; 249 return -EOPNOTSUPP;
250} 250}
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 58c4b0f7c4aa..57737b8d1711 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1119,6 +1119,7 @@ int inet_sk_rebuild_header(struct sock *sk)
1119{ 1119{
1120 struct flowi fl = { 1120 struct flowi fl = {
1121 .oif = sk->sk_bound_dev_if, 1121 .oif = sk->sk_bound_dev_if,
1122 .mark = sk->sk_mark,
1122 .nl_u = { 1123 .nl_u = {
1123 .ip4_u = { 1124 .ip4_u = {
1124 .daddr = daddr, 1125 .daddr = daddr,
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index e92f1fd28aa5..5df2f6a0b0f0 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -1077,12 +1077,16 @@ static int inetdev_event(struct notifier_block *this, unsigned long event,
1077 ip_mc_up(in_dev); 1077 ip_mc_up(in_dev);
1078 /* fall through */ 1078 /* fall through */
1079 case NETDEV_CHANGEADDR: 1079 case NETDEV_CHANGEADDR:
1080 if (IN_DEV_ARP_NOTIFY(in_dev)) 1080 /* Send gratuitous ARP to notify of link change */
1081 arp_send(ARPOP_REQUEST, ETH_P_ARP, 1081 if (IN_DEV_ARP_NOTIFY(in_dev)) {
1082 in_dev->ifa_list->ifa_address, 1082 struct in_ifaddr *ifa = in_dev->ifa_list;
1083 dev, 1083
1084 in_dev->ifa_list->ifa_address, 1084 if (ifa)
1085 NULL, dev->dev_addr, NULL); 1085 arp_send(ARPOP_REQUEST, ETH_P_ARP,
1086 ifa->ifa_address, dev,
1087 ifa->ifa_address, NULL,
1088 dev->dev_addr, NULL);
1089 }
1086 break; 1090 break;
1087 case NETDEV_DOWN: 1091 case NETDEV_DOWN:
1088 ip_mc_down(in_dev); 1092 ip_mc_down(in_dev);
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index 22cd19ee44e5..4351ca2cf0b8 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -714,7 +714,7 @@ int inet_csk_compat_getsockopt(struct sock *sk, int level, int optname,
714EXPORT_SYMBOL_GPL(inet_csk_compat_getsockopt); 714EXPORT_SYMBOL_GPL(inet_csk_compat_getsockopt);
715 715
716int inet_csk_compat_setsockopt(struct sock *sk, int level, int optname, 716int inet_csk_compat_setsockopt(struct sock *sk, int level, int optname,
717 char __user *optval, int optlen) 717 char __user *optval, unsigned int optlen)
718{ 718{
719 const struct inet_connection_sock *icsk = inet_csk(sk); 719 const struct inet_connection_sock *icsk = inet_csk(sk);
720 720
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 9fe5d7b81580..f9895180f481 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -335,6 +335,7 @@ int ip_queue_xmit(struct sk_buff *skb, int ipfragok)
335 335
336 { 336 {
337 struct flowi fl = { .oif = sk->sk_bound_dev_if, 337 struct flowi fl = { .oif = sk->sk_bound_dev_if,
338 .mark = sk->sk_mark,
338 .nl_u = { .ip4_u = 339 .nl_u = { .ip4_u =
339 { .daddr = daddr, 340 { .daddr = daddr,
340 .saddr = inet->saddr, 341 .saddr = inet->saddr,
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 5a0693576e82..0c0b6e363a20 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -440,7 +440,7 @@ out:
440 */ 440 */
441 441
442static int do_ip_setsockopt(struct sock *sk, int level, 442static int do_ip_setsockopt(struct sock *sk, int level,
443 int optname, char __user *optval, int optlen) 443 int optname, char __user *optval, unsigned int optlen)
444{ 444{
445 struct inet_sock *inet = inet_sk(sk); 445 struct inet_sock *inet = inet_sk(sk);
446 int val = 0, err; 446 int val = 0, err;
@@ -950,7 +950,7 @@ e_inval:
950} 950}
951 951
952int ip_setsockopt(struct sock *sk, int level, 952int ip_setsockopt(struct sock *sk, int level,
953 int optname, char __user *optval, int optlen) 953 int optname, char __user *optval, unsigned int optlen)
954{ 954{
955 int err; 955 int err;
956 956
@@ -975,7 +975,7 @@ EXPORT_SYMBOL(ip_setsockopt);
975 975
976#ifdef CONFIG_COMPAT 976#ifdef CONFIG_COMPAT
977int compat_ip_setsockopt(struct sock *sk, int level, int optname, 977int compat_ip_setsockopt(struct sock *sk, int level, int optname,
978 char __user *optval, int optlen) 978 char __user *optval, unsigned int optlen)
979{ 979{
980 int err; 980 int err;
981 981
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index c43ec2d51ce2..630a56df7b47 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -931,7 +931,7 @@ static void mrtsock_destruct(struct sock *sk)
931 * MOSPF/PIM router set up we can clean this up. 931 * MOSPF/PIM router set up we can clean this up.
932 */ 932 */
933 933
934int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, int optlen) 934int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsigned int optlen)
935{ 935{
936 int ret; 936 int ret;
937 struct vifctl vif; 937 struct vifctl vif;
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index ebb1e5848bc6..757c9171e7c2 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -741,7 +741,7 @@ out: return ret;
741} 741}
742 742
743static int do_raw_setsockopt(struct sock *sk, int level, int optname, 743static int do_raw_setsockopt(struct sock *sk, int level, int optname,
744 char __user *optval, int optlen) 744 char __user *optval, unsigned int optlen)
745{ 745{
746 if (optname == ICMP_FILTER) { 746 if (optname == ICMP_FILTER) {
747 if (inet_sk(sk)->num != IPPROTO_ICMP) 747 if (inet_sk(sk)->num != IPPROTO_ICMP)
@@ -753,7 +753,7 @@ static int do_raw_setsockopt(struct sock *sk, int level, int optname,
753} 753}
754 754
755static int raw_setsockopt(struct sock *sk, int level, int optname, 755static int raw_setsockopt(struct sock *sk, int level, int optname,
756 char __user *optval, int optlen) 756 char __user *optval, unsigned int optlen)
757{ 757{
758 if (level != SOL_RAW) 758 if (level != SOL_RAW)
759 return ip_setsockopt(sk, level, optname, optval, optlen); 759 return ip_setsockopt(sk, level, optname, optval, optlen);
@@ -762,7 +762,7 @@ static int raw_setsockopt(struct sock *sk, int level, int optname,
762 762
763#ifdef CONFIG_COMPAT 763#ifdef CONFIG_COMPAT
764static int compat_raw_setsockopt(struct sock *sk, int level, int optname, 764static int compat_raw_setsockopt(struct sock *sk, int level, int optname,
765 char __user *optval, int optlen) 765 char __user *optval, unsigned int optlen)
766{ 766{
767 if (level != SOL_RAW) 767 if (level != SOL_RAW)
768 return compat_ip_setsockopt(sk, level, optname, optval, optlen); 768 return compat_ip_setsockopt(sk, level, optname, optval, optlen);
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 21387ebabf00..64d0af675823 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -580,7 +580,7 @@ ssize_t tcp_splice_read(struct socket *sock, loff_t *ppos,
580 580
581 lock_sock(sk); 581 lock_sock(sk);
582 582
583 timeo = sock_rcvtimeo(sk, flags & SPLICE_F_NONBLOCK); 583 timeo = sock_rcvtimeo(sk, sock->file->f_flags & O_NONBLOCK);
584 while (tss.len) { 584 while (tss.len) {
585 ret = __tcp_splice_read(sk, &tss); 585 ret = __tcp_splice_read(sk, &tss);
586 if (ret < 0) 586 if (ret < 0)
@@ -2032,7 +2032,7 @@ int tcp_disconnect(struct sock *sk, int flags)
2032 * Socket option code for TCP. 2032 * Socket option code for TCP.
2033 */ 2033 */
2034static int do_tcp_setsockopt(struct sock *sk, int level, 2034static int do_tcp_setsockopt(struct sock *sk, int level,
2035 int optname, char __user *optval, int optlen) 2035 int optname, char __user *optval, unsigned int optlen)
2036{ 2036{
2037 struct tcp_sock *tp = tcp_sk(sk); 2037 struct tcp_sock *tp = tcp_sk(sk);
2038 struct inet_connection_sock *icsk = inet_csk(sk); 2038 struct inet_connection_sock *icsk = inet_csk(sk);
@@ -2047,7 +2047,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level,
2047 return -EINVAL; 2047 return -EINVAL;
2048 2048
2049 val = strncpy_from_user(name, optval, 2049 val = strncpy_from_user(name, optval,
2050 min(TCP_CA_NAME_MAX-1, optlen)); 2050 min_t(long, TCP_CA_NAME_MAX-1, optlen));
2051 if (val < 0) 2051 if (val < 0)
2052 return -EFAULT; 2052 return -EFAULT;
2053 name[val] = 0; 2053 name[val] = 0;
@@ -2220,7 +2220,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level,
2220} 2220}
2221 2221
2222int tcp_setsockopt(struct sock *sk, int level, int optname, char __user *optval, 2222int tcp_setsockopt(struct sock *sk, int level, int optname, char __user *optval,
2223 int optlen) 2223 unsigned int optlen)
2224{ 2224{
2225 struct inet_connection_sock *icsk = inet_csk(sk); 2225 struct inet_connection_sock *icsk = inet_csk(sk);
2226 2226
@@ -2232,7 +2232,7 @@ int tcp_setsockopt(struct sock *sk, int level, int optname, char __user *optval,
2232 2232
2233#ifdef CONFIG_COMPAT 2233#ifdef CONFIG_COMPAT
2234int compat_tcp_setsockopt(struct sock *sk, int level, int optname, 2234int compat_tcp_setsockopt(struct sock *sk, int level, int optname,
2235 char __user *optval, int optlen) 2235 char __user *optval, unsigned int optlen)
2236{ 2236{
2237 if (level != SOL_TCP) 2237 if (level != SOL_TCP)
2238 return inet_csk_compat_setsockopt(sk, level, optname, 2238 return inet_csk_compat_setsockopt(sk, level, optname,
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index 624c3c9b3c2b..e320afea07fc 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -644,6 +644,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,
644 /* If TCP_DEFER_ACCEPT is set, drop bare ACK. */ 644 /* If TCP_DEFER_ACCEPT is set, drop bare ACK. */
645 if (inet_csk(sk)->icsk_accept_queue.rskq_defer_accept && 645 if (inet_csk(sk)->icsk_accept_queue.rskq_defer_accept &&
646 TCP_SKB_CB(skb)->end_seq == tcp_rsk(req)->rcv_isn + 1) { 646 TCP_SKB_CB(skb)->end_seq == tcp_rsk(req)->rcv_isn + 1) {
647 inet_csk(sk)->icsk_accept_queue.rskq_defer_accept--;
647 inet_rsk(req)->acked = 1; 648 inet_rsk(req)->acked = 1;
648 return NULL; 649 return NULL;
649 } 650 }
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 5200aab0ca97..fcd278a7080e 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -361,6 +361,7 @@ static inline int tcp_urg_mode(const struct tcp_sock *tp)
361#define OPTION_SACK_ADVERTISE (1 << 0) 361#define OPTION_SACK_ADVERTISE (1 << 0)
362#define OPTION_TS (1 << 1) 362#define OPTION_TS (1 << 1)
363#define OPTION_MD5 (1 << 2) 363#define OPTION_MD5 (1 << 2)
364#define OPTION_WSCALE (1 << 3)
364 365
365struct tcp_out_options { 366struct tcp_out_options {
366 u8 options; /* bit field of OPTION_* */ 367 u8 options; /* bit field of OPTION_* */
@@ -427,7 +428,7 @@ static void tcp_options_write(__be32 *ptr, struct tcp_sock *tp,
427 TCPOLEN_SACK_PERM); 428 TCPOLEN_SACK_PERM);
428 } 429 }
429 430
430 if (unlikely(opts->ws)) { 431 if (unlikely(OPTION_WSCALE & opts->options)) {
431 *ptr++ = htonl((TCPOPT_NOP << 24) | 432 *ptr++ = htonl((TCPOPT_NOP << 24) |
432 (TCPOPT_WINDOW << 16) | 433 (TCPOPT_WINDOW << 16) |
433 (TCPOLEN_WINDOW << 8) | 434 (TCPOLEN_WINDOW << 8) |
@@ -494,8 +495,8 @@ static unsigned tcp_syn_options(struct sock *sk, struct sk_buff *skb,
494 } 495 }
495 if (likely(sysctl_tcp_window_scaling)) { 496 if (likely(sysctl_tcp_window_scaling)) {
496 opts->ws = tp->rx_opt.rcv_wscale; 497 opts->ws = tp->rx_opt.rcv_wscale;
497 if (likely(opts->ws)) 498 opts->options |= OPTION_WSCALE;
498 size += TCPOLEN_WSCALE_ALIGNED; 499 size += TCPOLEN_WSCALE_ALIGNED;
499 } 500 }
500 if (likely(sysctl_tcp_sack)) { 501 if (likely(sysctl_tcp_sack)) {
501 opts->options |= OPTION_SACK_ADVERTISE; 502 opts->options |= OPTION_SACK_ADVERTISE;
@@ -537,8 +538,8 @@ static unsigned tcp_synack_options(struct sock *sk,
537 538
538 if (likely(ireq->wscale_ok)) { 539 if (likely(ireq->wscale_ok)) {
539 opts->ws = ireq->rcv_wscale; 540 opts->ws = ireq->rcv_wscale;
540 if (likely(opts->ws)) 541 opts->options |= OPTION_WSCALE;
541 size += TCPOLEN_WSCALE_ALIGNED; 542 size += TCPOLEN_WSCALE_ALIGNED;
542 } 543 }
543 if (likely(doing_ts)) { 544 if (likely(doing_ts)) {
544 opts->options |= OPTION_TS; 545 opts->options |= OPTION_TS;
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index ebaaa7f973d7..d0d436d6216c 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -696,6 +696,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
696 696
697 if (rt == NULL) { 697 if (rt == NULL) {
698 struct flowi fl = { .oif = ipc.oif, 698 struct flowi fl = { .oif = ipc.oif,
699 .mark = sk->sk_mark,
699 .nl_u = { .ip4_u = 700 .nl_u = { .ip4_u =
700 { .daddr = faddr, 701 { .daddr = faddr,
701 .saddr = saddr, 702 .saddr = saddr,
@@ -840,6 +841,42 @@ out:
840 return ret; 841 return ret;
841} 842}
842 843
844
845/**
846 * first_packet_length - return length of first packet in receive queue
847 * @sk: socket
848 *
849 * Drops all bad checksum frames, until a valid one is found.
850 * Returns the length of found skb, or 0 if none is found.
851 */
852static unsigned int first_packet_length(struct sock *sk)
853{
854 struct sk_buff_head list_kill, *rcvq = &sk->sk_receive_queue;
855 struct sk_buff *skb;
856 unsigned int res;
857
858 __skb_queue_head_init(&list_kill);
859
860 spin_lock_bh(&rcvq->lock);
861 while ((skb = skb_peek(rcvq)) != NULL &&
862 udp_lib_checksum_complete(skb)) {
863 UDP_INC_STATS_BH(sock_net(sk), UDP_MIB_INERRORS,
864 IS_UDPLITE(sk));
865 __skb_unlink(skb, rcvq);
866 __skb_queue_tail(&list_kill, skb);
867 }
868 res = skb ? skb->len : 0;
869 spin_unlock_bh(&rcvq->lock);
870
871 if (!skb_queue_empty(&list_kill)) {
872 lock_sock(sk);
873 __skb_queue_purge(&list_kill);
874 sk_mem_reclaim_partial(sk);
875 release_sock(sk);
876 }
877 return res;
878}
879
843/* 880/*
844 * IOCTL requests applicable to the UDP protocol 881 * IOCTL requests applicable to the UDP protocol
845 */ 882 */
@@ -856,21 +893,16 @@ int udp_ioctl(struct sock *sk, int cmd, unsigned long arg)
856 893
857 case SIOCINQ: 894 case SIOCINQ:
858 { 895 {
859 struct sk_buff *skb; 896 unsigned int amount = first_packet_length(sk);
860 unsigned long amount;
861 897
862 amount = 0; 898 if (amount)
863 spin_lock_bh(&sk->sk_receive_queue.lock);
864 skb = skb_peek(&sk->sk_receive_queue);
865 if (skb != NULL) {
866 /* 899 /*
867 * We will only return the amount 900 * We will only return the amount
868 * of this packet since that is all 901 * of this packet since that is all
869 * that will be read. 902 * that will be read.
870 */ 903 */
871 amount = skb->len - sizeof(struct udphdr); 904 amount -= sizeof(struct udphdr);
872 } 905
873 spin_unlock_bh(&sk->sk_receive_queue.lock);
874 return put_user(amount, (int __user *)arg); 906 return put_user(amount, (int __user *)arg);
875 } 907 }
876 908
@@ -1359,7 +1391,7 @@ void udp_destroy_sock(struct sock *sk)
1359 * Socket option code for UDP 1391 * Socket option code for UDP
1360 */ 1392 */
1361int udp_lib_setsockopt(struct sock *sk, int level, int optname, 1393int udp_lib_setsockopt(struct sock *sk, int level, int optname,
1362 char __user *optval, int optlen, 1394 char __user *optval, unsigned int optlen,
1363 int (*push_pending_frames)(struct sock *)) 1395 int (*push_pending_frames)(struct sock *))
1364{ 1396{
1365 struct udp_sock *up = udp_sk(sk); 1397 struct udp_sock *up = udp_sk(sk);
@@ -1441,7 +1473,7 @@ int udp_lib_setsockopt(struct sock *sk, int level, int optname,
1441EXPORT_SYMBOL(udp_lib_setsockopt); 1473EXPORT_SYMBOL(udp_lib_setsockopt);
1442 1474
1443int udp_setsockopt(struct sock *sk, int level, int optname, 1475int udp_setsockopt(struct sock *sk, int level, int optname,
1444 char __user *optval, int optlen) 1476 char __user *optval, unsigned int optlen)
1445{ 1477{
1446 if (level == SOL_UDP || level == SOL_UDPLITE) 1478 if (level == SOL_UDP || level == SOL_UDPLITE)
1447 return udp_lib_setsockopt(sk, level, optname, optval, optlen, 1479 return udp_lib_setsockopt(sk, level, optname, optval, optlen,
@@ -1451,7 +1483,7 @@ int udp_setsockopt(struct sock *sk, int level, int optname,
1451 1483
1452#ifdef CONFIG_COMPAT 1484#ifdef CONFIG_COMPAT
1453int compat_udp_setsockopt(struct sock *sk, int level, int optname, 1485int compat_udp_setsockopt(struct sock *sk, int level, int optname,
1454 char __user *optval, int optlen) 1486 char __user *optval, unsigned int optlen)
1455{ 1487{
1456 if (level == SOL_UDP || level == SOL_UDPLITE) 1488 if (level == SOL_UDP || level == SOL_UDPLITE)
1457 return udp_lib_setsockopt(sk, level, optname, optval, optlen, 1489 return udp_lib_setsockopt(sk, level, optname, optval, optlen,
@@ -1539,29 +1571,11 @@ unsigned int udp_poll(struct file *file, struct socket *sock, poll_table *wait)
1539{ 1571{
1540 unsigned int mask = datagram_poll(file, sock, wait); 1572 unsigned int mask = datagram_poll(file, sock, wait);
1541 struct sock *sk = sock->sk; 1573 struct sock *sk = sock->sk;
1542 int is_lite = IS_UDPLITE(sk);
1543 1574
1544 /* Check for false positives due to checksum errors */ 1575 /* Check for false positives due to checksum errors */
1545 if ((mask & POLLRDNORM) && 1576 if ((mask & POLLRDNORM) && !(file->f_flags & O_NONBLOCK) &&
1546 !(file->f_flags & O_NONBLOCK) && 1577 !(sk->sk_shutdown & RCV_SHUTDOWN) && !first_packet_length(sk))
1547 !(sk->sk_shutdown & RCV_SHUTDOWN)) { 1578 mask &= ~(POLLIN | POLLRDNORM);
1548 struct sk_buff_head *rcvq = &sk->sk_receive_queue;
1549 struct sk_buff *skb;
1550
1551 spin_lock_bh(&rcvq->lock);
1552 while ((skb = skb_peek(rcvq)) != NULL &&
1553 udp_lib_checksum_complete(skb)) {
1554 UDP_INC_STATS_BH(sock_net(sk),
1555 UDP_MIB_INERRORS, is_lite);
1556 __skb_unlink(skb, rcvq);
1557 kfree_skb(skb);
1558 }
1559 spin_unlock_bh(&rcvq->lock);
1560
1561 /* nothing to see, move along */
1562 if (skb == NULL)
1563 mask &= ~(POLLIN | POLLRDNORM);
1564 }
1565 1579
1566 return mask; 1580 return mask;
1567 1581
diff --git a/net/ipv4/udp_impl.h b/net/ipv4/udp_impl.h
index 9f4a6165f722..aaad650d47d9 100644
--- a/net/ipv4/udp_impl.h
+++ b/net/ipv4/udp_impl.h
@@ -11,13 +11,13 @@ extern void __udp4_lib_err(struct sk_buff *, u32, struct udp_table *);
11extern int udp_v4_get_port(struct sock *sk, unsigned short snum); 11extern int udp_v4_get_port(struct sock *sk, unsigned short snum);
12 12
13extern int udp_setsockopt(struct sock *sk, int level, int optname, 13extern int udp_setsockopt(struct sock *sk, int level, int optname,
14 char __user *optval, int optlen); 14 char __user *optval, unsigned int optlen);
15extern int udp_getsockopt(struct sock *sk, int level, int optname, 15extern int udp_getsockopt(struct sock *sk, int level, int optname,
16 char __user *optval, int __user *optlen); 16 char __user *optval, int __user *optlen);
17 17
18#ifdef CONFIG_COMPAT 18#ifdef CONFIG_COMPAT
19extern int compat_udp_setsockopt(struct sock *sk, int level, int optname, 19extern int compat_udp_setsockopt(struct sock *sk, int level, int optname,
20 char __user *optval, int optlen); 20 char __user *optval, unsigned int optlen);
21extern int compat_udp_getsockopt(struct sock *sk, int level, int optname, 21extern int compat_udp_getsockopt(struct sock *sk, int level, int optname,
22 char __user *optval, int __user *optlen); 22 char __user *optval, int __user *optlen);
23#endif 23#endif
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index 090675e269ee..716153941fc4 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -1281,7 +1281,7 @@ int ip6mr_sk_done(struct sock *sk)
1281 * MOSPF/PIM router set up we can clean this up. 1281 * MOSPF/PIM router set up we can clean this up.
1282 */ 1282 */
1283 1283
1284int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, int optlen) 1284int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsigned int optlen)
1285{ 1285{
1286 int ret; 1286 int ret;
1287 struct mif6ctl vif; 1287 struct mif6ctl vif;
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index f5e0682b402d..14f54eb5a7fc 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -123,7 +123,7 @@ struct ipv6_txoptions *ipv6_update_options(struct sock *sk,
123} 123}
124 124
125static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, 125static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
126 char __user *optval, int optlen) 126 char __user *optval, unsigned int optlen)
127{ 127{
128 struct ipv6_pinfo *np = inet6_sk(sk); 128 struct ipv6_pinfo *np = inet6_sk(sk);
129 struct net *net = sock_net(sk); 129 struct net *net = sock_net(sk);
@@ -773,7 +773,7 @@ e_inval:
773} 773}
774 774
775int ipv6_setsockopt(struct sock *sk, int level, int optname, 775int ipv6_setsockopt(struct sock *sk, int level, int optname,
776 char __user *optval, int optlen) 776 char __user *optval, unsigned int optlen)
777{ 777{
778 int err; 778 int err;
779 779
@@ -801,7 +801,7 @@ EXPORT_SYMBOL(ipv6_setsockopt);
801 801
802#ifdef CONFIG_COMPAT 802#ifdef CONFIG_COMPAT
803int compat_ipv6_setsockopt(struct sock *sk, int level, int optname, 803int compat_ipv6_setsockopt(struct sock *sk, int level, int optname,
804 char __user *optval, int optlen) 804 char __user *optval, unsigned int optlen)
805{ 805{
806 int err; 806 int err;
807 807
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 7d675b8d82d3..4f24570b0869 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -957,7 +957,7 @@ static int rawv6_geticmpfilter(struct sock *sk, int level, int optname,
957 957
958 958
959static int do_rawv6_setsockopt(struct sock *sk, int level, int optname, 959static int do_rawv6_setsockopt(struct sock *sk, int level, int optname,
960 char __user *optval, int optlen) 960 char __user *optval, unsigned int optlen)
961{ 961{
962 struct raw6_sock *rp = raw6_sk(sk); 962 struct raw6_sock *rp = raw6_sk(sk);
963 int val; 963 int val;
@@ -1000,7 +1000,7 @@ static int do_rawv6_setsockopt(struct sock *sk, int level, int optname,
1000} 1000}
1001 1001
1002static int rawv6_setsockopt(struct sock *sk, int level, int optname, 1002static int rawv6_setsockopt(struct sock *sk, int level, int optname,
1003 char __user *optval, int optlen) 1003 char __user *optval, unsigned int optlen)
1004{ 1004{
1005 switch(level) { 1005 switch(level) {
1006 case SOL_RAW: 1006 case SOL_RAW:
@@ -1024,7 +1024,7 @@ static int rawv6_setsockopt(struct sock *sk, int level, int optname,
1024 1024
1025#ifdef CONFIG_COMPAT 1025#ifdef CONFIG_COMPAT
1026static int compat_rawv6_setsockopt(struct sock *sk, int level, int optname, 1026static int compat_rawv6_setsockopt(struct sock *sk, int level, int optname,
1027 char __user *optval, int optlen) 1027 char __user *optval, unsigned int optlen)
1028{ 1028{
1029 switch (level) { 1029 switch (level) {
1030 case SOL_RAW: 1030 case SOL_RAW:
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index d65e0c496cc0..dbd19a78ca73 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -274,7 +274,7 @@ static int ipip6_tunnel_get_prl(struct ip_tunnel *t,
274 274
275 c = 0; 275 c = 0;
276 for (prl = t->prl; prl; prl = prl->next) { 276 for (prl = t->prl; prl; prl = prl->next) {
277 if (c > cmax) 277 if (c >= cmax)
278 break; 278 break;
279 if (kprl.addr != htonl(INADDR_ANY) && prl->addr != kprl.addr) 279 if (kprl.addr != htonl(INADDR_ANY) && prl->addr != kprl.addr)
280 continue; 280 continue;
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index b265b7047d3e..3a60f12b34ed 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -1044,7 +1044,7 @@ void udpv6_destroy_sock(struct sock *sk)
1044 * Socket option code for UDP 1044 * Socket option code for UDP
1045 */ 1045 */
1046int udpv6_setsockopt(struct sock *sk, int level, int optname, 1046int udpv6_setsockopt(struct sock *sk, int level, int optname,
1047 char __user *optval, int optlen) 1047 char __user *optval, unsigned int optlen)
1048{ 1048{
1049 if (level == SOL_UDP || level == SOL_UDPLITE) 1049 if (level == SOL_UDP || level == SOL_UDPLITE)
1050 return udp_lib_setsockopt(sk, level, optname, optval, optlen, 1050 return udp_lib_setsockopt(sk, level, optname, optval, optlen,
@@ -1054,7 +1054,7 @@ int udpv6_setsockopt(struct sock *sk, int level, int optname,
1054 1054
1055#ifdef CONFIG_COMPAT 1055#ifdef CONFIG_COMPAT
1056int compat_udpv6_setsockopt(struct sock *sk, int level, int optname, 1056int compat_udpv6_setsockopt(struct sock *sk, int level, int optname,
1057 char __user *optval, int optlen) 1057 char __user *optval, unsigned int optlen)
1058{ 1058{
1059 if (level == SOL_UDP || level == SOL_UDPLITE) 1059 if (level == SOL_UDP || level == SOL_UDPLITE)
1060 return udp_lib_setsockopt(sk, level, optname, optval, optlen, 1060 return udp_lib_setsockopt(sk, level, optname, optval, optlen,
diff --git a/net/ipv6/udp_impl.h b/net/ipv6/udp_impl.h
index 6bb303471e20..d7571046bfc4 100644
--- a/net/ipv6/udp_impl.h
+++ b/net/ipv6/udp_impl.h
@@ -16,10 +16,10 @@ extern int udp_v6_get_port(struct sock *sk, unsigned short snum);
16extern int udpv6_getsockopt(struct sock *sk, int level, int optname, 16extern int udpv6_getsockopt(struct sock *sk, int level, int optname,
17 char __user *optval, int __user *optlen); 17 char __user *optval, int __user *optlen);
18extern int udpv6_setsockopt(struct sock *sk, int level, int optname, 18extern int udpv6_setsockopt(struct sock *sk, int level, int optname,
19 char __user *optval, int optlen); 19 char __user *optval, unsigned int optlen);
20#ifdef CONFIG_COMPAT 20#ifdef CONFIG_COMPAT
21extern int compat_udpv6_setsockopt(struct sock *sk, int level, int optname, 21extern int compat_udpv6_setsockopt(struct sock *sk, int level, int optname,
22 char __user *optval, int optlen); 22 char __user *optval, unsigned int optlen);
23extern int compat_udpv6_getsockopt(struct sock *sk, int level, int optname, 23extern int compat_udpv6_getsockopt(struct sock *sk, int level, int optname,
24 char __user *optval, int __user *optlen); 24 char __user *optval, int __user *optlen);
25#endif 25#endif
diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c
index f1118d92a191..66c7a20011f3 100644
--- a/net/ipx/af_ipx.c
+++ b/net/ipx/af_ipx.c
@@ -1292,7 +1292,7 @@ const char *ipx_device_name(struct ipx_interface *intrfc)
1292 * socket object. */ 1292 * socket object. */
1293 1293
1294static int ipx_setsockopt(struct socket *sock, int level, int optname, 1294static int ipx_setsockopt(struct socket *sock, int level, int optname,
1295 char __user *optval, int optlen) 1295 char __user *optval, unsigned int optlen)
1296{ 1296{
1297 struct sock *sk = sock->sk; 1297 struct sock *sk = sock->sk;
1298 int opt; 1298 int opt;
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c
index 50b43c57d5d8..dd35641835f4 100644
--- a/net/irda/af_irda.c
+++ b/net/irda/af_irda.c
@@ -1826,7 +1826,7 @@ static int irda_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned lon
1826 * 1826 *
1827 */ 1827 */
1828static int irda_setsockopt(struct socket *sock, int level, int optname, 1828static int irda_setsockopt(struct socket *sock, int level, int optname,
1829 char __user *optval, int optlen) 1829 char __user *optval, unsigned int optlen)
1830{ 1830{
1831 struct sock *sk = sock->sk; 1831 struct sock *sk = sock->sk;
1832 struct irda_sock *self = irda_sk(sk); 1832 struct irda_sock *self = irda_sk(sk);
diff --git a/net/irda/ircomm/ircomm_tty_attach.c b/net/irda/ircomm/ircomm_tty_attach.c
index eafc010907c2..3c1754023022 100644
--- a/net/irda/ircomm/ircomm_tty_attach.c
+++ b/net/irda/ircomm/ircomm_tty_attach.c
@@ -30,6 +30,7 @@
30 ********************************************************************/ 30 ********************************************************************/
31 31
32#include <linux/init.h> 32#include <linux/init.h>
33#include <linux/sched.h>
33 34
34#include <net/irda/irda.h> 35#include <net/irda/irda.h>
35#include <net/irda/irlmp.h> 36#include <net/irda/irlmp.h>
diff --git a/net/irda/irlan/irlan_common.c b/net/irda/irlan/irlan_common.c
index 62116829b817..315ead3cb926 100644
--- a/net/irda/irlan/irlan_common.c
+++ b/net/irda/irlan/irlan_common.c
@@ -30,6 +30,7 @@
30#include <linux/init.h> 30#include <linux/init.h>
31#include <linux/errno.h> 31#include <linux/errno.h>
32#include <linux/proc_fs.h> 32#include <linux/proc_fs.h>
33#include <linux/sched.h>
33#include <linux/seq_file.h> 34#include <linux/seq_file.h>
34#include <linux/random.h> 35#include <linux/random.h>
35#include <linux/netdevice.h> 36#include <linux/netdevice.h>
diff --git a/net/irda/irlan/irlan_eth.c b/net/irda/irlan/irlan_eth.c
index 7b6b631f647f..d340110f5c0c 100644
--- a/net/irda/irlan/irlan_eth.c
+++ b/net/irda/irlan/irlan_eth.c
@@ -30,6 +30,7 @@
30#include <linux/inetdevice.h> 30#include <linux/inetdevice.h>
31#include <linux/if_arp.h> 31#include <linux/if_arp.h>
32#include <linux/module.h> 32#include <linux/module.h>
33#include <linux/sched.h>
33#include <net/arp.h> 34#include <net/arp.h>
34 35
35#include <net/irda/irda.h> 36#include <net/irda/irda.h>
diff --git a/net/irda/irnet/irnet_irda.c b/net/irda/irnet/irnet_irda.c
index cf9a4b531a98..cccc2e93234f 100644
--- a/net/irda/irnet/irnet_irda.c
+++ b/net/irda/irnet/irnet_irda.c
@@ -9,6 +9,7 @@
9 */ 9 */
10 10
11#include "irnet_irda.h" /* Private header */ 11#include "irnet_irda.h" /* Private header */
12#include <linux/sched.h>
12#include <linux/seq_file.h> 13#include <linux/seq_file.h>
13#include <asm/unaligned.h> 14#include <asm/unaligned.h>
14 15
diff --git a/net/irda/irnet/irnet_ppp.c b/net/irda/irnet/irnet_ppp.c
index 68cbcb19cbd8..7dea882dbb75 100644
--- a/net/irda/irnet/irnet_ppp.c
+++ b/net/irda/irnet/irnet_ppp.c
@@ -13,6 +13,7 @@
13 * 2) as a control channel (write commands, read events) 13 * 2) as a control channel (write commands, read events)
14 */ 14 */
15 15
16#include <linux/sched.h>
16#include <linux/smp_lock.h> 17#include <linux/smp_lock.h>
17#include "irnet_ppp.h" /* Private header */ 18#include "irnet_ppp.h" /* Private header */
18/* Please put other headers in irnet.h - Thanks */ 19/* Please put other headers in irnet.h - Thanks */
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
index d985d163dcfc..bada1b9c670b 100644
--- a/net/iucv/af_iucv.c
+++ b/net/iucv/af_iucv.c
@@ -1387,7 +1387,7 @@ static int iucv_sock_release(struct socket *sock)
1387 1387
1388/* getsockopt and setsockopt */ 1388/* getsockopt and setsockopt */
1389static int iucv_sock_setsockopt(struct socket *sock, int level, int optname, 1389static int iucv_sock_setsockopt(struct socket *sock, int level, int optname,
1390 char __user *optval, int optlen) 1390 char __user *optval, unsigned int optlen)
1391{ 1391{
1392 struct sock *sk = sock->sk; 1392 struct sock *sk = sock->sk;
1393 struct iucv_sock *iucv = iucv_sk(sk); 1393 struct iucv_sock *iucv = iucv_sk(sk);
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
index c45eee1c0e8d..7aa4fd170104 100644
--- a/net/llc/af_llc.c
+++ b/net/llc/af_llc.c
@@ -973,7 +973,7 @@ static int llc_ui_ioctl(struct socket *sock, unsigned int cmd,
973 * Set various connection specific parameters. 973 * Set various connection specific parameters.
974 */ 974 */
975static int llc_ui_setsockopt(struct socket *sock, int level, int optname, 975static int llc_ui_setsockopt(struct socket *sock, int level, int optname,
976 char __user *optval, int optlen) 976 char __user *optval, unsigned int optlen)
977{ 977{
978 struct sock *sk = sock->sk; 978 struct sock *sk = sock->sk;
979 struct llc_sock *llc = llc_sk(sk); 979 struct llc_sock *llc = llc_sk(sk);
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 920ec8792f4b..6eaf69823439 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -544,7 +544,7 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
544 "%pM\n", bss->cbss.bssid, ifibss->bssid); 544 "%pM\n", bss->cbss.bssid, ifibss->bssid);
545#endif /* CONFIG_MAC80211_IBSS_DEBUG */ 545#endif /* CONFIG_MAC80211_IBSS_DEBUG */
546 546
547 if (bss && memcmp(ifibss->bssid, bss->cbss.bssid, ETH_ALEN)) { 547 if (bss && !memcmp(ifibss->bssid, bss->cbss.bssid, ETH_ALEN)) {
548 printk(KERN_DEBUG "%s: Selected IBSS BSSID %pM" 548 printk(KERN_DEBUG "%s: Selected IBSS BSSID %pM"
549 " based on configured SSID\n", 549 " based on configured SSID\n",
550 sdata->dev->name, bss->cbss.bssid); 550 sdata->dev->name, bss->cbss.bssid);
@@ -829,7 +829,7 @@ void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local)
829 if (!sdata->u.ibss.ssid_len) 829 if (!sdata->u.ibss.ssid_len)
830 continue; 830 continue;
831 sdata->u.ibss.last_scan_completed = jiffies; 831 sdata->u.ibss.last_scan_completed = jiffies;
832 ieee80211_sta_find_ibss(sdata); 832 mod_timer(&sdata->u.ibss.timer, 0);
833 } 833 }
834 mutex_unlock(&local->iflist_mtx); 834 mutex_unlock(&local->iflist_mtx);
835} 835}
diff --git a/net/mac80211/rc80211_pid_debugfs.c b/net/mac80211/rc80211_pid_debugfs.c
index a59043fbb0ff..45667054a5f3 100644
--- a/net/mac80211/rc80211_pid_debugfs.c
+++ b/net/mac80211/rc80211_pid_debugfs.c
@@ -6,6 +6,7 @@
6 * published by the Free Software Foundation. 6 * published by the Free Software Foundation.
7 */ 7 */
8 8
9#include <linux/sched.h>
9#include <linux/spinlock.h> 10#include <linux/spinlock.h>
10#include <linux/poll.h> 11#include <linux/poll.h>
11#include <linux/netdevice.h> 12#include <linux/netdevice.h>
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index c01588f9d453..7170bf4565a8 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2164,11 +2164,17 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
2164 2164
2165 skb = rx.skb; 2165 skb = rx.skb;
2166 2166
2167 list_for_each_entry_rcu(sdata, &local->interfaces, list) { 2167 if (rx.sdata && ieee80211_is_data(hdr->frame_control)) {
2168 rx.flags |= IEEE80211_RX_RA_MATCH;
2169 prepares = prepare_for_handlers(rx.sdata, &rx, hdr);
2170 if (prepares)
2171 prev = rx.sdata;
2172 } else list_for_each_entry_rcu(sdata, &local->interfaces, list) {
2168 if (!netif_running(sdata->dev)) 2173 if (!netif_running(sdata->dev))
2169 continue; 2174 continue;
2170 2175
2171 if (sdata->vif.type == NL80211_IFTYPE_MONITOR) 2176 if (sdata->vif.type == NL80211_IFTYPE_MONITOR ||
2177 sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
2172 continue; 2178 continue;
2173 2179
2174 rx.flags |= IEEE80211_RX_RA_MATCH; 2180 rx.flags |= IEEE80211_RX_RA_MATCH;
@@ -2447,6 +2453,8 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb)
2447 struct ieee80211_supported_band *sband; 2453 struct ieee80211_supported_band *sband;
2448 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); 2454 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
2449 2455
2456 WARN_ON_ONCE(softirq_count() == 0);
2457
2450 if (WARN_ON(status->band < 0 || 2458 if (WARN_ON(status->band < 0 ||
2451 status->band >= IEEE80211_NUM_BANDS)) 2459 status->band >= IEEE80211_NUM_BANDS))
2452 goto drop; 2460 goto drop;
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index eec001491e66..594f2318c3d8 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -361,6 +361,7 @@ int sta_info_insert(struct sta_info *sta)
361 u.ap); 361 u.ap);
362 362
363 drv_sta_notify(local, &sdata->vif, STA_NOTIFY_ADD, &sta->sta); 363 drv_sta_notify(local, &sdata->vif, STA_NOTIFY_ADD, &sta->sta);
364 sdata = sta->sdata;
364 } 365 }
365 366
366#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 367#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
@@ -496,6 +497,7 @@ static void __sta_info_unlink(struct sta_info **sta)
496 497
497 drv_sta_notify(local, &sdata->vif, STA_NOTIFY_REMOVE, 498 drv_sta_notify(local, &sdata->vif, STA_NOTIFY_REMOVE,
498 &(*sta)->sta); 499 &(*sta)->sta);
500 sdata = (*sta)->sdata;
499 } 501 }
500 502
501 if (ieee80211_vif_is_mesh(&sdata->vif)) { 503 if (ieee80211_vif_is_mesh(&sdata->vif)) {
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 5143d203256b..db4bda681ec9 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -367,7 +367,10 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
367 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; 367 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
368 u32 staflags; 368 u32 staflags;
369 369
370 if (unlikely(!sta || ieee80211_is_probe_resp(hdr->frame_control))) 370 if (unlikely(!sta || ieee80211_is_probe_resp(hdr->frame_control)
371 || ieee80211_is_auth(hdr->frame_control)
372 || ieee80211_is_assoc_resp(hdr->frame_control)
373 || ieee80211_is_reassoc_resp(hdr->frame_control)))
371 return TX_CONTINUE; 374 return TX_CONTINUE;
372 375
373 staflags = get_sta_flags(sta); 376 staflags = get_sta_flags(sta);
@@ -1701,7 +1704,8 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1701 if (!is_multicast_ether_addr(hdr.addr1)) { 1704 if (!is_multicast_ether_addr(hdr.addr1)) {
1702 rcu_read_lock(); 1705 rcu_read_lock();
1703 sta = sta_info_get(local, hdr.addr1); 1706 sta = sta_info_get(local, hdr.addr1);
1704 if (sta) 1707 /* XXX: in the future, use sdata to look up the sta */
1708 if (sta && sta->sdata == sdata)
1705 sta_flags = get_sta_flags(sta); 1709 sta_flags = get_sta_flags(sta);
1706 rcu_read_unlock(); 1710 rcu_read_unlock();
1707 } 1711 }
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index dd6564321369..aeb65b3d2295 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -339,7 +339,7 @@ void ieee80211_add_pending_skb(struct ieee80211_local *local,
339 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 339 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
340 340
341 if (WARN_ON(!info->control.vif)) { 341 if (WARN_ON(!info->control.vif)) {
342 kfree(skb); 342 kfree_skb(skb);
343 return; 343 return;
344 } 344 }
345 345
@@ -367,7 +367,7 @@ int ieee80211_add_pending_skbs(struct ieee80211_local *local,
367 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 367 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
368 368
369 if (WARN_ON(!info->control.vif)) { 369 if (WARN_ON(!info->control.vif)) {
370 kfree(skb); 370 kfree_skb(skb);
371 continue; 371 continue;
372 } 372 }
373 373
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 7c9ec3dee96e..ca6e68dcd8a8 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -14,6 +14,7 @@
14#include <linux/types.h> 14#include <linux/types.h>
15#include <linux/netfilter.h> 15#include <linux/netfilter.h>
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/sched.h>
17#include <linux/skbuff.h> 18#include <linux/skbuff.h>
18#include <linux/proc_fs.h> 19#include <linux/proc_fs.h>
19#include <linux/vmalloc.h> 20#include <linux/vmalloc.h>
diff --git a/net/netfilter/nf_sockopt.c b/net/netfilter/nf_sockopt.c
index 8ab829f86574..f042ae521557 100644
--- a/net/netfilter/nf_sockopt.c
+++ b/net/netfilter/nf_sockopt.c
@@ -113,7 +113,7 @@ static int nf_sockopt(struct sock *sk, u_int8_t pf, int val,
113} 113}
114 114
115int nf_setsockopt(struct sock *sk, u_int8_t pf, int val, char __user *opt, 115int nf_setsockopt(struct sock *sk, u_int8_t pf, int val, char __user *opt,
116 int len) 116 unsigned int len)
117{ 117{
118 return nf_sockopt(sk, pf, val, opt, &len, 0); 118 return nf_sockopt(sk, pf, val, opt, &len, 0);
119} 119}
@@ -154,7 +154,7 @@ static int compat_nf_sockopt(struct sock *sk, u_int8_t pf, int val,
154} 154}
155 155
156int compat_nf_setsockopt(struct sock *sk, u_int8_t pf, 156int compat_nf_setsockopt(struct sock *sk, u_int8_t pf,
157 int val, char __user *opt, int len) 157 int val, char __user *opt, unsigned int len)
158{ 158{
159 return compat_nf_sockopt(sk, pf, val, opt, &len, 0); 159 return compat_nf_sockopt(sk, pf, val, opt, &len, 0);
160} 160}
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index dd85320907cb..19e98007691c 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -1150,7 +1150,7 @@ static void netlink_update_socket_mc(struct netlink_sock *nlk,
1150} 1150}
1151 1151
1152static int netlink_setsockopt(struct socket *sock, int level, int optname, 1152static int netlink_setsockopt(struct socket *sock, int level, int optname,
1153 char __user *optval, int optlen) 1153 char __user *optval, unsigned int optlen)
1154{ 1154{
1155 struct sock *sk = sock->sk; 1155 struct sock *sk = sock->sk;
1156 struct netlink_sock *nlk = nlk_sk(sk); 1156 struct netlink_sock *nlk = nlk_sk(sk);
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
index ce1a34b99c23..7a834952f67f 100644
--- a/net/netrom/af_netrom.c
+++ b/net/netrom/af_netrom.c
@@ -301,7 +301,7 @@ void nr_destroy_socket(struct sock *sk)
301 */ 301 */
302 302
303static int nr_setsockopt(struct socket *sock, int level, int optname, 303static int nr_setsockopt(struct socket *sock, int level, int optname,
304 char __user *optval, int optlen) 304 char __user *optval, unsigned int optlen)
305{ 305{
306 struct sock *sk = sock->sk; 306 struct sock *sk = sock->sk;
307 struct nr_sock *nr = nr_sk(sk); 307 struct nr_sock *nr = nr_sk(sk);
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 103d5611b818..d7ecca0a0c07 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -1701,7 +1701,7 @@ static void packet_flush_mclist(struct sock *sk)
1701} 1701}
1702 1702
1703static int 1703static int
1704packet_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen) 1704packet_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
1705{ 1705{
1706 struct sock *sk = sock->sk; 1706 struct sock *sk = sock->sk;
1707 struct packet_sock *po = pkt_sk(sk); 1707 struct packet_sock *po = pkt_sk(sk);
diff --git a/net/phonet/pep.c b/net/phonet/pep.c
index b8252d289cd7..5f32d217535b 100644
--- a/net/phonet/pep.c
+++ b/net/phonet/pep.c
@@ -742,7 +742,7 @@ static int pep_init(struct sock *sk)
742} 742}
743 743
744static int pep_setsockopt(struct sock *sk, int level, int optname, 744static int pep_setsockopt(struct sock *sk, int level, int optname,
745 char __user *optval, int optlen) 745 char __user *optval, unsigned int optlen)
746{ 746{
747 struct pep_sock *pn = pep_sk(sk); 747 struct pep_sock *pn = pep_sk(sk);
748 int val = 0, err = 0; 748 int val = 0, err = 0;
diff --git a/net/phonet/socket.c b/net/phonet/socket.c
index 07aa9f08d5fb..aa5b5a972bff 100644
--- a/net/phonet/socket.c
+++ b/net/phonet/socket.c
@@ -407,7 +407,6 @@ int pn_sock_get_port(struct sock *sk, unsigned short sport)
407 return -EADDRINUSE; 407 return -EADDRINUSE;
408 408
409found: 409found:
410 mutex_unlock(&port_mutex);
411 pn->sobject = pn_object(pn_addr(pn->sobject), sport); 410 pn->sobject = pn_object(pn_addr(pn->sobject), sport);
412 return 0; 411 return 0;
413} 412}
diff --git a/net/rds/af_rds.c b/net/rds/af_rds.c
index 6b58aeff4c7a..98e05382fd3c 100644
--- a/net/rds/af_rds.c
+++ b/net/rds/af_rds.c
@@ -248,7 +248,7 @@ static int rds_cong_monitor(struct rds_sock *rs, char __user *optval,
248} 248}
249 249
250static int rds_setsockopt(struct socket *sock, int level, int optname, 250static int rds_setsockopt(struct socket *sock, int level, int optname,
251 char __user *optval, int optlen) 251 char __user *optval, unsigned int optlen)
252{ 252{
253 struct rds_sock *rs = rds_sk_to_rs(sock->sk); 253 struct rds_sock *rs = rds_sk_to_rs(sock->sk);
254 int ret; 254 int ret;
diff --git a/net/rfkill/core.c b/net/rfkill/core.c
index dbeaf2983822..ba2efb960c60 100644
--- a/net/rfkill/core.c
+++ b/net/rfkill/core.c
@@ -27,6 +27,7 @@
27#include <linux/list.h> 27#include <linux/list.h>
28#include <linux/mutex.h> 28#include <linux/mutex.h>
29#include <linux/rfkill.h> 29#include <linux/rfkill.h>
30#include <linux/sched.h>
30#include <linux/spinlock.h> 31#include <linux/spinlock.h>
31#include <linux/miscdevice.h> 32#include <linux/miscdevice.h>
32#include <linux/wait.h> 33#include <linux/wait.h>
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
index 1e166c9685aa..502cce76621d 100644
--- a/net/rose/af_rose.c
+++ b/net/rose/af_rose.c
@@ -370,7 +370,7 @@ void rose_destroy_socket(struct sock *sk)
370 */ 370 */
371 371
372static int rose_setsockopt(struct socket *sock, int level, int optname, 372static int rose_setsockopt(struct socket *sock, int level, int optname,
373 char __user *optval, int optlen) 373 char __user *optval, unsigned int optlen)
374{ 374{
375 struct sock *sk = sock->sk; 375 struct sock *sk = sock->sk;
376 struct rose_sock *rose = rose_sk(sk); 376 struct rose_sock *rose = rose_sk(sk);
diff --git a/net/rxrpc/af_rxrpc.c b/net/rxrpc/af_rxrpc.c
index bfe493ebf27c..a86afceaa94f 100644
--- a/net/rxrpc/af_rxrpc.c
+++ b/net/rxrpc/af_rxrpc.c
@@ -507,7 +507,7 @@ out:
507 * set RxRPC socket options 507 * set RxRPC socket options
508 */ 508 */
509static int rxrpc_setsockopt(struct socket *sock, int level, int optname, 509static int rxrpc_setsockopt(struct socket *sock, int level, int optname,
510 char __user *optval, int optlen) 510 char __user *optval, unsigned int optlen)
511{ 511{
512 struct rxrpc_sock *rx = rxrpc_sk(sock->sk); 512 struct rxrpc_sock *rx = rxrpc_sk(sock->sk);
513 unsigned min_sec_level; 513 unsigned min_sec_level;
diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c
index 96c0ed115e2a..6b0359a500e6 100644
--- a/net/sched/act_pedit.c
+++ b/net/sched/act_pedit.c
@@ -34,7 +34,7 @@ static struct tcf_hashinfo pedit_hash_info = {
34}; 34};
35 35
36static const struct nla_policy pedit_policy[TCA_PEDIT_MAX + 1] = { 36static const struct nla_policy pedit_policy[TCA_PEDIT_MAX + 1] = {
37 [TCA_PEDIT_PARMS] = { .len = sizeof(struct tcf_pedit) }, 37 [TCA_PEDIT_PARMS] = { .len = sizeof(struct tc_pedit) },
38}; 38};
39 39
40static int tcf_pedit_init(struct nlattr *nla, struct nlattr *est, 40static int tcf_pedit_init(struct nlattr *nla, struct nlattr *est,
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 6a536949cdc0..7cf6c0fbc7a6 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -350,7 +350,7 @@ static int tcf_fill_node(struct sk_buff *skb, struct tcf_proto *tp,
350 tcm = NLMSG_DATA(nlh); 350 tcm = NLMSG_DATA(nlh);
351 tcm->tcm_family = AF_UNSPEC; 351 tcm->tcm_family = AF_UNSPEC;
352 tcm->tcm__pad1 = 0; 352 tcm->tcm__pad1 = 0;
353 tcm->tcm__pad1 = 0; 353 tcm->tcm__pad2 = 0;
354 tcm->tcm_ifindex = qdisc_dev(tp->q)->ifindex; 354 tcm->tcm_ifindex = qdisc_dev(tp->q)->ifindex;
355 tcm->tcm_parent = tp->classid; 355 tcm->tcm_parent = tp->classid;
356 tcm->tcm_info = TC_H_MAKE(tp->prio, tp->protocol); 356 tcm->tcm_info = TC_H_MAKE(tp->prio, tp->protocol);
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 89af37a6c871..c8d05758661d 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -2027,7 +2027,8 @@ out:
2027 * instead a error will be indicated to the user. 2027 * instead a error will be indicated to the user.
2028 */ 2028 */
2029static int sctp_setsockopt_disable_fragments(struct sock *sk, 2029static int sctp_setsockopt_disable_fragments(struct sock *sk,
2030 char __user *optval, int optlen) 2030 char __user *optval,
2031 unsigned int optlen)
2031{ 2032{
2032 int val; 2033 int val;
2033 2034
@@ -2043,7 +2044,7 @@ static int sctp_setsockopt_disable_fragments(struct sock *sk,
2043} 2044}
2044 2045
2045static int sctp_setsockopt_events(struct sock *sk, char __user *optval, 2046static int sctp_setsockopt_events(struct sock *sk, char __user *optval,
2046 int optlen) 2047 unsigned int optlen)
2047{ 2048{
2048 if (optlen > sizeof(struct sctp_event_subscribe)) 2049 if (optlen > sizeof(struct sctp_event_subscribe))
2049 return -EINVAL; 2050 return -EINVAL;
@@ -2064,7 +2065,7 @@ static int sctp_setsockopt_events(struct sock *sk, char __user *optval,
2064 * association is closed. 2065 * association is closed.
2065 */ 2066 */
2066static int sctp_setsockopt_autoclose(struct sock *sk, char __user *optval, 2067static int sctp_setsockopt_autoclose(struct sock *sk, char __user *optval,
2067 int optlen) 2068 unsigned int optlen)
2068{ 2069{
2069 struct sctp_sock *sp = sctp_sk(sk); 2070 struct sctp_sock *sp = sctp_sk(sk);
2070 2071
@@ -2318,7 +2319,8 @@ static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params,
2318} 2319}
2319 2320
2320static int sctp_setsockopt_peer_addr_params(struct sock *sk, 2321static int sctp_setsockopt_peer_addr_params(struct sock *sk,
2321 char __user *optval, int optlen) 2322 char __user *optval,
2323 unsigned int optlen)
2322{ 2324{
2323 struct sctp_paddrparams params; 2325 struct sctp_paddrparams params;
2324 struct sctp_transport *trans = NULL; 2326 struct sctp_transport *trans = NULL;
@@ -2430,7 +2432,7 @@ static int sctp_setsockopt_peer_addr_params(struct sock *sk,
2430 */ 2432 */
2431 2433
2432static int sctp_setsockopt_delayed_ack(struct sock *sk, 2434static int sctp_setsockopt_delayed_ack(struct sock *sk,
2433 char __user *optval, int optlen) 2435 char __user *optval, unsigned int optlen)
2434{ 2436{
2435 struct sctp_sack_info params; 2437 struct sctp_sack_info params;
2436 struct sctp_transport *trans = NULL; 2438 struct sctp_transport *trans = NULL;
@@ -2546,7 +2548,7 @@ static int sctp_setsockopt_delayed_ack(struct sock *sk,
2546 * by the change). With TCP-style sockets, this option is inherited by 2548 * by the change). With TCP-style sockets, this option is inherited by
2547 * sockets derived from a listener socket. 2549 * sockets derived from a listener socket.
2548 */ 2550 */
2549static int sctp_setsockopt_initmsg(struct sock *sk, char __user *optval, int optlen) 2551static int sctp_setsockopt_initmsg(struct sock *sk, char __user *optval, unsigned int optlen)
2550{ 2552{
2551 struct sctp_initmsg sinit; 2553 struct sctp_initmsg sinit;
2552 struct sctp_sock *sp = sctp_sk(sk); 2554 struct sctp_sock *sp = sctp_sk(sk);
@@ -2583,7 +2585,8 @@ static int sctp_setsockopt_initmsg(struct sock *sk, char __user *optval, int opt
2583 * to this call if the caller is using the UDP model. 2585 * to this call if the caller is using the UDP model.
2584 */ 2586 */
2585static int sctp_setsockopt_default_send_param(struct sock *sk, 2587static int sctp_setsockopt_default_send_param(struct sock *sk,
2586 char __user *optval, int optlen) 2588 char __user *optval,
2589 unsigned int optlen)
2587{ 2590{
2588 struct sctp_sndrcvinfo info; 2591 struct sctp_sndrcvinfo info;
2589 struct sctp_association *asoc; 2592 struct sctp_association *asoc;
@@ -2622,7 +2625,7 @@ static int sctp_setsockopt_default_send_param(struct sock *sk,
2622 * association peer's addresses. 2625 * association peer's addresses.
2623 */ 2626 */
2624static int sctp_setsockopt_primary_addr(struct sock *sk, char __user *optval, 2627static int sctp_setsockopt_primary_addr(struct sock *sk, char __user *optval,
2625 int optlen) 2628 unsigned int optlen)
2626{ 2629{
2627 struct sctp_prim prim; 2630 struct sctp_prim prim;
2628 struct sctp_transport *trans; 2631 struct sctp_transport *trans;
@@ -2651,7 +2654,7 @@ static int sctp_setsockopt_primary_addr(struct sock *sk, char __user *optval,
2651 * integer boolean flag. 2654 * integer boolean flag.
2652 */ 2655 */
2653static int sctp_setsockopt_nodelay(struct sock *sk, char __user *optval, 2656static int sctp_setsockopt_nodelay(struct sock *sk, char __user *optval,
2654 int optlen) 2657 unsigned int optlen)
2655{ 2658{
2656 int val; 2659 int val;
2657 2660
@@ -2676,7 +2679,8 @@ static int sctp_setsockopt_nodelay(struct sock *sk, char __user *optval,
2676 * be changed. 2679 * be changed.
2677 * 2680 *
2678 */ 2681 */
2679static int sctp_setsockopt_rtoinfo(struct sock *sk, char __user *optval, int optlen) { 2682static int sctp_setsockopt_rtoinfo(struct sock *sk, char __user *optval, unsigned int optlen)
2683{
2680 struct sctp_rtoinfo rtoinfo; 2684 struct sctp_rtoinfo rtoinfo;
2681 struct sctp_association *asoc; 2685 struct sctp_association *asoc;
2682 2686
@@ -2728,7 +2732,7 @@ static int sctp_setsockopt_rtoinfo(struct sock *sk, char __user *optval, int opt
2728 * See [SCTP] for more information. 2732 * See [SCTP] for more information.
2729 * 2733 *
2730 */ 2734 */
2731static int sctp_setsockopt_associnfo(struct sock *sk, char __user *optval, int optlen) 2735static int sctp_setsockopt_associnfo(struct sock *sk, char __user *optval, unsigned int optlen)
2732{ 2736{
2733 2737
2734 struct sctp_assocparams assocparams; 2738 struct sctp_assocparams assocparams;
@@ -2800,7 +2804,7 @@ static int sctp_setsockopt_associnfo(struct sock *sk, char __user *optval, int o
2800 * addresses and a user will receive both PF_INET6 and PF_INET type 2804 * addresses and a user will receive both PF_INET6 and PF_INET type
2801 * addresses on the socket. 2805 * addresses on the socket.
2802 */ 2806 */
2803static int sctp_setsockopt_mappedv4(struct sock *sk, char __user *optval, int optlen) 2807static int sctp_setsockopt_mappedv4(struct sock *sk, char __user *optval, unsigned int optlen)
2804{ 2808{
2805 int val; 2809 int val;
2806 struct sctp_sock *sp = sctp_sk(sk); 2810 struct sctp_sock *sp = sctp_sk(sk);
@@ -2844,7 +2848,7 @@ static int sctp_setsockopt_mappedv4(struct sock *sk, char __user *optval, int op
2844 * changed (effecting future associations only). 2848 * changed (effecting future associations only).
2845 * assoc_value: This parameter specifies the maximum size in bytes. 2849 * assoc_value: This parameter specifies the maximum size in bytes.
2846 */ 2850 */
2847static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, int optlen) 2851static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, unsigned int optlen)
2848{ 2852{
2849 struct sctp_assoc_value params; 2853 struct sctp_assoc_value params;
2850 struct sctp_association *asoc; 2854 struct sctp_association *asoc;
@@ -2899,7 +2903,7 @@ static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, int optl
2899 * set primary request: 2903 * set primary request:
2900 */ 2904 */
2901static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char __user *optval, 2905static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char __user *optval,
2902 int optlen) 2906 unsigned int optlen)
2903{ 2907{
2904 struct sctp_sock *sp; 2908 struct sctp_sock *sp;
2905 struct sctp_endpoint *ep; 2909 struct sctp_endpoint *ep;
@@ -2950,7 +2954,7 @@ static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char __user *optva
2950} 2954}
2951 2955
2952static int sctp_setsockopt_adaptation_layer(struct sock *sk, char __user *optval, 2956static int sctp_setsockopt_adaptation_layer(struct sock *sk, char __user *optval,
2953 int optlen) 2957 unsigned int optlen)
2954{ 2958{
2955 struct sctp_setadaptation adaptation; 2959 struct sctp_setadaptation adaptation;
2956 2960
@@ -2979,7 +2983,7 @@ static int sctp_setsockopt_adaptation_layer(struct sock *sk, char __user *optval
2979 * saved with outbound messages. 2983 * saved with outbound messages.
2980 */ 2984 */
2981static int sctp_setsockopt_context(struct sock *sk, char __user *optval, 2985static int sctp_setsockopt_context(struct sock *sk, char __user *optval,
2982 int optlen) 2986 unsigned int optlen)
2983{ 2987{
2984 struct sctp_assoc_value params; 2988 struct sctp_assoc_value params;
2985 struct sctp_sock *sp; 2989 struct sctp_sock *sp;
@@ -3030,7 +3034,7 @@ static int sctp_setsockopt_context(struct sock *sk, char __user *optval,
3030 */ 3034 */
3031static int sctp_setsockopt_fragment_interleave(struct sock *sk, 3035static int sctp_setsockopt_fragment_interleave(struct sock *sk,
3032 char __user *optval, 3036 char __user *optval,
3033 int optlen) 3037 unsigned int optlen)
3034{ 3038{
3035 int val; 3039 int val;
3036 3040
@@ -3063,7 +3067,7 @@ static int sctp_setsockopt_fragment_interleave(struct sock *sk,
3063 */ 3067 */
3064static int sctp_setsockopt_partial_delivery_point(struct sock *sk, 3068static int sctp_setsockopt_partial_delivery_point(struct sock *sk,
3065 char __user *optval, 3069 char __user *optval,
3066 int optlen) 3070 unsigned int optlen)
3067{ 3071{
3068 u32 val; 3072 u32 val;
3069 3073
@@ -3096,7 +3100,7 @@ static int sctp_setsockopt_partial_delivery_point(struct sock *sk,
3096 */ 3100 */
3097static int sctp_setsockopt_maxburst(struct sock *sk, 3101static int sctp_setsockopt_maxburst(struct sock *sk,
3098 char __user *optval, 3102 char __user *optval,
3099 int optlen) 3103 unsigned int optlen)
3100{ 3104{
3101 struct sctp_assoc_value params; 3105 struct sctp_assoc_value params;
3102 struct sctp_sock *sp; 3106 struct sctp_sock *sp;
@@ -3140,8 +3144,8 @@ static int sctp_setsockopt_maxburst(struct sock *sk,
3140 * will only effect future associations on the socket. 3144 * will only effect future associations on the socket.
3141 */ 3145 */
3142static int sctp_setsockopt_auth_chunk(struct sock *sk, 3146static int sctp_setsockopt_auth_chunk(struct sock *sk,
3143 char __user *optval, 3147 char __user *optval,
3144 int optlen) 3148 unsigned int optlen)
3145{ 3149{
3146 struct sctp_authchunk val; 3150 struct sctp_authchunk val;
3147 3151
@@ -3172,8 +3176,8 @@ static int sctp_setsockopt_auth_chunk(struct sock *sk,
3172 * endpoint requires the peer to use. 3176 * endpoint requires the peer to use.
3173 */ 3177 */
3174static int sctp_setsockopt_hmac_ident(struct sock *sk, 3178static int sctp_setsockopt_hmac_ident(struct sock *sk,
3175 char __user *optval, 3179 char __user *optval,
3176 int optlen) 3180 unsigned int optlen)
3177{ 3181{
3178 struct sctp_hmacalgo *hmacs; 3182 struct sctp_hmacalgo *hmacs;
3179 u32 idents; 3183 u32 idents;
@@ -3215,7 +3219,7 @@ out:
3215 */ 3219 */
3216static int sctp_setsockopt_auth_key(struct sock *sk, 3220static int sctp_setsockopt_auth_key(struct sock *sk,
3217 char __user *optval, 3221 char __user *optval,
3218 int optlen) 3222 unsigned int optlen)
3219{ 3223{
3220 struct sctp_authkey *authkey; 3224 struct sctp_authkey *authkey;
3221 struct sctp_association *asoc; 3225 struct sctp_association *asoc;
@@ -3260,8 +3264,8 @@ out:
3260 * the association shared key. 3264 * the association shared key.
3261 */ 3265 */
3262static int sctp_setsockopt_active_key(struct sock *sk, 3266static int sctp_setsockopt_active_key(struct sock *sk,
3263 char __user *optval, 3267 char __user *optval,
3264 int optlen) 3268 unsigned int optlen)
3265{ 3269{
3266 struct sctp_authkeyid val; 3270 struct sctp_authkeyid val;
3267 struct sctp_association *asoc; 3271 struct sctp_association *asoc;
@@ -3288,8 +3292,8 @@ static int sctp_setsockopt_active_key(struct sock *sk,
3288 * This set option will delete a shared secret key from use. 3292 * This set option will delete a shared secret key from use.
3289 */ 3293 */
3290static int sctp_setsockopt_del_key(struct sock *sk, 3294static int sctp_setsockopt_del_key(struct sock *sk,
3291 char __user *optval, 3295 char __user *optval,
3292 int optlen) 3296 unsigned int optlen)
3293{ 3297{
3294 struct sctp_authkeyid val; 3298 struct sctp_authkeyid val;
3295 struct sctp_association *asoc; 3299 struct sctp_association *asoc;
@@ -3332,7 +3336,7 @@ static int sctp_setsockopt_del_key(struct sock *sk,
3332 * optlen - the size of the buffer. 3336 * optlen - the size of the buffer.
3333 */ 3337 */
3334SCTP_STATIC int sctp_setsockopt(struct sock *sk, int level, int optname, 3338SCTP_STATIC int sctp_setsockopt(struct sock *sk, int level, int optname,
3335 char __user *optval, int optlen) 3339 char __user *optval, unsigned int optlen)
3336{ 3340{
3337 int retval = 0; 3341 int retval = 0;
3338 3342
diff --git a/net/socket.c b/net/socket.c
index 41e8847508aa..75655365b5fd 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -2391,7 +2391,7 @@ int kernel_getsockopt(struct socket *sock, int level, int optname,
2391} 2391}
2392 2392
2393int kernel_setsockopt(struct socket *sock, int level, int optname, 2393int kernel_setsockopt(struct socket *sock, int level, int optname,
2394 char *optval, int optlen) 2394 char *optval, unsigned int optlen)
2395{ 2395{
2396 mm_segment_t oldfs = get_fs(); 2396 mm_segment_t oldfs = get_fs();
2397 int err; 2397 int err;
diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c
index 0cf5e8c27a10..3fa5751af0ec 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_transport.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c
@@ -42,6 +42,7 @@
42#include <linux/sunrpc/svc_xprt.h> 42#include <linux/sunrpc/svc_xprt.h>
43#include <linux/sunrpc/debug.h> 43#include <linux/sunrpc/debug.h>
44#include <linux/sunrpc/rpc_rdma.h> 44#include <linux/sunrpc/rpc_rdma.h>
45#include <linux/sched.h>
45#include <linux/spinlock.h> 46#include <linux/spinlock.h>
46#include <rdma/ib_verbs.h> 47#include <rdma/ib_verbs.h>
47#include <rdma/rdma_cm.h> 48#include <rdma/rdma_cm.h>
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index e8254e809b79..e6d9abf7440e 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -1658,7 +1658,7 @@ restart:
1658 */ 1658 */
1659 1659
1660static int setsockopt(struct socket *sock, 1660static int setsockopt(struct socket *sock,
1661 int lvl, int opt, char __user *ov, int ol) 1661 int lvl, int opt, char __user *ov, unsigned int ol)
1662{ 1662{
1663 struct sock *sk = sock->sk; 1663 struct sock *sk = sock->sk;
1664 struct tipc_port *tport = tipc_sk_port(sk); 1664 struct tipc_port *tport = tipc_sk_port(sk);
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 45b2be3274db..a595f712b5bf 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -14,6 +14,7 @@
14#include <linux/device.h> 14#include <linux/device.h>
15#include <linux/etherdevice.h> 15#include <linux/etherdevice.h>
16#include <linux/rtnetlink.h> 16#include <linux/rtnetlink.h>
17#include <linux/sched.h>
17#include <net/genetlink.h> 18#include <net/genetlink.h>
18#include <net/cfg80211.h> 19#include <net/cfg80211.h>
19#include "nl80211.h" 20#include "nl80211.h"
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index eddab097435c..ca3c92a0a14f 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -4029,7 +4029,7 @@ static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info)
4029 rdev = cfg80211_get_dev_from_info(info); 4029 rdev = cfg80211_get_dev_from_info(info);
4030 if (IS_ERR(rdev)) { 4030 if (IS_ERR(rdev)) {
4031 err = PTR_ERR(rdev); 4031 err = PTR_ERR(rdev);
4032 goto out; 4032 goto out_rtnl;
4033 } 4033 }
4034 4034
4035 net = get_net_ns_by_pid(pid); 4035 net = get_net_ns_by_pid(pid);
@@ -4049,6 +4049,7 @@ static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info)
4049 put_net(net); 4049 put_net(net);
4050 out: 4050 out:
4051 cfg80211_unlock_rdev(rdev); 4051 cfg80211_unlock_rdev(rdev);
4052 out_rtnl:
4052 rtnl_unlock(); 4053 rtnl_unlock();
4053 return err; 4054 return err;
4054} 4055}
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
index 5e6c072c64d3..7fa9c7ad3d3b 100644
--- a/net/x25/af_x25.c
+++ b/net/x25/af_x25.c
@@ -409,7 +409,7 @@ static void x25_destroy_socket(struct sock *sk)
409 */ 409 */
410 410
411static int x25_setsockopt(struct socket *sock, int level, int optname, 411static int x25_setsockopt(struct socket *sock, int level, int optname,
412 char __user *optval, int optlen) 412 char __user *optval, unsigned int optlen)
413{ 413{
414 int opt; 414 int opt;
415 struct sock *sk = sock->sk; 415 struct sock *sk = sock->sk;
diff --git a/samples/tracepoints/tracepoint-sample.c b/samples/tracepoints/tracepoint-sample.c
index 9cf80a11e8b6..26fab33ffa8c 100644
--- a/samples/tracepoints/tracepoint-sample.c
+++ b/samples/tracepoints/tracepoint-sample.c
@@ -28,7 +28,7 @@ static int my_open(struct inode *inode, struct file *file)
28 return -EPERM; 28 return -EPERM;
29} 29}
30 30
31static struct file_operations mark_ops = { 31static const struct file_operations mark_ops = {
32 .open = my_open, 32 .open = my_open,
33}; 33};
34 34
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include
index 4f9c1908593b..c67e73ecd5be 100644
--- a/scripts/Kbuild.include
+++ b/scripts/Kbuild.include
@@ -100,7 +100,7 @@ as-option = $(call try-run,\
100# Usage: cflags-y += $(call as-instr,instr,option1,option2) 100# Usage: cflags-y += $(call as-instr,instr,option1,option2)
101 101
102as-instr = $(call try-run,\ 102as-instr = $(call try-run,\
103 echo -e "$(1)" | $(CC) $(KBUILD_AFLAGS) -c -xassembler -o "$$TMP" -,$(2),$(3)) 103 /bin/echo -e "$(1)" | $(CC) $(KBUILD_AFLAGS) -c -xassembler -o "$$TMP" -,$(2),$(3))
104 104
105# cc-option 105# cc-option
106# Usage: cflags-y += $(call cc-option,-march=winchip-c6,-march=i586) 106# Usage: cflags-y += $(call cc-option,-march=winchip-c6,-march=i586)
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 7a7778746ea6..ffdafb26f539 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -208,7 +208,7 @@ cmd_gzip = (cat $(filter-out FORCE,$^) | gzip -f -9 > $@) || \
208 208
209# Bzip2 and LZMA do not include size in file... so we have to fake that; 209# Bzip2 and LZMA do not include size in file... so we have to fake that;
210# append the size as a 32-bit littleendian number as gzip does. 210# append the size as a 32-bit littleendian number as gzip does.
211size_append = echo -ne $(shell \ 211size_append = /bin/echo -ne $(shell \
212dec_size=0; \ 212dec_size=0; \
213for F in $1; do \ 213for F in $1; do \
214 fsize=$$(stat -c "%s" $$F); \ 214 fsize=$$(stat -c "%s" $$F); \
diff --git a/scripts/checkkconfigsymbols.sh b/scripts/checkkconfigsymbols.sh
index 39677c82747a..46be3c5a62b7 100755
--- a/scripts/checkkconfigsymbols.sh
+++ b/scripts/checkkconfigsymbols.sh
@@ -9,7 +9,7 @@ paths="$@"
9# Doing this once at the beginning saves a lot of time, on a cache-hot tree. 9# Doing this once at the beginning saves a lot of time, on a cache-hot tree.
10Kconfigs="`find . -name 'Kconfig' -o -name 'Kconfig*[^~]'`" 10Kconfigs="`find . -name 'Kconfig' -o -name 'Kconfig*[^~]'`"
11 11
12echo -e "File list \tundefined symbol used" 12/bin/echo -e "File list \tundefined symbol used"
13find $paths -name '*.[chS]' -o -name 'Makefile' -o -name 'Makefile*[^~]'| while read i 13find $paths -name '*.[chS]' -o -name 'Makefile' -o -name 'Makefile*[^~]'| while read i
14do 14do
15 # Output the bare Kconfig variable and the filename; the _MODULE part at 15 # Output the bare Kconfig variable and the filename; the _MODULE part at
@@ -54,6 +54,6 @@ while read symb files; do
54 # beyond the purpose of this script. 54 # beyond the purpose of this script.
55 symb_bare=`echo $symb | sed -e 's/_MODULE//'` 55 symb_bare=`echo $symb | sed -e 's/_MODULE//'`
56 if ! grep -q "\<$symb_bare\>" $Kconfigs; then 56 if ! grep -q "\<$symb_bare\>" $Kconfigs; then
57 echo -e "$files: \t$symb" 57 /bin/echo -e "$files: \t$symb"
58 fi 58 fi
59done|sort 59done|sort
diff --git a/scripts/headers_install.pl b/scripts/headers_install.pl
index c6ae4052ab43..b89ca2c58fdb 100644
--- a/scripts/headers_install.pl
+++ b/scripts/headers_install.pl
@@ -20,7 +20,7 @@ use strict;
20 20
21my ($readdir, $installdir, $arch, @files) = @ARGV; 21my ($readdir, $installdir, $arch, @files) = @ARGV;
22 22
23my $unifdef = "scripts/unifdef -U__KERNEL__"; 23my $unifdef = "scripts/unifdef -U__KERNEL__ -D__EXPORTED_HEADERS__";
24 24
25foreach my $file (@files) { 25foreach my $file (@files) {
26 local *INFILE; 26 local *INFILE;
diff --git a/scripts/mkcompile_h b/scripts/mkcompile_h
index 6a12dd9f1181..bce3d0fe6fbd 100755
--- a/scripts/mkcompile_h
+++ b/scripts/mkcompile_h
@@ -1,3 +1,5 @@
1#!/bin/sh
2
1TARGET=$1 3TARGET=$1
2ARCH=$2 4ARCH=$2
3SMP=$3 5SMP=$3
@@ -50,7 +52,7 @@ UTS_VERSION="$UTS_VERSION $CONFIG_FLAGS $TIMESTAMP"
50# Truncate to maximum length 52# Truncate to maximum length
51 53
52UTS_LEN=64 54UTS_LEN=64
53UTS_TRUNCATE="sed -e s/\(.\{1,$UTS_LEN\}\).*/\1/" 55UTS_TRUNCATE="cut -b -$UTS_LEN"
54 56
55# Generate a temporary compile.h 57# Generate a temporary compile.h
56 58
@@ -66,9 +68,13 @@ UTS_TRUNCATE="sed -e s/\(.\{1,$UTS_LEN\}\).*/\1/"
66 echo \#define LINUX_COMPILE_HOST \"`hostname | $UTS_TRUNCATE`\" 68 echo \#define LINUX_COMPILE_HOST \"`hostname | $UTS_TRUNCATE`\"
67 69
68 if [ -x /bin/dnsdomainname ]; then 70 if [ -x /bin/dnsdomainname ]; then
69 echo \#define LINUX_COMPILE_DOMAIN \"`dnsdomainname | $UTS_TRUNCATE`\" 71 domain=`dnsdomainname 2> /dev/null`
70 elif [ -x /bin/domainname ]; then 72 elif [ -x /bin/domainname ]; then
71 echo \#define LINUX_COMPILE_DOMAIN \"`domainname | $UTS_TRUNCATE`\" 73 domain=`domainname 2> /dev/null`
74 fi
75
76 if [ -n "$domain" ]; then
77 echo \#define LINUX_COMPILE_DOMAIN \"`echo $domain | $UTS_TRUNCATE`\"
72 else 78 else
73 echo \#define LINUX_COMPILE_DOMAIN 79 echo \#define LINUX_COMPILE_DOMAIN
74 fi 80 fi
diff --git a/scripts/package/Makefile b/scripts/package/Makefile
index fa4a0a17b7e0..f67cc885c807 100644
--- a/scripts/package/Makefile
+++ b/scripts/package/Makefile
@@ -18,6 +18,9 @@
18# e) generate the rpm files, based on kernel.spec 18# e) generate the rpm files, based on kernel.spec
19# - Use /. to avoid tar packing just the symlink 19# - Use /. to avoid tar packing just the symlink
20 20
21# Note that the rpm-pkg target cannot be used with KBUILD_OUTPUT,
22# but the binrpm-pkg target can; for some reason O= gets ignored.
23
21# Do we have rpmbuild, otherwise fall back to the older rpm 24# Do we have rpmbuild, otherwise fall back to the older rpm
22RPM := $(shell if [ -x "/usr/bin/rpmbuild" ]; then echo rpmbuild; \ 25RPM := $(shell if [ -x "/usr/bin/rpmbuild" ]; then echo rpmbuild; \
23 else echo rpm; fi) 26 else echo rpm; fi)
@@ -33,6 +36,12 @@ $(objtree)/kernel.spec: $(MKSPEC) $(srctree)/Makefile
33 $(CONFIG_SHELL) $(MKSPEC) > $@ 36 $(CONFIG_SHELL) $(MKSPEC) > $@
34 37
35rpm-pkg rpm: $(objtree)/kernel.spec FORCE 38rpm-pkg rpm: $(objtree)/kernel.spec FORCE
39 @if test -n "$(KBUILD_OUTPUT)"; then \
40 echo "Building source + binary RPM is not possible outside the"; \
41 echo "kernel source tree. Don't set KBUILD_OUTPUT, or use the"; \
42 echo "binrpm-pkg target instead."; \
43 false; \
44 fi
36 $(MAKE) clean 45 $(MAKE) clean
37 $(PREV) ln -sf $(srctree) $(KERNELPATH) 46 $(PREV) ln -sf $(srctree) $(KERNELPATH)
38 $(CONFIG_SHELL) $(srctree)/scripts/setlocalversion > $(objtree)/.scmversion 47 $(CONFIG_SHELL) $(srctree)/scripts/setlocalversion > $(objtree)/.scmversion
@@ -61,7 +70,7 @@ binrpm-pkg: $(objtree)/binkernel.spec FORCE
61 set -e; \ 70 set -e; \
62 mv -f $(objtree)/.tmp_version $(objtree)/.version 71 mv -f $(objtree)/.tmp_version $(objtree)/.version
63 72
64 $(RPM) $(RPMOPTS) --define "_builddir $(srctree)" --target \ 73 $(RPM) $(RPMOPTS) --define "_builddir $(objtree)" --target \
65 $(UTS_MACHINE) -bb $< 74 $(UTS_MACHINE) -bb $<
66 75
67clean-files += $(objtree)/binkernel.spec 76clean-files += $(objtree)/binkernel.spec
diff --git a/scripts/package/mkspec b/scripts/package/mkspec
index 3d93f8c81252..47bdd2f99b78 100755
--- a/scripts/package/mkspec
+++ b/scripts/package/mkspec
@@ -70,7 +70,7 @@ echo 'mkdir -p $RPM_BUILD_ROOT/boot $RPM_BUILD_ROOT/lib/modules'
70echo 'mkdir -p $RPM_BUILD_ROOT/lib/firmware' 70echo 'mkdir -p $RPM_BUILD_ROOT/lib/firmware'
71echo "%endif" 71echo "%endif"
72 72
73echo 'INSTALL_MOD_PATH=$RPM_BUILD_ROOT make %{_smp_mflags} modules_install' 73echo 'INSTALL_MOD_PATH=$RPM_BUILD_ROOT make %{_smp_mflags} KBUILD_SRC= modules_install'
74echo "%ifarch ia64" 74echo "%ifarch ia64"
75echo 'cp $KBUILD_IMAGE $RPM_BUILD_ROOT'"/boot/efi/vmlinuz-$KERNELRELEASE" 75echo 'cp $KBUILD_IMAGE $RPM_BUILD_ROOT'"/boot/efi/vmlinuz-$KERNELRELEASE"
76echo 'ln -s '"efi/vmlinuz-$KERNELRELEASE" '$RPM_BUILD_ROOT'"/boot/" 76echo 'ln -s '"efi/vmlinuz-$KERNELRELEASE" '$RPM_BUILD_ROOT'"/boot/"
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index 8e9777b76405..0c72c9c38956 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -43,7 +43,7 @@ static ssize_t ima_show_htable_violations(struct file *filp,
43 return ima_show_htable_value(buf, count, ppos, &ima_htable.violations); 43 return ima_show_htable_value(buf, count, ppos, &ima_htable.violations);
44} 44}
45 45
46static struct file_operations ima_htable_violations_ops = { 46static const struct file_operations ima_htable_violations_ops = {
47 .read = ima_show_htable_violations 47 .read = ima_show_htable_violations
48}; 48};
49 49
@@ -55,7 +55,7 @@ static ssize_t ima_show_measurements_count(struct file *filp,
55 55
56} 56}
57 57
58static struct file_operations ima_measurements_count_ops = { 58static const struct file_operations ima_measurements_count_ops = {
59 .read = ima_show_measurements_count 59 .read = ima_show_measurements_count
60}; 60};
61 61
@@ -158,7 +158,7 @@ static int ima_measurements_open(struct inode *inode, struct file *file)
158 return seq_open(file, &ima_measurments_seqops); 158 return seq_open(file, &ima_measurments_seqops);
159} 159}
160 160
161static struct file_operations ima_measurements_ops = { 161static const struct file_operations ima_measurements_ops = {
162 .open = ima_measurements_open, 162 .open = ima_measurements_open,
163 .read = seq_read, 163 .read = seq_read,
164 .llseek = seq_lseek, 164 .llseek = seq_lseek,
@@ -233,7 +233,7 @@ static int ima_ascii_measurements_open(struct inode *inode, struct file *file)
233 return seq_open(file, &ima_ascii_measurements_seqops); 233 return seq_open(file, &ima_ascii_measurements_seqops);
234} 234}
235 235
236static struct file_operations ima_ascii_measurements_ops = { 236static const struct file_operations ima_ascii_measurements_ops = {
237 .open = ima_ascii_measurements_open, 237 .open = ima_ascii_measurements_open,
238 .read = seq_read, 238 .read = seq_read,
239 .llseek = seq_lseek, 239 .llseek = seq_lseek,
@@ -313,7 +313,7 @@ static int ima_release_policy(struct inode *inode, struct file *file)
313 return 0; 313 return 0;
314} 314}
315 315
316static struct file_operations ima_measure_policy_ops = { 316static const struct file_operations ima_measure_policy_ops = {
317 .open = ima_open_policy, 317 .open = ima_open_policy,
318 .write = ima_write_policy, 318 .write = ima_write_policy,
319 .release = ima_release_policy 319 .release = ima_release_policy
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index 2fb28efc5326..06ec722897be 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -873,7 +873,7 @@ static long get_instantiation_keyring(key_serial_t ringid,
873 /* otherwise specify the destination keyring recorded in the 873 /* otherwise specify the destination keyring recorded in the
874 * authorisation key (any KEY_SPEC_*_KEYRING) */ 874 * authorisation key (any KEY_SPEC_*_KEYRING) */
875 if (ringid >= KEY_SPEC_REQUESTOR_KEYRING) { 875 if (ringid >= KEY_SPEC_REQUESTOR_KEYRING) {
876 *_dest_keyring = rka->dest_keyring; 876 *_dest_keyring = key_get(rka->dest_keyring);
877 return 0; 877 return 0;
878 } 878 }
879 879
diff --git a/sound/aoa/codecs/tas.c b/sound/aoa/codecs/tas.c
index f0ebc971c686..1dd66ddffcaf 100644
--- a/sound/aoa/codecs/tas.c
+++ b/sound/aoa/codecs/tas.c
@@ -897,6 +897,15 @@ static int tas_create(struct i2c_adapter *adapter,
897 client = i2c_new_device(adapter, &info); 897 client = i2c_new_device(adapter, &info);
898 if (!client) 898 if (!client)
899 return -ENODEV; 899 return -ENODEV;
900 /*
901 * We know the driver is already loaded, so the device should be
902 * already bound. If not it means binding failed, and then there
903 * is no point in keeping the device instantiated.
904 */
905 if (!client->driver) {
906 i2c_unregister_device(client);
907 return -ENODEV;
908 }
900 909
901 /* 910 /*
902 * Let i2c-core delete that device on driver removal. 911 * Let i2c-core delete that device on driver removal.
diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c
index dc78272fc39f..1f0f8213e2d5 100644
--- a/sound/arm/aaci.c
+++ b/sound/arm/aaci.c
@@ -937,6 +937,7 @@ static int __devinit aaci_probe_ac97(struct aaci *aaci)
937 struct snd_ac97 *ac97; 937 struct snd_ac97 *ac97;
938 int ret; 938 int ret;
939 939
940 writel(0, aaci->base + AC97_POWERDOWN);
940 /* 941 /*
941 * Assert AACIRESET for 2us 942 * Assert AACIRESET for 2us
942 */ 943 */
diff --git a/sound/drivers/opl3/opl3_midi.c b/sound/drivers/opl3/opl3_midi.c
index 6e7d09ae0e82..7d722a025d0d 100644
--- a/sound/drivers/opl3/opl3_midi.c
+++ b/sound/drivers/opl3/opl3_midi.c
@@ -29,6 +29,8 @@ extern char snd_opl3_regmap[MAX_OPL2_VOICES][4];
29 29
30extern int use_internal_drums; 30extern int use_internal_drums;
31 31
32static void snd_opl3_note_off_unsafe(void *p, int note, int vel,
33 struct snd_midi_channel *chan);
32/* 34/*
33 * The next table looks magical, but it certainly is not. Its values have 35 * The next table looks magical, but it certainly is not. Its values have
34 * been calculated as table[i]=8*log(i/64)/log(2) with an obvious exception 36 * been calculated as table[i]=8*log(i/64)/log(2) with an obvious exception
@@ -242,16 +244,20 @@ void snd_opl3_timer_func(unsigned long data)
242 int again = 0; 244 int again = 0;
243 int i; 245 int i;
244 246
245 spin_lock_irqsave(&opl3->sys_timer_lock, flags); 247 spin_lock_irqsave(&opl3->voice_lock, flags);
246 for (i = 0; i < opl3->max_voices; i++) { 248 for (i = 0; i < opl3->max_voices; i++) {
247 struct snd_opl3_voice *vp = &opl3->voices[i]; 249 struct snd_opl3_voice *vp = &opl3->voices[i];
248 if (vp->state > 0 && vp->note_off_check) { 250 if (vp->state > 0 && vp->note_off_check) {
249 if (vp->note_off == jiffies) 251 if (vp->note_off == jiffies)
250 snd_opl3_note_off(opl3, vp->note, 0, vp->chan); 252 snd_opl3_note_off_unsafe(opl3, vp->note, 0,
253 vp->chan);
251 else 254 else
252 again++; 255 again++;
253 } 256 }
254 } 257 }
258 spin_unlock_irqrestore(&opl3->voice_lock, flags);
259
260 spin_lock_irqsave(&opl3->sys_timer_lock, flags);
255 if (again) { 261 if (again) {
256 opl3->tlist.expires = jiffies + 1; /* invoke again */ 262 opl3->tlist.expires = jiffies + 1; /* invoke again */
257 add_timer(&opl3->tlist); 263 add_timer(&opl3->tlist);
@@ -658,15 +664,14 @@ static void snd_opl3_kill_voice(struct snd_opl3 *opl3, int voice)
658/* 664/*
659 * Release a note in response to a midi note off. 665 * Release a note in response to a midi note off.
660 */ 666 */
661void snd_opl3_note_off(void *p, int note, int vel, struct snd_midi_channel *chan) 667static void snd_opl3_note_off_unsafe(void *p, int note, int vel,
668 struct snd_midi_channel *chan)
662{ 669{
663 struct snd_opl3 *opl3; 670 struct snd_opl3 *opl3;
664 671
665 int voice; 672 int voice;
666 struct snd_opl3_voice *vp; 673 struct snd_opl3_voice *vp;
667 674
668 unsigned long flags;
669
670 opl3 = p; 675 opl3 = p;
671 676
672#ifdef DEBUG_MIDI 677#ifdef DEBUG_MIDI
@@ -674,12 +679,9 @@ void snd_opl3_note_off(void *p, int note, int vel, struct snd_midi_channel *chan
674 chan->number, chan->midi_program, note); 679 chan->number, chan->midi_program, note);
675#endif 680#endif
676 681
677 spin_lock_irqsave(&opl3->voice_lock, flags);
678
679 if (opl3->synth_mode == SNDRV_OPL3_MODE_SEQ) { 682 if (opl3->synth_mode == SNDRV_OPL3_MODE_SEQ) {
680 if (chan->drum_channel && use_internal_drums) { 683 if (chan->drum_channel && use_internal_drums) {
681 snd_opl3_drum_switch(opl3, note, vel, 0, chan); 684 snd_opl3_drum_switch(opl3, note, vel, 0, chan);
682 spin_unlock_irqrestore(&opl3->voice_lock, flags);
683 return; 685 return;
684 } 686 }
685 /* this loop will hopefully kill all extra voices, because 687 /* this loop will hopefully kill all extra voices, because
@@ -697,6 +699,16 @@ void snd_opl3_note_off(void *p, int note, int vel, struct snd_midi_channel *chan
697 snd_opl3_kill_voice(opl3, voice); 699 snd_opl3_kill_voice(opl3, voice);
698 } 700 }
699 } 701 }
702}
703
704void snd_opl3_note_off(void *p, int note, int vel,
705 struct snd_midi_channel *chan)
706{
707 struct snd_opl3 *opl3 = p;
708 unsigned long flags;
709
710 spin_lock_irqsave(&opl3->voice_lock, flags);
711 snd_opl3_note_off_unsafe(p, note, vel, chan);
700 spin_unlock_irqrestore(&opl3->voice_lock, flags); 712 spin_unlock_irqrestore(&opl3->voice_lock, flags);
701} 713}
702 714
diff --git a/sound/mips/hal2.c b/sound/mips/hal2.c
index c52691c2fc46..9a88cdfd952a 100644
--- a/sound/mips/hal2.c
+++ b/sound/mips/hal2.c
@@ -915,7 +915,7 @@ static int __devinit hal2_probe(struct platform_device *pdev)
915 return 0; 915 return 0;
916} 916}
917 917
918static int __exit hal2_remove(struct platform_device *pdev) 918static int __devexit hal2_remove(struct platform_device *pdev)
919{ 919{
920 struct snd_card *card = platform_get_drvdata(pdev); 920 struct snd_card *card = platform_get_drvdata(pdev);
921 921
diff --git a/sound/mips/sgio2audio.c b/sound/mips/sgio2audio.c
index e497525bc11b..8691f4cf6191 100644
--- a/sound/mips/sgio2audio.c
+++ b/sound/mips/sgio2audio.c
@@ -973,7 +973,7 @@ static int __devinit snd_sgio2audio_probe(struct platform_device *pdev)
973 return 0; 973 return 0;
974} 974}
975 975
976static int __exit snd_sgio2audio_remove(struct platform_device *pdev) 976static int __devexit snd_sgio2audio_remove(struct platform_device *pdev)
977{ 977{
978 struct snd_card *card = platform_get_drvdata(pdev); 978 struct snd_card *card = platform_get_drvdata(pdev);
979 979
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c
index 24585c6c6d01..4e2b925a94cc 100644
--- a/sound/pci/bt87x.c
+++ b/sound/pci/bt87x.c
@@ -808,6 +808,8 @@ static struct pci_device_id snd_bt87x_ids[] = {
808 BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1002, 0x0001, GENERIC), 808 BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1002, 0x0001, GENERIC),
809 /* Leadtek Winfast tv 2000xp delux */ 809 /* Leadtek Winfast tv 2000xp delux */
810 BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x107d, 0x6606, GENERIC), 810 BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x107d, 0x6606, GENERIC),
811 /* Pinnacle PCTV */
812 BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x11bd, 0x0012, GENERIC),
811 /* Voodoo TV 200 */ 813 /* Voodoo TV 200 */
812 BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x121a, 0x3000, GENERIC), 814 BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x121a, 0x3000, GENERIC),
813 /* Askey Computer Corp. MagicTView'99 */ 815 /* Askey Computer Corp. MagicTView'99 */
diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c
index b1b3a644f738..75454648d50c 100644
--- a/sound/pci/ctxfi/ctatc.c
+++ b/sound/pci/ctxfi/ctatc.c
@@ -1037,7 +1037,7 @@ static int atc_line_front_unmute(struct ct_atc *atc, unsigned char state)
1037 1037
1038static int atc_line_surround_unmute(struct ct_atc *atc, unsigned char state) 1038static int atc_line_surround_unmute(struct ct_atc *atc, unsigned char state)
1039{ 1039{
1040 return atc_daio_unmute(atc, state, LINEO4); 1040 return atc_daio_unmute(atc, state, LINEO2);
1041} 1041}
1042 1042
1043static int atc_line_clfe_unmute(struct ct_atc *atc, unsigned char state) 1043static int atc_line_clfe_unmute(struct ct_atc *atc, unsigned char state)
@@ -1047,7 +1047,7 @@ static int atc_line_clfe_unmute(struct ct_atc *atc, unsigned char state)
1047 1047
1048static int atc_line_rear_unmute(struct ct_atc *atc, unsigned char state) 1048static int atc_line_rear_unmute(struct ct_atc *atc, unsigned char state)
1049{ 1049{
1050 return atc_daio_unmute(atc, state, LINEO2); 1050 return atc_daio_unmute(atc, state, LINEO4);
1051} 1051}
1052 1052
1053static int atc_line_in_unmute(struct ct_atc *atc, unsigned char state) 1053static int atc_line_in_unmute(struct ct_atc *atc, unsigned char state)
diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c
index da2065cd2c0d..1305f7ca02c3 100644
--- a/sound/pci/echoaudio/echoaudio.c
+++ b/sound/pci/echoaudio/echoaudio.c
@@ -950,7 +950,7 @@ static int __devinit snd_echo_new_pcm(struct echoaudio *chip)
950 Control interface 950 Control interface
951******************************************************************************/ 951******************************************************************************/
952 952
953#ifndef ECHOCARD_HAS_VMIXER 953#if !defined(ECHOCARD_HAS_VMIXER) || defined(ECHOCARD_HAS_LINE_OUT_GAIN)
954 954
955/******************* PCM output volume *******************/ 955/******************* PCM output volume *******************/
956static int snd_echo_output_gain_info(struct snd_kcontrol *kcontrol, 956static int snd_echo_output_gain_info(struct snd_kcontrol *kcontrol,
@@ -1003,6 +1003,19 @@ static int snd_echo_output_gain_put(struct snd_kcontrol *kcontrol,
1003 return changed; 1003 return changed;
1004} 1004}
1005 1005
1006#ifdef ECHOCARD_HAS_LINE_OUT_GAIN
1007/* On the Mia this one controls the line-out volume */
1008static struct snd_kcontrol_new snd_echo_line_output_gain __devinitdata = {
1009 .name = "Line Playback Volume",
1010 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1011 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
1012 SNDRV_CTL_ELEM_ACCESS_TLV_READ,
1013 .info = snd_echo_output_gain_info,
1014 .get = snd_echo_output_gain_get,
1015 .put = snd_echo_output_gain_put,
1016 .tlv = {.p = db_scale_output_gain},
1017};
1018#else
1006static struct snd_kcontrol_new snd_echo_pcm_output_gain __devinitdata = { 1019static struct snd_kcontrol_new snd_echo_pcm_output_gain __devinitdata = {
1007 .name = "PCM Playback Volume", 1020 .name = "PCM Playback Volume",
1008 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1021 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -1012,9 +1025,10 @@ static struct snd_kcontrol_new snd_echo_pcm_output_gain __devinitdata = {
1012 .put = snd_echo_output_gain_put, 1025 .put = snd_echo_output_gain_put,
1013 .tlv = {.p = db_scale_output_gain}, 1026 .tlv = {.p = db_scale_output_gain},
1014}; 1027};
1015
1016#endif 1028#endif
1017 1029
1030#endif /* !ECHOCARD_HAS_VMIXER || ECHOCARD_HAS_LINE_OUT_GAIN */
1031
1018 1032
1019 1033
1020#ifdef ECHOCARD_HAS_INPUT_GAIN 1034#ifdef ECHOCARD_HAS_INPUT_GAIN
@@ -2030,10 +2044,18 @@ static int __devinit snd_echo_probe(struct pci_dev *pci,
2030 snd_echo_vmixer.count = num_pipes_out(chip) * num_busses_out(chip); 2044 snd_echo_vmixer.count = num_pipes_out(chip) * num_busses_out(chip);
2031 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_vmixer, chip))) < 0) 2045 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_vmixer, chip))) < 0)
2032 goto ctl_error; 2046 goto ctl_error;
2033#else 2047#ifdef ECHOCARD_HAS_LINE_OUT_GAIN
2034 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_pcm_output_gain, chip))) < 0) 2048 err = snd_ctl_add(chip->card,
2049 snd_ctl_new1(&snd_echo_line_output_gain, chip));
2050 if (err < 0)
2035 goto ctl_error; 2051 goto ctl_error;
2036#endif 2052#endif
2053#else /* ECHOCARD_HAS_VMIXER */
2054 err = snd_ctl_add(chip->card,
2055 snd_ctl_new1(&snd_echo_pcm_output_gain, chip));
2056 if (err < 0)
2057 goto ctl_error;
2058#endif /* ECHOCARD_HAS_VMIXER */
2037 2059
2038#ifdef ECHOCARD_HAS_INPUT_GAIN 2060#ifdef ECHOCARD_HAS_INPUT_GAIN
2039 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_line_input_gain, chip))) < 0) 2061 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_echo_line_input_gain, chip))) < 0)
diff --git a/sound/pci/echoaudio/mia.c b/sound/pci/echoaudio/mia.c
index f3b9b45c9c1b..f05c8c097aa8 100644
--- a/sound/pci/echoaudio/mia.c
+++ b/sound/pci/echoaudio/mia.c
@@ -29,6 +29,7 @@
29#define ECHOCARD_HAS_ADAT FALSE 29#define ECHOCARD_HAS_ADAT FALSE
30#define ECHOCARD_HAS_STEREO_BIG_ENDIAN32 30#define ECHOCARD_HAS_STEREO_BIG_ENDIAN32
31#define ECHOCARD_HAS_MIDI 31#define ECHOCARD_HAS_MIDI
32#define ECHOCARD_HAS_LINE_OUT_GAIN
32 33
33/* Pipe indexes */ 34/* Pipe indexes */
34#define PX_ANALOG_OUT 0 /* 8 */ 35#define PX_ANALOG_OUT 0 /* 8 */
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 20a66f85f0a4..c9ad182e1b4b 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -2303,6 +2303,7 @@ static void __devinit check_probe_mask(struct azx *chip, int dev)
2303 * white-list for enable_msi 2303 * white-list for enable_msi
2304 */ 2304 */
2305static struct snd_pci_quirk msi_white_list[] __devinitdata = { 2305static struct snd_pci_quirk msi_white_list[] __devinitdata = {
2306 SND_PCI_QUIRK(0x103c, 0x30f7, "HP Pavilion dv4t-1300", 1),
2306 SND_PCI_QUIRK(0x103c, 0x3607, "HP Compa CQ40", 1), 2307 SND_PCI_QUIRK(0x103c, 0x3607, "HP Compa CQ40", 1),
2307 {} 2308 {}
2308}; 2309};
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 215e72a87113..2d603f6aba63 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -4032,6 +4032,127 @@ static int ad1984a_thinkpad_init(struct hda_codec *codec)
4032} 4032}
4033 4033
4034/* 4034/*
4035 * HP Touchsmart
4036 * port-A (0x11) - front hp-out
4037 * port-B (0x14) - unused
4038 * port-C (0x15) - unused
4039 * port-D (0x12) - rear line out
4040 * port-E (0x1c) - front mic-in
4041 * port-F (0x16) - Internal speakers
4042 * digital-mic (0x17) - Internal mic
4043 */
4044
4045static struct hda_verb ad1984a_touchsmart_verbs[] = {
4046 /* DACs; unmute as default */
4047 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4048 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4049 /* Port-A (HP) mixer - route only from analog mixer */
4050 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4051 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4052 /* Port-A pin */
4053 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4054 /* Port-A (HP) pin - always unmuted */
4055 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4056 /* Port-E (int speaker) mixer - route only from analog mixer */
4057 {0x25, AC_VERB_SET_AMP_GAIN_MUTE, 0x03},
4058 /* Port-E pin */
4059 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4060 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4061 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4062 /* Port-F (int speaker) mixer - route only from analog mixer */
4063 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4064 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4065 /* Port-F pin */
4066 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4067 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4068 /* Analog mixer; mute as default */
4069 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4070 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4071 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4072 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4073 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4074 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
4075 /* Analog Mix output amp */
4076 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4077 /* capture sources */
4078 /* {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0}, */ /* set via unsol */
4079 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4080 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
4081 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4082 /* unsolicited event for pin-sense */
4083 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4084 {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
4085 /* allow to touch GPIO1 (for mute control) */
4086 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
4087 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
4088 {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, /* first muted */
4089 /* internal mic - dmic */
4090 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4091 /* set magic COEFs for dmic */
4092 {0x01, AC_VERB_SET_COEF_INDEX, 0x13f7},
4093 {0x01, AC_VERB_SET_PROC_COEF, 0x08},
4094 { } /* end */
4095};
4096
4097static struct snd_kcontrol_new ad1984a_touchsmart_mixers[] = {
4098 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
4099/* HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/
4100 {
4101 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4102 .name = "Master Playback Switch",
4103 .info = snd_hda_mixer_amp_switch_info,
4104 .get = snd_hda_mixer_amp_switch_get,
4105 .put = ad1884a_mobile_master_sw_put,
4106 .private_value = HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
4107 },
4108 HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
4109 HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
4110 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4111 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4112 HDA_CODEC_VOLUME("Mic Boost", 0x25, 0x0, HDA_OUTPUT),
4113 HDA_CODEC_VOLUME("Internal Mic Boost", 0x17, 0x0, HDA_INPUT),
4114 { } /* end */
4115};
4116
4117/* switch to external mic if plugged */
4118static void ad1984a_touchsmart_automic(struct hda_codec *codec)
4119{
4120 if (snd_hda_codec_read(codec, 0x1c, 0,
4121 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000) {
4122 snd_hda_codec_write(codec, 0x0c, 0,
4123 AC_VERB_SET_CONNECT_SEL, 0x4);
4124 } else {
4125 snd_hda_codec_write(codec, 0x0c, 0,
4126 AC_VERB_SET_CONNECT_SEL, 0x5);
4127 }
4128}
4129
4130
4131/* unsolicited event for HP jack sensing */
4132static void ad1984a_touchsmart_unsol_event(struct hda_codec *codec,
4133 unsigned int res)
4134{
4135 switch (res >> 26) {
4136 case AD1884A_HP_EVENT:
4137 ad1884a_hp_automute(codec);
4138 break;
4139 case AD1884A_MIC_EVENT:
4140 ad1984a_touchsmart_automic(codec);
4141 break;
4142 }
4143}
4144
4145/* initialize jack-sensing, too */
4146static int ad1984a_touchsmart_init(struct hda_codec *codec)
4147{
4148 ad198x_init(codec);
4149 ad1884a_hp_automute(codec);
4150 ad1984a_touchsmart_automic(codec);
4151 return 0;
4152}
4153
4154
4155/*
4035 */ 4156 */
4036 4157
4037enum { 4158enum {
@@ -4039,6 +4160,7 @@ enum {
4039 AD1884A_LAPTOP, 4160 AD1884A_LAPTOP,
4040 AD1884A_MOBILE, 4161 AD1884A_MOBILE,
4041 AD1884A_THINKPAD, 4162 AD1884A_THINKPAD,
4163 AD1984A_TOUCHSMART,
4042 AD1884A_MODELS 4164 AD1884A_MODELS
4043}; 4165};
4044 4166
@@ -4047,6 +4169,7 @@ static const char *ad1884a_models[AD1884A_MODELS] = {
4047 [AD1884A_LAPTOP] = "laptop", 4169 [AD1884A_LAPTOP] = "laptop",
4048 [AD1884A_MOBILE] = "mobile", 4170 [AD1884A_MOBILE] = "mobile",
4049 [AD1884A_THINKPAD] = "thinkpad", 4171 [AD1884A_THINKPAD] = "thinkpad",
4172 [AD1984A_TOUCHSMART] = "touchsmart",
4050}; 4173};
4051 4174
4052static struct snd_pci_quirk ad1884a_cfg_tbl[] = { 4175static struct snd_pci_quirk ad1884a_cfg_tbl[] = {
@@ -4059,6 +4182,7 @@ static struct snd_pci_quirk ad1884a_cfg_tbl[] = {
4059 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3600, "HP laptop", AD1884A_LAPTOP), 4182 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3600, "HP laptop", AD1884A_LAPTOP),
4060 SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x7010, "HP laptop", AD1884A_MOBILE), 4183 SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x7010, "HP laptop", AD1884A_MOBILE),
4061 SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X300", AD1884A_THINKPAD), 4184 SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X300", AD1884A_THINKPAD),
4185 SND_PCI_QUIRK(0x103c, 0x2a82, "Touchsmart", AD1984A_TOUCHSMART),
4062 {} 4186 {}
4063}; 4187};
4064 4188
@@ -4142,6 +4266,21 @@ static int patch_ad1884a(struct hda_codec *codec)
4142 codec->patch_ops.unsol_event = ad1984a_thinkpad_unsol_event; 4266 codec->patch_ops.unsol_event = ad1984a_thinkpad_unsol_event;
4143 codec->patch_ops.init = ad1984a_thinkpad_init; 4267 codec->patch_ops.init = ad1984a_thinkpad_init;
4144 break; 4268 break;
4269 case AD1984A_TOUCHSMART:
4270 spec->mixers[0] = ad1984a_touchsmart_mixers;
4271 spec->init_verbs[0] = ad1984a_touchsmart_verbs;
4272 spec->multiout.dig_out_nid = 0;
4273 codec->patch_ops.unsol_event = ad1984a_touchsmart_unsol_event;
4274 codec->patch_ops.init = ad1984a_touchsmart_init;
4275 /* set the upper-limit for mixer amp to 0dB for avoiding the
4276 * possible damage by overloading
4277 */
4278 snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT,
4279 (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
4280 (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
4281 (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
4282 (1 << AC_AMPCAP_MUTE_SHIFT));
4283 break;
4145 } 4284 }
4146 4285
4147 return 0; 4286 return 0;
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 9d899eda44d7..3fbbc8c01e70 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -682,11 +682,13 @@ static struct hda_input_mux cxt5045_capture_source = {
682}; 682};
683 683
684static struct hda_input_mux cxt5045_capture_source_benq = { 684static struct hda_input_mux cxt5045_capture_source_benq = {
685 .num_items = 3, 685 .num_items = 5,
686 .items = { 686 .items = {
687 { "IntMic", 0x1 }, 687 { "IntMic", 0x1 },
688 { "ExtMic", 0x2 }, 688 { "ExtMic", 0x2 },
689 { "LineIn", 0x3 }, 689 { "LineIn", 0x3 },
690 { "CD", 0x4 },
691 { "Mixer", 0x0 },
690 } 692 }
691}; 693};
692 694
@@ -811,11 +813,19 @@ static struct snd_kcontrol_new cxt5045_mixers[] = {
811}; 813};
812 814
813static struct snd_kcontrol_new cxt5045_benq_mixers[] = { 815static struct snd_kcontrol_new cxt5045_benq_mixers[] = {
816 HDA_CODEC_VOLUME("CD Capture Volume", 0x1a, 0x04, HDA_INPUT),
817 HDA_CODEC_MUTE("CD Capture Switch", 0x1a, 0x04, HDA_INPUT),
818 HDA_CODEC_VOLUME("CD Playback Volume", 0x17, 0x4, HDA_INPUT),
819 HDA_CODEC_MUTE("CD Playback Switch", 0x17, 0x4, HDA_INPUT),
820
814 HDA_CODEC_VOLUME("Line In Capture Volume", 0x1a, 0x03, HDA_INPUT), 821 HDA_CODEC_VOLUME("Line In Capture Volume", 0x1a, 0x03, HDA_INPUT),
815 HDA_CODEC_MUTE("Line In Capture Switch", 0x1a, 0x03, HDA_INPUT), 822 HDA_CODEC_MUTE("Line In Capture Switch", 0x1a, 0x03, HDA_INPUT),
816 HDA_CODEC_VOLUME("Line In Playback Volume", 0x17, 0x3, HDA_INPUT), 823 HDA_CODEC_VOLUME("Line In Playback Volume", 0x17, 0x3, HDA_INPUT),
817 HDA_CODEC_MUTE("Line In Playback Switch", 0x17, 0x3, HDA_INPUT), 824 HDA_CODEC_MUTE("Line In Playback Switch", 0x17, 0x3, HDA_INPUT),
818 825
826 HDA_CODEC_VOLUME("Mixer Capture Volume", 0x1a, 0x0, HDA_INPUT),
827 HDA_CODEC_MUTE("Mixer Capture Switch", 0x1a, 0x0, HDA_INPUT),
828
819 {} 829 {}
820}; 830};
821 831
diff --git a/sound/pci/hda/patch_nvhdmi.c b/sound/pci/hda/patch_nvhdmi.c
index c8435c9a97f9..9fb60276f5c9 100644
--- a/sound/pci/hda/patch_nvhdmi.c
+++ b/sound/pci/hda/patch_nvhdmi.c
@@ -29,6 +29,9 @@
29#include "hda_codec.h" 29#include "hda_codec.h"
30#include "hda_local.h" 30#include "hda_local.h"
31 31
32/* define below to restrict the supported rates and formats */
33/* #define LIMITED_RATE_FMT_SUPPORT */
34
32struct nvhdmi_spec { 35struct nvhdmi_spec {
33 struct hda_multi_out multiout; 36 struct hda_multi_out multiout;
34 37
@@ -60,6 +63,22 @@ static struct hda_verb nvhdmi_basic_init[] = {
60 {} /* terminator */ 63 {} /* terminator */
61}; 64};
62 65
66#ifdef LIMITED_RATE_FMT_SUPPORT
67/* support only the safe format and rate */
68#define SUPPORTED_RATES SNDRV_PCM_RATE_48000
69#define SUPPORTED_MAXBPS 16
70#define SUPPORTED_FORMATS SNDRV_PCM_FMTBIT_S16_LE
71#else
72/* support all rates and formats */
73#define SUPPORTED_RATES \
74 (SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\
75 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |\
76 SNDRV_PCM_RATE_192000)
77#define SUPPORTED_MAXBPS 24
78#define SUPPORTED_FORMATS \
79 (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE)
80#endif
81
63/* 82/*
64 * Controls 83 * Controls
65 */ 84 */
@@ -258,9 +277,9 @@ static struct hda_pcm_stream nvhdmi_pcm_digital_playback_8ch = {
258 .channels_min = 2, 277 .channels_min = 2,
259 .channels_max = 8, 278 .channels_max = 8,
260 .nid = Nv_Master_Convert_nid, 279 .nid = Nv_Master_Convert_nid,
261 .rates = SNDRV_PCM_RATE_48000, 280 .rates = SUPPORTED_RATES,
262 .maxbps = 16, 281 .maxbps = SUPPORTED_MAXBPS,
263 .formats = SNDRV_PCM_FMTBIT_S16_LE, 282 .formats = SUPPORTED_FORMATS,
264 .ops = { 283 .ops = {
265 .open = nvhdmi_dig_playback_pcm_open, 284 .open = nvhdmi_dig_playback_pcm_open,
266 .close = nvhdmi_dig_playback_pcm_close_8ch, 285 .close = nvhdmi_dig_playback_pcm_close_8ch,
@@ -273,9 +292,9 @@ static struct hda_pcm_stream nvhdmi_pcm_digital_playback_2ch = {
273 .channels_min = 2, 292 .channels_min = 2,
274 .channels_max = 2, 293 .channels_max = 2,
275 .nid = Nv_Master_Convert_nid, 294 .nid = Nv_Master_Convert_nid,
276 .rates = SNDRV_PCM_RATE_48000, 295 .rates = SUPPORTED_RATES,
277 .maxbps = 16, 296 .maxbps = SUPPORTED_MAXBPS,
278 .formats = SNDRV_PCM_FMTBIT_S16_LE, 297 .formats = SUPPORTED_FORMATS,
279 .ops = { 298 .ops = {
280 .open = nvhdmi_dig_playback_pcm_open, 299 .open = nvhdmi_dig_playback_pcm_open,
281 .close = nvhdmi_dig_playback_pcm_close_2ch, 300 .close = nvhdmi_dig_playback_pcm_close_2ch,
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 129605819560..c08ca660daba 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -275,7 +275,7 @@ struct alc_spec {
275 struct snd_kcontrol_new *cap_mixer; /* capture mixer */ 275 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
276 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */ 276 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
277 277
278 const struct hda_verb *init_verbs[5]; /* initialization verbs 278 const struct hda_verb *init_verbs[10]; /* initialization verbs
279 * don't forget NULL 279 * don't forget NULL
280 * termination! 280 * termination!
281 */ 281 */
@@ -1332,15 +1332,20 @@ do_sku:
1332 * when the external headphone out jack is plugged" 1332 * when the external headphone out jack is plugged"
1333 */ 1333 */
1334 if (!spec->autocfg.hp_pins[0]) { 1334 if (!spec->autocfg.hp_pins[0]) {
1335 hda_nid_t nid;
1335 tmp = (ass >> 11) & 0x3; /* HP to chassis */ 1336 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1336 if (tmp == 0) 1337 if (tmp == 0)
1337 spec->autocfg.hp_pins[0] = porta; 1338 nid = porta;
1338 else if (tmp == 1) 1339 else if (tmp == 1)
1339 spec->autocfg.hp_pins[0] = porte; 1340 nid = porte;
1340 else if (tmp == 2) 1341 else if (tmp == 2)
1341 spec->autocfg.hp_pins[0] = portd; 1342 nid = portd;
1342 else 1343 else
1343 return 1; 1344 return 1;
1345 for (i = 0; i < spec->autocfg.line_outs; i++)
1346 if (spec->autocfg.line_out_pins[i] == nid)
1347 return 1;
1348 spec->autocfg.hp_pins[0] = nid;
1344 } 1349 }
1345 1350
1346 alc_init_auto_hp(codec); 1351 alc_init_auto_hp(codec);
@@ -1362,7 +1367,7 @@ static void alc_ssid_check(struct hda_codec *codec,
1362} 1367}
1363 1368
1364/* 1369/*
1365 * Fix-up pin default configurations 1370 * Fix-up pin default configurations and add default verbs
1366 */ 1371 */
1367 1372
1368struct alc_pincfg { 1373struct alc_pincfg {
@@ -1370,9 +1375,14 @@ struct alc_pincfg {
1370 u32 val; 1375 u32 val;
1371}; 1376};
1372 1377
1373static void alc_fix_pincfg(struct hda_codec *codec, 1378struct alc_fixup {
1379 const struct alc_pincfg *pins;
1380 const struct hda_verb *verbs;
1381};
1382
1383static void alc_pick_fixup(struct hda_codec *codec,
1374 const struct snd_pci_quirk *quirk, 1384 const struct snd_pci_quirk *quirk,
1375 const struct alc_pincfg **pinfix) 1385 const struct alc_fixup *fix)
1376{ 1386{
1377 const struct alc_pincfg *cfg; 1387 const struct alc_pincfg *cfg;
1378 1388
@@ -1380,9 +1390,14 @@ static void alc_fix_pincfg(struct hda_codec *codec,
1380 if (!quirk) 1390 if (!quirk)
1381 return; 1391 return;
1382 1392
1383 cfg = pinfix[quirk->value]; 1393 fix += quirk->value;
1384 for (; cfg->nid; cfg++) 1394 cfg = fix->pins;
1385 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val); 1395 if (cfg) {
1396 for (; cfg->nid; cfg++)
1397 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
1398 }
1399 if (fix->verbs)
1400 add_verb(codec->spec, fix->verbs);
1386} 1401}
1387 1402
1388/* 1403/*
@@ -9593,11 +9608,13 @@ static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
9593 { } 9608 { }
9594}; 9609};
9595 9610
9596static const struct alc_pincfg *alc882_pin_fixes[] = { 9611static const struct alc_fixup alc882_fixups[] = {
9597 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix, 9612 [PINFIX_ABIT_AW9D_MAX] = {
9613 .pins = alc882_abit_aw9d_pinfix
9614 },
9598}; 9615};
9599 9616
9600static struct snd_pci_quirk alc882_pinfix_tbl[] = { 9617static struct snd_pci_quirk alc882_fixup_tbl[] = {
9601 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX), 9618 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
9602 {} 9619 {}
9603}; 9620};
@@ -9869,7 +9886,7 @@ static int patch_alc882(struct hda_codec *codec)
9869 board_config = ALC882_AUTO; 9886 board_config = ALC882_AUTO;
9870 } 9887 }
9871 9888
9872 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes); 9889 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups);
9873 9890
9874 if (board_config == ALC882_AUTO) { 9891 if (board_config == ALC882_AUTO) {
9875 /* automatic parse from the BIOS config */ 9892 /* automatic parse from the BIOS config */
@@ -12660,7 +12677,7 @@ static struct alc_config_preset alc268_presets[] = {
12660 .init_hook = alc268_toshiba_automute, 12677 .init_hook = alc268_toshiba_automute,
12661 }, 12678 },
12662 [ALC268_ACER] = { 12679 [ALC268_ACER] = {
12663 .mixers = { alc268_acer_mixer, alc268_capture_nosrc_mixer, 12680 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
12664 alc268_beep_mixer }, 12681 alc268_beep_mixer },
12665 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 12682 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12666 alc268_acer_verbs }, 12683 alc268_acer_verbs },
@@ -12842,12 +12859,15 @@ static int patch_alc268(struct hda_codec *codec)
12842 unsigned int wcap = get_wcaps(codec, 0x07); 12859 unsigned int wcap = get_wcaps(codec, 0x07);
12843 int i; 12860 int i;
12844 12861
12862 spec->capsrc_nids = alc268_capsrc_nids;
12845 /* get type */ 12863 /* get type */
12846 wcap = get_wcaps_type(wcap); 12864 wcap = get_wcaps_type(wcap);
12847 if (spec->auto_mic || 12865 if (spec->auto_mic ||
12848 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) { 12866 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
12849 spec->adc_nids = alc268_adc_nids_alt; 12867 spec->adc_nids = alc268_adc_nids_alt;
12850 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt); 12868 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
12869 if (spec->auto_mic)
12870 fixup_automic_adc(codec);
12851 if (spec->auto_mic || spec->input_mux->num_items == 1) 12871 if (spec->auto_mic || spec->input_mux->num_items == 1)
12852 add_mixer(spec, alc268_capture_nosrc_mixer); 12872 add_mixer(spec, alc268_capture_nosrc_mixer);
12853 else 12873 else
@@ -12857,7 +12877,6 @@ static int patch_alc268(struct hda_codec *codec)
12857 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids); 12877 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
12858 add_mixer(spec, alc268_capture_mixer); 12878 add_mixer(spec, alc268_capture_mixer);
12859 } 12879 }
12860 spec->capsrc_nids = alc268_capsrc_nids;
12861 /* set default input source */ 12880 /* set default input source */
12862 for (i = 0; i < spec->num_adc_nids; i++) 12881 for (i = 0; i < spec->num_adc_nids; i++)
12863 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i], 12882 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
@@ -14357,15 +14376,16 @@ static void alc861_auto_init_multi_out(struct hda_codec *codec)
14357static void alc861_auto_init_hp_out(struct hda_codec *codec) 14376static void alc861_auto_init_hp_out(struct hda_codec *codec)
14358{ 14377{
14359 struct alc_spec *spec = codec->spec; 14378 struct alc_spec *spec = codec->spec;
14360 hda_nid_t pin;
14361 14379
14362 pin = spec->autocfg.hp_pins[0]; 14380 if (spec->autocfg.hp_outs)
14363 if (pin) 14381 alc861_auto_set_output_and_unmute(codec,
14364 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP, 14382 spec->autocfg.hp_pins[0],
14383 PIN_HP,
14365 spec->multiout.hp_nid); 14384 spec->multiout.hp_nid);
14366 pin = spec->autocfg.speaker_pins[0]; 14385 if (spec->autocfg.speaker_outs)
14367 if (pin) 14386 alc861_auto_set_output_and_unmute(codec,
14368 alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 14387 spec->autocfg.speaker_pins[0],
14388 PIN_OUT,
14369 spec->multiout.dac_nids[0]); 14389 spec->multiout.dac_nids[0]);
14370} 14390}
14371 14391
@@ -15158,7 +15178,7 @@ static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
15158 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST), 15178 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
15159 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP), 15179 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
15160 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST), 15180 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
15161 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST), 15181 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
15162 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S), 15182 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
15163 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG), 15183 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
15164 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST), 15184 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
@@ -15551,6 +15571,29 @@ static void alc861vd_auto_init(struct hda_codec *codec)
15551 alc_inithook(codec); 15571 alc_inithook(codec);
15552} 15572}
15553 15573
15574enum {
15575 ALC660VD_FIX_ASUS_GPIO1
15576};
15577
15578/* reset GPIO1 */
15579static const struct hda_verb alc660vd_fix_asus_gpio1_verbs[] = {
15580 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
15581 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
15582 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
15583 { }
15584};
15585
15586static const struct alc_fixup alc861vd_fixups[] = {
15587 [ALC660VD_FIX_ASUS_GPIO1] = {
15588 .verbs = alc660vd_fix_asus_gpio1_verbs,
15589 },
15590};
15591
15592static struct snd_pci_quirk alc861vd_fixup_tbl[] = {
15593 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
15594 {}
15595};
15596
15554static int patch_alc861vd(struct hda_codec *codec) 15597static int patch_alc861vd(struct hda_codec *codec)
15555{ 15598{
15556 struct alc_spec *spec; 15599 struct alc_spec *spec;
@@ -15572,6 +15615,8 @@ static int patch_alc861vd(struct hda_codec *codec)
15572 board_config = ALC861VD_AUTO; 15615 board_config = ALC861VD_AUTO;
15573 } 15616 }
15574 15617
15618 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups);
15619
15575 if (board_config == ALC861VD_AUTO) { 15620 if (board_config == ALC861VD_AUTO) {
15576 /* automatic parse from the BIOS config */ 15621 /* automatic parse from the BIOS config */
15577 err = alc861vd_parse_auto_config(codec); 15622 err = alc861vd_parse_auto_config(codec);
@@ -16852,6 +16897,7 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = {
16852 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS), 16897 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
16853 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K", 16898 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
16854 ALC662_3ST_6ch_DIG), 16899 ALC662_3ST_6ch_DIG),
16900 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB200", ALC663_ASUS_MODE4),
16855 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10), 16901 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
16856 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L", 16902 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
16857 ALC662_3ST_6ch_DIG), 16903 ALC662_3ST_6ch_DIG),
@@ -17145,70 +17191,145 @@ static struct alc_config_preset alc662_presets[] = {
17145 * BIOS auto configuration 17191 * BIOS auto configuration
17146 */ 17192 */
17147 17193
17194/* convert from MIX nid to DAC */
17195static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid)
17196{
17197 if (nid == 0x0f)
17198 return 0x02;
17199 else if (nid >= 0x0c && nid <= 0x0e)
17200 return nid - 0x0c + 0x02;
17201 else
17202 return 0;
17203}
17204
17205/* get MIX nid connected to the given pin targeted to DAC */
17206static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
17207 hda_nid_t dac)
17208{
17209 hda_nid_t mix[4];
17210 int i, num;
17211
17212 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
17213 for (i = 0; i < num; i++) {
17214 if (alc662_mix_to_dac(mix[i]) == dac)
17215 return mix[i];
17216 }
17217 return 0;
17218}
17219
17220/* look for an empty DAC slot */
17221static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
17222{
17223 struct alc_spec *spec = codec->spec;
17224 hda_nid_t srcs[5];
17225 int i, j, num;
17226
17227 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
17228 if (num < 0)
17229 return 0;
17230 for (i = 0; i < num; i++) {
17231 hda_nid_t nid = alc662_mix_to_dac(srcs[i]);
17232 if (!nid)
17233 continue;
17234 for (j = 0; j < spec->multiout.num_dacs; j++)
17235 if (spec->multiout.dac_nids[j] == nid)
17236 break;
17237 if (j >= spec->multiout.num_dacs)
17238 return nid;
17239 }
17240 return 0;
17241}
17242
17243/* fill in the dac_nids table from the parsed pin configuration */
17244static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
17245 const struct auto_pin_cfg *cfg)
17246{
17247 struct alc_spec *spec = codec->spec;
17248 int i;
17249 hda_nid_t dac;
17250
17251 spec->multiout.dac_nids = spec->private_dac_nids;
17252 for (i = 0; i < cfg->line_outs; i++) {
17253 dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]);
17254 if (!dac)
17255 continue;
17256 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
17257 }
17258 return 0;
17259}
17260
17261static int alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
17262 hda_nid_t nid, unsigned int chs)
17263{
17264 char name[32];
17265 sprintf(name, "%s Playback Volume", pfx);
17266 return add_control(spec, ALC_CTL_WIDGET_VOL, name,
17267 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
17268}
17269
17270static int alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
17271 hda_nid_t nid, unsigned int chs)
17272{
17273 char name[32];
17274 sprintf(name, "%s Playback Switch", pfx);
17275 return add_control(spec, ALC_CTL_WIDGET_MUTE, name,
17276 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
17277}
17278
17279#define alc662_add_stereo_vol(spec, pfx, nid) \
17280 alc662_add_vol_ctl(spec, pfx, nid, 3)
17281#define alc662_add_stereo_sw(spec, pfx, nid) \
17282 alc662_add_sw_ctl(spec, pfx, nid, 3)
17283
17148/* add playback controls from the parsed DAC table */ 17284/* add playback controls from the parsed DAC table */
17149static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec, 17285static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
17150 const struct auto_pin_cfg *cfg) 17286 const struct auto_pin_cfg *cfg)
17151{ 17287{
17152 char name[32]; 17288 struct alc_spec *spec = codec->spec;
17153 static const char *chname[4] = { 17289 static const char *chname[4] = {
17154 "Front", "Surround", NULL /*CLFE*/, "Side" 17290 "Front", "Surround", NULL /*CLFE*/, "Side"
17155 }; 17291 };
17156 hda_nid_t nid; 17292 hda_nid_t nid, mix;
17157 int i, err; 17293 int i, err;
17158 17294
17159 for (i = 0; i < cfg->line_outs; i++) { 17295 for (i = 0; i < cfg->line_outs; i++) {
17160 if (!spec->multiout.dac_nids[i]) 17296 nid = spec->multiout.dac_nids[i];
17297 if (!nid)
17298 continue;
17299 mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid);
17300 if (!mix)
17161 continue; 17301 continue;
17162 nid = alc880_idx_to_dac(i);
17163 if (i == 2) { 17302 if (i == 2) {
17164 /* Center/LFE */ 17303 /* Center/LFE */
17165 err = add_control(spec, ALC_CTL_WIDGET_VOL, 17304 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
17166 "Center Playback Volume",
17167 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
17168 HDA_OUTPUT));
17169 if (err < 0) 17305 if (err < 0)
17170 return err; 17306 return err;
17171 err = add_control(spec, ALC_CTL_WIDGET_VOL, 17307 err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
17172 "LFE Playback Volume",
17173 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
17174 HDA_OUTPUT));
17175 if (err < 0) 17308 if (err < 0)
17176 return err; 17309 return err;
17177 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 17310 err = alc662_add_sw_ctl(spec, "Center", mix, 1);
17178 "Center Playback Switch",
17179 HDA_COMPOSE_AMP_VAL(0x0e, 1, 0,
17180 HDA_INPUT));
17181 if (err < 0) 17311 if (err < 0)
17182 return err; 17312 return err;
17183 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 17313 err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
17184 "LFE Playback Switch",
17185 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
17186 HDA_INPUT));
17187 if (err < 0) 17314 if (err < 0)
17188 return err; 17315 return err;
17189 } else { 17316 } else {
17190 const char *pfx; 17317 const char *pfx;
17191 if (cfg->line_outs == 1 && 17318 if (cfg->line_outs == 1 &&
17192 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) { 17319 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
17193 if (!cfg->hp_pins) 17320 if (cfg->hp_outs)
17194 pfx = "Speaker"; 17321 pfx = "Speaker";
17195 else 17322 else
17196 pfx = "PCM"; 17323 pfx = "PCM";
17197 } else 17324 } else
17198 pfx = chname[i]; 17325 pfx = chname[i];
17199 sprintf(name, "%s Playback Volume", pfx); 17326 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
17200 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
17201 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
17202 HDA_OUTPUT));
17203 if (err < 0) 17327 if (err < 0)
17204 return err; 17328 return err;
17205 if (cfg->line_outs == 1 && 17329 if (cfg->line_outs == 1 &&
17206 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 17330 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
17207 pfx = "Speaker"; 17331 pfx = "Speaker";
17208 sprintf(name, "%s Playback Switch", pfx); 17332 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
17209 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
17210 HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i),
17211 3, 0, HDA_INPUT));
17212 if (err < 0) 17333 if (err < 0)
17213 return err; 17334 return err;
17214 } 17335 }
@@ -17217,54 +17338,38 @@ static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
17217} 17338}
17218 17339
17219/* add playback controls for speaker and HP outputs */ 17340/* add playback controls for speaker and HP outputs */
17220static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, 17341/* return DAC nid if any new DAC is assigned */
17342static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
17221 const char *pfx) 17343 const char *pfx)
17222{ 17344{
17223 hda_nid_t nid; 17345 struct alc_spec *spec = codec->spec;
17346 hda_nid_t nid, mix;
17224 int err; 17347 int err;
17225 char name[32];
17226 17348
17227 if (!pin) 17349 if (!pin)
17228 return 0; 17350 return 0;
17229 17351 nid = alc662_look_for_dac(codec, pin);
17230 if (pin == 0x17) { 17352 if (!nid) {
17231 /* ALC663 has a mono output pin on 0x17 */ 17353 char name[32];
17354 /* the corresponding DAC is already occupied */
17355 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
17356 return 0; /* no way */
17357 /* create a switch only */
17232 sprintf(name, "%s Playback Switch", pfx); 17358 sprintf(name, "%s Playback Switch", pfx);
17233 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, 17359 return add_control(spec, ALC_CTL_WIDGET_MUTE, name,
17234 HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT)); 17360 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
17235 return err;
17236 } 17361 }
17237 17362
17238 if (alc880_is_fixed_pin(pin)) { 17363 mix = alc662_dac_to_mix(codec, pin, nid);
17239 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); 17364 if (!mix)
17240 /* printk(KERN_DEBUG "DAC nid=%x\n",nid); */ 17365 return 0;
17241 /* specify the DAC as the extra output */ 17366 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
17242 if (!spec->multiout.hp_nid) 17367 if (err < 0)
17243 spec->multiout.hp_nid = nid; 17368 return err;
17244 else 17369 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
17245 spec->multiout.extra_out_nid[0] = nid; 17370 if (err < 0)
17246 /* control HP volume/switch on the output mixer amp */ 17371 return err;
17247 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); 17372 return nid;
17248 sprintf(name, "%s Playback Volume", pfx);
17249 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
17250 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
17251 if (err < 0)
17252 return err;
17253 sprintf(name, "%s Playback Switch", pfx);
17254 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
17255 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
17256 if (err < 0)
17257 return err;
17258 } else if (alc880_is_multi_pin(pin)) {
17259 /* set manual connection */
17260 /* we have only a switch on HP-out PIN */
17261 sprintf(name, "%s Playback Switch", pfx);
17262 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
17263 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
17264 if (err < 0)
17265 return err;
17266 }
17267 return 0;
17268} 17373}
17269 17374
17270/* create playback/capture controls for input pins */ 17375/* create playback/capture controls for input pins */
@@ -17273,30 +17378,35 @@ static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
17273 17378
17274static void alc662_auto_set_output_and_unmute(struct hda_codec *codec, 17379static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
17275 hda_nid_t nid, int pin_type, 17380 hda_nid_t nid, int pin_type,
17276 int dac_idx) 17381 hda_nid_t dac)
17277{ 17382{
17383 int i, num;
17384 hda_nid_t srcs[4];
17385
17278 alc_set_pin_output(codec, nid, pin_type); 17386 alc_set_pin_output(codec, nid, pin_type);
17279 /* need the manual connection? */ 17387 /* need the manual connection? */
17280 if (alc880_is_multi_pin(nid)) { 17388 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
17281 struct alc_spec *spec = codec->spec; 17389 if (num <= 1)
17282 int idx = alc880_multi_pin_idx(nid); 17390 return;
17283 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0, 17391 for (i = 0; i < num; i++) {
17284 AC_VERB_SET_CONNECT_SEL, 17392 if (alc662_mix_to_dac(srcs[i]) != dac)
17285 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx])); 17393 continue;
17394 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
17395 return;
17286 } 17396 }
17287} 17397}
17288 17398
17289static void alc662_auto_init_multi_out(struct hda_codec *codec) 17399static void alc662_auto_init_multi_out(struct hda_codec *codec)
17290{ 17400{
17291 struct alc_spec *spec = codec->spec; 17401 struct alc_spec *spec = codec->spec;
17402 int pin_type = get_pin_type(spec->autocfg.line_out_type);
17292 int i; 17403 int i;
17293 17404
17294 for (i = 0; i <= HDA_SIDE; i++) { 17405 for (i = 0; i <= HDA_SIDE; i++) {
17295 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 17406 hda_nid_t nid = spec->autocfg.line_out_pins[i];
17296 int pin_type = get_pin_type(spec->autocfg.line_out_type);
17297 if (nid) 17407 if (nid)
17298 alc662_auto_set_output_and_unmute(codec, nid, pin_type, 17408 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
17299 i); 17409 spec->multiout.dac_nids[i]);
17300 } 17410 }
17301} 17411}
17302 17412
@@ -17306,12 +17416,13 @@ static void alc662_auto_init_hp_out(struct hda_codec *codec)
17306 hda_nid_t pin; 17416 hda_nid_t pin;
17307 17417
17308 pin = spec->autocfg.hp_pins[0]; 17418 pin = spec->autocfg.hp_pins[0];
17309 if (pin) /* connect to front */ 17419 if (pin)
17310 /* use dac 0 */ 17420 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
17311 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 17421 spec->multiout.hp_nid);
17312 pin = spec->autocfg.speaker_pins[0]; 17422 pin = spec->autocfg.speaker_pins[0];
17313 if (pin) 17423 if (pin)
17314 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); 17424 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
17425 spec->multiout.extra_out_nid[0]);
17315} 17426}
17316 17427
17317#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID 17428#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
@@ -17349,21 +17460,25 @@ static int alc662_parse_auto_config(struct hda_codec *codec)
17349 if (!spec->autocfg.line_outs) 17460 if (!spec->autocfg.line_outs)
17350 return 0; /* can't find valid BIOS pin config */ 17461 return 0; /* can't find valid BIOS pin config */
17351 17462
17352 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 17463 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
17353 if (err < 0) 17464 if (err < 0)
17354 return err; 17465 return err;
17355 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg); 17466 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
17356 if (err < 0) 17467 if (err < 0)
17357 return err; 17468 return err;
17358 err = alc662_auto_create_extra_out(spec, 17469 err = alc662_auto_create_extra_out(codec,
17359 spec->autocfg.speaker_pins[0], 17470 spec->autocfg.speaker_pins[0],
17360 "Speaker"); 17471 "Speaker");
17361 if (err < 0) 17472 if (err < 0)
17362 return err; 17473 return err;
17363 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], 17474 if (err)
17475 spec->multiout.extra_out_nid[0] = err;
17476 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
17364 "Headphone"); 17477 "Headphone");
17365 if (err < 0) 17478 if (err < 0)
17366 return err; 17479 return err;
17480 if (err)
17481 spec->multiout.hp_nid = err;
17367 err = alc662_auto_create_input_ctls(codec, &spec->autocfg); 17482 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
17368 if (err < 0) 17483 if (err < 0)
17369 return err; 17484 return err;
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 826137ec3002..66c0876bf734 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -158,6 +158,7 @@ enum {
158 STAC_D965_5ST_NO_FP, 158 STAC_D965_5ST_NO_FP,
159 STAC_DELL_3ST, 159 STAC_DELL_3ST,
160 STAC_DELL_BIOS, 160 STAC_DELL_BIOS,
161 STAC_927X_VOLKNOB,
161 STAC_927X_MODELS 162 STAC_927X_MODELS
162}; 163};
163 164
@@ -182,8 +183,8 @@ struct sigmatel_jack {
182 183
183struct sigmatel_mic_route { 184struct sigmatel_mic_route {
184 hda_nid_t pin; 185 hda_nid_t pin;
185 unsigned char mux_idx; 186 signed char mux_idx;
186 unsigned char dmux_idx; 187 signed char dmux_idx;
187}; 188};
188 189
189struct sigmatel_spec { 190struct sigmatel_spec {
@@ -907,6 +908,16 @@ static struct hda_verb d965_core_init[] = {
907 {} 908 {}
908}; 909};
909 910
911static struct hda_verb dell_3st_core_init[] = {
912 /* don't set delta bit */
913 {0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0x7f},
914 /* unmute node 0x1b */
915 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
916 /* select node 0x03 as DAC */
917 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x01},
918 {}
919};
920
910static struct hda_verb stac927x_core_init[] = { 921static struct hda_verb stac927x_core_init[] = {
911 /* set master volume and direct control */ 922 /* set master volume and direct control */
912 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 923 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
@@ -915,6 +926,14 @@ static struct hda_verb stac927x_core_init[] = {
915 {} 926 {}
916}; 927};
917 928
929static struct hda_verb stac927x_volknob_core_init[] = {
930 /* don't set delta bit */
931 {0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0x7f},
932 /* enable analog pc beep path */
933 {0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5},
934 {}
935};
936
918static struct hda_verb stac9205_core_init[] = { 937static struct hda_verb stac9205_core_init[] = {
919 /* set master volume and direct control */ 938 /* set master volume and direct control */
920 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 939 { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
@@ -1999,6 +2018,7 @@ static unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = {
1999 [STAC_D965_5ST_NO_FP] = d965_5st_no_fp_pin_configs, 2018 [STAC_D965_5ST_NO_FP] = d965_5st_no_fp_pin_configs,
2000 [STAC_DELL_3ST] = dell_3st_pin_configs, 2019 [STAC_DELL_3ST] = dell_3st_pin_configs,
2001 [STAC_DELL_BIOS] = NULL, 2020 [STAC_DELL_BIOS] = NULL,
2021 [STAC_927X_VOLKNOB] = NULL,
2002}; 2022};
2003 2023
2004static const char *stac927x_models[STAC_927X_MODELS] = { 2024static const char *stac927x_models[STAC_927X_MODELS] = {
@@ -2010,6 +2030,7 @@ static const char *stac927x_models[STAC_927X_MODELS] = {
2010 [STAC_D965_5ST_NO_FP] = "5stack-no-fp", 2030 [STAC_D965_5ST_NO_FP] = "5stack-no-fp",
2011 [STAC_DELL_3ST] = "dell-3stack", 2031 [STAC_DELL_3ST] = "dell-3stack",
2012 [STAC_DELL_BIOS] = "dell-bios", 2032 [STAC_DELL_BIOS] = "dell-bios",
2033 [STAC_927X_VOLKNOB] = "volknob",
2013}; 2034};
2014 2035
2015static struct snd_pci_quirk stac927x_cfg_tbl[] = { 2036static struct snd_pci_quirk stac927x_cfg_tbl[] = {
@@ -2045,6 +2066,8 @@ static struct snd_pci_quirk stac927x_cfg_tbl[] = {
2045 "Intel D965", STAC_D965_5ST), 2066 "Intel D965", STAC_D965_5ST),
2046 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2500, 2067 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2500,
2047 "Intel D965", STAC_D965_5ST), 2068 "Intel D965", STAC_D965_5ST),
2069 /* volume-knob fixes */
2070 SND_PCI_QUIRK_VENDOR(0x10cf, "FSC", STAC_927X_VOLKNOB),
2048 {} /* terminator */ 2071 {} /* terminator */
2049}; 2072};
2050 2073
@@ -3469,18 +3492,26 @@ static int set_mic_route(struct hda_codec *codec,
3469 break; 3492 break;
3470 if (i <= AUTO_PIN_FRONT_MIC) { 3493 if (i <= AUTO_PIN_FRONT_MIC) {
3471 /* analog pin */ 3494 /* analog pin */
3472 mic->dmux_idx = 0;
3473 i = get_connection_index(codec, spec->mux_nids[0], pin); 3495 i = get_connection_index(codec, spec->mux_nids[0], pin);
3474 if (i < 0) 3496 if (i < 0)
3475 return -1; 3497 return -1;
3476 mic->mux_idx = i; 3498 mic->mux_idx = i;
3499 mic->dmux_idx = -1;
3500 if (spec->dmux_nids)
3501 mic->dmux_idx = get_connection_index(codec,
3502 spec->dmux_nids[0],
3503 spec->mux_nids[0]);
3477 } else if (spec->dmux_nids) { 3504 } else if (spec->dmux_nids) {
3478 /* digital pin */ 3505 /* digital pin */
3479 mic->mux_idx = 0;
3480 i = get_connection_index(codec, spec->dmux_nids[0], pin); 3506 i = get_connection_index(codec, spec->dmux_nids[0], pin);
3481 if (i < 0) 3507 if (i < 0)
3482 return -1; 3508 return -1;
3483 mic->dmux_idx = i; 3509 mic->dmux_idx = i;
3510 mic->mux_idx = -1;
3511 if (spec->mux_nids)
3512 mic->mux_idx = get_connection_index(codec,
3513 spec->mux_nids[0],
3514 spec->dmux_nids[0]);
3484 } 3515 }
3485 return 0; 3516 return 0;
3486} 3517}
@@ -4557,11 +4588,11 @@ static void stac92xx_mic_detect(struct hda_codec *codec)
4557 mic = &spec->ext_mic; 4588 mic = &spec->ext_mic;
4558 else 4589 else
4559 mic = &spec->int_mic; 4590 mic = &spec->int_mic;
4560 if (mic->dmux_idx) 4591 if (mic->dmux_idx >= 0)
4561 snd_hda_codec_write_cache(codec, spec->dmux_nids[0], 0, 4592 snd_hda_codec_write_cache(codec, spec->dmux_nids[0], 0,
4562 AC_VERB_SET_CONNECT_SEL, 4593 AC_VERB_SET_CONNECT_SEL,
4563 mic->dmux_idx); 4594 mic->dmux_idx);
4564 else 4595 if (mic->mux_idx >= 0)
4565 snd_hda_codec_write_cache(codec, spec->mux_nids[0], 0, 4596 snd_hda_codec_write_cache(codec, spec->mux_nids[0], 0,
4566 AC_VERB_SET_CONNECT_SEL, 4597 AC_VERB_SET_CONNECT_SEL,
4567 mic->mux_idx); 4598 mic->mux_idx);
@@ -5604,10 +5635,14 @@ static int patch_stac927x(struct hda_codec *codec)
5604 spec->dmic_nids = stac927x_dmic_nids; 5635 spec->dmic_nids = stac927x_dmic_nids;
5605 spec->num_dmics = STAC927X_NUM_DMICS; 5636 spec->num_dmics = STAC927X_NUM_DMICS;
5606 5637
5607 spec->init = d965_core_init; 5638 spec->init = dell_3st_core_init;
5608 spec->dmux_nids = stac927x_dmux_nids; 5639 spec->dmux_nids = stac927x_dmux_nids;
5609 spec->num_dmuxes = ARRAY_SIZE(stac927x_dmux_nids); 5640 spec->num_dmuxes = ARRAY_SIZE(stac927x_dmux_nids);
5610 break; 5641 break;
5642 case STAC_927X_VOLKNOB:
5643 spec->num_dmics = 0;
5644 spec->init = stac927x_volknob_core_init;
5645 break;
5611 default: 5646 default:
5612 spec->num_dmics = 0; 5647 spec->num_dmics = 0;
5613 spec->init = stac927x_core_init; 5648 spec->init = stac927x_core_init;
diff --git a/sound/pci/ice1712/amp.c b/sound/pci/ice1712/amp.c
index 37564300b50d..6da21a2bcade 100644
--- a/sound/pci/ice1712/amp.c
+++ b/sound/pci/ice1712/amp.c
@@ -52,11 +52,13 @@ static int __devinit snd_vt1724_amp_init(struct snd_ice1712 *ice)
52 52
53 /* only use basic functionality for now */ 53 /* only use basic functionality for now */
54 54
55 ice->num_total_dacs = 2; /* only PSDOUT0 is connected */ 55 /* VT1616 6ch codec connected to PSDOUT0 using packed mode */
56 ice->num_total_dacs = 6;
56 ice->num_total_adcs = 2; 57 ice->num_total_adcs = 2;
57 58
58 /* Chaintech AV-710 has another codecs, which need initialization */ 59 /* Chaintech AV-710 has another WM8728 codec connected to PSDOUT4
59 /* initialize WM8728 codec */ 60 (shared with the SPDIF output). Mixer control for this codec
61 is not yet supported. */
60 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AV710) { 62 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AV710) {
61 for (i = 0; i < ARRAY_SIZE(wm_inits); i += 2) 63 for (i = 0; i < ARRAY_SIZE(wm_inits); i += 2)
62 wm_put(ice, wm_inits[i], wm_inits[i+1]); 64 wm_put(ice, wm_inits[i], wm_inits[i+1]);
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
index cecf1ffeeaaa..d74033a2cfbe 100644
--- a/sound/pci/ice1712/ice1712.c
+++ b/sound/pci/ice1712/ice1712.c
@@ -2259,7 +2259,7 @@ static int snd_ice1712_pro_peak_get(struct snd_kcontrol *kcontrol,
2259} 2259}
2260 2260
2261static struct snd_kcontrol_new snd_ice1712_mixer_pro_peak __devinitdata = { 2261static struct snd_kcontrol_new snd_ice1712_mixer_pro_peak __devinitdata = {
2262 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2262 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
2263 .name = "Multi Track Peak", 2263 .name = "Multi Track Peak",
2264 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 2264 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
2265 .info = snd_ice1712_pro_peak_info, 2265 .info = snd_ice1712_pro_peak_info,
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index af6e00148621..10fc92c05574 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -648,7 +648,7 @@ static int snd_vt1724_set_pro_rate(struct snd_ice1712 *ice, unsigned int rate,
648 (inb(ICEMT1724(ice, DMA_PAUSE)) & DMA_PAUSES)) { 648 (inb(ICEMT1724(ice, DMA_PAUSE)) & DMA_PAUSES)) {
649 /* running? we cannot change the rate now... */ 649 /* running? we cannot change the rate now... */
650 spin_unlock_irqrestore(&ice->reg_lock, flags); 650 spin_unlock_irqrestore(&ice->reg_lock, flags);
651 return -EBUSY; 651 return ((rate == ice->cur_rate) && !force) ? 0 : -EBUSY;
652 } 652 }
653 if (!force && is_pro_rate_locked(ice)) { 653 if (!force && is_pro_rate_locked(ice)) {
654 spin_unlock_irqrestore(&ice->reg_lock, flags); 654 spin_unlock_irqrestore(&ice->reg_lock, flags);
@@ -1294,7 +1294,7 @@ static int __devinit snd_vt1724_pcm_spdif(struct snd_ice1712 *ice, int device)
1294 1294
1295 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, 1295 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1296 snd_dma_pci_data(ice->pci), 1296 snd_dma_pci_data(ice->pci),
1297 64*1024, 64*1024); 1297 256*1024, 256*1024);
1298 1298
1299 ice->pcm = pcm; 1299 ice->pcm = pcm;
1300 1300
@@ -1408,7 +1408,7 @@ static int __devinit snd_vt1724_pcm_indep(struct snd_ice1712 *ice, int device)
1408 1408
1409 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, 1409 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1410 snd_dma_pci_data(ice->pci), 1410 snd_dma_pci_data(ice->pci),
1411 64*1024, 64*1024); 1411 256*1024, 256*1024);
1412 1412
1413 ice->pcm_ds = pcm; 1413 ice->pcm_ds = pcm;
1414 1414
@@ -2110,7 +2110,7 @@ static int snd_vt1724_pro_peak_get(struct snd_kcontrol *kcontrol,
2110} 2110}
2111 2111
2112static struct snd_kcontrol_new snd_vt1724_mixer_pro_peak __devinitdata = { 2112static struct snd_kcontrol_new snd_vt1724_mixer_pro_peak __devinitdata = {
2113 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2113 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
2114 .name = "Multi Track Peak", 2114 .name = "Multi Track Peak",
2115 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 2115 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
2116 .info = snd_vt1724_pro_peak_info, 2116 .info = snd_vt1724_pro_peak_info,
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index 171ada535209..754867ed4785 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -1954,6 +1954,18 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
1954 .name = "Sony S1XP", 1954 .name = "Sony S1XP",
1955 .type = AC97_TUNE_INV_EAPD 1955 .type = AC97_TUNE_INV_EAPD
1956 }, 1956 },
1957 {
1958 .subvendor = 0x104d,
1959 .subdevice = 0x81c0,
1960 .name = "Sony VAIO VGN-T350P", /*AD1981B*/
1961 .type = AC97_TUNE_INV_EAPD
1962 },
1963 {
1964 .subvendor = 0x104d,
1965 .subdevice = 0x81c5,
1966 .name = "Sony VAIO VGN-B1VP", /*AD1981B*/
1967 .type = AC97_TUNE_INV_EAPD
1968 },
1957 { 1969 {
1958 .subvendor = 0x1043, 1970 .subvendor = 0x1043,
1959 .subdevice = 0x80f3, 1971 .subdevice = 0x80f3,
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index acfa4760da49..91683a349035 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -1626,7 +1626,7 @@ static int snd_via8233_dxs_volume_get(struct snd_kcontrol *kcontrol,
1626 struct snd_ctl_elem_value *ucontrol) 1626 struct snd_ctl_elem_value *ucontrol)
1627{ 1627{
1628 struct via82xx *chip = snd_kcontrol_chip(kcontrol); 1628 struct via82xx *chip = snd_kcontrol_chip(kcontrol);
1629 unsigned int idx = snd_ctl_get_ioff(kcontrol, &ucontrol->id); 1629 unsigned int idx = kcontrol->id.subdevice;
1630 1630
1631 ucontrol->value.integer.value[0] = VIA_DXS_MAX_VOLUME - chip->playback_volume[idx][0]; 1631 ucontrol->value.integer.value[0] = VIA_DXS_MAX_VOLUME - chip->playback_volume[idx][0];
1632 ucontrol->value.integer.value[1] = VIA_DXS_MAX_VOLUME - chip->playback_volume[idx][1]; 1632 ucontrol->value.integer.value[1] = VIA_DXS_MAX_VOLUME - chip->playback_volume[idx][1];
@@ -1646,7 +1646,7 @@ static int snd_via8233_dxs_volume_put(struct snd_kcontrol *kcontrol,
1646 struct snd_ctl_elem_value *ucontrol) 1646 struct snd_ctl_elem_value *ucontrol)
1647{ 1647{
1648 struct via82xx *chip = snd_kcontrol_chip(kcontrol); 1648 struct via82xx *chip = snd_kcontrol_chip(kcontrol);
1649 unsigned int idx = snd_ctl_get_ioff(kcontrol, &ucontrol->id); 1649 unsigned int idx = kcontrol->id.subdevice;
1650 unsigned long port = chip->port + 0x10 * idx; 1650 unsigned long port = chip->port + 0x10 * idx;
1651 unsigned char val; 1651 unsigned char val;
1652 int i, change = 0; 1652 int i, change = 0;
@@ -1705,11 +1705,12 @@ static struct snd_kcontrol_new snd_via8233_pcmdxs_volume_control __devinitdata =
1705}; 1705};
1706 1706
1707static struct snd_kcontrol_new snd_via8233_dxs_volume_control __devinitdata = { 1707static struct snd_kcontrol_new snd_via8233_dxs_volume_control __devinitdata = {
1708 .name = "VIA DXS Playback Volume", 1708 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1709 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1709 .device = 0,
1710 /* .subdevice set later */
1711 .name = "PCM Playback Volume",
1710 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 1712 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1711 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 1713 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1712 .count = 4,
1713 .info = snd_via8233_dxs_volume_info, 1714 .info = snd_via8233_dxs_volume_info,
1714 .get = snd_via8233_dxs_volume_get, 1715 .get = snd_via8233_dxs_volume_get,
1715 .put = snd_via8233_dxs_volume_put, 1716 .put = snd_via8233_dxs_volume_put,
@@ -1936,10 +1937,18 @@ static int __devinit snd_via8233_init_misc(struct via82xx *chip)
1936 } 1937 }
1937 else /* Using DXS when PCM emulation is enabled is really weird */ 1938 else /* Using DXS when PCM emulation is enabled is really weird */
1938 { 1939 {
1939 /* Standalone DXS controls */ 1940 for (i = 0; i < 4; ++i) {
1940 err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_via8233_dxs_volume_control, chip)); 1941 struct snd_kcontrol *kctl;
1941 if (err < 0) 1942
1942 return err; 1943 kctl = snd_ctl_new1(
1944 &snd_via8233_dxs_volume_control, chip);
1945 if (!kctl)
1946 return -ENOMEM;
1947 kctl->id.subdevice = i;
1948 err = snd_ctl_add(chip->card, kctl);
1949 if (err < 0)
1950 return err;
1951 }
1943 } 1952 }
1944 } 1953 }
1945 /* select spdif data slot 10/11 */ 1954 /* select spdif data slot 10/11 */
diff --git a/sound/ppc/keywest.c b/sound/ppc/keywest.c
index 835fa19ed461..d06f780bd7e8 100644
--- a/sound/ppc/keywest.c
+++ b/sound/ppc/keywest.c
@@ -59,6 +59,18 @@ static int keywest_attach_adapter(struct i2c_adapter *adapter)
59 strlcpy(info.type, "keywest", I2C_NAME_SIZE); 59 strlcpy(info.type, "keywest", I2C_NAME_SIZE);
60 info.addr = keywest_ctx->addr; 60 info.addr = keywest_ctx->addr;
61 keywest_ctx->client = i2c_new_device(adapter, &info); 61 keywest_ctx->client = i2c_new_device(adapter, &info);
62 if (!keywest_ctx->client)
63 return -ENODEV;
64 /*
65 * We know the driver is already loaded, so the device should be
66 * already bound. If not it means binding failed, and then there
67 * is no point in keeping the device instantiated.
68 */
69 if (!keywest_ctx->client->driver) {
70 i2c_unregister_device(keywest_ctx->client);
71 keywest_ctx->client = NULL;
72 return -ENODEV;
73 }
62 74
63 /* 75 /*
64 * Let i2c-core delete that device on driver removal. 76 * Let i2c-core delete that device on driver removal.
@@ -86,7 +98,7 @@ static const struct i2c_device_id keywest_i2c_id[] = {
86 { } 98 { }
87}; 99};
88 100
89struct i2c_driver keywest_driver = { 101static struct i2c_driver keywest_driver = {
90 .driver = { 102 .driver = {
91 .name = "PMac Keywest Audio", 103 .name = "PMac Keywest Audio",
92 }, 104 },
diff --git a/sound/soc/blackfin/Kconfig b/sound/soc/blackfin/Kconfig
index ac927ffdc961..97f1a251e446 100644
--- a/sound/soc/blackfin/Kconfig
+++ b/sound/soc/blackfin/Kconfig
@@ -7,15 +7,6 @@ config SND_BF5XX_I2S
7 mode (supports single stereo In/Out). 7 mode (supports single stereo In/Out).
8 You will also need to select the audio interfaces to support below. 8 You will also need to select the audio interfaces to support below.
9 9
10config SND_BF5XX_TDM
11 tristate "SoC I2S(TDM mode) Audio for the ADI BF5xx chip"
12 depends on (BLACKFIN && SND_SOC)
13 help
14 Say Y or M if you want to add support for codecs attached to
15 the Blackfin SPORT (synchronous serial ports) interface in TDM
16 mode.
17 You will also need to select the audio interfaces to support below.
18
19config SND_BF5XX_SOC_SSM2602 10config SND_BF5XX_SOC_SSM2602
20 tristate "SoC SSM2602 Audio support for BF52x ezkit" 11 tristate "SoC SSM2602 Audio support for BF52x ezkit"
21 depends on SND_BF5XX_I2S 12 depends on SND_BF5XX_I2S
@@ -41,6 +32,31 @@ config SND_BFIN_AD73311_SE
41 Enter the GPIO used to control AD73311's SE pin. Acceptable 32 Enter the GPIO used to control AD73311's SE pin. Acceptable
42 values are 0 to 7 33 values are 0 to 7
43 34
35config SND_BF5XX_TDM
36 tristate "SoC I2S(TDM mode) Audio for the ADI BF5xx chip"
37 depends on (BLACKFIN && SND_SOC)
38 help
39 Say Y or M if you want to add support for codecs attached to
40 the Blackfin SPORT (synchronous serial ports) interface in TDM
41 mode.
42 You will also need to select the audio interfaces to support below.
43
44config SND_BF5XX_SOC_AD1836
45 tristate "SoC AD1836 Audio support for BF5xx"
46 depends on SND_BF5XX_TDM
47 select SND_BF5XX_SOC_TDM
48 select SND_SOC_AD1836
49 help
50 Say Y if you want to add support for SoC audio on BF5xx STAMP/EZKIT.
51
52config SND_BF5XX_SOC_AD1938
53 tristate "SoC AD1938 Audio support for Blackfin"
54 depends on SND_BF5XX_TDM
55 select SND_BF5XX_SOC_TDM
56 select SND_SOC_AD1938
57 help
58 Say Y if you want to add support for AD1938 codec on Blackfin.
59
44config SND_BF5XX_AC97 60config SND_BF5XX_AC97
45 tristate "SoC AC97 Audio for the ADI BF5xx chip" 61 tristate "SoC AC97 Audio for the ADI BF5xx chip"
46 depends on BLACKFIN 62 depends on BLACKFIN
@@ -71,6 +87,30 @@ config SND_BF5XX_MULTICHAN_SUPPORT
71 Say y if you want AC97 driver to support up to 5.1 channel audio. 87 Say y if you want AC97 driver to support up to 5.1 channel audio.
72 this mode will consume much more memory for DMA. 88 this mode will consume much more memory for DMA.
73 89
90config SND_BF5XX_HAVE_COLD_RESET
91 bool "BOARD has COLD Reset GPIO"
92 depends on SND_BF5XX_AC97
93 default y if BFIN548_EZKIT
94 default n if !BFIN548_EZKIT
95
96config SND_BF5XX_RESET_GPIO_NUM
97 int "Set a GPIO for cold reset"
98 depends on SND_BF5XX_HAVE_COLD_RESET
99 range 0 159
100 default 19 if BFIN548_EZKIT
101 default 5 if BFIN537_STAMP
102 default 0
103 help
104 Set the correct GPIO for RESET the sound chip.
105
106config SND_BF5XX_SOC_AD1980
107 tristate "SoC AD1980/1 Audio support for BF5xx"
108 depends on SND_BF5XX_AC97
109 select SND_BF5XX_SOC_AC97
110 select SND_SOC_AD1980
111 help
112 Say Y if you want to add support for SoC audio on BF5xx STAMP/EZKIT.
113
74config SND_BF5XX_SOC_SPORT 114config SND_BF5XX_SOC_SPORT
75 tristate 115 tristate
76 116
@@ -88,30 +128,6 @@ config SND_BF5XX_SOC_AC97
88 select SND_SOC_AC97_BUS 128 select SND_SOC_AC97_BUS
89 select SND_BF5XX_SOC_SPORT 129 select SND_BF5XX_SOC_SPORT
90 130
91config SND_BF5XX_SOC_AD1836
92 tristate "SoC AD1836 Audio support for BF5xx"
93 depends on SND_BF5XX_TDM
94 select SND_BF5XX_SOC_TDM
95 select SND_SOC_AD1836
96 help
97 Say Y if you want to add support for SoC audio on BF5xx STAMP/EZKIT.
98
99config SND_BF5XX_SOC_AD1980
100 tristate "SoC AD1980/1 Audio support for BF5xx"
101 depends on SND_BF5XX_AC97
102 select SND_BF5XX_SOC_AC97
103 select SND_SOC_AD1980
104 help
105 Say Y if you want to add support for SoC audio on BF5xx STAMP/EZKIT.
106
107config SND_BF5XX_SOC_AD1938
108 tristate "SoC AD1938 Audio support for Blackfin"
109 depends on SND_BF5XX_TDM
110 select SND_BF5XX_SOC_TDM
111 select SND_SOC_AD1938
112 help
113 Say Y if you want to add support for AD1938 codec on Blackfin.
114
115config SND_BF5XX_SPORT_NUM 131config SND_BF5XX_SPORT_NUM
116 int "Set a SPORT for Sound chip" 132 int "Set a SPORT for Sound chip"
117 depends on (SND_BF5XX_I2S || SND_BF5XX_AC97 || SND_BF5XX_TDM) 133 depends on (SND_BF5XX_I2S || SND_BF5XX_AC97 || SND_BF5XX_TDM)
@@ -120,19 +136,3 @@ config SND_BF5XX_SPORT_NUM
120 default 0 136 default 0
121 help 137 help
122 Set the correct SPORT for sound chip. 138 Set the correct SPORT for sound chip.
123
124config SND_BF5XX_HAVE_COLD_RESET
125 bool "BOARD has COLD Reset GPIO"
126 depends on SND_BF5XX_AC97
127 default y if BFIN548_EZKIT
128 default n if !BFIN548_EZKIT
129
130config SND_BF5XX_RESET_GPIO_NUM
131 int "Set a GPIO for cold reset"
132 depends on SND_BF5XX_HAVE_COLD_RESET
133 range 0 159
134 default 19 if BFIN548_EZKIT
135 default 5 if BFIN537_STAMP
136 default 0
137 help
138 Set the correct GPIO for RESET the sound chip.
diff --git a/sound/soc/blackfin/bf5xx-i2s.c b/sound/soc/blackfin/bf5xx-i2s.c
index 1e9d161c76c4..084b68884ada 100644
--- a/sound/soc/blackfin/bf5xx-i2s.c
+++ b/sound/soc/blackfin/bf5xx-i2s.c
@@ -77,12 +77,12 @@ static struct sport_param sport_params[2] = {
77 * TFS. When Port G is selected and EMAC then there is a conflict between 77 * TFS. When Port G is selected and EMAC then there is a conflict between
78 * the PHY interrupt line and TFS. Current settings prevent the conflict 78 * the PHY interrupt line and TFS. Current settings prevent the conflict
79 * by ignoring the TFS pin when Port G is selected. This allows both 79 * by ignoring the TFS pin when Port G is selected. This allows both
80 * ssm2602 using Port G and EMAC concurrently. 80 * codecs and EMAC using Port G concurrently.
81 */ 81 */
82#ifdef CONFIG_BF527_SPORT0_PORTF 82#ifdef CONFIG_BF527_SPORT0_PORTG
83#define LOCAL_SPORT0_TFS (P_SPORT0_TFS)
84#else
85#define LOCAL_SPORT0_TFS (0) 83#define LOCAL_SPORT0_TFS (0)
84#else
85#define LOCAL_SPORT0_TFS (P_SPORT0_TFS)
86#endif 86#endif
87 87
88static u16 sport_req[][7] = { {P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, 88static u16 sport_req[][7] = { {P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
diff --git a/sound/soc/blackfin/bf5xx-tdm.c b/sound/soc/blackfin/bf5xx-tdm.c
index 3096badf09a5..ff546e91a22e 100644
--- a/sound/soc/blackfin/bf5xx-tdm.c
+++ b/sound/soc/blackfin/bf5xx-tdm.c
@@ -78,12 +78,12 @@ static struct sport_param sport_params[2] = {
78 * TFS. When Port G is selected and EMAC then there is a conflict between 78 * TFS. When Port G is selected and EMAC then there is a conflict between
79 * the PHY interrupt line and TFS. Current settings prevent the conflict 79 * the PHY interrupt line and TFS. Current settings prevent the conflict
80 * by ignoring the TFS pin when Port G is selected. This allows both 80 * by ignoring the TFS pin when Port G is selected. This allows both
81 * ssm2602 using Port G and EMAC concurrently. 81 * codecs and EMAC using Port G concurrently.
82 */ 82 */
83#ifdef CONFIG_BF527_SPORT0_PORTF 83#ifdef CONFIG_BF527_SPORT0_PORTG
84#define LOCAL_SPORT0_TFS (P_SPORT0_TFS)
85#else
86#define LOCAL_SPORT0_TFS (0) 84#define LOCAL_SPORT0_TFS (0)
85#else
86#define LOCAL_SPORT0_TFS (P_SPORT0_TFS)
87#endif 87#endif
88 88
89static u16 sport_req[][7] = { {P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, 89static u16 sport_req[][7] = { {P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
index 3ff0373dff89..593d5b9c9f03 100644
--- a/sound/soc/codecs/wm8350.c
+++ b/sound/soc/codecs/wm8350.c
@@ -579,7 +579,7 @@ static const struct snd_kcontrol_new wm8350_left_capt_mixer_controls[] = {
579 SOC_DAPM_SINGLE_TLV("L3 Capture Volume", 579 SOC_DAPM_SINGLE_TLV("L3 Capture Volume",
580 WM8350_INPUT_MIXER_VOLUME_L, 9, 7, 0, out_mix_tlv), 580 WM8350_INPUT_MIXER_VOLUME_L, 9, 7, 0, out_mix_tlv),
581 SOC_DAPM_SINGLE("PGA Capture Switch", 581 SOC_DAPM_SINGLE("PGA Capture Switch",
582 WM8350_LEFT_INPUT_VOLUME, 14, 1, 0), 582 WM8350_LEFT_INPUT_VOLUME, 14, 1, 1),
583}; 583};
584 584
585/* Right Input Mixer */ 585/* Right Input Mixer */
@@ -589,7 +589,7 @@ static const struct snd_kcontrol_new wm8350_right_capt_mixer_controls[] = {
589 SOC_DAPM_SINGLE_TLV("L3 Capture Volume", 589 SOC_DAPM_SINGLE_TLV("L3 Capture Volume",
590 WM8350_INPUT_MIXER_VOLUME_R, 13, 7, 0, out_mix_tlv), 590 WM8350_INPUT_MIXER_VOLUME_R, 13, 7, 0, out_mix_tlv),
591 SOC_DAPM_SINGLE("PGA Capture Switch", 591 SOC_DAPM_SINGLE("PGA Capture Switch",
592 WM8350_RIGHT_INPUT_VOLUME, 14, 1, 0), 592 WM8350_RIGHT_INPUT_VOLUME, 14, 1, 1),
593}; 593};
594 594
595/* Left Mic Mixer */ 595/* Left Mic Mixer */
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c
index da97aae475a2..1ef2454c5205 100644
--- a/sound/soc/codecs/wm8940.c
+++ b/sound/soc/codecs/wm8940.c
@@ -790,7 +790,7 @@ static int wm8940_register(struct wm8940_priv *wm8940,
790 codec->reg_cache = &wm8940->reg_cache; 790 codec->reg_cache = &wm8940->reg_cache;
791 791
792 ret = snd_soc_codec_set_cache_io(codec, 8, 16, control); 792 ret = snd_soc_codec_set_cache_io(codec, 8, 16, control);
793 if (ret == 0) { 793 if (ret < 0) {
794 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 794 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
795 return ret; 795 return ret;
796 } 796 }
diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c
index 12a6c549ee6e..4ae707048021 100644
--- a/sound/soc/davinci/davinci-i2s.c
+++ b/sound/soc/davinci/davinci-i2s.c
@@ -97,22 +97,19 @@ enum {
97 DAVINCI_MCBSP_WORD_32, 97 DAVINCI_MCBSP_WORD_32,
98}; 98};
99 99
100static struct davinci_pcm_dma_params davinci_i2s_pcm_out = {
101 .name = "I2S PCM Stereo out",
102};
103
104static struct davinci_pcm_dma_params davinci_i2s_pcm_in = {
105 .name = "I2S PCM Stereo in",
106};
107
108struct davinci_mcbsp_dev { 100struct davinci_mcbsp_dev {
101 /*
102 * dma_params must be first because rtd->dai->cpu_dai->private_data
103 * is cast to a pointer of an array of struct davinci_pcm_dma_params in
104 * davinci_pcm_open.
105 */
106 struct davinci_pcm_dma_params dma_params[2];
109 void __iomem *base; 107 void __iomem *base;
110#define MOD_DSP_A 0 108#define MOD_DSP_A 0
111#define MOD_DSP_B 1 109#define MOD_DSP_B 1
112 int mode; 110 int mode;
113 u32 pcr; 111 u32 pcr;
114 struct clk *clk; 112 struct clk *clk;
115 struct davinci_pcm_dma_params *dma_params[2];
116}; 113};
117 114
118static inline void davinci_mcbsp_write_reg(struct davinci_mcbsp_dev *dev, 115static inline void davinci_mcbsp_write_reg(struct davinci_mcbsp_dev *dev,
@@ -215,14 +212,6 @@ static void davinci_mcbsp_stop(struct davinci_mcbsp_dev *dev, int playback)
215 toggle_clock(dev, playback); 212 toggle_clock(dev, playback);
216} 213}
217 214
218static int davinci_i2s_startup(struct snd_pcm_substream *substream,
219 struct snd_soc_dai *cpu_dai)
220{
221 struct davinci_mcbsp_dev *dev = cpu_dai->private_data;
222 cpu_dai->dma_data = dev->dma_params[substream->stream];
223 return 0;
224}
225
226#define DEFAULT_BITPERSAMPLE 16 215#define DEFAULT_BITPERSAMPLE 16
227 216
228static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, 217static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
@@ -353,8 +342,9 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
353 struct snd_pcm_hw_params *params, 342 struct snd_pcm_hw_params *params,
354 struct snd_soc_dai *dai) 343 struct snd_soc_dai *dai)
355{ 344{
356 struct davinci_pcm_dma_params *dma_params = dai->dma_data;
357 struct davinci_mcbsp_dev *dev = dai->private_data; 345 struct davinci_mcbsp_dev *dev = dai->private_data;
346 struct davinci_pcm_dma_params *dma_params =
347 &dev->dma_params[substream->stream];
358 struct snd_interval *i = NULL; 348 struct snd_interval *i = NULL;
359 int mcbsp_word_length; 349 int mcbsp_word_length;
360 unsigned int rcr, xcr, srgr; 350 unsigned int rcr, xcr, srgr;
@@ -472,7 +462,6 @@ static void davinci_i2s_shutdown(struct snd_pcm_substream *substream,
472#define DAVINCI_I2S_RATES SNDRV_PCM_RATE_8000_96000 462#define DAVINCI_I2S_RATES SNDRV_PCM_RATE_8000_96000
473 463
474static struct snd_soc_dai_ops davinci_i2s_dai_ops = { 464static struct snd_soc_dai_ops davinci_i2s_dai_ops = {
475 .startup = davinci_i2s_startup,
476 .shutdown = davinci_i2s_shutdown, 465 .shutdown = davinci_i2s_shutdown,
477 .prepare = davinci_i2s_prepare, 466 .prepare = davinci_i2s_prepare,
478 .trigger = davinci_i2s_trigger, 467 .trigger = davinci_i2s_trigger,
@@ -534,12 +523,10 @@ static int davinci_i2s_probe(struct platform_device *pdev)
534 523
535 dev->base = (void __iomem *)IO_ADDRESS(mem->start); 524 dev->base = (void __iomem *)IO_ADDRESS(mem->start);
536 525
537 dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK] = &davinci_i2s_pcm_out; 526 dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].dma_addr =
538 dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]->dma_addr =
539 (dma_addr_t)(io_v2p(dev->base) + DAVINCI_MCBSP_DXR_REG); 527 (dma_addr_t)(io_v2p(dev->base) + DAVINCI_MCBSP_DXR_REG);
540 528
541 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE] = &davinci_i2s_pcm_in; 529 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].dma_addr =
542 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE]->dma_addr =
543 (dma_addr_t)(io_v2p(dev->base) + DAVINCI_MCBSP_DRR_REG); 530 (dma_addr_t)(io_v2p(dev->base) + DAVINCI_MCBSP_DRR_REG);
544 531
545 /* first TX, then RX */ 532 /* first TX, then RX */
@@ -549,7 +536,7 @@ static int davinci_i2s_probe(struct platform_device *pdev)
549 ret = -ENXIO; 536 ret = -ENXIO;
550 goto err_free_mem; 537 goto err_free_mem;
551 } 538 }
552 dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]->channel = res->start; 539 dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].channel = res->start;
553 540
554 res = platform_get_resource(pdev, IORESOURCE_DMA, 1); 541 res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
555 if (!res) { 542 if (!res) {
@@ -557,7 +544,7 @@ static int davinci_i2s_probe(struct platform_device *pdev)
557 ret = -ENXIO; 544 ret = -ENXIO;
558 goto err_free_mem; 545 goto err_free_mem;
559 } 546 }
560 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE]->channel = res->start; 547 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].channel = res->start;
561 548
562 davinci_i2s_dai.private_data = dev; 549 davinci_i2s_dai.private_data = dev;
563 ret = snd_soc_register_dai(&davinci_i2s_dai); 550 ret = snd_soc_register_dai(&davinci_i2s_dai);
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index 7a06c0a86665..5d1f98a4c978 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -332,14 +332,6 @@ static inline void mcasp_set_ctl_reg(void __iomem *regs, u32 val)
332 printk(KERN_ERR "GBLCTL write error\n"); 332 printk(KERN_ERR "GBLCTL write error\n");
333} 333}
334 334
335static int davinci_mcasp_startup(struct snd_pcm_substream *substream,
336 struct snd_soc_dai *cpu_dai)
337{
338 struct davinci_audio_dev *dev = cpu_dai->private_data;
339 cpu_dai->dma_data = dev->dma_params[substream->stream];
340 return 0;
341}
342
343static void mcasp_start_rx(struct davinci_audio_dev *dev) 335static void mcasp_start_rx(struct davinci_audio_dev *dev)
344{ 336{
345 mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXHCLKRST); 337 mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXHCLKRST);
@@ -386,17 +378,17 @@ static void mcasp_start_tx(struct davinci_audio_dev *dev)
386 378
387static void davinci_mcasp_start(struct davinci_audio_dev *dev, int stream) 379static void davinci_mcasp_start(struct davinci_audio_dev *dev, int stream)
388{ 380{
389 if (stream == SNDRV_PCM_STREAM_PLAYBACK) 381 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
382 if (dev->txnumevt) /* enable FIFO */
383 mcasp_set_bits(dev->base + DAVINCI_MCASP_WFIFOCTL,
384 FIFO_ENABLE);
390 mcasp_start_tx(dev); 385 mcasp_start_tx(dev);
391 else 386 } else {
387 if (dev->rxnumevt) /* enable FIFO */
388 mcasp_set_bits(dev->base + DAVINCI_MCASP_RFIFOCTL,
389 FIFO_ENABLE);
392 mcasp_start_rx(dev); 390 mcasp_start_rx(dev);
393 391 }
394 /* enable FIFO */
395 if (dev->txnumevt)
396 mcasp_set_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, FIFO_ENABLE);
397
398 if (dev->rxnumevt)
399 mcasp_set_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, FIFO_ENABLE);
400} 392}
401 393
402static void mcasp_stop_rx(struct davinci_audio_dev *dev) 394static void mcasp_stop_rx(struct davinci_audio_dev *dev)
@@ -413,17 +405,17 @@ static void mcasp_stop_tx(struct davinci_audio_dev *dev)
413 405
414static void davinci_mcasp_stop(struct davinci_audio_dev *dev, int stream) 406static void davinci_mcasp_stop(struct davinci_audio_dev *dev, int stream)
415{ 407{
416 if (stream == SNDRV_PCM_STREAM_PLAYBACK) 408 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
409 if (dev->txnumevt) /* disable FIFO */
410 mcasp_clr_bits(dev->base + DAVINCI_MCASP_WFIFOCTL,
411 FIFO_ENABLE);
417 mcasp_stop_tx(dev); 412 mcasp_stop_tx(dev);
418 else 413 } else {
414 if (dev->rxnumevt) /* disable FIFO */
415 mcasp_clr_bits(dev->base + DAVINCI_MCASP_RFIFOCTL,
416 FIFO_ENABLE);
419 mcasp_stop_rx(dev); 417 mcasp_stop_rx(dev);
420 418 }
421 /* disable FIFO */
422 if (dev->txnumevt)
423 mcasp_clr_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, FIFO_ENABLE);
424
425 if (dev->rxnumevt)
426 mcasp_clr_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, FIFO_ENABLE);
427} 419}
428 420
429static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, 421static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
@@ -720,7 +712,7 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
720{ 712{
721 struct davinci_audio_dev *dev = cpu_dai->private_data; 713 struct davinci_audio_dev *dev = cpu_dai->private_data;
722 struct davinci_pcm_dma_params *dma_params = 714 struct davinci_pcm_dma_params *dma_params =
723 dev->dma_params[substream->stream]; 715 &dev->dma_params[substream->stream];
724 int word_length; 716 int word_length;
725 u8 numevt; 717 u8 numevt;
726 718
@@ -798,7 +790,6 @@ static int davinci_mcasp_trigger(struct snd_pcm_substream *substream,
798} 790}
799 791
800static struct snd_soc_dai_ops davinci_mcasp_dai_ops = { 792static struct snd_soc_dai_ops davinci_mcasp_dai_ops = {
801 .startup = davinci_mcasp_startup,
802 .trigger = davinci_mcasp_trigger, 793 .trigger = davinci_mcasp_trigger,
803 .hw_params = davinci_mcasp_hw_params, 794 .hw_params = davinci_mcasp_hw_params,
804 .set_fmt = davinci_mcasp_set_dai_fmt, 795 .set_fmt = davinci_mcasp_set_dai_fmt,
@@ -849,20 +840,12 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
849 struct resource *mem, *ioarea, *res; 840 struct resource *mem, *ioarea, *res;
850 struct snd_platform_data *pdata; 841 struct snd_platform_data *pdata;
851 struct davinci_audio_dev *dev; 842 struct davinci_audio_dev *dev;
852 int count = 0;
853 int ret = 0; 843 int ret = 0;
854 844
855 dev = kzalloc(sizeof(struct davinci_audio_dev), GFP_KERNEL); 845 dev = kzalloc(sizeof(struct davinci_audio_dev), GFP_KERNEL);
856 if (!dev) 846 if (!dev)
857 return -ENOMEM; 847 return -ENOMEM;
858 848
859 dma_data = kzalloc(sizeof(struct davinci_pcm_dma_params) * 2,
860 GFP_KERNEL);
861 if (!dma_data) {
862 ret = -ENOMEM;
863 goto err_release_dev;
864 }
865
866 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 849 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
867 if (!mem) { 850 if (!mem) {
868 dev_err(&pdev->dev, "no mem resource?\n"); 851 dev_err(&pdev->dev, "no mem resource?\n");
@@ -897,11 +880,10 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
897 dev->txnumevt = pdata->txnumevt; 880 dev->txnumevt = pdata->txnumevt;
898 dev->rxnumevt = pdata->rxnumevt; 881 dev->rxnumevt = pdata->rxnumevt;
899 882
900 dma_data[count].name = "I2S PCM Stereo out"; 883 dma_data = &dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK];
901 dma_data[count].eventq_no = pdata->eventq_no; 884 dma_data->eventq_no = pdata->eventq_no;
902 dma_data[count].dma_addr = (dma_addr_t) (pdata->tx_dma_offset + 885 dma_data->dma_addr = (dma_addr_t) (pdata->tx_dma_offset +
903 io_v2p(dev->base)); 886 io_v2p(dev->base));
904 dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK] = &dma_data[count];
905 887
906 /* first TX, then RX */ 888 /* first TX, then RX */
907 res = platform_get_resource(pdev, IORESOURCE_DMA, 0); 889 res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
@@ -910,13 +892,12 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
910 goto err_release_region; 892 goto err_release_region;
911 } 893 }
912 894
913 dma_data[count].channel = res->start; 895 dma_data->channel = res->start;
914 count++; 896
915 dma_data[count].name = "I2S PCM Stereo in"; 897 dma_data = &dev->dma_params[SNDRV_PCM_STREAM_CAPTURE];
916 dma_data[count].eventq_no = pdata->eventq_no; 898 dma_data->eventq_no = pdata->eventq_no;
917 dma_data[count].dma_addr = (dma_addr_t)(pdata->rx_dma_offset + 899 dma_data->dma_addr = (dma_addr_t)(pdata->rx_dma_offset +
918 io_v2p(dev->base)); 900 io_v2p(dev->base));
919 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE] = &dma_data[count];
920 901
921 res = platform_get_resource(pdev, IORESOURCE_DMA, 1); 902 res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
922 if (!res) { 903 if (!res) {
@@ -924,7 +905,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
924 goto err_release_region; 905 goto err_release_region;
925 } 906 }
926 907
927 dma_data[count].channel = res->start; 908 dma_data->channel = res->start;
928 davinci_mcasp_dai[pdata->op_mode].private_data = dev; 909 davinci_mcasp_dai[pdata->op_mode].private_data = dev;
929 davinci_mcasp_dai[pdata->op_mode].dev = &pdev->dev; 910 davinci_mcasp_dai[pdata->op_mode].dev = &pdev->dev;
930 ret = snd_soc_register_dai(&davinci_mcasp_dai[pdata->op_mode]); 911 ret = snd_soc_register_dai(&davinci_mcasp_dai[pdata->op_mode]);
@@ -936,8 +917,6 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
936err_release_region: 917err_release_region:
937 release_mem_region(mem->start, (mem->end - mem->start) + 1); 918 release_mem_region(mem->start, (mem->end - mem->start) + 1);
938err_release_data: 919err_release_data:
939 kfree(dma_data);
940err_release_dev:
941 kfree(dev); 920 kfree(dev);
942 921
943 return ret; 922 return ret;
@@ -946,7 +925,6 @@ err_release_dev:
946static int davinci_mcasp_remove(struct platform_device *pdev) 925static int davinci_mcasp_remove(struct platform_device *pdev)
947{ 926{
948 struct snd_platform_data *pdata = pdev->dev.platform_data; 927 struct snd_platform_data *pdata = pdev->dev.platform_data;
949 struct davinci_pcm_dma_params *dma_data;
950 struct davinci_audio_dev *dev; 928 struct davinci_audio_dev *dev;
951 struct resource *mem; 929 struct resource *mem;
952 930
@@ -959,8 +937,6 @@ static int davinci_mcasp_remove(struct platform_device *pdev)
959 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 937 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
960 release_mem_region(mem->start, (mem->end - mem->start) + 1); 938 release_mem_region(mem->start, (mem->end - mem->start) + 1);
961 939
962 dma_data = dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK];
963 kfree(dma_data);
964 kfree(dev); 940 kfree(dev);
965 941
966 return 0; 942 return 0;
diff --git a/sound/soc/davinci/davinci-mcasp.h b/sound/soc/davinci/davinci-mcasp.h
index 554354c1cc2f..9d179cc88f7b 100644
--- a/sound/soc/davinci/davinci-mcasp.h
+++ b/sound/soc/davinci/davinci-mcasp.h
@@ -39,10 +39,15 @@ enum {
39}; 39};
40 40
41struct davinci_audio_dev { 41struct davinci_audio_dev {
42 /*
43 * dma_params must be first because rtd->dai->cpu_dai->private_data
44 * is cast to a pointer of an array of struct davinci_pcm_dma_params in
45 * davinci_pcm_open.
46 */
47 struct davinci_pcm_dma_params dma_params[2];
42 void __iomem *base; 48 void __iomem *base;
43 int sample_rate; 49 int sample_rate;
44 struct clk *clk; 50 struct clk *clk;
45 struct davinci_pcm_dma_params *dma_params[2];
46 unsigned int codec_fmt; 51 unsigned int codec_fmt;
47 52
48 /* McASP specific data */ 53 /* McASP specific data */
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c
index 2f7da49ed34f..c73a915f233f 100644
--- a/sound/soc/davinci/davinci-pcm.c
+++ b/sound/soc/davinci/davinci-pcm.c
@@ -126,16 +126,9 @@ static void davinci_pcm_dma_irq(unsigned lch, u16 ch_status, void *data)
126static int davinci_pcm_dma_request(struct snd_pcm_substream *substream) 126static int davinci_pcm_dma_request(struct snd_pcm_substream *substream)
127{ 127{
128 struct davinci_runtime_data *prtd = substream->runtime->private_data; 128 struct davinci_runtime_data *prtd = substream->runtime->private_data;
129 struct snd_soc_pcm_runtime *rtd = substream->private_data;
130 struct davinci_pcm_dma_params *dma_data = rtd->dai->cpu_dai->dma_data;
131 struct edmacc_param p_ram; 129 struct edmacc_param p_ram;
132 int ret; 130 int ret;
133 131
134 if (!dma_data)
135 return -ENODEV;
136
137 prtd->params = dma_data;
138
139 /* Request master DMA channel */ 132 /* Request master DMA channel */
140 ret = edma_alloc_channel(prtd->params->channel, 133 ret = edma_alloc_channel(prtd->params->channel,
141 davinci_pcm_dma_irq, substream, 134 davinci_pcm_dma_irq, substream,
@@ -244,6 +237,11 @@ static int davinci_pcm_open(struct snd_pcm_substream *substream)
244 struct snd_pcm_runtime *runtime = substream->runtime; 237 struct snd_pcm_runtime *runtime = substream->runtime;
245 struct davinci_runtime_data *prtd; 238 struct davinci_runtime_data *prtd;
246 int ret = 0; 239 int ret = 0;
240 struct snd_soc_pcm_runtime *rtd = substream->private_data;
241 struct davinci_pcm_dma_params *pa = rtd->dai->cpu_dai->private_data;
242 struct davinci_pcm_dma_params *params = &pa[substream->stream];
243 if (!params)
244 return -ENODEV;
247 245
248 snd_soc_set_runtime_hwparams(substream, &davinci_pcm_hardware); 246 snd_soc_set_runtime_hwparams(substream, &davinci_pcm_hardware);
249 /* ensure that buffer size is a multiple of period size */ 247 /* ensure that buffer size is a multiple of period size */
@@ -257,6 +255,7 @@ static int davinci_pcm_open(struct snd_pcm_substream *substream)
257 return -ENOMEM; 255 return -ENOMEM;
258 256
259 spin_lock_init(&prtd->lock); 257 spin_lock_init(&prtd->lock);
258 prtd->params = params;
260 259
261 runtime->private_data = prtd; 260 runtime->private_data = prtd;
262 261
diff --git a/sound/soc/davinci/davinci-pcm.h b/sound/soc/davinci/davinci-pcm.h
index 63d96253c73a..8746606efc89 100644
--- a/sound/soc/davinci/davinci-pcm.h
+++ b/sound/soc/davinci/davinci-pcm.h
@@ -17,7 +17,6 @@
17 17
18 18
19struct davinci_pcm_dma_params { 19struct davinci_pcm_dma_params {
20 char *name; /* stream identifier */
21 int channel; /* sync dma channel ID */ 20 int channel; /* sync dma channel ID */
22 unsigned short acnt; 21 unsigned short acnt;
23 dma_addr_t dma_addr; /* device physical address for DMA */ 22 dma_addr_t dma_addr; /* device physical address for DMA */
diff --git a/sound/soc/imx/mxc-ssi.c b/sound/soc/imx/mxc-ssi.c
index 3806ff2c0cd4..ccdefe60e752 100644
--- a/sound/soc/imx/mxc-ssi.c
+++ b/sound/soc/imx/mxc-ssi.c
@@ -397,14 +397,6 @@ static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai,
397 break; 397 break;
398 } 398 }
399 399
400 /* sync */
401 if (!(fmt & SND_SOC_DAIFMT_ASYNC))
402 scr |= SSI_SCR_SYN;
403
404 /* tdm - only for stereo atm */
405 if (fmt & SND_SOC_DAIFMT_TDM)
406 scr |= SSI_SCR_NET;
407
408 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) { 400 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
409 SSI1_STCR = stcr; 401 SSI1_STCR = stcr;
410 SSI1_SRCR = srcr; 402 SSI1_SRCR = srcr;
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig
index 6375b4ea525d..dcb3181bb340 100644
--- a/sound/soc/pxa/Kconfig
+++ b/sound/soc/pxa/Kconfig
@@ -138,7 +138,7 @@ config SND_PXA2XX_SOC_MIOA701
138 138
139config SND_PXA2XX_SOC_IMOTE2 139config SND_PXA2XX_SOC_IMOTE2
140 tristate "SoC Audio support for IMote 2" 140 tristate "SoC Audio support for IMote 2"
141 depends on SND_PXA2XX_SOC && MACH_INTELMOTE2 141 depends on SND_PXA2XX_SOC && MACH_INTELMOTE2 && I2C
142 select SND_PXA2XX_SOC_I2S 142 select SND_PXA2XX_SOC_I2S
143 select SND_SOC_WM8940 143 select SND_SOC_WM8940
144 help 144 help
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index f79711b9fa5b..8de6f9dec4a2 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -524,7 +524,7 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget)
524 524
525 /* connected jack or spk ? */ 525 /* connected jack or spk ? */
526 if (widget->id == snd_soc_dapm_hp || widget->id == snd_soc_dapm_spk || 526 if (widget->id == snd_soc_dapm_hp || widget->id == snd_soc_dapm_spk ||
527 widget->id == snd_soc_dapm_line) 527 (widget->id == snd_soc_dapm_line && !list_empty(&widget->sources)))
528 return 1; 528 return 1;
529 } 529 }
530 530
@@ -573,7 +573,8 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget)
573 return 1; 573 return 1;
574 574
575 /* connected jack ? */ 575 /* connected jack ? */
576 if (widget->id == snd_soc_dapm_mic || widget->id == snd_soc_dapm_line) 576 if (widget->id == snd_soc_dapm_mic ||
577 (widget->id == snd_soc_dapm_line && !list_empty(&widget->sinks)))
577 return 1; 578 return 1;
578 } 579 }
579 580
diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c
index ab5a3ac2ac47..9efcfd08d747 100644
--- a/sound/usb/usbmixer.c
+++ b/sound/usb/usbmixer.c
@@ -898,6 +898,11 @@ static struct snd_kcontrol_new usb_feature_unit_ctl = {
898 * build a feature control 898 * build a feature control
899 */ 899 */
900 900
901static size_t append_ctl_name(struct snd_kcontrol *kctl, const char *str)
902{
903 return strlcat(kctl->id.name, str, sizeof(kctl->id.name));
904}
905
901static void build_feature_ctl(struct mixer_build *state, unsigned char *desc, 906static void build_feature_ctl(struct mixer_build *state, unsigned char *desc,
902 unsigned int ctl_mask, int control, 907 unsigned int ctl_mask, int control,
903 struct usb_audio_term *iterm, int unitid) 908 struct usb_audio_term *iterm, int unitid)
@@ -978,13 +983,13 @@ static void build_feature_ctl(struct mixer_build *state, unsigned char *desc,
978 */ 983 */
979 if (! mapped_name && ! (state->oterm.type >> 16)) { 984 if (! mapped_name && ! (state->oterm.type >> 16)) {
980 if ((state->oterm.type & 0xff00) == 0x0100) { 985 if ((state->oterm.type & 0xff00) == 0x0100) {
981 len = strlcat(kctl->id.name, " Capture", sizeof(kctl->id.name)); 986 len = append_ctl_name(kctl, " Capture");
982 } else { 987 } else {
983 len = strlcat(kctl->id.name + len, " Playback", sizeof(kctl->id.name)); 988 len = append_ctl_name(kctl, " Playback");
984 } 989 }
985 } 990 }
986 strlcat(kctl->id.name + len, control == USB_FEATURE_MUTE ? " Switch" : " Volume", 991 append_ctl_name(kctl, control == USB_FEATURE_MUTE ?
987 sizeof(kctl->id.name)); 992 " Switch" : " Volume");
988 if (control == USB_FEATURE_VOLUME) { 993 if (control == USB_FEATURE_VOLUME) {
989 kctl->tlv.c = mixer_vol_tlv; 994 kctl->tlv.c = mixer_vol_tlv;
990 kctl->vd[0].access |= 995 kctl->vd[0].access |=
@@ -1143,7 +1148,7 @@ static void build_mixer_unit_ctl(struct mixer_build *state, unsigned char *desc,
1143 len = get_term_name(state, iterm, kctl->id.name, sizeof(kctl->id.name), 0); 1148 len = get_term_name(state, iterm, kctl->id.name, sizeof(kctl->id.name), 0);
1144 if (! len) 1149 if (! len)
1145 len = sprintf(kctl->id.name, "Mixer Source %d", in_ch + 1); 1150 len = sprintf(kctl->id.name, "Mixer Source %d", in_ch + 1);
1146 strlcat(kctl->id.name + len, " Volume", sizeof(kctl->id.name)); 1151 append_ctl_name(kctl, " Volume");
1147 1152
1148 snd_printdd(KERN_INFO "[%d] MU [%s] ch = %d, val = %d/%d\n", 1153 snd_printdd(KERN_INFO "[%d] MU [%s] ch = %d, val = %d/%d\n",
1149 cval->id, kctl->id.name, cval->channels, cval->min, cval->max); 1154 cval->id, kctl->id.name, cval->channels, cval->min, cval->max);
@@ -1400,8 +1405,8 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned
1400 if (! len) 1405 if (! len)
1401 strlcpy(kctl->id.name, name, sizeof(kctl->id.name)); 1406 strlcpy(kctl->id.name, name, sizeof(kctl->id.name));
1402 } 1407 }
1403 strlcat(kctl->id.name, " ", sizeof(kctl->id.name)); 1408 append_ctl_name(kctl, " ");
1404 strlcat(kctl->id.name, valinfo->suffix, sizeof(kctl->id.name)); 1409 append_ctl_name(kctl, valinfo->suffix);
1405 1410
1406 snd_printdd(KERN_INFO "[%d] PU [%s] ch = %d, val = %d/%d\n", 1411 snd_printdd(KERN_INFO "[%d] PU [%s] ch = %d, val = %d/%d\n",
1407 cval->id, kctl->id.name, cval->channels, cval->min, cval->max); 1412 cval->id, kctl->id.name, cval->channels, cval->min, cval->max);
@@ -1610,9 +1615,9 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsi
1610 strlcpy(kctl->id.name, "USB", sizeof(kctl->id.name)); 1615 strlcpy(kctl->id.name, "USB", sizeof(kctl->id.name));
1611 1616
1612 if ((state->oterm.type & 0xff00) == 0x0100) 1617 if ((state->oterm.type & 0xff00) == 0x0100)
1613 strlcat(kctl->id.name, " Capture Source", sizeof(kctl->id.name)); 1618 append_ctl_name(kctl, " Capture Source");
1614 else 1619 else
1615 strlcat(kctl->id.name, " Playback Source", sizeof(kctl->id.name)); 1620 append_ctl_name(kctl, " Playback Source");
1616 } 1621 }
1617 1622
1618 snd_printdd(KERN_INFO "[%d] SU [%s] items = %d\n", 1623 snd_printdd(KERN_INFO "[%d] SU [%s] items = %d\n",
diff --git a/tools/perf/Documentation/perf-timechart.txt b/tools/perf/Documentation/perf-timechart.txt
index 1c2ed3090cce..a7910099d6fd 100644
--- a/tools/perf/Documentation/perf-timechart.txt
+++ b/tools/perf/Documentation/perf-timechart.txt
@@ -31,6 +31,9 @@ OPTIONS
31-w:: 31-w::
32--width=:: 32--width=::
33 Select the width of the SVG file (default: 1000) 33 Select the width of the SVG file (default: 1000)
34-p::
35--power-only::
36 Only output the CPU power section of the diagram
34 37
35 38
36SEE ALSO 39SEE ALSO
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index b5f1953b6144..742a32eee8fc 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -157,11 +157,18 @@ uname_R := $(shell sh -c 'uname -r 2>/dev/null || echo not')
157uname_P := $(shell sh -c 'uname -p 2>/dev/null || echo not') 157uname_P := $(shell sh -c 'uname -p 2>/dev/null || echo not')
158uname_V := $(shell sh -c 'uname -v 2>/dev/null || echo not') 158uname_V := $(shell sh -c 'uname -v 2>/dev/null || echo not')
159 159
160# If we're on a 64-bit kernel, use -m64 160#
161ifndef NO_64BIT 161# Add -m32 for cross-builds:
162 ifneq ($(patsubst %64,%,$(uname_M)),$(uname_M)) 162#
163 M64 := -m64 163ifdef NO_64BIT
164 endif 164 MBITS := -m32
165else
166 #
167 # If we're on a 64-bit kernel, use -m64:
168 #
169 ifneq ($(patsubst %64,%,$(uname_M)),$(uname_M))
170 MBITS := -m64
171 endif
165endif 172endif
166 173
167# CFLAGS and LDFLAGS are for the users to override from the command line. 174# CFLAGS and LDFLAGS are for the users to override from the command line.
@@ -194,7 +201,7 @@ EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wold-style-definition
194EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wstrict-prototypes 201EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wstrict-prototypes
195EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wdeclaration-after-statement 202EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wdeclaration-after-statement
196 203
197CFLAGS = $(M64) -ggdb3 -Wall -Wextra -std=gnu99 -Werror -O6 -fstack-protector-all -D_FORTIFY_SOURCE=2 $(EXTRA_WARNINGS) 204CFLAGS = $(MBITS) -ggdb3 -Wall -Wextra -std=gnu99 -Werror -O6 -fstack-protector-all -D_FORTIFY_SOURCE=2 $(EXTRA_WARNINGS)
198LDFLAGS = -lpthread -lrt -lelf -lm 205LDFLAGS = -lpthread -lrt -lelf -lm
199ALL_CFLAGS = $(CFLAGS) 206ALL_CFLAGS = $(CFLAGS)
200ALL_LDFLAGS = $(LDFLAGS) 207ALL_LDFLAGS = $(LDFLAGS)
@@ -416,7 +423,7 @@ ifeq ($(uname_S),Darwin)
416endif 423endif
417 424
418ifneq ($(shell sh -c "(echo '\#include <libelf.h>'; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ_MMAP, 0); return (long)elf; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o /dev/null $(ALL_LDFLAGS) > /dev/null 2>&1 && echo y"), y) 425ifneq ($(shell sh -c "(echo '\#include <libelf.h>'; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ_MMAP, 0); return (long)elf; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o /dev/null $(ALL_LDFLAGS) > /dev/null 2>&1 && echo y"), y)
419 msg := $(error No libelf.h/libelf found, please install libelf-dev/elfutils-libelf-devel); 426 msg := $(error No libelf.h/libelf found, please install libelf-dev/elfutils-libelf-devel and glibc-dev[el]);
420endif 427endif
421 428
422ifdef NO_DEMANGLE 429ifdef NO_DEMANGLE
@@ -728,7 +735,7 @@ $(BUILT_INS): perf$X
728common-cmds.h: util/generate-cmdlist.sh command-list.txt 735common-cmds.h: util/generate-cmdlist.sh command-list.txt
729 736
730common-cmds.h: $(wildcard Documentation/perf-*.txt) 737common-cmds.h: $(wildcard Documentation/perf-*.txt)
731 $(QUIET_GEN)util/generate-cmdlist.sh > $@+ && mv $@+ $@ 738 $(QUIET_GEN). util/generate-cmdlist.sh > $@+ && mv $@+ $@
732 739
733$(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh 740$(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh
734 $(QUIET_GEN)$(RM) $@ $@+ && \ 741 $(QUIET_GEN)$(RM) $@ $@+ && \
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index a5a050af8e7d..3eeef339c787 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -41,6 +41,7 @@ static int raw_samples = 0;
41static int system_wide = 0; 41static int system_wide = 0;
42static int profile_cpu = -1; 42static int profile_cpu = -1;
43static pid_t target_pid = -1; 43static pid_t target_pid = -1;
44static pid_t child_pid = -1;
44static int inherit = 1; 45static int inherit = 1;
45static int force = 0; 46static int force = 0;
46static int append_file = 0; 47static int append_file = 0;
@@ -184,6 +185,9 @@ static void sig_handler(int sig)
184 185
185static void sig_atexit(void) 186static void sig_atexit(void)
186{ 187{
188 if (child_pid != -1)
189 kill(child_pid, SIGTERM);
190
187 if (signr == -1) 191 if (signr == -1)
188 return; 192 return;
189 193
@@ -610,6 +614,8 @@ static int __cmd_record(int argc, const char **argv)
610 exit(-1); 614 exit(-1);
611 } 615 }
612 } 616 }
617
618 child_pid = pid;
613 } 619 }
614 620
615 if (realtime_prio) { 621 if (realtime_prio) {
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index ea9c15c0cdfe..ce2d5be4f30e 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -1287,7 +1287,7 @@ static struct sort_dimension *available_sorts[] = {
1287 1287
1288static LIST_HEAD(sort_list); 1288static LIST_HEAD(sort_list);
1289 1289
1290static int sort_dimension__add(char *tok, struct list_head *list) 1290static int sort_dimension__add(const char *tok, struct list_head *list)
1291{ 1291{
1292 int i; 1292 int i;
1293 1293
@@ -1917,7 +1917,7 @@ static void setup_sorting(void)
1917 1917
1918 free(str); 1918 free(str);
1919 1919
1920 sort_dimension__add((char *)"pid", &cmp_pid); 1920 sort_dimension__add("pid", &cmp_pid);
1921} 1921}
1922 1922
1923static const char *record_args[] = { 1923static const char *record_args[] = {
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index e5f6ece65a13..3db31e7bf173 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -69,7 +69,8 @@ static int run_idx = 0;
69static int run_count = 1; 69static int run_count = 1;
70static int inherit = 1; 70static int inherit = 1;
71static int scale = 1; 71static int scale = 1;
72static int target_pid = -1; 72static pid_t target_pid = -1;
73static pid_t child_pid = -1;
73static int null_run = 0; 74static int null_run = 0;
74 75
75static int fd[MAX_NR_CPUS][MAX_COUNTERS]; 76static int fd[MAX_NR_CPUS][MAX_COUNTERS];
@@ -285,6 +286,8 @@ static int run_perf_stat(int argc __used, const char **argv)
285 exit(-1); 286 exit(-1);
286 } 287 }
287 288
289 child_pid = pid;
290
288 /* 291 /*
289 * Wait for the child to be ready to exec. 292 * Wait for the child to be ready to exec.
290 */ 293 */
@@ -433,6 +436,9 @@ static void skip_signal(int signo)
433 436
434static void sig_atexit(void) 437static void sig_atexit(void)
435{ 438{
439 if (child_pid != -1)
440 kill(child_pid, SIGTERM);
441
436 if (signr == -1) 442 if (signr == -1)
437 return; 443 return;
438 444
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c
index 4405681b3134..702d8fe58fbc 100644
--- a/tools/perf/builtin-timechart.c
+++ b/tools/perf/builtin-timechart.c
@@ -46,6 +46,8 @@ static u64 turbo_frequency;
46 46
47static u64 first_time, last_time; 47static u64 first_time, last_time;
48 48
49static int power_only;
50
49 51
50static struct perf_header *header; 52static struct perf_header *header;
51 53
@@ -547,7 +549,7 @@ static void end_sample_processing(void)
547 u64 cpu; 549 u64 cpu;
548 struct power_event *pwr; 550 struct power_event *pwr;
549 551
550 for (cpu = 0; cpu < numcpus; cpu++) { 552 for (cpu = 0; cpu <= numcpus; cpu++) {
551 pwr = malloc(sizeof(struct power_event)); 553 pwr = malloc(sizeof(struct power_event));
552 if (!pwr) 554 if (!pwr)
553 return; 555 return;
@@ -871,7 +873,7 @@ static int determine_display_tasks(u64 threshold)
871 /* no exit marker, task kept running to the end */ 873 /* no exit marker, task kept running to the end */
872 if (p->end_time == 0) 874 if (p->end_time == 0)
873 p->end_time = last_time; 875 p->end_time = last_time;
874 if (p->total_time >= threshold) 876 if (p->total_time >= threshold && !power_only)
875 p->display = 1; 877 p->display = 1;
876 878
877 c = p->all; 879 c = p->all;
@@ -882,7 +884,7 @@ static int determine_display_tasks(u64 threshold)
882 if (c->start_time == 1) 884 if (c->start_time == 1)
883 c->start_time = first_time; 885 c->start_time = first_time;
884 886
885 if (c->total_time >= threshold) { 887 if (c->total_time >= threshold && !power_only) {
886 c->display = 1; 888 c->display = 1;
887 count++; 889 count++;
888 } 890 }
@@ -1134,6 +1136,8 @@ static const struct option options[] = {
1134 "output file name"), 1136 "output file name"),
1135 OPT_INTEGER('w', "width", &svg_page_width, 1137 OPT_INTEGER('w', "width", &svg_page_width,
1136 "page width"), 1138 "page width"),
1139 OPT_BOOLEAN('p', "power-only", &power_only,
1140 "output power data only"),
1137 OPT_END() 1141 OPT_END()
1138}; 1142};
1139 1143
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 1ca88896eee4..37512e936235 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -782,6 +782,7 @@ static const char *skip_symbols[] = {
782 "exit_idle", 782 "exit_idle",
783 "mwait_idle", 783 "mwait_idle",
784 "mwait_idle_with_hints", 784 "mwait_idle_with_hints",
785 "poll_idle",
785 "ppc64_runlatch_off", 786 "ppc64_runlatch_off",
786 "pseries_dedicated_idle_sleep", 787 "pseries_dedicated_idle_sleep",
787 NULL 788 NULL
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index e9d256e2f47d..0c5e4f72f2ba 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -219,10 +219,6 @@ remap:
219more: 219more:
220 event = (event_t *)(buf + head); 220 event = (event_t *)(buf + head);
221 221
222 size = event->header.size;
223 if (!size)
224 size = 8;
225
226 if (head + event->header.size >= page_size * mmap_window) { 222 if (head + event->header.size >= page_size * mmap_window) {
227 unsigned long shift = page_size * (head / page_size); 223 unsigned long shift = page_size * (head / page_size);
228 int res; 224 int res;
@@ -237,7 +233,6 @@ more:
237 233
238 size = event->header.size; 234 size = event->header.size;
239 235
240
241 if (!size || process_event(event, offset, head) < 0) { 236 if (!size || process_event(event, offset, head) < 0) {
242 237
243 /* 238 /*
@@ -290,7 +285,6 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used)
290 usage_with_options(annotate_usage, options); 285 usage_with_options(annotate_usage, options);
291 } 286 }
292 287
293
294 setup_pager(); 288 setup_pager();
295 289
296 return __cmd_trace(); 290 return __cmd_trace();
diff --git a/tools/perf/design.txt b/tools/perf/design.txt
index f1946d107b10..fdd42a824c98 100644
--- a/tools/perf/design.txt
+++ b/tools/perf/design.txt
@@ -455,3 +455,6 @@ will need at least this:
455 455
456If your architecture does have hardware capabilities, you can override the 456If your architecture does have hardware capabilities, you can override the
457weak stub hw_perf_event_init() to register hardware counters. 457weak stub hw_perf_event_init() to register hardware counters.
458
459Architectures that have d-cache aliassing issues, such as Sparc and ARM,
460should select PERF_USE_VMALLOC in order to avoid these for perf mmap().
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 87c424de79ee..8cfb48cbbea0 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -691,7 +691,10 @@ static void store_event_type(const char *orgname)
691 FILE *file; 691 FILE *file;
692 int id; 692 int id;
693 693
694 sprintf(filename, "/sys/kernel/debug/tracing/events/%s/id", orgname); 694 sprintf(filename, "%s/", debugfs_path);
695 strncat(filename, orgname, strlen(orgname));
696 strcat(filename, "/id");
697
695 c = strchr(filename, ':'); 698 c = strchr(filename, ':');
696 if (c) 699 if (c)
697 *c = '/'; 700 *c = '/';
diff --git a/tools/perf/util/svghelper.c b/tools/perf/util/svghelper.c
index a778fd0f4ae4..856655d8b0b8 100644
--- a/tools/perf/util/svghelper.c
+++ b/tools/perf/util/svghelper.c
@@ -28,7 +28,7 @@ static u64 turbo_frequency, max_freq;
28 28
29int svg_page_width = 1000; 29int svg_page_width = 1000;
30 30
31#define MIN_TEXT_SIZE 0.001 31#define MIN_TEXT_SIZE 0.01
32 32
33static u64 total_height; 33static u64 total_height;
34static FILE *svgfile; 34static FILE *svgfile;
@@ -217,6 +217,18 @@ static char *cpu_model(void)
217 } 217 }
218 fclose(file); 218 fclose(file);
219 } 219 }
220
221 /* CPU type */
222 file = fopen("/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies", "r");
223 if (file) {
224 while (fgets(buf, 255, file)) {
225 unsigned int freq;
226 freq = strtoull(buf, NULL, 10);
227 if (freq > max_freq)
228 max_freq = freq;
229 }
230 fclose(file);
231 }
220 return cpu_m; 232 return cpu_m;
221} 233}
222 234
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 559fb06210f5..47ea0609a760 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -324,8 +324,7 @@ static inline int elf_sym__is_function(const GElf_Sym *sym)
324{ 324{
325 return elf_sym__type(sym) == STT_FUNC && 325 return elf_sym__type(sym) == STT_FUNC &&
326 sym->st_name != 0 && 326 sym->st_name != 0 &&
327 sym->st_shndx != SHN_UNDEF && 327 sym->st_shndx != SHN_UNDEF;
328 sym->st_size != 0;
329} 328}
330 329
331static inline int elf_sym__is_label(const GElf_Sym *sym) 330static inline int elf_sym__is_label(const GElf_Sym *sym)
diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c
index f6a8437141c8..55c9659a56e2 100644
--- a/tools/perf/util/trace-event-parse.c
+++ b/tools/perf/util/trace-event-parse.c
@@ -618,7 +618,7 @@ static int test_type(enum event_type type, enum event_type expect)
618} 618}
619 619
620static int test_type_token(enum event_type type, char *token, 620static int test_type_token(enum event_type type, char *token,
621 enum event_type expect, char *expect_tok) 621 enum event_type expect, const char *expect_tok)
622{ 622{
623 if (type != expect) { 623 if (type != expect) {
624 die("Error: expected type %d but read %d", 624 die("Error: expected type %d but read %d",
@@ -650,7 +650,7 @@ static int read_expect_type(enum event_type expect, char **tok)
650 return __read_expect_type(expect, tok, 1); 650 return __read_expect_type(expect, tok, 1);
651} 651}
652 652
653static int __read_expected(enum event_type expect, char *str, int newline_ok) 653static int __read_expected(enum event_type expect, const char *str, int newline_ok)
654{ 654{
655 enum event_type type; 655 enum event_type type;
656 char *token; 656 char *token;
@@ -668,12 +668,12 @@ static int __read_expected(enum event_type expect, char *str, int newline_ok)
668 return 0; 668 return 0;
669} 669}
670 670
671static int read_expected(enum event_type expect, char *str) 671static int read_expected(enum event_type expect, const char *str)
672{ 672{
673 return __read_expected(expect, str, 1); 673 return __read_expected(expect, str, 1);
674} 674}
675 675
676static int read_expected_item(enum event_type expect, char *str) 676static int read_expected_item(enum event_type expect, const char *str)
677{ 677{
678 return __read_expected(expect, str, 0); 678 return __read_expected(expect, str, 0);
679} 679}
@@ -1968,10 +1968,11 @@ static const struct flag flags[] = {
1968 { "NET_TX_SOFTIRQ", 2 }, 1968 { "NET_TX_SOFTIRQ", 2 },
1969 { "NET_RX_SOFTIRQ", 3 }, 1969 { "NET_RX_SOFTIRQ", 3 },
1970 { "BLOCK_SOFTIRQ", 4 }, 1970 { "BLOCK_SOFTIRQ", 4 },
1971 { "TASKLET_SOFTIRQ", 5 }, 1971 { "BLOCK_IOPOLL_SOFTIRQ", 5 },
1972 { "SCHED_SOFTIRQ", 6 }, 1972 { "TASKLET_SOFTIRQ", 6 },
1973 { "HRTIMER_SOFTIRQ", 7 }, 1973 { "SCHED_SOFTIRQ", 7 },
1974 { "RCU_SOFTIRQ", 8 }, 1974 { "HRTIMER_SOFTIRQ", 8 },
1975 { "RCU_SOFTIRQ", 9 },
1975 1976
1976 { "HRTIMER_NORESTART", 0 }, 1977 { "HRTIMER_NORESTART", 0 },
1977 { "HRTIMER_RESTART", 1 }, 1978 { "HRTIMER_RESTART", 1 },
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index b5e7e3f1183f..b7c78a403dc2 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -850,6 +850,19 @@ static void kvm_mmu_notifier_invalidate_page(struct mmu_notifier *mn,
850 850
851} 851}
852 852
853static void kvm_mmu_notifier_change_pte(struct mmu_notifier *mn,
854 struct mm_struct *mm,
855 unsigned long address,
856 pte_t pte)
857{
858 struct kvm *kvm = mmu_notifier_to_kvm(mn);
859
860 spin_lock(&kvm->mmu_lock);
861 kvm->mmu_notifier_seq++;
862 kvm_set_spte_hva(kvm, address, pte);
863 spin_unlock(&kvm->mmu_lock);
864}
865
853static void kvm_mmu_notifier_invalidate_range_start(struct mmu_notifier *mn, 866static void kvm_mmu_notifier_invalidate_range_start(struct mmu_notifier *mn,
854 struct mm_struct *mm, 867 struct mm_struct *mm,
855 unsigned long start, 868 unsigned long start,
@@ -929,6 +942,7 @@ static const struct mmu_notifier_ops kvm_mmu_notifier_ops = {
929 .invalidate_range_start = kvm_mmu_notifier_invalidate_range_start, 942 .invalidate_range_start = kvm_mmu_notifier_invalidate_range_start,
930 .invalidate_range_end = kvm_mmu_notifier_invalidate_range_end, 943 .invalidate_range_end = kvm_mmu_notifier_invalidate_range_end,
931 .clear_flush_young = kvm_mmu_notifier_clear_flush_young, 944 .clear_flush_young = kvm_mmu_notifier_clear_flush_young,
945 .change_pte = kvm_mmu_notifier_change_pte,
932 .release = kvm_mmu_notifier_release, 946 .release = kvm_mmu_notifier_release,
933}; 947};
934#endif /* CONFIG_MMU_NOTIFIER && KVM_ARCH_WANT_MMU_NOTIFIER */ 948#endif /* CONFIG_MMU_NOTIFIER && KVM_ARCH_WANT_MMU_NOTIFIER */
@@ -2625,7 +2639,7 @@ static int vcpu_stat_get(void *_offset, u64 *val)
2625 2639
2626DEFINE_SIMPLE_ATTRIBUTE(vcpu_stat_fops, vcpu_stat_get, NULL, "%llu\n"); 2640DEFINE_SIMPLE_ATTRIBUTE(vcpu_stat_fops, vcpu_stat_get, NULL, "%llu\n");
2627 2641
2628static struct file_operations *stat_fops[] = { 2642static const struct file_operations *stat_fops[] = {
2629 [KVM_STAT_VCPU] = &vcpu_stat_fops, 2643 [KVM_STAT_VCPU] = &vcpu_stat_fops,
2630 [KVM_STAT_VM] = &vm_stat_fops, 2644 [KVM_STAT_VM] = &vm_stat_fops,
2631}; 2645};